Hi,
sorry if I made you going crazy. ;)
My comment aimed to discuss the selection of the correct redirect address. See my further comments below(;)). I fear forcing requests to the right address is a bit more complex than it looked at the first approach.
Am 06.06.2021 um 19:35 schrieb Matthias Fischer:
Hi,
On 06.06.2021 10:59, Bernhard Bitsch wrote:
Hi,
thanks for implementing this idea.
I tried my best, but when reading further I realized that I've missed something... See below.
[Sorry for the noise, but I thought it would be the best to keep this unshortened.]
Am 04.06.2021 um 14:17 schrieb Matthias Fischer: There was not much feedback on the list, so I send this now. This is V4 - open for discussion, opinions or (perhaps ;-) ) changes:
Originally triggered by: https://community.ipfire.org/t/forcing-all-dns-traffic-from-the-lan-to-the-f...
Discussion: https://community.ipfire.org/t/testing-dns-redirect-code-snippet/3888
Could fix(?): https://bugzilla.ipfire.org/show_bug.cgi?id=11168
Changelog since V3:
Replaced 'green0'/'blue0' with '${GREEN_DEV}' / '${BLUE_DEV}' - these values are read from '/var/ipfire/ethernet/settings', thanks to "someone" for the hint (sorry, I didn't find the author)! ;-)
Replaced port numbers '123' / '53' with service names 'domain' / 'ntp' (dto.).
As mentioned on the list (05.03.2021, BB), 'well-behaving' requests are now handled through RETURN rules, others through REDIRECT.
Background (cited from BB, 06.03.2021): "Concerning performance, we want to minimize the rule set to the amount really necessary. On the other hand, it may be quicker to do just a RETURN than a REDIRECT. The cases for the RETURN (DNS requests direct to IPFire) should be nearly 100%. DNS and NTP servers are published by DHCP or should be configured in the static case."
Sorry, I did not realize that this 'well-behaving' must be defined more exactly. See beyond.
Yep. No problem. Now I know what you meant. And again, "see beyond"... ;-)
Further comments follow below ;-)
I made it that way. Statistics during the last 62 days show that this worked as intended. IMHO. I've sent a screenshot to the list (the other day) so everyone could take a look.
That's my experience with the rules located in firewall.local, too.
Removed GUI links to DNS and NTP options in 'optionsfw.cgi'.
Moved creation of the iptable rules in '/etc/init.d/firewall' behind
'# WIRELESS chains'
Summary and functionality: These patches are controlled through "Firewall Options". They add new firewall-[DNS/NTP]_FORCED_ON_[INTERFACE]-options to '/var/ipfire/optionsfw/settings'. They activate/deactivate appropriate RETURN and REDIRECT rules through a new ctrl file ('/usr/local/bin/dnsntpctrl') and a new init file ('/etc/rc.d/init.d/dnsntp').
Default of all new rules is OFF (set in 'lfs/configroot'). If set to ON, they REDIRECT all DNS and NTP requests (TCP/UDP) to the DNS and NTP servers specified in IPFire. Flaw/ToDo: To make things work as I wanted I had to add a 'dnsntpctrl' file which calls the actual init file, 'dnsntp'. As I see it, this is actually an unnecessary detour. In fact I wanted to merge these two files in *one* C file, but this was beyond my capabilities, perhaps "someone" else knows how to program this.
Changed visibility (GUI, 'optionsfw.cgi') and some cosmetics: The corresponding interface options - including 'Masquerade ...' - are only visible if the respective interface actually exists. E.g.: if BLUE interface doesn't exist, there are no ON/OFF switches for 'DNS/NTP on BLUE' or logging options for BLUE available. Added text colors for better readability. Separated logging options per interface.
No reboot required: Rules can be switched ON/OFF without rebooting IPFire. Changes immedediately take effect after clicking 'Save'.
Changes to '/etc/rc.d/init.d/firewall' and '/etc/rc.d/init.d/dnsntpctrl': Fixed a 'trafic' typo. To avoid collisions with existing CUSTOM rules, I added a new PREROUTING chain: 'DNS_NTP_REDIRECT'. This chain is flushed by 'dnsntpctrl' prior applying the choosen settings.
[cutting off parts of the main patch for discussion]
diff --git a/src/initscripts/system/dnsntp b/src/initscripts/system/dnsntp new file mode 100644 index 000000000..54fdfc685 --- /dev/null +++ b/src/initscripts/system/dnsntp @@ -0,0 +1,43 @@ +#!/bin/sh +######################################################################## +# Begin $rc_base/init.d/dnsntp +# +# Description : dnsntp init script for DNS/NTP rules only +# +########################################################################
+# flush chain +iptables -t nat -F DNS_NTP_REDIRECT
+eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings) +eval $(/usr/local/bin/readhash /var/ipfire/optionsfw/settings)
The 'well-behaving' request destinations should be DNS1_GREEN, DNS2_GREEN, DNS1_BLUE, DNS2_BLUE ( stored in /var/ipfire/dhcp/settings and set in the dhcp.cgi ). If they are defined and distrubited by DHCP or set by other mechanism.
Ok, here we are. Ups! "DNS1_..." and "DNS2_..." entries. What/where are these? You've got me!
I think we have two kinds of DNS/NTP servers to be forced. - IPFire includes these servers, which should be used. - The DHCP server can ( should? ) distribute these addresses. The WUI allows on the other hand the specification of some other addresses, which should be located in the local networks. That is my interpretation of these fields.
But now I'm a bit puzzled. Perhaps I need some hints again.
Because until now I completely ignored DNS1_GREEN, DNS2_... etc. from DHCP. They existed in my installation(s) - but DHCP didn't play a role in my considerations. Never. I always used the local IPFire addresses (GREEN/BLUE). Nothing else. The addresses for "GREEN_ADDRESS" (Ethernet settings), "DNS1_GREEN" and "NTP1_GREEN" (dhcp settings) were always the same. Of course, this also applied to BLUE.
That's also my config. Therefore I didn't think about this before. ;)
BTW, what would be the sense of distributing different DNS1/DNS2 entries through DHCP vs. the DOT entries under "domain name system" (e.g.)?
DOT under 'domain name system' is a definition for the sources of name information of unbound.
What I don't understand - call it "I'm thick at the moment...": Through the current GUIs it would be possible to choose and distribute (e.g.) 8.8.8.8 as "DNS1" or "DNS2" through DHCP, while the "Domain Name System" page contains totally different (or ISP servers). Are there any circumstances where this would be useful or needed? And which could these be?
I don't think it is useful/legal to define DNS servers outside the local networks. Defining DNS servers in DHCP other than IPFire makes only sense when these use IPFire.
Is GREEN_ADDRESS / BLUE_ADDRESS the desired destination otherwise?
Yes. That was my only intention in the first place. I wanted to keep it simple. I wanted to make sure that my clients only use the specific *local* DNS servers running on GREEN / BLUE. And I didn't realize the possibility to enter completely different servers (through DHCP). That's why I ignored DHCP and chose the GREEN and BLUE interface (ethernet) addresses. I never thought of writing other addresses than the local IPFire GREEN/BLUE addresses in the first required DHCP fields for GREEN / BLUE. My fault(?). Hm.
This was my first thought also.
Regarding 'forcing dns': You can of course always turn these OFF if they don't correspond with your wanted installation and use other DNS1 / DNS2 entries. ;-)
Last question(s): If I got you right it would make more sense or be better to change the RETURN rules to use the DHCP values from "$DNS1/2_GREEN/BLUE"!?
And what would be the best way to integrate *both* possible DNS entries in the initscript? Regarding DoT, are these two really needed anymore? At the moment, I'm using nine through DoT...
First needed change in 'dnsntpctrl' => evaluate DHCP settings. Add: ... eval $(/usr/local/bin/readhash /var/ipfire/dhcp/settings) ...
New: iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -d ${DNS1_GREEN} -p udp -m udp --dport domain -j RETURN
And then?
I must think this over...its been a long week... ;-)
Regards, Matthias
I must think this over, also. Especially about DNS traffic. If I define a configuration with a dedicated DNS server A in my GREEN net, which itself questions the IPFire DNS server, and informing all 'normal' clients in GREEN to use A via DHCP, are these DNS request received by IPFire? If this isn't possible by design, our first simple implementation of 'forcing' ( redirecting to GREEN_ADDRESS/BLUE_ADDESS ) is right.
Could someone other look at this?
Regard, Bernhard
[ rest of patch ]
+# Force DNS REDIRECTs on GREEN (udp, tcp, 53) +if [ "$DNS_FORCE_ON_GREEN" == "on" ]; then
- iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -d ${GREEN_ADDRESS} -p udp -m udp --dport domain -j RETURN
- iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -p udp -m udp --dport domain -j REDIRECT
- iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -d ${GREEN_ADDRESS} -p tcp -m tcp --dport domain -j RETURN
- iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -p tcp -m tcp --dport domain -j REDIRECT
+fi
+# Force DNS REDIRECTs on BLUE (udp, tcp, 53) +if [ "$DNS_FORCE_ON_BLUE" == "on" ]; then
- iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -d ${BLUE_ADDRESS} -p udp -m udp --dport domain -j RETURN
- iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -p udp -m udp --dport domain -j REDIRECT
- iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -d ${BLUE_ADDRESS} -p tcp -m tcp --dport domain -j RETURN
- iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -p tcp -m tcp --dport domain -j REDIRECT
+fi
See above.
Regards, Bernhard
+# Force NTP REDIRECTs on GREEN (udp, 123) +if [ "$NTP_FORCE_ON_GREEN" == "on" ]; then
- iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -d ${GREEN_ADDRESS} -p udp -m udp --dport ntp -j RETURN
- iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -p udp -m udp --dport ntp -j REDIRECT
+fi
+# Force DNS REDIRECTs on BLUE (udp, 123) +if [ "$NTP_FORCE_ON_BLUE" == "on" ]; then
- iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -d ${BLUE_ADDRESS} -p udp -m udp --dport ntp -j RETURN
- iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -p udp -m udp --dport ntp -j REDIRECT
+fi
+# End $rc_base/init.d/dnsntp diff --git a/src/initscripts/system/firewall b/src/initscripts/system/firewall index 1e558ee86..047946a86 100644 --- a/src/initscripts/system/firewall +++ b/src/initscripts/system/firewall @@ -218,7 +218,7 @@ iptables_init() { iptables -A INPUT -j LOCATIONBLOCK iptables -A FORWARD -j LOCATIONBLOCK
- # trafic from ipsecX/TUN/TAP interfaces, before "-i GREEN_DEV" accept everything
- # traffic from ipsecX/TUN/TAP interfaces, before "-i GREEN_DEV" accept everything iptables -N IPSECINPUT iptables -N IPSECFORWARD iptables -N IPSECOUTPUT
@@ -242,6 +242,10 @@ iptables_init() { iptables -N WIRELESSFORWARD iptables -A FORWARD -m conntrack --ctstate NEW -j WIRELESSFORWARD
- # Redirecting DNS and NTP requests
- iptables -t nat -N DNS_NTP_REDIRECT
- iptables -t nat -A PREROUTING -j DNS_NTP_REDIRECT
- # OpenVPN iptables -N OVPNINPUT iptables -A INPUT -j OVPNINPUT
@@ -320,6 +324,9 @@ iptables_init() { # run captivectrl /usr/local/bin/captivectrl
- # run dnsntpctrl
- /usr/local/bin/dnsntpctrl
- # POLICY CHAIN iptables -N POLICYIN iptables -A INPUT -j POLICYIN
diff --git a/src/misc-progs/Makefile b/src/misc-progs/Makefile index 7c3ef7529..229d122d6 100644 --- a/src/misc-progs/Makefile +++ b/src/misc-progs/Makefile @@ -30,7 +30,7 @@ SUID_PROGS = squidctrl sshctrl ipfirereboot \ wirelessctrl getipstat qosctrl \ redctrl syslogdctrl extrahdctrl sambactrl \ smartctrl clamavctrl addonctrl pakfire mpfirectrl wlanapctrl \
- setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes \
- setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes dnsntpctrl \ getconntracktable wirelessclient torctrl ddnsctrl unboundctrl \ captivectrl
diff --git a/src/misc-progs/dnsntpctrl.c b/src/misc-progs/dnsntpctrl.c new file mode 100644 index 000000000..f2a3b89e3 --- /dev/null +++ b/src/misc-progs/dnsntpctrl.c @@ -0,0 +1,19 @@ +/* This file is part of the IPFire Firewall.
- This program is distributed under the terms of the GNU General Public
- Licence. See the file COPYING for details.
- */
+#include <stdlib.h> +#include "setuid.h"
+int main(void) +{
- if (!(initsetuid()))
exit(1);
- safe_system("/etc/rc.d/init.d/dnsntp >/dev/null 2>&1");
- return 0;
+}