Firewall UI: Add iptables rules for XDP SYNPROXY

Add firewall WebUI and firewall iptables rules
for XDP SYNPROXY

Signed-off-by: Vincent Li <vincent.mc.li@gmail.com>
This commit is contained in:
Vincent Li
2025-03-27 19:24:05 -07:00
parent 0f9937c78f
commit 6ff3d8e48e
4 changed files with 80 additions and 4 deletions

View File

@@ -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;

View File

@@ -129,9 +129,15 @@ print<<END;
// Check if we are dealing with a protocol, that knows ports.
if (\$.inArray(protocol, PROTOCOLS_WITH_PORTS) >= 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'}."<br>";
@@ -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
</tr>
</table>
<table width="40%" border="0" id="XDP_SYNPROXY">
<tr>
<!-- #XDP_SYNPROXY_ACCELERATION -->
<td>
$Lang::tr{'fwdfw use synproxy'}
</td>
<td>
<input type='checkbox' name='XDP_SYNPROXY_ACCELERATION' id='XDP_SYNPROXY_ACCELERATION' value="ON" $checked{'XDP_SYNPROXY_ACCELERATION'}{'ON'}>
</td>
</tr>
</table>
<table width="100%" border="0" id="PROTOCOL_PORTS">
<tr>
<!-- #SOURCEPORT -->
@@ -2192,6 +2216,7 @@ END
<input type='hidden' name='oldruleremark' value='$fwdfwsettings{'oldruleremark'}' />
<input type='hidden' name='oldorange' value='$fwdfwsettings{'oldorange'}' />
<input type='hidden' name='oldnat' value='$fwdfwsettings{'oldnat'}' />
<input type='hidden' name='oldxdpsynproxyacceleration' value='$fwdfwsettings{'oldxdpsynproxyacceleration'}' />
<input type='hidden' name='oldruletype' value='$fwdfwsettings{'oldruletype'}' />
<input type='hidden' name='oldconcon' value='$fwdfwsettings{'oldconcon'}' />
<input type='hidden' name='ACTION' value='saverule' ></form><form method='post' style='display:inline'><input type='submit' value='$Lang::tr{'fwhost back'}' style='min-width:100px;'><input type='hidden' name='ACTION' value'reset'></td></td>
@@ -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;
}
}

View File

@@ -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.',

View File

@@ -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