From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matthias Fischer To: development@lists.ipfire.org Subject: [PATCH 1/2] optionsfw.cgi: Forcing DNS and NTP requests to use only local servers on GREEN/BLUE Date: Sun, 27 Dec 2020 13:30:19 +0100 Message-ID: <20201227123020.4556-1-matthias.fischer@ipfire.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6325502275546387456==" List-Id: --===============6325502275546387456== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Originally triggered by: https://community.ipfire.org/t/forcing-all-dns-traffic-from-the-lan-to-the-fi= rewall/3512 Current discussion: https://community.ipfire.org/t/testing-dns-redirect-code-snippet/3888 Screenshots: =3D> https://community.ipfire.org/t/testing-dns-redirect-code-snippet/3888/= 38 Summary and functionality: These new firewall-options add [DNS/NTP]_FORCED_ON_[INTERFACE] options to '/var/ipfire/optionsfw/settings'. They activate/deactivate appropriate REDIRECT rules in '/etc/rc.d/init.d/firewall'. Default of the new rules is OFF. If set to ON, they try to REDIRECT all DNS and NTP requests (TCP/UDP) to th= e DNS and NTP servers specified in IPFire. Changed visibility (GUI): The corresponding interface options are only visible if the respective inte= rface does actually exist. If BLUE interface doesn't exist, there are no ON/OFF switch= es for 'DNS/NTP on BLUE' or BLUE logging options available. No reboot required: Rules can be switched ON/OFF without rebooting IPFire by choosing a new 'Sa= ve And Restart'-button. Restarting is done with the help of a new binary: 'optionsfwctrl', which ca= n also be used in a console session to restart/reload all firewall rules. For 'optionsfwctrl.= c', see other patch #2. I used 'unboundctrl.c' as template. Changes to '/etc/rc.d/init.d/firewall': I used REDIRECT rules and placed them just behind the CAPTIVE_PORTAL_CHAIN,= as Michael mentioned on the list. All rules are tested for former existence to avoid setting multiple REDIREC= TS. I used code like 'if ! iptables -t nat -C...' or 'if iptables -t nat -C...'= ("Check for the existence of a rule") for these queries. Testing was ok - if just *one* rule is manually deleted, only the *missing*= rule will be created through the next 'Save And Restart' - I found no duplicates. ON/OFF switche= s worked as expected. Testing with DNSSEC was also successful. Other changes: Language strings, 'lfs/configroot' and 'update.sh' for Core update were alt= ered accordingly. Signed-off-by: Matthias Fischer --- config/rootfiles/core/154/update.sh | 10 +++ html/cgi-bin/optionsfw.cgi | 101 ++++++++++++++++++++++++---- langs/de/cgi-bin/de.pl | 6 ++ langs/en/cgi-bin/en.pl | 6 ++ lfs/configroot | 4 ++ src/initscripts/system/firewall | 71 +++++++++++++++++++ 6 files changed, 184 insertions(+), 14 deletions(-) diff --git a/config/rootfiles/core/154/update.sh b/config/rootfiles/core/154/= update.sh index 37348e0df..62bee565c 100644 --- a/config/rootfiles/core/154/update.sh +++ b/config/rootfiles/core/154/update.sh @@ -31,6 +31,16 @@ for (( i=3D1; i<=3D$core; i++ )); do rm -f /var/cache/pakfire/core-upgrade-*-$i.ipfire done =20 +# Add default lines for new firewall options +optionsfw_file=3D"/var/ipfire/optionsfw/settings" + + echo "FORCE_DNS_ON_GREEN=3Doff" >> ${optionsfw_file} + echo "FORCE_DNS_ON_BLUE=3Doff" >> ${optionsfw_file} + echo "FORCE_NTP_ON_GREEN=3Doff" >> ${optionsfw_file} + echo "FORCE_NTP_ON_BLUE=3Doff" >> ${optionsfw_file} + +unset optionsfw_file + # Remove files =20 # Stop services diff --git a/html/cgi-bin/optionsfw.cgi b/html/cgi-bin/optionsfw.cgi index 47aba59cb..8771a85ba 100644 --- a/html/cgi-bin/optionsfw.cgi +++ b/html/cgi-bin/optionsfw.cgi @@ -69,6 +69,31 @@ if ($settings{'ACTION'} eq $Lang::tr{'save'}) { &General::readhash($filename, \%settings); # Load good settings } =20 +if ($settings{'ACTION'} eq $Lang::tr{'fw settings save and restart'}) { + if ($settings{'defpol'} ne '1'){ + &General::writehash($filename, \%settings); # Save good settin= gs + system("/usr/local/bin/firewallctrl"); + system("/usr/local/bin/optionsfwctrl restart >/dev/null 2>&1"); + }else{ + if ($settings{'POLICY'} ne ''){ + $fwdfwsettings{'POLICY'} =3D $settings{'POLICY'}; + } + if ($settings{'POLICY1'} ne ''){ + $fwdfwsettings{'POLICY1'} =3D $settings{'POLICY1'}; + } + my $MODE =3D $fwdfwsettings{'POLICY'}; + my $MODE1 =3D $fwdfwsettings{'POLICY1'}; + %fwdfwsettings =3D (); + $fwdfwsettings{'POLICY'} =3D "$MODE"; + $fwdfwsettings{'POLICY1'} =3D "$MODE1"; + &General::writehash("${General::swroot}/firewall/settings", \%fwdfwsetting= s); + &General::readhash("${General::swroot}/firewall/settings", \%fwdfwsettings= ); + system("/usr/local/bin/firewallctrl"); + system("/usr/local/bin/optionsfwctrl restart >/dev/null 2>&1"); + } + &General::readhash($filename, \%settings); # Load good settings +} + &Header::openpage($Lang::tr{'options fw'}, 1, ''); &Header::openbigbox('100%', 'left', '', $errormessage); &General::readhash($filename, \%settings); @@ -158,6 +183,18 @@ $selected{'MASQUERADE_ORANGE'}{$settings{'MASQUERADE_ORA= NGE'}} =3D 'selected=3D"sele $selected{'MASQUERADE_BLUE'}{'off'} =3D ''; $selected{'MASQUERADE_BLUE'}{'on'} =3D ''; $selected{'MASQUERADE_BLUE'}{$settings{'MASQUERADE_BLUE'}} =3D 'selected=3D"= selected"'; +$checked{'DNS_FORCE_ON_GREEN'}{'off'} =3D ''; +$checked{'DNS_FORCE_ON_GREEN'}{'on'} =3D ''; +$checked{'DNS_FORCE_ON_GREEN'}{$settings{'DNS_FORCE_ON_GREEN'}} =3D "checked= =3D'checked'"; +$checked{'DNS_FORCE_ON_BLUE'}{'off'} =3D ''; +$checked{'DNS_FORCE_ON_BLUE'}{'on'} =3D ''; +$checked{'DNS_FORCE_ON_BLUE'}{$settings{'DNS_FORCE_ON_BLUE'}} =3D "checked= =3D'checked'"; +$checked{'NTP_FORCE_ON_GREEN'}{'off'} =3D ''; +$checked{'NTP_FORCE_ON_GREEN'}{'on'} =3D ''; +$checked{'NTP_FORCE_ON_GREEN'}{$settings{'NTP_FORCE_ON_GREEN'}} =3D "checked= =3D'checked'"; +$checked{'NTP_FORCE_ON_BLUE'}{'off'} =3D ''; +$checked{'NTP_FORCE_ON_BLUE'}{'on'} =3D ''; +$checked{'NTP_FORCE_ON_BLUE'}{$settings{'NTP_FORCE_ON_BLUE'}} =3D "checked= =3D'checked'"; =20 &Header::openbox('100%', 'center',); print "
"; @@ -207,7 +244,38 @@ END END } =20 - print < + +   + $Lang::tr{'fw green'} + + $Lang::tr{'dns force on green'}<= td align=3D'left'>$Lang::tr{'on'} / + $Lang::tr{'off'} + $Lang::tr{'ntp force on green'}<= td align=3D'left'>$Lang::tr{'on'} / + $Lang::tr{'off'} +END + + if (&Header::blue_used()) { + print < + $Lan= g::tr{'fw blue'} +   + + $Lang::tr{'dns force on blue'}<= td align=3D'left'>$Lang::tr{'on'} / + $Lang::tr{'off'} + $Lang::tr{'ntp force on blue'}<= td align=3D'left'>$Lang::tr{'on'} / + $Lang::tr{'off'} + $Lang::tr{'drop proxy'}$Lang::tr{'on'} / + $Lang::tr{'off'} + $Lang::tr{'drop samba'}$Lang::tr{'on'} / + $Lang::tr{'off'} + + +END + } + + print < =20
@@ -224,21 +292,25 @@ END $Lang::tr{'off'} $Lang::tr{'drop portscan'}$Lang::tr{'on'} / $Lang::tr{'off'} -$Lang::tr{'drop wirelessinput'}$Lang::tr{'on'} / +END + + if (&Header::blue_used()) { + print < + + $Lang::tr{'drop wirelessinput'}= $Lang::tr{'on'} / $Lang::tr{'off'} -$Lang::tr{'drop wirelessforward'}<= td align=3D'left'>$Lang::tr{'on'} / + $Lang::tr{'drop wirelessforward'}$Lang::tr{'on'} / $Lang::tr{'off'} - -
+ +END + } + + print < + +
=20 - - - - -
$Lang:= :tr{'fw blue'}
$Lang::tr{'drop proxy'}$Lang::tr{'on'} / - $Lang::tr{'off'}
$Lang::tr{'drop samba'}$Lang::tr{'on'} / - $Lang::tr{'off'}
-
$Lang:= :tr{'fw settings'}
$Lang::tr{'fw settings color'}$Lang::tr{'on'} / @@ -323,7 +395,8 @@ END
- + +
diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl index 87181c184..74f8d0f41 100644 --- a/langs/de/cgi-bin/de.pl +++ b/langs/de/cgi-bin/de.pl @@ -836,6 +836,8 @@ 'dns error 0' =3D> 'Die IP Adresse vom prim=C3=A4ren DNS Se= rver ist nicht g=C3=BCltig, bitte =C3=BCberpr=C3=BCfen Sie Ihre Eingabe!
Die eingegebene sekund=C3=A4ren DNS Server Adresse ist jedo= ch g=C3=BCltig.
', 'dns error 01' =3D> 'Die eingegebene IP Adresse des prim=C3=A4ren wie auch des sekund=C3=A4ren DNS-Servers sind nicht g= =C3=BCltig, bitte =C3=BCberpr=C3=BCfen Sie Ihre Eingaben!', 'dns error 1' =3D> 'Die IP Adresse vom sekund=C3=A4ren DNS = Server ist nicht g=C3=BCltig, bitte =C3=BCberpr=C3=BCfen Sie Ihre Eingabe!Die eingegebene prim=C3=A4re DNS Server Adresse ist jedoc= h g=C3=BCltig.', +'dns force on blue' =3D> 'Erzwinge lokale DNS-Server auf BLAU', +'dns force on green' =3D> 'Erzwinge lokale DNS-Server auf GR=C3=9CN', 'dns forward disable dnssec' =3D> 'DNSSEC deaktivieren (nicht empfohlen)', 'dns forwarding dnssec disabled notice' =3D> '(DNSSEC deaktiviert)', 'dns header' =3D> 'DNS Server Adressen zuweisen nur mit DHCP an red0', @@ -1104,12 +1106,14 @@ 'from warn email bad' =3D> 'Von E-Mail-Adresse ist nicht g=C3=BCltig', 'fw blue' =3D> 'Firewalloptionen f=C3=BCr das Blaue Interface', 'fw default drop' =3D> 'Firewallrichtlinie', +'fw green' =3D> 'Firewalloptionen f=C3=BCr das Gr=C3=BCne Interface', 'fw logging' =3D> 'Firewallprotokollierung', 'fw settings' =3D> 'Firewalleinstellungen', 'fw settings color' =3D> 'Farben in Regeltabelle anzeigen', 'fw settings dropdown' =3D> 'Alle Netzwerke auf Regelerstellungsseite anzeig= en', 'fw settings remark' =3D> 'Anmerkungen in Regeltabelle anzeigen', 'fw settings ruletable' =3D> 'Leere Regeltabellen anzeigen', +'fw settings save and restart' =3D> 'Speichern und Neustart', 'fwdfw ACCEPT' =3D> 'Akzeptieren (ACCEPT)', 'fwdfw DROP' =3D> 'Verwerfen (DROP)', 'fwdfw MODE1' =3D> 'Alle Pakete verwerfen', @@ -1814,6 +1818,8 @@ 'november' =3D> 'November', 'ntp common settings' =3D> 'Allgemeine Einstellungen', 'ntp configuration' =3D> 'Zeitserverkonfiguration', +'ntp force on blue' =3D> 'Erzwinge lokale NTP-Server auf BLAU', +'ntp force on green' =3D> 'Erzwinge lokale NTP-Server auf GR=C3=9CN', 'ntp must be enabled to have clients' =3D> 'Um Clients annehmen zu k=C3=B6nn= en, muss NTP vorher aktiviert sein.', 'ntp server' =3D> 'NTP-Server', 'ntp sync' =3D> 'Synchronisation', diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 625c6899f..252af7536 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -859,6 +859,8 @@ 'dns error 0' =3D> 'The IP address of the primary DNS serve= r is not valid, please check your entries!
The entered secondary= DNS server address is valid.', 'dns error 01' =3D> 'The entered IP address of the primary = and secondary DNS server are not valid, please check your en= tries!', 'dns error 1' =3D> 'The IP address of the secondary DNS ser= ver is not valid, please check your entries!
The entered primary= DNS server address is valid.', +'dns force on green' =3D> 'Force DNS to use local DNS servers on GREEN', +'dns force on blue' =3D> 'Force DNS to use local DNS servers on BLUE', 'dns forward disable dnssec' =3D> 'Disable DNSSEC (dangerous)', 'dns forwarding dnssec disabled notice' =3D> '(DNSSEC disabled)', 'dns header' =3D> 'Assign DNS server addresses only for DHCP on red0', @@ -1130,12 +1132,14 @@ 'from warn email bad' =3D> 'From e-mail address is not valid', 'fw blue' =3D> 'Firewall options for BLUE interface', 'fw default drop' =3D> 'Firewall policy', +'fw green' =3D> 'Firewall options for GREEN interface', 'fw logging' =3D> 'Firewall logging', 'fw settings' =3D> 'Firewall settings', 'fw settings color' =3D> 'Show colors in ruletable', 'fw settings dropdown' =3D> 'Show all networks on rulecreation site', 'fw settings remark' =3D> 'Show remarks in ruletable', 'fw settings ruletable' =3D> 'Show empty ruletables', +'fw settings save and restart' =3D> 'Save and Restart', 'fwdfw ACCEPT' =3D> 'ACCEPT', 'fwdfw DROP' =3D> 'DROP', 'fwdfw MODE1' =3D> 'Drop all packets', @@ -1844,6 +1848,8 @@ 'november' =3D> 'November', 'ntp common settings' =3D> 'Common settings', 'ntp configuration' =3D> 'NTP Configuration', +'ntp force on green' =3D> 'Force NTP to use local NTP servers on GREEN', +'ntp force on blue' =3D> 'Force NTP to use local NTP servers on BLUE', 'ntp must be enabled to have clients' =3D> 'NTP must be enabled to have clie= nts.', 'ntp server' =3D> 'NTP Server', 'ntp sync' =3D> 'Synchronization', diff --git a/lfs/configroot b/lfs/configroot index a37c2c401..2d8a5de46 100644 --- a/lfs/configroot +++ b/lfs/configroot @@ -129,6 +129,10 @@ $(TARGET) : echo "SHOWDROPDOWN=3Doff" >> $(CONFIG_ROOT)/optionsfw/settings echo "DROPWIRELESSINPUT=3Don" >> $(CONFIG_ROOT)/optionsfw/settings echo "DROPWIRELESSFORWARD=3Don" >> $(CONFIG_ROOT)/optionsfw/settings + echo "FORCE_DNS_ON_GREEN=3Doff" >> $(CONFIG_ROOT)/optionsfw/settings + echo "FORCE_DNS_ON_BLUE=3Doff" >> $(CONFIG_ROOT)/optionsfw/settings + echo "FORCE_NTP_ON_GREEN=3Doff" >> $(CONFIG_ROOT)/optionsfw/settings + echo "FORCE_NTP_ON_BLUE=3Doff" >> $(CONFIG_ROOT)/optionsfw/settings echo "POLICY=3DMODE2" >> $(CONFIG_ROOT)/firewall/settings echo "POLICY1=3DMODE2" >> $(CONFIG_ROOT)/firewall/settings echo "USE_ISP_NAMESERVERS=3Don" >> $(CONFIG_ROOT)/dns/settings diff --git a/src/initscripts/system/firewall b/src/initscripts/system/firewall index 65f1c979b..4e02bd3d9 100644 --- a/src/initscripts/system/firewall +++ b/src/initscripts/system/firewall @@ -246,6 +246,77 @@ iptables_init() { iptables -A ${i} -j CAPTIVE_PORTAL done =20 +# Force DNS REDIRECT on GREEN (udp, tcp, 53) +if [ "$DNS_FORCE_ON_GREEN" =3D=3D "on" ]; then + if ! iptables -t nat -C CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53= -j REDIRECT >/dev/null 2>&1; then + iptables -t nat -A CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53 -j = REDIRECT + fi + + if ! iptables -t nat -C CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53= -j REDIRECT >/dev/null 2>&1; then + iptables -t nat -A CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53 -j = REDIRECT + fi + +else + + if iptables -t nat -C CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53 -= j REDIRECT >/dev/null 2>&1; then + iptables -t nat -D CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53 -j = REDIRECT >/dev/null 2>&1 + fi + + if iptables -t nat -C CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53 -= j REDIRECT >/dev/null 2>&1; then + iptables -t nat -D CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53 -j = REDIRECT >/dev/null 2>&1 + fi +fi + +# Force DNS REDIRECT on BLUE (udp, tcp, 53) +if [ "$DNS_FORCE_ON_BLUE" =3D=3D "on" ]; then + if ! iptables -t nat -C CUSTOMPREROUTING -i blue0 -p udp -m udp --dport 53 = -j REDIRECT >/dev/null 2>&1; then + iptables -t nat -A CUSTOMPREROUTING -i blue0 -p udp -m udp --dport 53 -j R= EDIRECT + fi + + if ! iptables -t nat -C CUSTOMPREROUTING -i blue0 -p tcp -m tcp --dport 53 = -j REDIRECT >/dev/null 2>&1; then + iptables -t nat -A CUSTOMPREROUTING -i blue0 -p tcp -m tcp --dport 53 -j R= EDIRECT + fi + +else + + if iptables -t nat -C CUSTOMPREROUTING -i blue0 -p udp -m udp --dport 53 -j= REDIRECT >/dev/null 2>&1; then + iptables -t nat -D CUSTOMPREROUTING -i blue0 -p udp -m udp --dport 53 -j R= EDIRECT >/dev/null 2>&1 + fi + + if iptables -t nat -C CUSTOMPREROUTING -i blue0 -p tcp -m tcp --dport 53 -j= REDIRECT >/dev/null 2>&1; then + iptables -t nat -D CUSTOMPREROUTING -i blue0 -p tcp -m tcp --dport 53 -j R= EDIRECT >/dev/null 2>&1 + fi + +fi + +# Force NTP REDIRECT on GREEN (udp, 123) +if [ "$NTP_FORCE_ON_GREEN" =3D=3D "on" ]; then + if ! iptables -t nat -C CUSTOMPREROUTING -i green0 -p udp -m udp --dport 12= 3 -j REDIRECT >/dev/null 2>&1; then + iptables -t nat -A CUSTOMPREROUTING -i green0 -p udp -m udp --dport 123 -j= REDIRECT + fi + +else + + if iptables -t nat -C CUSTOMPREROUTING -i green0 -p udp -m udp --dport 123 = -j REDIRECT >/dev/null 2>&1; then + iptables -t nat -D CUSTOMPREROUTING -i green0 -p udp -m udp --dport 123 -j= REDIRECT >/dev/null 2>&1 + fi + +fi + +# Force DNS REDIRECT on BLUE (udp, 123) +if [ "$NTP_FORCE_ON_BLUE" =3D=3D "on" ]; then + if ! iptables -t nat -C CUSTOMPREROUTING -i blue0 -p udp -m udp --dport 123= -j REDIRECT >/dev/null 2>&1; then + iptables -t nat -A CUSTOMPREROUTING -i blue0 -p udp -m udp --dport 123 -j = REDIRECT + fi + +else + + if iptables -t nat -C CUSTOMPREROUTING -i blue0 -p udp -m udp --dport 123 -= j REDIRECT >/dev/null 2>&1; then + iptables -t nat -D CUSTOMPREROUTING -i blue0 -p udp -m udp --dport 123 -j = REDIRECT >/dev/null 2>&1 + fi + +fi + # Accept everything connected for i in INPUT FORWARD OUTPUT; do iptables -A ${i} -j CONNTRACK --=20 2.18.0 --===============6325502275546387456==--