#!/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"); &General::system('/usr/local/bin/ddosctrl', 'start'); #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'}); &General::system('/usr/local/bin/ddosctrl', 'stop'); 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("/usr/local/bin/ddosctrl", "status"); chomp(@output); # list active logins... foreach my $line (@output) { my $interface; my $prio; my $prog; my $mode; my $id; my $tag; my $action; #comment next below when having issue #next if $line !~ /^red0/; #next if $line !~ /^\s=>/; next if $line =~ /No XDP program loaded!/; if ($line =~ /^red0/) { my @arry = split(/\s+/, $line); $interface = $arry[0]; $prio = "N/A"; $prog = $arry[1]; $mode = $arry[2]; $id = $arry[3]; $tag = $arry[4]; $action = "N/A"; } elsif ($line =~ /^\s=>/) { my @arry = split(/\s+/, $line); $interface = "red0"; $prio = $arry[2]; $prog = $arry[3]; $mode = "N/A"; $id = $arry[4]; $tag = $arry[5]; $action = $arry[6]; } if ($line =~ /^red0/ or $line =~ /^\s=>/) { my $table_colour = ($id % 2) ? $color{'color20'} : $color{'color22'}; print < $interface $prio $prog $mode $id $tag $action END ; } } }