For the vast majority of IPFire installations (i. e. those who do not make use of asymmetric routing), it is safe to run the Linux kernel's Reverse Path Forwarding in 'strict' mode, as specified in RFC 3704, section 2.2, significantly hampering spoofing attacks.
However, we cannot switch to this operating mode globally, since (a) some IPFire installations cannot use it and (b) we need to avoid a breaking change on this end.
Therefore, this patch adds a switch to the firewall options CGI, permitting users to choose between 'loose' and 'strict' RPF mode, whereas 'loose' is the current default. On existing installations, this should be left untouched - although users are urged to check whether they can switch to the 'strict' mode -; similar to the 'drop hostile' feature, this should be set to 'strict' by default on new installations.
Since only a sysctl is changed under the hood, changes do not require a reboot, but an execution of the /etc/rc.d/init.d/sysctl initscript. The corresponding misc-prog has been adjusted to reflect this.
Signed-off-by: Peter Müller peter.mueller@ipfire.org --- html/cgi-bin/optionsfw.cgi | 18 ++++++++++++++++++ langs/de/cgi-bin/de.pl | 3 +++ langs/en/cgi-bin/en.pl | 5 ++++- src/initscripts/system/sysctl | 11 ++++++++++- src/misc-progs/firewallctrl.c | 1 + 5 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/html/cgi-bin/optionsfw.cgi b/html/cgi-bin/optionsfw.cgi index fbff67b2f..72a4cddc8 100644 --- a/html/cgi-bin/optionsfw.cgi +++ b/html/cgi-bin/optionsfw.cgi @@ -158,6 +158,9 @@ $selected{'MASQUERADE_ORANGE'}{$settings{'MASQUERADE_ORANGE'}} = 'selected="sele $selected{'MASQUERADE_BLUE'}{'off'} = ''; $selected{'MASQUERADE_BLUE'}{'on'} = ''; $selected{'MASQUERADE_BLUE'}{$settings{'MASQUERADE_BLUE'}} = 'selected="selected"'; +$checked{'RPFORWARDINGMODE'}{'loose'} = ''; +$checked{'RPFORWARDINGMODE'}{'strict'} = ''; +$checked{'RPFORWARDINGMODE'}{$settings{'RPFORWARDINGMODE'}} = "checked='checked'";
&Header::openbox('100%', 'center',); print "<form method='post' action='$ENV{'SCRIPT_NAME'}'>"; @@ -334,6 +337,21 @@ END </table>
<br /> + +<table width='95%' cellspacing='0'> + <tr bgcolor='$color{'color20'}'> + <td colspan='2' align='left'><b>$Lang::tr{'reverse path forwarding'}</b></td> + </tr> + <tr> + <td align='left' width='60%'>$Lang::tr{'reverse path forwarding mode'}</td> + <td align='left'> + $Lang::tr{'strict'} <input type='radio' name='RPFORWARDINGMODE' value='strict' $checked{'RPFORWARDINGMODE'}{'strict'} />/ + <input type='radio' name='RPFORWARDINGMODE' value='loose' $checked{'RPFORWARDINGMODE'}{'loose'} /> $Lang::tr{'loose'} + </td> + </tr> +</table> +<br> + <table width='100%' cellspacing='0'> <tr><td align='right'><form method='post' action='$ENV{'SCRIPT_NAME'}'> <input type='submit' name='ACTION' value='$Lang::tr{'save'}' /> diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl index 6094c191a..047d47fe0 100644 --- a/langs/de/cgi-bin/de.pl +++ b/langs/de/cgi-bin/de.pl @@ -1623,6 +1623,7 @@ 'logging server' => 'Protokollierungsserver', 'loginlogout' => 'Login/Logout', 'logs' => 'Protokolldateien', +'loose' => 'locker', 'loosedirectorychecking' => 'Loose directorychecking', 'low' => 'Niedrig', 'ls_dhcpd' => 'DHCP-Server:', @@ -2159,6 +2160,8 @@ 'restore defaults' => 'Voreinstellungen wiederherstellen', 'restore hardware settings' => 'Hardwareeinstellungen wiederherstellen', 'restore settings' => 'Einstellungen wiederherstellen', +'reverse path forwarding' => 'Reverse Path Forwarding', +'reverse path forwarding mode' => 'Betriebsmodus des Reverse Path Forwarding (siehe <a href="https://datatracker.ietf.org/doc/html/rfc3704#section-2" target="_blank">RFC 3704, Abschnitt 2</a>)', 'reverse sort' => 'In umgekehrter chronologischer Reihenfolge sortieren', 'root' => 'Root', 'root certificate' => 'Root-Zertifikat', diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 510ed095b..80d8f7f1a 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -1671,6 +1671,7 @@ 'logging server' => 'Logging Server', 'loginlogout' => 'Login/Logout', 'logs' => 'logs', +'loose' => 'loose', 'loosedirectorychecking' => 'Loosedirectorychecking', 'low' => 'Low', 'ls_dhcpd' => 'DHCP Server:', @@ -2211,6 +2212,8 @@ 'restore defaults' => 'Restore defaults', 'restore hardware settings' => 'Restore hardware settings', 'restore settings' => 'Reset Settings', +'reverse path forwarding' => 'Reverse Path Forwarding', +'reverse path forwarding mode' => 'Operating mode of Reverse Path Forwarding (see <a href="https://datatracker.ietf.org/doc/html/rfc3704#section-2" target="_blank">RFC 3704, section 2</a>)', 'reverse sort' => 'Sort in reverse chronological order', 'root' => 'Root', 'root certificate' => 'Root Certificate', @@ -2394,7 +2397,7 @@ 'stop' => 'Stop', 'stop ovpn server' => 'Stop OpenVPN Server', 'stopped' => 'STOPPED', -'strict' => 'Strict', +'strict' => 'strict', 'subject' => 'Subject', 'subject test' => 'Teste-mail', 'subject warn' => 'Warning - warnlevel reached', diff --git a/src/initscripts/system/sysctl b/src/initscripts/system/sysctl index 8897c1faa..c7aebbc8d 100644 --- a/src/initscripts/system/sysctl +++ b/src/initscripts/system/sysctl @@ -22,6 +22,8 @@ . /etc/sysconfig/rc . ${rc_functions}
+eval $(/usr/local/bin/readhash /var/ipfire/optionsfw/settings) + case "${1}" in start) if [ -f "/etc/sysctl.conf" ]; then @@ -29,7 +31,7 @@ case "${1}" in sysctl -q -p evaluate_retval fi - arch=`uname -m` + arch=$(uname -m) case "${arch}" in armv*) arch="armv6l": @@ -40,6 +42,13 @@ case "${1}" in sysctl -q -p /etc/sysctl-${arch}.conf evaluate_retval fi + + if [ "$RPFORWARDINGMODE" == "strict" ]; then + boot_mesg "Setting Reverse Path Forwarding mode to 'strict'..." + sysctl -q -w net.ipv4.conf.all.rp_filter=1 + evaluate_retval + fi + ;;
status) diff --git a/src/misc-progs/firewallctrl.c b/src/misc-progs/firewallctrl.c index 0f176597d..b6756b0b1 100644 --- a/src/misc-progs/firewallctrl.c +++ b/src/misc-progs/firewallctrl.c @@ -13,6 +13,7 @@ int main(int argc, char *argv[]) { if (!(initsetuid())) exit(1);
+ safe_system("/etc/rc.d/init.d/sysctl start"); int retval = safe_system("/usr/lib/firewall/rules.pl");
/* If rules.pl has been successfully executed, the indicator