From 8e4e24a9b943f911d30ffb7e31a1fd099c5258bc Mon Sep 17 00:00:00 2001 From: Vincent Li Date: Sun, 17 Mar 2024 01:49:10 +0000 Subject: [PATCH] Add XDP DDoS ddos.cgi Signed-off-by: Vincent Li --- config/cfgroot/ddos-settings | 9 + config/cfgroot/tcp_ports | 8 + config/rootfiles/common/configroot | 1 + config/rootfiles/common/web-user-interface | 1 + html/cgi-bin/ddos.cgi | 303 +++++++++++++++++++++ langs/en/cgi-bin/en.pl | 13 +- lfs/configroot | 6 +- 7 files changed, 338 insertions(+), 3 deletions(-) create mode 100644 config/cfgroot/ddos-settings create mode 100644 config/cfgroot/tcp_ports create mode 100755 html/cgi-bin/ddos.cgi diff --git a/config/cfgroot/ddos-settings b/config/cfgroot/ddos-settings new file mode 100644 index 000000000..24fbf50bf --- /dev/null +++ b/config/cfgroot/ddos-settings @@ -0,0 +1,9 @@ +22=off +ENABLE_DDOS=off +25=off +80=off +53=off +8080=off +8090=off +443=off +5555=off diff --git a/config/cfgroot/tcp_ports b/config/cfgroot/tcp_ports new file mode 100644 index 000000000..b32990a2e --- /dev/null +++ b/config/cfgroot/tcp_ports @@ -0,0 +1,8 @@ +ssh 22/tcp # The Secure Shell (SSH) Protocol +smtp 25/tcp # Simple Mail Transfer +http 80/tcp # World Wide Web HTTP +https 443/tcp # http protocol over TLS/SSL +domain 53/tcp # Domain Name Server +httpalt 8080/tcp # HTTP Alternate (see port 80) +opsmessaging 8090/tcp # Vehicle to station messaging +userdefined 5555/tcp # Vehicle to station messaging diff --git a/config/rootfiles/common/configroot b/config/rootfiles/common/configroot index b920dd248..37779f0dd 100644 --- a/config/rootfiles/common/configroot +++ b/config/rootfiles/common/configroot @@ -199,3 +199,4 @@ var/ipfire/wakeonlan var/ipfire/wireless #var/ipfire/wireless/config #var/ipfire/wireless/settings +var/ipfire/ddos diff --git a/config/rootfiles/common/web-user-interface b/config/rootfiles/common/web-user-interface index 2fbbcbcf2..de959e3e8 100644 --- a/config/rootfiles/common/web-user-interface +++ b/config/rootfiles/common/web-user-interface @@ -90,6 +90,7 @@ srv/web/ipfire/cgi-bin/wireless.cgi srv/web/ipfire/cgi-bin/wirelessclient.cgi srv/web/ipfire/cgi-bin/wlanap.cgi srv/web/ipfire/cgi-bin/zoneconf.cgi +srv/web/ipfire/cgi-bin/ddos.cgi #srv/web/ipfire/html srv/web/ipfire/html/blob.gif #srv/web/ipfire/html/captive diff --git a/html/cgi-bin/ddos.cgi b/html/cgi-bin/ddos.cgi new file mode 100755 index 000000000..4e236ac58 --- /dev/null +++ b/html/cgi-bin/ddos.cgi @@ -0,0 +1,303 @@ +#!/usr/bin/perl +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007-2020 IPFire Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +use strict; + +# enable only the following on debugging purpose +#use warnings; +#use CGI::Carp 'fatalsToBrowser'; + +use IO::Socket; + +require '/var/ipfire/general-functions.pl'; +require "${General::swroot}/location-functions.pl"; +require "${General::swroot}/lang.pl"; +require "${General::swroot}/header.pl"; + +my %color = (); +my %mainsettings = (); +my %ddossettings=(); +my %cgiparams=(); +my %checked=(); +my $errormessage=''; +my $counter = 0; +my %tcp_ports=(); +my $portfile = "${General::swroot}/ddos/tcp_ports"; +my $ddossettingfile = "${General::swroot}/ddos/settings"; + +&get_tcp_ports(); + +# Read configuration file. +&General::readhash("$ddossettingfile", \%ddossettings); + +&General::readhash("${General::swroot}/main/settings", \%mainsettings); +&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color); + +&Header::showhttpheaders(); + +$ddossettings{'ENABLE_DDOS'} = 'off'; +$ddossettings{'ACTION'} = ''; +&Header::getcgihash(\%cgiparams); + +if ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) +{ + + if (exists $cgiparams{'ENABLE_DDOS'}) { + $ddossettings{'ENABLE_DDOS'} = "on"; + &General::log($Lang::tr{'ddos is enabled'}); + &General::system('/usr/bin/touch', "${General::swroot}/ddos/enableddos"); + #system('/usr/local/bin/sshctrl') == 0 + # or $errormessage = "$Lang::tr{'bad return code'} " . $?/256; + } else { + $ddossettings{'ENABLE_DDOS'} = "off"; + &General::log($Lang::tr{'ddos is disabled'}); + unlink "${General::swroot}/ddos/enableddos"; + } + + # Loop through our locations array to prevent from + # non existing countries or code. + foreach my $p (values %tcp_ports) { + # Check if blocking for this country should be enabled/disabled. + if (exists $cgiparams{$p}) { + $ddossettings{$p} = "on"; + } else { + $ddossettings{$p} = "off"; + } + } + &General::writehash("$ddossettingfile", \%ddossettings); + +} + +# Read configuration file. +&General::readhash("$ddossettingfile", \%ddossettings); + +&Header::openpage($Lang::tr{'ebpf xdp ddos'}, 1, ''); + +# Checkbox pre-selection. +my $checked; +if ($ddossettings{'ENABLE_DDOS'} eq "on") { + $checked = "checked='checked'"; +} + +&Header::openbigbox('100%', 'left', '', $errormessage); + +if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage \n"; + &Header::closebox(); +} + +# Print box to enable/disable locationblock. +print"
\n"; + +&Header::openbox('100%', 'center', $Lang::tr{'xdp'}); +print < + + $Lang::tr{'xdp enable'} + + + + + +END + +&Header::closebox(); + +&Header::openbox('100%', 'center', $Lang::tr{'xdp port'}); +print < + + + + $Lang::tr{'port'} + + + $Lang::tr{'service'} + + +   + + + + $Lang::tr{'port'} + + + $Lang::tr{'service'} + + + +END + +my $lines; +my $lines2; +my $col; + + +# Sort output based on hash value port number +for my $service ( sort { $tcp_ports{$a} cmp $tcp_ports{$b} } + keys %tcp_ports ) +{ + my $port = $tcp_ports{$service}; + + # Checkbox pre-selection. + my $checked; + if ($ddossettings{$port} eq "on") { + $checked = "checked='checked'"; + } + + # Colour lines. + if ($lines % 2) { + $col="bgcolor='$color{'color20'}'"; + } else { + $col="bgcolor='$color{'color22'}'"; + } + + # Grouping elements. + my $line_start; + my $line_end; + if ($lines2 % 2) { + # Increase lines (background color by once. + $lines++; + + # Add empty column in front. + $line_start=" "; + + # When the line number can be diveded by "2", + # we are going to close the line. + $line_end=""; + } else { + # When the line number is not divideable by "2", + # we are starting a new line. + $line_start=""; + $line_end; + } + + print "$line_start\n"; + print "$port\n"; + print "$service$line_end\n"; + +$lines2++; +} + +print < + +END + +&Header::closebox(); + +print "\n"; + +&Header::openbox('100%', 'center', $Lang::tr{'xdp status'}); + +print < + + + + $Lang::tr{'xdp interface'} + + + $Lang::tr{'xdp prio'} + + + $Lang::tr{'xdp program'} + + + $Lang::tr{'xdp mode'} + + + $Lang::tr{'xdp id'} + + + $Lang::tr{'xdp tag'} + + + $Lang::tr{'xdp action'} + + + + +END + +&printxdp(); + +print "\n\n"; + +&Header::closebox(); + +&Header::closebigbox(); + +&Header::closepage(); + +sub get_tcp_ports() +{ + open(my $fh, '<', $portfile) or die "Unable to open file: $!"; + while (my $line = <$fh>) { + chomp $line; + next if $line =~ /^\s*#/; # Skip comments + my ($service, $port) = $line =~ /^(\w+)\s+(\d+)\/tcp/; + if ($service && $port) { + $tcp_ports{$service} = $port; + } + } + close($fh); +} + +sub printxdp() +{ + # print active SSH logins (grep outpout of "who -s") + my @output = &General::system_output("xdp-loader", "status"); + chomp(@output); + + # list active logins... + foreach my $line (@output) + { + #next if $line !~ /^red0/; + #next if $line !~ /^\s=>/; + my @arry = split(/\ +/, $line); + + my $interface = $arry[0]; + my $prio = $arry[1]; + my $prog = $arry[2]; + my $mode = $arry[3]; + my $id = $arry[4]; + my $tag = $arry[5]; + my $action = $arry[6]; + + my $table_colour = ($id % 2) ? $color{'color20'} : $color{'color22'}; + + print < + $interface + $prio + $prog + $mode + $id + $tag + $action + +END +; + } +} diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 43d0a62c7..30284762d 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -703,7 +703,7 @@ 'could not retrieve common name from certificate' => 'Could not retrieve common name from certificate.', 'count' => 'Count', 'countries' => 'Countries', -'country' => 'Country', +'country' => 'Country/Region', 'country codes and flags' => 'Country Codes and Flags:', 'countrycode' => 'Code', 'cpu frequency' => 'CPU frequency', @@ -1513,6 +1513,17 @@ 'intrusion prevention system' => 'Intrusion Prevention System', 'ebpf xdp ddos' => 'eBPF XDP DDoS Protection', 'ebpf xdp ddos system' => 'eBPF XDP DDoS Protection System', +'xdp' => 'XDP', +'xdp enable' => 'Enable XDP DDoS Feature', +'xdp port' => 'XDP DDoS Protected TCP Ports', +'xdp status' => 'XDP Program Status', +'xdp interface' => 'Interface', +'xdp prio' => 'Prio', +'xdp program' => 'Program name', +'xdp mode' => 'Mode', +'xdp id' => 'ID', +'xdp tag' => 'Tag', +'xdp action' => 'Chain actions', 'invalid broadcast ip' => 'Invalid broadcast IP', 'invalid cache size' => 'Invalid cache size.', 'invalid characters found in pre-shared key' => 'Invalid characters found in pre-shared key.', diff --git a/lfs/configroot b/lfs/configroot index 66efe04b5..d4989248e 100644 --- a/lfs/configroot +++ b/lfs/configroot @@ -54,7 +54,7 @@ $(TARGET) : ethernet extrahd/bin fwlogs fwhosts firewall ipblocklist key langs logging mac main \ menu.d modem optionsfw \ ovpn patches pakfire portfw ppp private proxy/advanced/cre \ - proxy/calamaris/bin qos/bin red remote sensors suricata time \ + proxy/calamaris/bin qos/bin red remote ddos sensors suricata time \ updatexlrator/bin updatexlrator/autocheck urlfilter/autoupdate urlfilter/bin vpn \ wakeonlan wireless ; do \ mkdir -p $(CONFIG_ROOT)/$$i; \ @@ -68,7 +68,7 @@ $(TARGET) : fwhosts/customnetworks fwhosts/customhosts fwhosts/customgroups fwhosts/customservicegrp fwhosts/customlocationgrp fwlogs/ipsettings fwlogs/portsettings ipblocklist/modified \ ipblocklist/settings mac/settings main/hosts main/routing main/security main/settings optionsfw/settings \ ovpn/ccd.conf ovpn/ccdroute ovpn/ccdroute2 pakfire/settings portfw/config ppp/settings-1 ppp/settings-2 ppp/settings-3 ppp/settings-4 \ - ppp/settings-5 ppp/settings proxy/settings proxy/squid.conf proxy/advanced/settings proxy/advanced/cre/enable remote/settings qos/settings qos/classes qos/subclasses qos/level7config qos/portconfig \ + ppp/settings-5 ppp/settings proxy/settings proxy/squid.conf proxy/advanced/settings proxy/advanced/cre/enable remote/settings ddos/settings ddos/tcp_ports qos/settings qos/classes qos/subclasses qos/level7config qos/portconfig \ qos/tosconfig suricata/settings vpn/config vpn/settings vpn/ipsec.conf \ vpn/ipsec.secrets vpn/caconfig wakeonlan/clients.conf wireless/config wireless/settings; do \ touch $(CONFIG_ROOT)/$$i; \ @@ -98,6 +98,8 @@ $(TARGET) : cp $(DIR_SRC)/config/cfgroot/main-settings $(CONFIG_ROOT)/main/settings cp $(DIR_SRC)/config/cfgroot/manualpages $(CONFIG_ROOT)/main/ cp $(DIR_SRC)/config/cfgroot/ssh-settings $(CONFIG_ROOT)/remote/settings + cp $(DIR_SRC)/config/cfgroot/ddos-settings $(CONFIG_ROOT)/ddos/settings + cp $(DIR_SRC)/config/cfgroot/tcp_ports $(CONFIG_ROOT)/ddos/tcp_ports cp $(DIR_SRC)/config/cfgroot/time-settings $(CONFIG_ROOT)/time/settings cp $(DIR_SRC)/config/cfgroot/logging-settings $(CONFIG_ROOT)/logging/settings cp $(DIR_SRC)/config/cfgroot/ethernet-vlans $(CONFIG_ROOT)/ethernet/vlans