diff --git a/config/firewall/rules.pl b/config/firewall/rules.pl index c414f172c..592ecf4a7 100644 --- a/config/firewall/rules.pl +++ b/config/firewall/rules.pl @@ -42,6 +42,7 @@ my $CHAIN = $CHAIN_FORWARD; my $CHAIN_NAT_SOURCE = "NAT_SOURCE"; my $CHAIN_NAT_DESTINATION = "NAT_DESTINATION"; my $CHAIN_MANGLE_NAT_DESTINATION_FIX = "NAT_DESTINATION"; +my $CHAIN_XDP_SYNPROXY = "XDP_SYNPROXY"; my @VALID_CHAINS = ($CHAIN_INPUT, $CHAIN_FORWARD, $CHAIN_OUTPUT); my @ANY_ADDRESSES = ("0.0.0.0/0.0.0.0", "0.0.0.0/0", "0/0"); @@ -222,6 +223,8 @@ sub flush { run("$IPTABLES -t nat -F $CHAIN_NAT_DESTINATION"); run("$IPTABLES -t mangle -F $CHAIN_MANGLE_NAT_DESTINATION_FIX"); run("$IPTABLES -t raw -F SYN_FLOOD_PROTECT"); + run("$IPTABLES -F $CHAIN_XDP_SYNPROXY"); + run("$IPTABLES -t raw -F $CHAIN_XDP_SYNPROXY"); } sub buildrules { @@ -301,6 +304,9 @@ sub buildrules { # Enable SYN flood protection? my $SYN_FLOOD_PROTECTION = 0; + # Enable XDP SYNPROXY acceleration? + my $XDP_SYNPROXY_ACCELERATION = 0; + # Set up time constraints. my @time_options = (); if ($$hash{$key}[18] eq 'ON') { @@ -379,6 +385,11 @@ sub buildrules { $SYN_FLOOD_PROTECTION = 1; } + # XDP SYNPROXY DDoS Protection Acceleration + if (($elements ge 39) && ($$hash{$key}[38] eq "ON")) { + $XDP_SYNPROXY_ACCELERATION = 1; + } + # Check which protocols are used in this rule and so that we can # later group rules by protocols. my @protocols = &get_protocols($hash, $key); @@ -621,6 +632,23 @@ sub buildrules { run("$IPTABLES -t raw -A SYN_FLOOD_PROTECT @options -j CT --notrack"); } + if ($XDP_SYNPROXY_ACCELERATION && ($protocol eq "tcp")) { + my $dport = &get_external_port($hash, $key); + my @raw_options = ("-p", "tcp", "-m", "tcp", "--syn"); + my @in_options = ("-p", "tcp", "-m", "tcp"); + my @options = ("--sack-perm", "--timestamp", "--wscale", "7", "--mss", "1460"); + push(@raw_options, "--dport", "$dport"); + push(@in_options, "--dport", "$dport", "-m", "state", "--state", "INVALID,UNTRACKED"); + if ($LOG) { + run("$IPTABLES -t raw -A $CHAIN_XDP_SYNPROXY -i $RED_DEV @raw_options -j LOG --log-prefix '$CHAIN_XDP_SYNPROXY '"); + } + run("$IPTABLES -t raw -A $CHAIN_XDP_SYNPROXY -i $RED_DEV @raw_options -j CT --notrack"); + if ($LOG) { + run("$IPTABLES -A $CHAIN_XDP_SYNPROXY -i $RED_DEV @in_options -j LOG --log-prefix '$CHAIN_XDP_SYNPROXY ' @options"); + } + run("$IPTABLES -A $CHAIN_XDP_SYNPROXY -i $RED_DEV @in_options -j SYNPROXY @options"); + } + # Handle forwarding rules and add corresponding rules for firewall access. if ($chain eq $CHAIN_FORWARD) { # If the firewall is part of the destination subnet and access to the destination network @@ -958,6 +986,22 @@ sub get_dnat_target_port { } } +sub get_external_port { + my $hash = shift; + my $key = shift; + + if ($$hash{$key}[14] eq "TGT_PORT") { + my $port = $$hash{$key}[15]; + my $external_port = $$hash{$key}[30]; + + if ($external_port && ($port ne $external_port)) { + return $external_port; + } else { + return $port; + } + } +} + sub add_dnat_mangle_rules { my $nat_address = shift; my $interface = shift; diff --git a/html/cgi-bin/firewall.cgi b/html/cgi-bin/firewall.cgi index e87a7fed0..374cf4d66 100644 --- a/html/cgi-bin/firewall.cgi +++ b/html/cgi-bin/firewall.cgi @@ -129,9 +129,15 @@ print<= 0) { + if (protocol === "TCP") { + \$("#XDP_SYNPROXY").show(); + } else { + \$("#XDP_SYNPROXY").hide(); + } \$("#PROTOCOL_PORTS").show(); } else { \$("#PROTOCOL_PORTS").hide(); + \$("#XDP_SYNPROXY").hide(); } // Handle ICMP. @@ -301,8 +307,8 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule') #check if we have an identical rule already if($fwdfwsettings{'oldrulenumber'} eq $fwdfwsettings{'rulepos'}){ foreach my $key (sort keys %rulehash){ - if ( "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'ruleremark'},$fwdfwsettings{'LOG'},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'},$fwdfwsettings{'LIMIT_CON_CON'},$fwdfwsettings{'concon'},$fwdfwsettings{'RATE_LIMIT'},$fwdfwsettings{'ratecon'},$fwdfwsettings{'RATETIME'},$fwdfwsettings{'SYN_FLOOD_PROTECTION'}" - eq "$rulehash{$key}[0],$rulehash{$key}[2],$rulehash{$key}[3],$rulehash{$key}[4],$rulehash{$key}[5],$rulehash{$key}[6],$rulehash{$key}[7],$rulehash{$key}[8],$rulehash{$key}[9],$rulehash{$key}[10],$rulehash{$key}[11],$rulehash{$key}[12],$rulehash{$key}[13],$rulehash{$key}[14],$rulehash{$key}[15],$rulehash{$key}[16],$rulehash{$key}[17],$rulehash{$key}[18],$rulehash{$key}[19],$rulehash{$key}[20],$rulehash{$key}[21],$rulehash{$key}[22],$rulehash{$key}[23],$rulehash{$key}[24],$rulehash{$key}[25],$rulehash{$key}[26],$rulehash{$key}[27],$rulehash{$key}[28],$rulehash{$key}[29],$rulehash{$key}[30],$rulehash{$key}[31],$rulehash{$key}[32],$rulehash{$key}[33],$rulehash{$key}[34],$rulehash{$key}[35],$rulehash{$key}[36],$rulehash{$key}[37]"){ + if ( "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'ruleremark'},$fwdfwsettings{'LOG'},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'},$fwdfwsettings{'LIMIT_CON_CON'},$fwdfwsettings{'concon'},$fwdfwsettings{'RATE_LIMIT'},$fwdfwsettings{'ratecon'},$fwdfwsettings{'RATETIME'},$fwdfwsettings{'SYN_FLOOD_PROTECTION'},$fwdfwsettings{'XDP_SYNPROXY_ACCELERATION'}" + eq "$rulehash{$key}[0],$rulehash{$key}[2],$rulehash{$key}[3],$rulehash{$key}[4],$rulehash{$key}[5],$rulehash{$key}[6],$rulehash{$key}[7],$rulehash{$key}[8],$rulehash{$key}[9],$rulehash{$key}[10],$rulehash{$key}[11],$rulehash{$key}[12],$rulehash{$key}[13],$rulehash{$key}[14],$rulehash{$key}[15],$rulehash{$key}[16],$rulehash{$key}[17],$rulehash{$key}[18],$rulehash{$key}[19],$rulehash{$key}[20],$rulehash{$key}[21],$rulehash{$key}[22],$rulehash{$key}[23],$rulehash{$key}[24],$rulehash{$key}[25],$rulehash{$key}[26],$rulehash{$key}[27],$rulehash{$key}[28],$rulehash{$key}[29],$rulehash{$key}[30],$rulehash{$key}[31],$rulehash{$key}[32],$rulehash{$key}[33],$rulehash{$key}[34],$rulehash{$key}[35],$rulehash{$key}[36],$rulehash{$key}[37],$rulehash{$key}[38]"){ $errormessage.=$Lang::tr{'fwdfw err ruleexists'}; if($fwdfwsettings{'oldruleremark'} ne $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'updatefwrule'} eq 'on' && $fwdfwsettings{'ruleremark'} ne '' && !&validremark($fwdfwsettings{'ruleremark'})){ $errormessage=$Lang::tr{'fwdfw err remark'}."
"; @@ -320,8 +326,8 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule') if($fwdfwsettings{'rulepos'} > 0 && !$fwdfwsettings{'oldrulenumber'}){ $fwdfwsettings{'oldrulenumber'}=$maxkey; foreach my $key (sort keys %rulehash){ - if ( "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'},$fwdfwsettings{'LIMIT_CON_CON'},$fwdfwsettings{'concon'},$fwdfwsettings{'RATE_LIMIT'},$fwdfwsettings{'ratecon'},$fwdfwsettings{'RATETIME'}" - eq "$rulehash{$key}[0],$rulehash{$key}[2],$rulehash{$key}[3],$rulehash{$key}[4],$rulehash{$key}[5],$rulehash{$key}[6],$rulehash{$key}[7],$rulehash{$key}[8],$rulehash{$key}[9],$rulehash{$key}[10],$rulehash{$key}[11],$rulehash{$key}[12],$rulehash{$key}[13],$rulehash{$key}[14],$rulehash{$key}[15],$rulehash{$key}[18],$rulehash{$key}[19],$rulehash{$key}[20],$rulehash{$key}[21],$rulehash{$key}[22],$rulehash{$key}[23],$rulehash{$key}[24],$rulehash{$key}[25],$rulehash{$key}[26],$rulehash{$key}[27],$rulehash{$key}[28],$rulehash{$key}[29],$rulehash{$key}[30],$rulehash{$key}[31],$rulehash{$key}[32],$rulehash{$key}[33],$rulehash{$key}[34],$rulehash{$key}[35],$rulehash{$key}[36]"){ + if ( "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'},$fwdfwsettings{'LIMIT_CON_CON'},$fwdfwsettings{'concon'},$fwdfwsettings{'RATE_LIMIT'},$fwdfwsettings{'ratecon'},$fwdfwsettings{'RATETIME'},$fwdfwsettings{'XDP_SYNPROXY_ACCELERATION'}" + eq "$rulehash{$key}[0],$rulehash{$key}[2],$rulehash{$key}[3],$rulehash{$key}[4],$rulehash{$key}[5],$rulehash{$key}[6],$rulehash{$key}[7],$rulehash{$key}[8],$rulehash{$key}[9],$rulehash{$key}[10],$rulehash{$key}[11],$rulehash{$key}[12],$rulehash{$key}[13],$rulehash{$key}[14],$rulehash{$key}[15],$rulehash{$key}[18],$rulehash{$key}[19],$rulehash{$key}[20],$rulehash{$key}[21],$rulehash{$key}[22],$rulehash{$key}[23],$rulehash{$key}[24],$rulehash{$key}[25],$rulehash{$key}[26],$rulehash{$key}[27],$rulehash{$key}[28],$rulehash{$key}[29],$rulehash{$key}[30],$rulehash{$key}[31],$rulehash{$key}[32],$rulehash{$key}[33],$rulehash{$key}[34],$rulehash{$key}[35],$rulehash{$key}[36],$rulehash{$key}[38]"){ $errormessage.=$Lang::tr{'fwdfw err ruleexists'}; } } @@ -1624,6 +1630,7 @@ sub newrule $fwdfwsettings{'ratecon'} = $hash{$key}[35]; $fwdfwsettings{'RATETIME'} = $hash{$key}[36]; $fwdfwsettings{'SYN_FLOOD_PROTECTION'} = $hash{$key}[37]; + $fwdfwsettings{'XDP_SYNPROXY_ACCELERATION'} = $hash{$key}[38]; $checked{'grp1'}{$fwdfwsettings{'grp1'}} = 'CHECKED'; $checked{'grp2'}{$fwdfwsettings{'grp2'}} = 'CHECKED'; $checked{'grp3'}{$fwdfwsettings{'grp3'}} = 'CHECKED'; @@ -1632,6 +1639,7 @@ sub newrule $checked{'ACTIVE'}{$fwdfwsettings{'ACTIVE'}} = 'CHECKED'; $checked{'LOG'}{$fwdfwsettings{'LOG'}} = 'CHECKED'; $checked{'SYN_FLOOD_PROTECTION'}{$fwdfwsettings{'SYN_FLOOD_PROTECTION'}} = 'CHECKED'; + $checked{'XDP_SYNPROXY_ACCELERATION'}{$fwdfwsettings{'XDP_SYNPROXY_ACCELERATION'}} = 'CHECKED'; $checked{'TIME'}{$fwdfwsettings{'TIME'}} = 'CHECKED'; $checked{'TIME_MON'}{$fwdfwsettings{'TIME_MON'}} = 'CHECKED'; $checked{'TIME_TUE'}{$fwdfwsettings{'TIME_TUE'}} = 'CHECKED'; @@ -1667,6 +1675,7 @@ sub newrule $fwdfwsettings{'olduseratelimit'}=$fwdfwsettings{'RATE_LIMIT'}; $fwdfwsettings{'olduseratelimitamount'}=$fwdfwsettings{'ratecon'}; $fwdfwsettings{'oldratelimittime'}=$fwdfwsettings{'RATETIME'}; + $fwdfwsettings{'oldxdpsynproxyacceleration'}=$fwdfwsettings{'XDP_SYNPROXY_ACCELERATION'}; #check if manual ip (source) is orange network if ($fwdfwsettings{'grp1'} eq 'src_addr'){ @@ -1690,6 +1699,7 @@ sub newrule $fwdfwsettings{'oldruleremark'}=$fwdfwsettings{'ruleremark'}; $fwdfwsettings{'oldnat'}=$fwdfwsettings{'USE_NAT'}; $fwdfwsettings{'oldconcon'}=$fwdfwsettings{'LIMIT_CON_CON'}; + $fwdfwsettings{'oldxdpsynproxyacceleration'}=$fwdfwsettings{'XDP_SYNPROXY_ACCELERATION'}; #check if manual ip (source) is orange network if ($fwdfwsettings{'grp1'} eq 'src_addr'){ my ($sip,$scidr) = split("/",$fwdfwsettings{$fwdfwsettings{'grp1'}}); @@ -1902,6 +1912,20 @@ END + + + + + + + +
+ $Lang::tr{'fwdfw use synproxy'} + + +
+ + @@ -2192,6 +2216,7 @@ END + @@ -2336,6 +2361,7 @@ sub saverule $$hash{$key}[35] = $fwdfwsettings{'ratecon'}; $$hash{$key}[36] = $fwdfwsettings{'RATETIME'}; $$hash{$key}[37] = $fwdfwsettings{'SYN_FLOOD_PROTECTION'}; + $$hash{$key}[38] = $fwdfwsettings{'XDP_SYNPROXY_ACCELERATION'}; &General::writehasharray("$config", $hash); }else{ foreach my $key (sort {$a <=> $b} keys %$hash){ @@ -2378,6 +2404,7 @@ sub saverule $$hash{$key}[35] = $fwdfwsettings{'ratecon'}; $$hash{$key}[36] = $fwdfwsettings{'RATETIME'}; $$hash{$key}[37] = $fwdfwsettings{'SYN_FLOOD_PROTECTION'}; + $$hash{$key}[38] = $fwdfwsettings{'XDP_SYNPROXY_ACCELERATION'}; last; } } diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 2a81d6b29..a0cc3d921 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -1257,6 +1257,7 @@ 'fwdfw toggle' => 'Activate or deactivate', 'fwdfw togglelog' => 'Activate or deactivate logging', 'fwdfw use nat' => 'Use Network Address Translation (NAT)', +'fwdfw use synproxy' => 'Use XDP SYNPROXY acceleration:', 'fwdfw use srcport' => 'Source port:', 'fwdfw use srv' => 'Destination port:', 'fwdfw useless rule' => 'This rule is useless.', diff --git a/src/initscripts/system/firewall b/src/initscripts/system/firewall index 139d94aa0..cc859e3b9 100644 --- a/src/initscripts/system/firewall +++ b/src/initscripts/system/firewall @@ -403,6 +403,10 @@ iptables_init() { iptables -t raw -N SYN_FLOOD_PROTECT iptables -t raw -A PREROUTING -p tcp --syn -j SYN_FLOOD_PROTECT + # XDP SYNPROXY acceleration + iptables -N XDP_SYNPROXY + iptables -t raw -N XDP_SYNPROXY + # Populate IPsec chains /usr/lib/firewall/ipsec-policy