File: //sbin/csf
#!/usr/local/cpanel/3rdparty/bin/perl
###############################################################################
# Copyright (C) 2006-2025 Jonathan Michaelson
#
# https://github.com/waytotheweb/scripts
#
# 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 <https://www.gnu.org/licenses>.
###############################################################################
# Strip PERL5LIB paths when running csf in the event of rogue .bashrc environment variables.
BEGIN {
index( $^X, '/usr/local/cpanel/3rdparty' ) == 0 or die "This program requires cpanel-perl\n";
if ( length $ENV{'PERL5LIB'} ) {
shift @INC while ( $INC[0] ne '/usr/local/cpanel' );
}
}
package sbin::csf;
use cPstrict;
no warnings;
use lib '/usr/local/csf/lib';
use Fcntl qw(:DEFAULT :flock);
use File::Basename;
use IO::Handle;
use IPC::Open3 ();
use IO::Select;
use Net::CIDR::Lite;
use Socket;
use ConfigServer::Config;
use ConfigServer::Slurp qw(slurp slurpee);
use ConfigServer::CheckIP qw(checkip cccheckip);
use ConfigServer::Ports;
use ConfigServer::URLGet;
use ConfigServer::Sanity ();
use ConfigServer::ServerCheck;
use ConfigServer::ServerStats;
use ConfigServer::Service;
use ConfigServer::Messenger;
use ConfigServer::RBLCheck;
use ConfigServer::GetEthDev ();
use ConfigServer::Sendmail;
use ConfigServer::LookUpIP qw(iplookup);
umask(0177);
our (
$verbose, $version, $logintarget, $noowner, $warning, $accept, $ipscidr,
$ipv6reg, $ipv4reg, $ethdevin, $ethdevout, $ipscidr6, $eth6devin,
$eth6devout, $statemodule, $logouttarget, $cleanreg, $slurpreg,
$faststart, $urlget, $statemodulenew, $statemodule6new, $cxsreputation,
$csflockfile_fh, $iptableslock_fh
);
our (
%input, %config, %ips, %ifaces, %messengerports, %sanitydefault,
%blocklists, %cxsports
);
our (
@ipset, @faststart4, @faststart6, @faststart4nat, @faststartipset,
@faststart6nat
);
# Run main script logic only when executed directly, not when loaded as module
__PACKAGE__->run() unless caller;
sub run {
my $class = shift;
# Initialize package variables
$version = version();
$ipscidr6 = Net::CIDR::Lite->new;
$ipscidr = Net::CIDR::Lite->new;
eval { local $SIG{__DIE__} = undef; $ipscidr6->add("::1/128") };
eval { local $SIG{__DIE__} = undef; $ipscidr->add("127.0.0.0/8") };
$slurpreg = ConfigServer::Slurp->slurpreg;
$cleanreg = ConfigServer::Slurp->cleanreg;
$faststart = 0;
process_input();
load_config();
$urlget = ConfigServer::URLGet->new( $config{URLGET}, "csf/$version", $config{URLPROXY} );
unless ( defined $urlget ) {
if ( -e $config{CURL} or -e $config{WGET} ) {
$config{URLGET} = 3;
$urlget = ConfigServer::URLGet->new( $config{URLGET}, "csf/$version", $config{URLPROXY} );
print "*WARNING* URLGET set to use LWP but perl module is not installed, fallback to using CURL/WGET\n";
$warning .= "*WARNING* URLGET set to use LWP but perl module is not installed, fallback to using CURL/WGET\n";
}
else {
$config{URLGET} = 1;
$urlget = ConfigServer::URLGet->new( $config{URLGET}, "csf/$version", $config{URLPROXY} );
print "*WARNING* URLGET set to use LWP but perl module is not installed, reverting to HTTP::Tiny\n";
$warning .= "*WARNING* URLGET set to use LWP but perl module is not installed, reverting to HTTP::Tiny\n";
}
}
if ( ( -e "/etc/csf/csf.disable" ) and ( $input{command} ne "--enable" ) and ( $input{command} ne "-e" ) ) {
print "csf and lfd have been disabled, use 'csf -e' to enable\n";
my $ok = 0;
foreach my $opt ( "--version", "-v", "--check", "-c", "--ports", "-p", "--help", "-h", "--update", "-u", "-uf", "--flush", "-f", "--profile", "" ) {
if ( $input{command} eq $opt ) {
$ok = 1;
last;
}
}
unless ($ok) { return 1 }
}
unless ( -e $config{IPTABLES} ) { error( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} (iptables binary location) does not exist!" ) }
if ( $config{IPV6} and !( -e $config{IP6TABLES} ) ) { error( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} (ip6tables binary location) does not exist!" ) }
if ( ( -e "/etc/csf/csf.error" ) and ( $input{command} ne "--startf" ) and ( $input{command} ne "-sf" ) and ( $input{command} ne "-q" ) and ( $input{command} ne "--startq" ) and ( $input{command} ne "--start" ) and ( $input{command} ne "-s" ) and ( $input{command} ne "--restart" ) and ( $input{command} ne "-r" ) and ( $input{command} ne "--enable" ) and ( $input{command} ne "-e" ) ) {
my ($error) = slurpee( "/etc/csf/csf.error", 'fatal' => 1 );
chomp $error;
print "You have an unresolved error when starting csf:\n$error\n\nYou need to restart csf successfully to remove this warning, or delete /etc/csf/csf.error\n";
return 1;
}
unless ( $input{command} =~ /^--(stop|initdown|initup)$/ ) {
if ( -e "/var/lib/csf/csf.4.saved" ) { unlink "/var/lib/csf/csf.4.saved" }
if ( -e "/var/lib/csf/csf.4.ipsets" ) { unlink "/var/lib/csf/csf.4.ipsets" }
if ( -e "/var/lib/csf/csf.6.saved" ) { unlink "/var/lib/csf/csf.6.saved" }
}
if ( ( $input{command} eq "--status" ) or ( $input{command} eq "-l" ) ) { dostatus() }
elsif ( ( $input{command} eq "--status6" ) or ( $input{command} eq "-l6" ) ) { dostatus6() }
elsif ( ( $input{command} eq "--version" ) or ( $input{command} eq "-v" ) ) { doversion() }
elsif ( ( $input{command} eq "--stop" ) or ( $input{command} eq "-f" ) ) { csflock("lock"); dostop(0); csflock("unlock") }
elsif ( ( $input{command} eq "--startf" ) or ( $input{command} eq "-sf" ) ) { csflock("lock"); dostop(1); dostart(); csflock("unlock") }
elsif ( ( $input{command} eq "--start" ) or ( $input{command} eq "-s" ) or ( $input{command} eq "--restart" ) or ( $input{command} eq "-r" ) ) {
if ( $config{LFDSTART} ) { lfdstart() }
else { csflock("lock"); dostop(1); dostart(); csflock("unlock") }
}
elsif ( ( $input{command} eq "--startq" ) or ( $input{command} eq "-q" ) ) { lfdstart() }
elsif ( ( $input{command} eq "--restartall" ) or ( $input{command} eq "-ra" ) ) { dorestartall() }
elsif ( ( $input{command} eq "--add" ) or ( $input{command} eq "-a" ) ) { doadd() }
elsif ( ( $input{command} eq "--deny" ) or ( $input{command} eq "-d" ) ) { dodeny() }
elsif ( ( $input{command} eq "--denyrm" ) or ( $input{command} eq "-dr" ) ) { dokill() }
elsif ( ( $input{command} eq "--denyf" ) or ( $input{command} eq "-df" ) ) { dokillall() }
elsif ( ( $input{command} eq "--addrm" ) or ( $input{command} eq "-ar" ) ) { doakill() }
elsif ( ( $input{command} eq "--disable" ) or ( $input{command} eq "-x" ) ) { csflock("lock"); dodisable(); csflock("unlock") }
elsif ( ( $input{command} eq "--enable" ) or ( $input{command} eq "-e" ) ) { csflock("lock"); doenable(); csflock("unlock") }
elsif ( ( $input{command} eq "--check" ) or ( $input{command} eq "-c" ) ) { docheck() }
elsif ( ( $input{command} eq "--grep" ) or ( $input{command} eq "-g" ) ) { dogrep() }
elsif ( ( $input{command} eq "--iplookup" ) or ( $input{command} eq "-i" ) ) { doiplookup() }
elsif ( ( $input{command} eq "--temp" ) or ( $input{command} eq "-t" ) ) { dotempban() }
elsif ( ( $input{command} eq "--temprm" ) or ( $input{command} eq "-tr" ) ) { dotemprm() }
elsif ( ( $input{command} eq "--temprma" ) or ( $input{command} eq "-tra" ) ) { dotemprma() }
elsif ( ( $input{command} eq "--temprmd" ) or ( $input{command} eq "-trd" ) ) { dotemprmd() }
elsif ( ( $input{command} eq "--tempdeny" ) or ( $input{command} eq "-td" ) ) { dotempdeny() }
elsif ( ( $input{command} eq "--tempallow" ) or ( $input{command} eq "-ta" ) ) { dotempallow() }
elsif ( ( $input{command} eq "--tempf" ) or ( $input{command} eq "-tf" ) ) { dotempf() }
elsif ( ( $input{command} eq "--mail" ) or ( $input{command} eq "-m" ) ) { domail() }
elsif ( ( $input{command} eq "--cdeny" ) or ( $input{command} eq "-cd" ) ) { doclusterdeny() }
elsif ( ( $input{command} eq "--ctempdeny" ) or ( $input{command} eq "-ctd" ) ) { doclustertempdeny() }
elsif ( ( $input{command} eq "--callow" ) or ( $input{command} eq "-ca" ) ) { doclusterallow() }
elsif ( ( $input{command} eq "--ctempallow" ) or ( $input{command} eq "-cta" ) ) { doclustertempallow() }
elsif ( ( $input{command} eq "--crm" ) or ( $input{command} eq "-cr" ) ) { doclusterrm() }
elsif ( ( $input{command} eq "--carm" ) or ( $input{command} eq "-car" ) ) { doclusterarm() }
elsif ( ( $input{command} eq "--cignore" ) or ( $input{command} eq "-ci" ) ) { doclusterignore() }
elsif ( ( $input{command} eq "--cirm" ) or ( $input{command} eq "-cir" ) ) { doclusterirm() }
elsif ( ( $input{command} eq "--cping" ) or ( $input{command} eq "-cp" ) ) { clustersend("PING") }
elsif ( ( $input{command} eq "--cgrep" ) or ( $input{command} eq "-cg" ) ) { doclustergrep() }
elsif ( ( $input{command} eq "--cconfig" ) or ( $input{command} eq "-cc" ) ) { docconfig() }
elsif ( ( $input{command} eq "--cfile" ) or ( $input{command} eq "-cf" ) ) { docfile() }
elsif ( ( $input{command} eq "--crestart" ) or ( $input{command} eq "-crs" ) ) { docrestart() }
elsif ( ( $input{command} eq "--watch" ) or ( $input{command} eq "-w" ) ) { dowatch() }
elsif ( ( $input{command} eq "--logrun" ) or ( $input{command} eq "-lr" ) ) { dologrun() }
elsif ( ( $input{command} eq "--ports" ) or ( $input{command} eq "-p" ) ) { doports() }
elsif ( $input{command} eq "--cloudflare" ) { docloudflare() }
elsif ( $input{command} eq "--graphs" ) { dographs() }
elsif ( $input{command} eq "--lfd" ) { dolfd() }
elsif ( $input{command} eq "--rbl" ) { dorbls() }
elsif ( $input{command} eq "--initup" ) { doinitup() }
elsif ( $input{command} eq "--initdown" ) { doinitdown() }
elsif ( $input{command} eq "--profile" ) { doprofile() }
elsif ( $input{command} eq "--mregen" ) { domessengerv2() }
elsif ( $input{command} eq "--trace" ) { dotrace() }
else { dohelp() }
if ( $config{TESTING} ) { print "*WARNING* TESTING mode is enabled - do not forget to disable it in the configuration\n" }
if ( ( $input{command} eq "--start" ) or ( $input{command} eq "-s" ) or ( $input{command} eq "--restart" ) or ( $input{command} eq "-r" ) or ( $input{command} eq "--restartall" ) or ( $input{command} eq "-ra" ) ) {
if ($warning) { print $warning }
foreach my $key ( keys %config ) {
my ( $insane, $range, $default ) = ConfigServer::Sanity::sanity( $key, $config{$key} );
if ($insane) { print "*WARNING* $key sanity check. $key = $config{$key}. Recommended range: $range (Default: $default)\n" }
}
unless ( $config{RESTRICT_SYSLOG} ) { print "\n*WARNING* RESTRICT_SYSLOG is disabled. See SECURITY WARNING in /etc/csf/csf.conf.\n" }
}
return 0;
}
# End of run() subroutine - all other subroutines follow below
sub csflock {
my $lock = shift;
if ( $lock eq "lock" ) {
sysopen( $csflockfile_fh, "/var/lib/csf/csf.lock", O_RDWR | O_CREAT ) or die("Error: Unable to open csf lock file: $!");
flock( $csflockfile_fh, LOCK_EX | LOCK_NB ) or die "Error: csf is being restarted, try again in a moment: $!";
}
else {
close($csflockfile_fh) if defined $csflockfile_fh;
}
return;
}
sub load_config {
my $config = ConfigServer::Config->loadconfig();
%config = $config->config;
my %configsetting = $config->configsetting;
$ipv4reg = $config->ipv4reg;
$ipv6reg = $config->ipv6reg;
$warning .= $config->{warning} // "";
if ( $config{CLUSTER_SENDTO} or $config{CLUSTER_RECVFROM} ) {
require Crypt::CBC;
import Crypt::CBC;
require File::Basename;
import File::Basename;
require IO::Socket::INET;
import IO::Socket::INET;
}
if ( $config{CF_ENABLE} ) {
require ConfigServer::CloudFlare;
import ConfigServer::CloudFlare;
}
$verbose = "";
if ( $config{VERBOSE} or $config{DEBUG} >= 1 ) { $verbose = "-v" }
$logintarget = "LOG --log-prefix";
$logouttarget = "LOG --log-uid --log-prefix";
unless ( $config{DROP_UID_LOGGING} ) { $logouttarget = "LOG --log-prefix" }
$accept = "ACCEPT";
if ( $config{WATCH_MODE} ) {
$accept = "LOGACCEPT";
$config{DROP_NOLOG} = "";
$config{DROP_LOGGING} = "1";
$config{DROP_IP_LOGGING} = "1";
$config{DROP_OUT_LOGGING} = "1";
$config{DROP_PF_LOGGING} = "1";
$config{PS_INTERVAL} = "0";
$config{DROP_ONLYRES} = "0";
}
if ( $config{MESSENGER} ) {
foreach my $port ( split( /\,/, $config{MESSENGER_HTTPS_IN} ) ) { $messengerports{$port} = 1 }
foreach my $port ( split( /\,/, $config{MESSENGER_HTML_IN} ) ) { $messengerports{$port} = 1 }
foreach my $port ( split( /\,/, $config{MESSENGER_TEXT_IN} ) ) { $messengerports{$port} = 1 }
}
$statemodule = "-m state --state";
if ( $config{USE_CONNTRACK} ) { $statemodule = "-m conntrack --ctstate" }
if ( $config{LF_SPI} ) {
$statemodulenew = "$statemodule NEW";
}
else {
$statemodulenew = "";
}
if ( $config{IPV6_SPI} ) {
$statemodule6new = "$statemodule NEW";
}
else {
$statemodule6new = "";
}
my @entries = slurp("/etc/csf/csf.blocklists");
foreach my $line (@entries) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @entries, @incfile;
}
}
foreach my $line (@entries) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $name, $interval, $max, $url ) = split( /\|/, $line );
if ( $name =~ /^\w+$/ ) {
$name = substr( uc $name, 0, 25 );
if ( $name =~ /^CXS_/ ) { $name =~ s/^CXS_/X_CXS_/ }
if ( $interval < 3600 ) { $interval = 3600 }
if ( $max eq "" ) { $max = 0 }
$blocklists{$name}{interval} = $interval;
$blocklists{$name}{max} = $max;
$blocklists{$name}{url} = $url;
}
}
if ( -e "/etc/cxs/cxs.reputation" and -e "/usr/local/csf/lib/ConfigServer/cxs.pm" ) {
require ConfigServer::cxs;
import ConfigServer::cxs;
$cxsreputation = 1;
if ( -e "/etc/cxs/cxs.blocklists" ) {
my $all = 0;
my @lines = slurp("/etc/cxs/cxs.blocklists");
if ( grep { $_ =~ /^CXS_ALL/ } @lines ) {
$all = 1;
}
foreach my $line (@lines) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $name, $interval, $max, $url ) = split( /\|/, $line );
if ( $all and $name ne "CXS_ALL" ) { next }
if ( $name =~ /^\w+$/ ) {
$name = substr( uc $name, 0, 25 );
if ( $max eq "" ) { $max = 0 }
$blocklists{$name}{interval} = $interval;
$blocklists{$name}{max} = $max;
$blocklists{$name}{url} = $url;
}
}
}
%cxsports = ConfigServer::cxs::Rports();
}
my @binaries = ( "IPTABLES", "IPTABLES_SAVE", "IPTABLES_RESTORE", "MODPROBE", "SENDMAIL", "PS", "VMSTAT", "LS", "MD5SUM", "TAR", "CHATTR", "UNZIP", "GUNZIP", "DD", "TAIL", "GREP", "HOST" );
if ( $config{IPV6} ) { push @binaries, ( "IP6TABLES", "IP6TABLES_SAVE", "IP6TABLES_RESTORE" ) }
if ( $config{LF_IPSET} ) { push @binaries, ("IPSET") }
if ( ConfigServer::Service::type() eq "systemd" ) { push @binaries, ("SYSTEMCTL") }
my $hit = 0;
foreach my $bin (@binaries) {
if ( $bin eq "SENDMAIL" and $config{LF_ALERT_SMTP} ) { next }
unless ( -e $config{$bin} and -x $config{$bin} ) {
$warning .= "*WARNING* Binary location for [$bin] [$config{$bin}] in /etc/csf/csf.conf is either incorrect, is not installed or is not executable\n";
$hit = 1;
}
}
my $iphit = 0;
if ( -e $config{IP} or -e $config{IFCONFIG} ) { $iphit = 1 }
unless ($iphit) {
$warning .= "*WARNING* Binary location for either [IP] [$config{IP}] or [IFCONFIG] [$config{IFCONFIG}] in /etc/csf/csf.conf must be set correctly, installed and executable\n";
$hit = 1;
}
if ($hit) { $warning .= "*WARNING* Missing or incorrect binary locations will break csf and lfd functionality\n" }
return;
}
sub process_input {
# Make a copy of @ARGV to avoid modifying it as it is used elsewhere in the script
my @arguments = @ARGV;
$input{command} = lc shift @arguments;
$input{argument} = \@arguments;
# Some functions use the rest of the arguments as a comment
$input{comment} = join( " ", @arguments[ 1 .. $#arguments ] );
return;
}
sub dostatus {
print "iptables filter table\n";
print "=====================\n";
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} -v -L -n --line-numbers" );
if ( $config{MANGLE} ) {
print "\n\n";
print "iptables mangle table\n";
print "=====================\n";
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} -v -t mangle -L -n --line-numbers" );
}
if ( $config{RAW} ) {
print "\n\n";
print "iptables raw table\n";
print "==================\n";
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} -v -t raw -L -n --line-numbers" );
}
if ( $config{NAT} ) {
print "\n\n";
print "iptables nat table\n";
print "==================\n";
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} -v -t nat -L -n --line-numbers" );
}
return;
}
sub dostatus6 {
if ( $config{IPV6} ) {
print "ip6tables filter table\n";
print "======================\n";
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} -v -L -n --line-numbers" );
if ( $config{MANGLE6} ) {
print "\n\n";
print "ip6tables mangle table\n";
print "======================\n";
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} -v -t mangle -L -n --line-numbers" );
}
if ( $config{RAW6} ) {
print "\n\n";
print "ip6tables raw table\n";
print "===================\n";
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} -v -t raw -L -n --line-numbers" );
}
if ( $config{NAT6} ) {
print "\n\n";
print "ip6tables nat table\n";
print "===================\n";
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} -v -t nat -L -n --line-numbers" );
}
}
else {
print "csf: IPV6 firewall not enabled\n";
}
return;
}
sub doversion {
print "csf: v$version (cPanel)\n";
return;
}
sub dolfd {
my $lfd = $input{argument}[0];
if ( $lfd eq "start" ) { ConfigServer::Service::startlfd() }
elsif ( $lfd eq "stop" ) { ConfigServer::Service::stoplfd() }
elsif ( $lfd eq "restart" ) { ConfigServer::Service::restartlfd() }
elsif ( $lfd eq "status" ) { ConfigServer::Service::statuslfd() }
else { print "csf: usage: csf --lfd [stop|start|restart|status]\n" }
return;
}
sub dorestartall {
csflock("lock");
dostop(1);
dostart();
csflock("unlock");
ConfigServer::Service::restartlfd();
return;
}
sub doinitup {
csflock("lock");
if ( $config{FASTSTART} ) {
modprobe();
if ( -e "/var/lib/csf/csf.4.saved" ) {
if ( $config{LF_IPSET} ) {
if ( -x $config{IPSET} ) {
print "(restoring ipsets) ";
my @data = slurpee( "/var/lib/csf/csf.4.ipsets", 'fatal' => 1 );
chomp @data;
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{IPSET}, "restore" );
print $childin join( "\n", @data ) . "\n";
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
unlink "/var/lib/csf/csf.4.ipsets";
}
}
print "(restoring iptables) ";
my @data = slurpee( "/var/lib/csf/csf.4.saved", 'fatal' => 1 );
chomp @data;
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{IPTABLES_RESTORE} );
print $childin join( "\n", @data ) . "\n";
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
unlink "/var/lib/csf/csf.4.saved";
}
else {
dostop(1);
dostart();
exit 0; ## no critic (Cpanel::NoExitsFromSubroutines) - CLI command completion after restart
}
if ( $config{IPV6} ) {
if ( -e "/var/lib/csf/csf.6.saved" ) {
print "(restoring ip6tables) ";
my @data = slurpee( "/var/lib/csf/csf.6.saved", 'fatal' => 1 );
chomp @data;
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{IP6TABLES_RESTORE} );
print $childin join( "\n", @data ) . "\n";
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
unlink "/var/lib/csf/csf.6.saved";
}
else {
dostop(1);
dostart();
exit 0;
}
}
}
else {
dostop(1);
dostart();
}
csflock("unlock");
return;
}
sub doinitdown {
if ( $config{FASTSTART} ) {
if ( -x $config{IPTABLES_SAVE} ) {
print "(saving iptables) ";
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{IPTABLES_SAVE} );
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
open( my $OUT, ">", "/var/lib/csf/csf.4.saved" );
flock( $OUT, LOCK_EX );
print $OUT join( "\n", @results ) . "\n";
close($OUT);
if ( $config{LF_IPSET} ) {
if ( -x $config{IPSET} ) {
print "(saving ipsets) ";
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{IPSET}, "save" );
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
open( my $OUT, ">", "/var/lib/csf/csf.4.ipsets" );
flock( $OUT, LOCK_EX );
print $OUT join( "\n", @results ) . "\n";
close($OUT);
}
}
}
if ( $config{IPV6} and -x $config{IP6TABLES_SAVE} ) {
print "(saving ip6tables) ";
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{IP6TABLES_SAVE} );
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
open( my $OUT, ">", "/var/lib/csf/csf.6.saved" );
flock( $OUT, LOCK_EX );
print $OUT join( "\n", @results ) . "\n";
close($OUT);
}
}
return;
}
sub doclusterdeny {
my $ip = $input{argument}[0];
my $comment = $input{comment};
if ( !checkip( \$ip ) ) {
print "[$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
clustersend("D $ip 1 * inout 3600 $comment");
return;
}
sub doclustertempdeny {
my ( $ip, $timeout, $portdir ) = @{ $input{argument} }[ 0 .. 2 ];
my $inout = "in";
my $ports = "";
my $perm = 0;
if ( $timeout =~ /^(\d*)([mhd])/i ) {
my $secs = $1;
my $dur = lc $2;
if ( $dur eq "m" ) { $timeout = $secs * 60 }
elsif ( $dur eq "h" ) { $timeout = $secs * 60 * 60 }
elsif ( $dur eq "d" ) { $timeout = $secs * 60 * 60 * 24 }
else { $timeout = $secs }
}
my $iptype = checkip( \$ip );
if ( !$iptype ) {
print "csf: [$ip] is not a valid PUBLIC IP\n";
return;
}
if ( $iptype == 6 and !$config{IPV6} ) {
print "failed: [$ip] is valid IPv6 but IPV6 is not enabled in csf.conf\n";
}
if ( $timeout =~ /\D/ ) {
$portdir = join( " ", $timeout, $portdir );
$timeout = 0;
}
if ( $portdir =~ /\-d\s*out/i ) { $inout = "out" }
if ( $portdir =~ /\-d\s*inout/i ) { $inout = "inout" }
if ( $portdir =~ /\-p\s*([\w\,\*\;]+)/ ) { $ports = $1 }
my $comment = $portdir;
$comment =~ s/\-d\s*out//ig;
$comment =~ s/\-d\s*inout//ig;
$comment =~ s/\-d\s*in//ig;
$comment =~ s/\-p\s*[\w\,\*\;]+//ig;
$comment =~ s/^\s*|\s*$//g;
if ( $comment eq "" ) { $comment = "Manually added: " . iplookup($ip) }
if ( !length $timeout || $timeout < 2 ) { $timeout = 3600 }
if ( $ports eq "" ) { $ports = "*" }
if ( !checkip( \$ip ) ) {
print "[$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
clustersend("TD $ip $perm $ports $inout $timeout $comment");
return;
}
sub doclusterrm {
my $ip = $input{argument}[0];
my $comment = $input{comment};
if ( !checkip( \$ip ) ) {
print "[$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
clustersend("R $ip");
return;
}
sub doclusterarm {
my $ip = $input{argument}[0];
my $comment = $input{comment};
if ( !checkip( \$ip ) ) {
print "[$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
clustersend("AR $ip");
return;
}
sub doclusterallow {
my $ip = $input{argument}[0];
my $comment = $input{comment};
if ( !checkip( \$ip ) ) {
print "[$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
clustersend("A $ip 1 * inout 3600 $comment");
return;
}
sub doclustertempallow {
my ( $ip, $timeout, $portdir ) = @{ $input{argument} }[ 0 .. 2 ];
my $inout = "in";
my $ports = "";
my $perm = 0;
if ( $timeout =~ /^(\d*)([mhd])/i ) {
my $secs = $1;
my $dur = lc $2;
if ( $dur eq "m" ) { $timeout = $secs * 60 }
elsif ( $dur eq "h" ) { $timeout = $secs * 60 * 60 }
elsif ( $dur eq "d" ) { $timeout = $secs * 60 * 60 * 24 }
else { $timeout = $secs }
}
my $iptype = checkip( \$ip );
if ( $iptype == 6 and !$config{IPV6} ) {
print "failed: [$ip] is valid IPv6 but IPV6 is not enabled in csf.conf\n";
}
unless ($iptype) {
print "csf: [$ip] is not a valid PUBLIC IP\n";
return;
}
if ( $timeout =~ /\D/ ) {
$portdir = join( " ", $timeout, $portdir );
$timeout = 0;
}
if ( $portdir =~ /\-d\s*out/i ) { $inout = "out" }
if ( $portdir =~ /\-d\s*inout/i ) { $inout = "inout" }
if ( $portdir =~ /\-p\s*([\w\,\*\;]+)/ ) { $ports = $1 }
my $comment = $portdir;
$comment =~ s/\-d\s*out//ig;
$comment =~ s/\-d\s*inout//ig;
$comment =~ s/\-d\s*in//ig;
$comment =~ s/\-p\s*[\w\,\*\;]+//ig;
$comment =~ s/^\s*|\s*$//g;
if ( $comment eq "" ) { $comment = "Manually added: " . iplookup($ip) }
if ( $timeout < 2 ) { $timeout = 3600 }
if ( $ports eq "" ) { $ports = "*" }
if ( !checkip( \$ip ) ) {
print "[$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
clustersend("TA $ip $perm $ports $inout $timeout $comment");
return;
}
sub doclusterignore {
my $ip = $input{argument}[0];
my $comment = $input{comment};
if ( !checkip( \$ip ) ) {
print "[$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
clustersend("I $ip $comment");
return;
}
sub doclusterirm {
my $ip = $input{argument}[0];
my $comment = $input{comment};
if ( !checkip( \$ip ) ) {
print "[$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
clustersend("IR $ip");
return;
}
sub docconfig {
my ( $name, $value ) = @{ $input{argument} }[ 0, 1 ];
unless ( $config{CLUSTER_CONFIG} ) { print "No configuration setting requests allowed\n"; return }
unless ($name) { print "No configuration setting entered\n"; return }
clustersend("C $name $value");
return;
}
sub doclustergrep {
my $ip = $input{argument}[0];
if ( !checkip( \$ip ) ) {
print "[$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
clustersend("G $ip");
return;
}
sub docfile {
my $name = $input{argument}[0];
unless ( $config{CLUSTER_CONFIG} ) { print "No configuration setting requests allowed\n"; return }
unless ($name) { print "No file entered\n"; return }
if ( -e $name ) {
my @data = slurpee( $name, 'fatal' => 1 );
my ( $file, $filedir ) = File::Basename::fileparse($name);
my $send = "FILE $file\n";
foreach my $line (@data) { $send .= $line }
clustersend($send);
}
else {
print "csf: Error [$name] does not exist\n";
}
return;
}
sub docrestart {
clustersend("RESTART");
return;
}
sub clustersend {
my $text = shift;
my $cipher = Crypt::CBC->new( -key => $config{CLUSTER_KEY}, -cipher => 'Blowfish' );
my $encrypted = $cipher->encrypt($text) . "END\n";
foreach my $cip ( split( /\,/, $config{CLUSTER_SENDTO} ) ) {
my $localaddr = "0.0.0.0";
if ( $config{CLUSTER_LOCALADDR} ) { $localaddr = $config{CLUSTER_LOCALADDR} }
my $sock;
eval { $sock = IO::Socket::INET->new( PeerAddr => $cip, PeerPort => $config{CLUSTER_PORT}, LocalAddr => $localaddr, Timeout => '10' ) or print "Cluster error connecting to $cip: $!\n"; };
unless ( defined $sock ) {
print "Failed to connect to $cip\n";
}
else {
my $status = send( $sock, $encrypted, 0 );
unless ($status) {
print "Failed for $cip: $status\n";
}
else {
print "Sent request to $cip";
my $select = IO::Select->new($sock);
if ( $select->can_read(5) ) {
my $line;
while (<$sock>) { $line .= $_ }
chomp $line;
if ( $text =~ /^G / ) {
print ", reply:\n";
print "=" x 80;
print $line;
print "=" x 80;
print "\n";
}
else {
print ", replied: [$line]";
}
}
else {
print ", no reply";
}
print "\n";
}
shutdown( $sock, 2 );
}
}
return;
}
sub lfdstart {
open( my $FH, ">", "/var/lib/csf/csf.restart" ) or die "Failed to create csf.restart - $!";
flock( $FH, LOCK_EX );
close($FH);
print "lfd will restart csf within the next $config{LF_PARSE} seconds\n";
return;
}
sub dostop {
my $restart = shift;
syscommand( __LINE__, "$config{IPTABLES} $verbose --policy INPUT ACCEPT" );
syscommand( __LINE__, "$config{IPTABLES} $verbose --policy OUTPUT ACCEPT" );
syscommand( __LINE__, "$config{IPTABLES} $verbose --policy FORWARD ACCEPT" );
syscommand( __LINE__, "$config{IPTABLES} $verbose --flush" );
syscommand( __LINE__, "$config{IPTABLES} $verbose --delete-chain" );
if ( $config{NAT} ) {
syscommand( __LINE__, "$config{IPTABLES} $verbose -t nat --flush" );
syscommand( __LINE__, "$config{IPTABLES} $verbose -t nat --delete-chain" );
}
if ( $config{RAW} ) {
syscommand( __LINE__, "$config{IPTABLES} $verbose -t raw --flush" );
syscommand( __LINE__, "$config{IPTABLES} $verbose -t raw --delete-chain" );
}
if ( $config{MANGLE} ) {
syscommand( __LINE__, "$config{IPTABLES} $verbose -t mangle --flush" );
syscommand( __LINE__, "$config{IPTABLES} $verbose -t mangle --delete-chain" );
}
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $verbose --policy INPUT ACCEPT" );
syscommand( __LINE__, "$config{IP6TABLES} $verbose --policy OUTPUT ACCEPT" );
syscommand( __LINE__, "$config{IP6TABLES} $verbose --policy FORWARD ACCEPT" );
syscommand( __LINE__, "$config{IP6TABLES} $verbose --flush" );
syscommand( __LINE__, "$config{IP6TABLES} $verbose --delete-chain" );
if ( $config{NAT6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t nat --flush" );
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t nat --delete-chain" );
}
if ( $config{RAW6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t raw --flush" );
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t raw --delete-chain" );
}
if ( $config{MANGLE6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t mangle --flush" );
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t mangle --delete-chain" );
}
}
if ( $config{LF_IPSET} ) {
syscommand( __LINE__, "$config{IPSET} flush" );
syscommand( __LINE__, "$config{IPSET} destroy" );
}
if ( $config{TESTING} ) { crontab("remove") }
return;
}
sub dostart {
if ( ConfigServer::Service::type() eq "systemd" ) {
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{SYSTEMCTL}, "is-active", "firewalld" );
my @reply = <$childout>;
waitpid( $cmdpid, 0 );
chomp @reply;
if ( $reply[0] eq "active" or $reply[0] eq "activating" ) {
error( __LINE__, "*Error* firewalld found to be running. You must stop and disable firewalld when using csf" );
exit 1; ## no critic (Cpanel::NoExitsFromSubroutines) - Fatal configuration error - conflicting firewall service
}
}
if ( $config{TESTING} ) { crontab("add") }
else { crontab("remove") }
if ( -e "/etc/csf/csf.error" ) { unlink("/etc/csf/csf.error") }
getethdev();
modprobe();
$noowner = 0;
if ( $config{VPS} and $config{SMTP_BLOCK} ) {
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, "$config{IPTABLES} $config{IPTABLESWAIT} -I OUTPUT -p tcp --dport 9999 -m owner --uid-owner 0 -j $accept" );
my @ipdata = <$childout>;
waitpid( $cmdpid, 0 );
chomp @ipdata;
if ( $ipdata[0] =~ /# Warning: iptables-legacy tables present/ ) { shift @ipdata }
if ( $ipdata[0] =~ /^iptables/ ) {
$warning .= "*WARNING* Cannot use SMTP_BLOCK on this VPS as the Monolithic kernel does not support the iptables module ipt_owner/xt_owner - SMTP_BLOCK disabled\n";
$config{SMTP_BLOCK} = 0;
$noowner = 1;
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} -D OUTPUT -p tcp --dport 9999 -m owner --uid-owner 0 -j $accept", 0 );
}
}
my $path = "PATH=\$PATH:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin";
my $csfpre = "";
my $csfpost = "";
if ( -e "/usr/local/csf/bin/csfpre.sh" ) { $csfpre = "/usr/local/csf/bin/csfpre.sh" }
elsif ( -e "/etc/csf/csfpre.sh" ) { $csfpre = "/etc/csf/csfpre.sh" }
if ( -e "/usr/local/csf/bin/csfpost.sh" ) { $csfpost = "/usr/local/csf/bin/csfpost.sh" }
elsif ( -e "/etc/csf/csfpost.sh" ) { $csfpost = "/etc/csf/csfpost.sh" }
if ( $csfpre ne "" ) {
chmod( 0700, $csfpre );
my @conf = slurp($csfpre);
if ( $conf[0] !~ /^\#\!/ ) {
open( my $CONF, ">", $csfpre );
flock( $CONF, LOCK_EX );
print $CONF "#!/bin/bash\n";
foreach my $line (@conf) {
$line =~ s/$cleanreg//g;
print $CONF "$line\n";
}
close($CONF);
}
print "Running $csfpre\n";
syscommand( __LINE__, "$path ; $csfpre" );
}
if ( $config{WATCH_MODE} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N LOGACCEPT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOGACCEPT -j ACCEPT" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N LOGACCEPT" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOGACCEPT -j ACCEPT" );
}
}
foreach my $name ( keys %blocklists ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N $name" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N $name" );
}
}
if ( $config{CC_ALLOW_FILTER} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N CC_ALLOWF" ) }
if ( $config{CC_ALLOW_PORTS} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N CC_ALLOWP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N CC_ALLOWPORTS" );
}
if ( $config{CC_DENY_PORTS} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N CC_DENYP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N CC_DENYPORTS" );
}
if ( $config{CC_ALLOW} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N CC_ALLOW" ) }
if ( $config{CC_DENY} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N CC_DENY" ) }
if ( scalar( keys %blocklists ) > 0 and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N BLOCKDROP" ) }
if ( ( $config{CC_DENY} or $config{CC_ALLOW_FILTER} ) and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N CCDROP" ) }
if ( $config{IPV6} ) {
if ( $config{CC_ALLOW_FILTER} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N CC_ALLOWF" ) }
if ( $config{CC_ALLOW_PORTS} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N CC_ALLOWP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N CC_ALLOWPORTS" );
}
if ( $config{CC_DENY_PORTS} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N CC_DENYP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N CC_DENYPORTS" );
}
if ( $config{CC_ALLOW} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N CC_ALLOW" ) }
if ( $config{CC_DENY} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N CC_DENY" ) }
if ( scalar( keys %blocklists ) > 0 and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N BLOCKDROP" ) }
if ( ( $config{CC_DENY} or $config{CC_ALLOW_FILTER} ) and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N CCDROP" ) }
}
if ( $config{GLOBAL_ALLOW} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N GALLOWIN" ) }
if ( $config{GLOBAL_ALLOW} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N GALLOWOUT" ) }
if ( $config{GLOBAL_DENY} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N GDENYIN" ) }
if ( $config{GLOBAL_DENY} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N GDENYOUT" ) }
if ( $config{DYNDNS} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N ALLOWDYNIN" ) }
if ( $config{DYNDNS} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N ALLOWDYNOUT" ) }
if ( $config{GLOBAL_DYNDNS} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N GDYNIN" ) }
if ( $config{GLOBAL_DYNDNS} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N GDYNOUT" ) }
if ( $config{SYNFLOOD} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N SYNFLOOD" ) }
if ( $config{PORTFLOOD} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N PORTFLOOD" ) }
if ( $config{CONNLIMIT} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N CONNLIMIT" ) }
if ( $config{UDPFLOOD} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N UDPFLOOD" ) }
if ( $config{IPV6} ) {
if ( $config{GLOBAL_ALLOW} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N GALLOWIN" ) }
if ( $config{GLOBAL_ALLOW} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N GALLOWOUT" ) }
if ( $config{GLOBAL_DENY} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N GDENYIN" ) }
if ( $config{GLOBAL_DENY} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N GDENYOUT" ) }
if ( $config{DYNDNS} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N ALLOWDYNIN" ) }
if ( $config{DYNDNS} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N ALLOWDYNOUT" ) }
if ( $config{GLOBAL_DYNDNS} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N GDYNIN" ) }
if ( $config{GLOBAL_DYNDNS} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N GDYNOUT" ) }
if ( $config{SYNFLOOD} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N SYNFLOOD" ) }
if ( $config{PORTFLOOD6} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N PORTFLOOD" ) }
if ( $config{CONNLIMIT6} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N CONNLIMIT" ) }
if ( $config{UDPFLOOD} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N UDPFLOOD" ) }
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N LOGDROPIN" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N LOGDROPOUT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N DENYIN" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N DENYOUT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N ALLOWIN" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N ALLOWOUT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N LOCALINPUT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N LOCALOUTPUT" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N LOGDROPIN" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N LOGDROPOUT" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N DENYIN" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N DENYOUT" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N ALLOWIN" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N ALLOWOUT" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N LOCALINPUT" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N LOCALOUTPUT" );
}
if ( $config{DROP_LOGGING} ) {
my $dports = "";
if ( $config{DROP_ONLYRES} ) { $dports = "--dport 0:1023" }
$config{DROP_NOLOG} =~ s/\s//g;
if ( $config{DROP_NOLOG} ne "" ) {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $port ( split( /\,/, $config{DROP_NOLOG} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid DROP_NOLOG port [$port]" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -p tcp --dport $port -j $config{DROP}" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -p udp --dport $port -j $config{DROP}" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -p tcp --dport $port -j $config{DROP}" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -p udp --dport $port -j $config{DROP}" );
}
}
if ( $config{FASTSTART} ) { faststart("DROP no logging") }
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -p tcp $dports -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *TCP_IN Blocked* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPOUT -p tcp --syn -m limit --limit 30/m --limit-burst 5 -j $logouttarget 'Firewall: *TCP_OUT Blocked* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -p udp $dports -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *UDP_IN Blocked* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPOUT -p udp -m limit --limit 30/m --limit-burst 5 -j $logouttarget 'Firewall: *UDP_OUT Blocked* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -p icmp -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *ICMP_IN Blocked* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPOUT -p icmp -m limit --limit 30/m --limit-burst 5 -j $logouttarget 'Firewall: *ICMP_OUT Blocked* '" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -p tcp $dports -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *TCP6IN Blocked* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPOUT -p tcp --syn -m limit --limit 30/m --limit-burst 5 -j $logouttarget 'Firewall: *TCP6OUT Blocked* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -p udp $dports -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *UDP6IN Blocked* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPOUT -p udp -m limit --limit 30/m --limit-burst 5 -j $logouttarget 'Firewall: *UDP6OUT Blocked* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -p icmpv6 -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *ICMP6IN Blocked* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPOUT -p icmpv6 -m limit --limit 30/m --limit-burst 5 -j $logouttarget 'Firewall: *ICMP6OUT Blocked* '" );
}
if ( scalar( keys %blocklists ) > 0 and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A BLOCKDROP -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *BLOCK_LIST* '" ); }
if ( ( $config{CC_DENY} or $config{CC_ALLOW_FILTER} ) and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CCDROP -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *CC_DENY* '" ); }
if ( $config{PORTFLOOD} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A PORTFLOOD -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *Port Flood* '" ); }
if ( $config{IPV6} ) {
if ( scalar( keys %blocklists ) > 0 and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A BLOCKDROP -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *BLOCK_LIST* '" ); }
if ( ( $config{CC_DENY} or $config{CC_ALLOW_FILTER} ) and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CCDROP -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *CC_DENY* '" ); }
if ( $config{PORTFLOOD6} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A PORTFLOOD -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *Port Flood* '" ); }
}
}
if ( scalar( keys %blocklists ) > 0 and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A BLOCKDROP -j $config{DROP}" ); }
if ( ( $config{CC_DENY} or $config{CC_ALLOW_FILTER} ) and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CCDROP -j $config{DROP}" ); }
if ( $config{IPV6} ) {
if ( scalar( keys %blocklists ) > 0 and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A BLOCKDROP -j $config{DROP}" ); }
if ( ( $config{CC_DENY} or $config{CC_ALLOW_FILTER} ) and $config{DROP_IP_LOGGING} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CCDROP -j $config{DROP}" ); }
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -j $config{DROP}" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPOUT -j $config{DROP_OUT}" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPIN -j $config{DROP}" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOGDROPOUT -j $config{DROP_OUT}" );
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALOUTPUT $ethdevout -j DENYOUT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j DENYIN" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I LOCALOUTPUT $ethdevout -j ALLOWOUT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I LOCALINPUT $ethdevin -j ALLOWIN" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALOUTPUT $ethdevout -j DENYOUT" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j DENYIN" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I LOCALOUTPUT $ethdevout -j ALLOWOUT" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I LOCALINPUT $ethdevin -j ALLOWIN" );
}
if ( $config{MESSENGER} ) {
if ( $config{LF_IPSET} ) {
ipsetcreate("MESSENGER");
if ( $config{MESSENGER6} ) { ipsetcreate("MESSENGER_6") }
domessenger( "-m set --match-set MESSENGER src", "A" );
}
}
dopacketfilters();
doportfilters();
my $skipin = 1;
my $skipout = 1;
my $skipin6 = 1;
my $skipout6 = 1;
my $dropout = $config{DROP_OUT};
if ( $config{DROP_OUT_LOGGING} ) { $dropout = "LOGDROPOUT" }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT -i lo -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT -o lo -j $accept" );
unless ( $config{LF_SPI} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -j $accept" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -j $dropout" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -j LOGDROPIN" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT -i lo -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT -o lo -j $accept" );
unless ( $config{IPV6_SPI} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -j $accept" ) }
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -j $dropout" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -j LOGDROPIN" );
}
if ( $config{SMTP_BLOCK} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N SMTPOUTPUT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT -j SMTPOUTPUT" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N SMTPOUTPUT" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT -j SMTPOUTPUT" );
}
if ( $config{FASTSTART} ) { $faststart = 1 }
my $dropout = $config{DROP_OUT};
if ( $config{DROP_OUT_LOGGING} ) { $dropout = "LOGDROPOUT" }
$config{SMTP_PORTS} =~ s/\s//g;
if ( $config{SMTP_PORTS} ne "" ) {
unless ( $config{SMTP_REDIRECT} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I SMTPOUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -j $dropout", 1 ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I SMTPOUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --uid-owner 0 -j $accept", 1 );
if ( $config{IPV6} ) {
unless ( $config{SMTP_REDIRECT} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I SMTPOUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -j $dropout", 1 ) }
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I SMTPOUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --uid-owner 0 -j $accept", 1 );
}
foreach my $item ( split( /\,/, $config{SMTP_ALLOWUSER} ) ) {
$item =~ s/\s//g;
my $uid = ( getpwnam($item) )[2];
if ($uid) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I SMTPOUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --uid-owner $uid -j $accept", 1 );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I SMTPOUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --uid-owner $uid -j $accept", 1 );
}
}
}
foreach my $item ( split( /\,/, $config{SMTP_ALLOWGROUP} ) ) {
$item =~ s/\s//g;
my $gid = ( getgrnam($item) )[2];
if ($gid) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I SMTPOUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --gid-owner $gid -j $accept", 1 );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I SMTPOUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --gid-owner $gid -j $accept", 1 );
}
}
}
if ( $config{SMTP_ALLOWLOCAL} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I SMTPOUTPUT -o lo -p tcp -m multiport --dports $config{SMTP_PORTS} -j $accept", 1 );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I SMTPOUTPUT -o lo -p tcp -m multiport --dports $config{SMTP_PORTS} -j $accept", 1 );
}
}
if ( $config{SMTP_REDIRECT} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -I OUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -j REDIRECT", 1 );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -I OUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --uid-owner 0 -j RETURN", 1 );
if ( $config{IPV6} and $config{SMTP_REDIRECT6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t nat -I OUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -j REDIRECT", 1 );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t nat -I OUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --uid-owner 0 -j RETURN", 1 );
}
foreach my $item ( split( /\,/, $config{SMTP_ALLOWUSER} ) ) {
$item =~ s/\s//g;
my $uid = ( getpwnam($item) )[2];
if ($uid) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -I OUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --uid-owner $uid -j RETURN", 1 );
if ( $config{IPV6} and $config{SMTP_REDIRECT6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t nat -I OUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --uid-owner $uid -j RETURN", 1 );
}
}
}
foreach my $item ( split( /\,/, $config{SMTP_ALLOWGROUP} ) ) {
$item =~ s/\s//g;
my $gid = ( getgrnam($item) )[2];
if ($gid) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -I OUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --gid-owner $gid -j RETURN", 1 );
if ( $config{IPV6} and $config{SMTP_REDIRECT6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t nat -I OUTPUT -p tcp -m multiport --dports $config{SMTP_PORTS} -m owner --gid-owner $gid -j RETURN", 1 );
}
}
}
if ( $config{SMTP_ALLOWLOCAL} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -I OUTPUT -o lo -p tcp -m multiport --dports $config{SMTP_PORTS} -j RETURN", 1 );
if ( $config{IPV6} and $config{SMTP_REDIRECT6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t nat -I OUTPUT -o lo -p tcp -m multiport --dports $config{SMTP_PORTS} -j RETURN", 1 );
}
}
}
}
if ( $config{FASTSTART} ) { faststart("SMTP Block") }
}
if ( $config{FASTSTART} ) { $faststart = 1 }
unless ( $config{DNS_STRICT} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -p udp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -p tcp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -p udp --dport 53 -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -p tcp --dport 53 -j $accept" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $eth6devout -p udp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $eth6devout -p tcp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $eth6devout -p udp --dport 53 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $eth6devout -p tcp --dport 53 -j $accept" );
}
}
unless ( $config{DNS_STRICT_NS} ) {
foreach my $line ( slurp("/etc/resolv.conf") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
if ( $line =~ /^nameserver\s+($ipv4reg)/ ) {
my $ip = $1;
unless ( $ips{$ip} or $ipscidr->find($ip) ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -s $ip -p udp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -s $ip -p tcp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -s $ip -p udp --dport 53 -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -s $ip -p tcp --dport 53 -j $accept" );
$skipin += 4;
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -d $ip -p udp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -d $ip -p tcp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -d $ip -p udp --dport 53 -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -d $ip -p tcp --dport 53 -j $accept" );
$skipout += 4;
}
}
if ( $line =~ /^nameserver\s+($ipv6reg)/ ) {
my $ip = $1;
unless ( $ips{$ip} or $ipscidr6->find($ip) ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -s $ip -p udp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -s $ip -p tcp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -s $ip -p udp --dport 53 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -s $ip -p tcp --dport 53 -j $accept" );
$skipin6 += 4;
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -d $ip -p udp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -d $ip -p tcp --sport 53 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -d $ip -p udp --dport 53 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -d $ip -p tcp --dport 53 -j $accept" );
$skipout6 += 4;
}
}
}
}
if ( $config{FASTSTART} ) { faststart("DNS") }
if ( $config{MESSENGER} ) {
$skipin += 2;
$skipout += 2;
if ( $config{MESSENGER_HTTPS_IN} ) {
$skipin += 1;
$skipout += 1;
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -p tcp --dport $config{MESSENGER_HTTPS} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -p tcp --sport $config{MESSENGER_HTTPS} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -p tcp --dport $config{MESSENGER_HTML} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -p tcp --dport $config{MESSENGER_TEXT} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -p tcp --sport $config{MESSENGER_HTML} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -p tcp --sport $config{MESSENGER_TEXT} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
if ( $config{MESSENGER6} ) {
$skipin6 += 2;
$skipout6 += 2;
if ( $config{MESSENGER_HTTPS_IN} ) {
$skipin6 += 1;
$skipout6 += 1;
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -p tcp --dport $config{MESSENGER_HTTPS} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -p tcp --sport $config{MESSENGER_HTTPS} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
}
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -p tcp --dport $config{MESSENGER_HTML} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -p tcp --dport $config{MESSENGER_TEXT} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -p tcp --sport $config{MESSENGER_HTML} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -p tcp --sport $config{MESSENGER_TEXT} -m limit --limit $config{MESSENGER_RATE} --limit-burst $config{MESSENGER_BURST} -j $accept" );
}
}
if ( $config{DOCKER} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N DOCKER" );
if ( $config{NAT} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -N DOCKER" );
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -A POSTROUTING -s $config{DOCKER_NETWORK4} ! -o $config{DOCKER_DEVICE} -j MASQUERADE" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A FORWARD -o $config{DOCKER_DEVICE} $statemodule RELATED,ESTABLISHED -j ACCEPT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A FORWARD -i $config{DOCKER_DEVICE} ! -o $config{DOCKER_DEVICE} -j ACCEPT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A FORWARD -i $config{DOCKER_DEVICE} -o $config{DOCKER_DEVICE} -j ACCEPT" );
if ( $config{IPV6} and $config{NAT6} and $config{DOCKER_NETWORK6} ne "" ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N DOCKER" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t nat -A POSTROUTING -s $config{DOCKER_NETWORK6} ! -o $config{DOCKER_DEVICE} -j MASQUERADE" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A FORWARD -o $config{DOCKER_DEVICE} $statemodule RELATED,ESTABLISHED -j ACCEPT" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A FORWARD -i $config{DOCKER_DEVICE} ! -o $config{DOCKER_DEVICE} -j ACCEPT" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A FORWARD -i $config{DOCKER_DEVICE} -o $config{DOCKER_DEVICE} -j ACCEPT" );
}
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $skipout $ethdevout -j LOCALOUTPUT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT $skipin $ethdevin -j LOCALINPUT" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $skipout6 $eth6devout -j LOCALOUTPUT" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT $skipin6 $eth6devin -j LOCALINPUT" );
}
$config{ETH_DEVICE_SKIP} =~ s/\s//g;
if ( $config{ETH_DEVICE_SKIP} ne "" ) {
foreach my $device ( split( /\,/, $config{ETH_DEVICE_SKIP} ) ) {
if ( $ifaces{$device} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT -i $device -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT -o $device -j $accept" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT -i $device -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT -o $device -j $accept" );
}
}
else {
$warning .= "*WARNING* ETH_DEVICE_SKIP device [$device] not listed in ip/ifconfig\n";
}
}
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose --policy INPUT DROP", 1 );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose --policy OUTPUT DROP", 1 );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose --policy FORWARD DROP", 1 );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose --policy INPUT DROP", 1 );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose --policy OUTPUT DROP", 1 );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose --policy FORWARD DROP", 1 );
}
if ( $csfpost ne "" ) {
chmod( 0700, $csfpost );
my @conf = slurp($csfpost);
if ( $conf[0] !~ /^\#\!/ ) {
open( my $CONF, ">", $csfpost );
flock( $CONF, LOCK_EX );
print $CONF "#!/bin/bash\n";
foreach my $line (@conf) {
$line =~ s/$cleanreg//g;
print $CONF "$line\n";
}
close($CONF);
}
print "Running $csfpost\n";
syscommand( __LINE__, "$path ; $csfpost" );
}
if ( $config{VPS} ) {
my @data = slurpee( "/proc/sys/kernel/osrelease", 'fatal' => 1 );
chomp @data;
if ( $data[0] =~ /^(\d+)\.(\d+)\.(\d+)/ ) {
my $maj = $1;
my $mid = $2;
my $min = $3;
if ( ( $maj > 2 ) or ( ( $maj > 1 ) and ( $mid > 5 ) and ( $min > 26 ) ) ) {
}
else {
my $status = 0;
if ( -e "/etc/pure-ftpd.conf" ) {
my @conf = slurp("/etc/pure-ftpd.conf");
if ( my @ls = grep { $_ =~ /^PassivePortRange\s+(\d+)\s+(\d+)/ } @conf ) {
if ( $ls[0] =~ /^PassivePortRange\s+(\d+)\s+(\d+)/ ) {
if ( $config{TCP_IN} !~ /\b$1:$2\b/ ) { $status = 1 }
}
}
else { $status = 1 }
if ($status) { $warning .= "*WARNING* Since the Virtuozzo VPS iptables ip_conntrack_ftp kernel module is currently broken you have to open a PASV port hole in iptables for incoming FTP connections to work correctly. See the csf readme.txt under 'A note about FTP Connection Issues' on how to do this if you have not already done so.\n" }
}
elsif ( -e "/etc/proftpd.conf" ) {
my @conf = slurp("/etc/proftpd.conf");
if ( my @ls = grep { $_ =~ /^PassivePorts\s+(\d+)\s+(\d+)/ } @conf ) {
if ( $ls[0] =~ /^PassivePorts\s+(\d+)\s+(\d+)/ ) {
if ( $config{TCP_IN} !~ /\b$1:$2\b/ ) { $status = 1 }
}
}
else { $status = 1 }
if ($status) { $warning .= "*WARNING* Since the Virtuozzo VPS iptables ip_conntrack_ftp kernel module is currently broken you have to open a PASV port hole in iptables for incoming FTP connections to work correctly. See the csf readme.txt under 'A note about FTP Connection Issues' on how to do this if you have not already done so.\n" }
}
}
}
}
return;
}
sub doadd {
my $ip = $input{argument}[0];
my $comment = $input{comment};
my $checkip = checkip( \$ip );
getethdev();
if ( $ips{$ip} or $ipscidr->find($ip) or $ipscidr6->find($ip) ) {
print "add failed: $ip is one of this servers addresses!\n";
return;
}
if ( $checkip and $checkip == 6 and !$config{IPV6} ) {
print "add failed: [$ip] is valid IPv6 but IPV6 is not enabled in csf.conf\n";
return;
}
if ( !$checkip and !( ( $ip =~ /[:|]/ ) and ( $ip =~ /=/ ) ) ) {
print "add failed: [$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
my $hit;
my @deny = slurp("/etc/csf/csf.deny");
foreach my $line (@deny) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $ipd, $commentd ) = split( /\s/, $line, 2 );
$ipd //= '';
checkip( \$ipd );
if ( $ipd eq $ip ) {
$hit = 1;
last;
}
}
if ($hit) {
print "Removing $ip from csf.deny...\n";
$input{argument}[0] = $ip;
dokill();
}
my $allowmatches;
my @allow = slurp("/etc/csf/csf.allow");
foreach my $line (@allow) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @allow, @incfile;
}
}
foreach my $line (@allow) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $ipd, $commentd ) = split( /\s/, $line, 2 );
$ipd //= '';
checkip( \$ipd );
if ( $ipd eq $ip ) {
$allowmatches = 1;
last;
}
}
my $ipstring = quotemeta($ip);
sysopen( my $ALLOW, "/etc/csf/csf.allow", O_RDWR | O_CREAT ) or error( __LINE__, "Could not open /etc/csf/csf.allow: $!" );
flock( $ALLOW, LOCK_EX ) or error( __LINE__, "Could not lock /etc/csf/csf.allow: $!" );
my $text = join( "", <$ALLOW> );
@allow = split( /$slurpreg/, $text );
chomp @allow;
unless ($allowmatches) {
if ( $comment eq "" ) { $comment = "Manually allowed: " . iplookup($ip) }
print $ALLOW "$ip \# $comment - " . localtime(time) . "\n";
if ( $config{TESTING} ) {
print "Adding $ip to csf.allow only while in TESTING mode (not iptables ACCEPT)\n";
}
else {
print "Adding $ip to csf.allow and iptables ACCEPT...\n";
linefilter( $ip, "allow" );
}
}
else {
print "add failed: $ip is in already in the allow file /etc/csf/csf.allow\n";
}
close($ALLOW) or error( __LINE__, "Could not close /etc/csf/csf.allow: $!" );
return;
}
sub dodeny {
my $ip = $input{argument}[0];
my $comment = $input{comment};
my $checkip = checkip( \$ip );
getethdev();
if ( $ips{$ip} or $ipscidr->find($ip) or $ipscidr6->find($ip) ) {
print "deny failed: [$ip] is one of this servers addresses!\n";
return;
}
if ( $checkip and $checkip == 6 and !$config{IPV6} ) {
print "deny failed: [$ip] is valid IPv6 but IPV6 is not enabled in csf.conf\n";
return;
}
if ( !$checkip and !( ( $ip =~ /[:|]/ ) and ( $ip =~ /=/ ) ) ) {
print "deny failed: [$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
my @allow = slurp("/etc/csf/csf.allow");
foreach my $line (@allow) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @allow, @incfile;
}
}
foreach my $line (@allow) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $ipd, $commentd ) = split( /\s/, $line, 2 );
$ipd //= '';
checkip( \$ipd );
if ( $ipd eq $ip ) {
print "deny failed: $ip is in the allow file /etc/csf/csf.allow\n";
return;
}
elsif ( $ipd =~ /(.*\/\d+)/ ) {
my $cidrhit = $1;
if ( checkip( \$cidrhit ) ) {
my $cidr = Net::CIDR::Lite->new;
eval { local $SIG{__DIE__} = undef; $cidr->add($cidrhit) };
if ( $cidr->find($ip) ) {
print "deny failed: $ip is in the allow file /etc/csf/csf.allow\n";
return;
}
}
}
}
my @ignore = slurp("/etc/csf/csf.ignore");
foreach my $line (@ignore) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @ignore, @incfile;
}
}
foreach my $line (@ignore) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $ipd, $commentd ) = split( /\s/, $line, 2 );
$ipd //= '';
checkip( \$ipd );
if ( $ipd eq $ip ) {
print "deny failed: $ip is in the ignore file /etc/csf/csf.ignore\n";
return;
}
elsif ( $ipd =~ /(.*\/\d+)/ ) {
my $cidrhit = $1;
if ( checkip( \$cidrhit ) ) {
my $cidr = Net::CIDR::Lite->new;
eval { local $SIG{__DIE__} = undef; $cidr->add($cidrhit) };
if ( $cidr->find($ip) ) {
print "deny failed: $ip is in the ignore file /etc/csf/csf.ignore\n";
return;
}
}
}
}
my $denymatches = 0;
my @deny = slurp("/etc/csf/csf.deny");
foreach my $line (@deny) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @deny, @incfile;
}
}
foreach my $line (@deny) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $ipd, $commentd ) = split( /\s/, $line, 2 );
$ipd //= '';
checkip( \$ipd );
if ( $ipd eq $ip ) {
$denymatches = 1;
last;
}
}
sysopen( my $DENY, "/etc/csf/csf.deny", O_RDWR | O_CREAT ) or error( __LINE__, "Could not open /etc/csf/csf.deny: $!" );
flock( $DENY, LOCK_EX ) or error( __LINE__, "Could not lock /etc/csf/csf.deny: $!" );
my $text = join( "", <$DENY> );
@deny = split( /$slurpreg/, $text );
chomp @deny;
if ( $config{LF_REPEATBLOCK} and $denymatches < $config{LF_REPEATBLOCK} ) { $denymatches = 0 }
if ( $denymatches == 0 ) {
my $ipcount = 0;
my @denyips;
foreach my $line (@deny) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
if ( $line =~ /do not delete/i ) { next }
my ( $ipd, $commentd ) = split( /\s/, $line, 2 );
$ipd //= '';
$ipcount++;
push @denyips, $line;
}
if ( ( $config{DENY_IP_LIMIT} > 0 ) and ( $ipcount >= $config{DENY_IP_LIMIT} ) ) {
seek( $DENY, 0, 0 );
truncate( $DENY, 0 );
foreach my $line (@deny) {
my $hit = 0;
for ( my $x = 0; $x < ( $ipcount - $config{DENY_IP_LIMIT} ) + 1; $x++ ) {
if ( $line eq $denyips[$x] ) { $hit = 1; }
}
if ($hit) { next }
print $DENY $line . "\n";
}
print "csf: DENY_IP_LIMIT ($config{DENY_IP_LIMIT}), the following IP's were removed from /etc/csf/csf.deny:\n";
for ( my $x = 0; $x < ( $ipcount - $config{DENY_IP_LIMIT} ) + 1; $x++ ) {
print "$denyips[$x]\n";
my ( $kip, undef ) = split( /\s/, $denyips[$x], 2 );
linefilter( $kip, "deny", "", 1 );
# sysopen (my $TEMPIP, "/var/lib/csf/csf.tempip", O_RDWR | O_CREAT);
# flock ($TEMPIP, LOCK_EX);
# my @data = <$TEMPIP>;
# chomp @data;
# seek ($TEMPIP, 0, 0);
# truncate ($TEMPIP, 0);
# foreach my $line (@data) {
# my ($oip,undef,undef,undef) = split(/\|/,$line,4);
# checkip(\$oip);
# if ($oip eq $kip) {next}
# print $TEMPIP "$line\n";
# }
# close ($TEMPIP);
}
}
if ( $comment eq "" ) { $comment = "Manually denied: " . iplookup($ip) }
print $DENY "$ip \# $comment - " . localtime(time) . "\n";
if ( $config{TESTING} ) {
print "Adding $ip to csf.deny only while in TESTING mode (not iptables DROP)\n";
}
else {
print "Adding $ip to csf.deny and iptables DROP...\n";
linefilter( $ip, "deny" );
}
}
else {
print "deny failed: $ip is in already in the deny file /etc/csf/csf.deny $denymatches times\n";
}
close($DENY) or error( __LINE__, "Could not close /etc/csf/csf.deny: $!" );
return;
}
sub dokill {
my $ip = $input{argument}[0];
my $is_ip = 0;
if ( checkip( \$ip ) ) { $is_ip = 1 }
if ( !$is_ip and !( ( $ip =~ /[:|]/ ) and ( $ip =~ /=/ ) ) ) {
print "[$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
getethdev();
sysopen( my $DENY, "/etc/csf/csf.deny", O_RDWR | O_CREAT ) or error( __LINE__, "Could not open /etc/csf/csf.deny: $!" );
flock( $DENY, LOCK_EX ) or error( __LINE__, "Could not lock /etc/csf/csf.deny: $!" );
my $text = join( "", <$DENY> );
my @deny = split( /$slurpreg/, $text );
chomp @deny;
seek( $DENY, 0, 0 );
truncate( $DENY, 0 );
my $hit = 0;
foreach my $line (@deny) {
$line =~ s/$cleanreg//g;
my ( $ipd, $commentd ) = split( /\s/, $line, 2 );
$ipd //= '';
my $ipmatch = $ipd;
if ( $is_ip and $ipd =~ /($ipv4reg|$ipv6reg)/ ) {
$ipmatch = $1;
if ( $ipd =~ /(\/\d+)$/ ) { $ipmatch .= $1 }
}
checkip( \$ipd );
if ( uc $ip eq uc $ipmatch ) {
if ( $commentd =~ /do not delete/i ) {
print "csf: $ip set as \"do not delete\" - not removed\n";
$hit = -1;
}
else {
print "Removing rule...\n";
linefilter( $ipd, "deny", "", 1 );
$hit = 1;
next;
}
}
print $DENY $line . "\n";
}
close($DENY) or error( __LINE__, "Could not close /etc/csf/csf.deny: $!" );
if ( $hit and ( $config{LF_PERMBLOCK} or $config{LF_NETBLOCK} ) ) {
sysopen( my $TEMPIP, "/var/lib/csf/csf.tempip", O_RDWR | O_CREAT );
flock( $TEMPIP, LOCK_EX );
my @data = <$TEMPIP>;
chomp @data;
seek( $TEMPIP, 0, 0 );
truncate( $TEMPIP, 0 );
foreach my $line (@data) {
my ( $oip, undef, undef, undef ) = split( /\|/, $line, 4 );
if ( $oip eq $ip ) { next }
print $TEMPIP "$line\n";
}
close($TEMPIP);
}
elsif ( $hit == -1 ) { }
elsif ( !$hit ) {
print "csf: $ip not found in csf.deny\n";
}
return;
}
sub dokillall {
getethdev();
sysopen( my $DENY, "/etc/csf/csf.deny", O_RDWR | O_CREAT ) or error( __LINE__, "Could not open /etc/csf/csf.deny: $!" );
flock( $DENY, LOCK_EX ) or error( __LINE__, "Could not lock /etc/csf/csf.deny: $!" );
my $text = join( "", <$DENY> );
my @deny = split( /$slurpreg/, $text );
chomp @deny;
seek( $DENY, 0, 0 );
truncate( $DENY, 0 );
my $hit = 0;
foreach my $line (@deny) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^([#\n]|Include)/ ) {
print $DENY $line . "\n";
}
elsif ( $line =~ /do not delete/i ) {
print $DENY $line . "\n";
print "csf: skipped line: $line\n";
}
else {
my ( $ipd, $commentd ) = split( /\s/, $line, 2 );
$ipd //= '';
linefilter( $ipd, "deny", "", 1 );
}
}
close($DENY) or error( __LINE__, "Could not close /etc/csf/csf.deny: $!" );
print "csf: all entries removed from csf.deny\n";
return;
}
sub doakill {
my $ip = $input{argument}[0];
if ( !checkip( \$ip ) and !( ( $ip =~ /[:|]/ ) and ( $ip =~ /=/ ) ) ) {
print "[$ip] is not a valid PUBLIC IP/CIDR\n";
return;
}
getethdev();
sysopen( my $ALLOW, "/etc/csf/csf.allow", O_RDWR | O_CREAT ) or error( __LINE__, "Could not open /etc/csf/csf.allow: $!" );
flock( $ALLOW, LOCK_EX ) or error( __LINE__, "Could not lock /etc/csf/csf.allow: $!" );
my $text = join( "", <$ALLOW> );
my @allow = split( /$slurpreg/, $text );
chomp @allow;
seek( $ALLOW, 0, 0 );
truncate( $ALLOW, 0 );
my $hit = 0;
foreach my $line (@allow) {
$line =~ s/$cleanreg//g;
my ( $ipd, $commentd ) = split( /\s/, $line, 2 );
$ipd //= '';
checkip( \$ipd );
if ( uc $ipd eq uc $ip ) {
print "Removing rule...\n";
linefilter( $ipd, "allow", "", 1 );
$hit = 1;
next;
}
print $ALLOW $line . "\n";
}
close($ALLOW) or error( __LINE__, "Could not close /etc/csf/csf.allow: $!" );
unless ($hit) {
print "csf: $ip not found in csf.allow\n";
}
return;
}
sub dohelp {
print "csf: v$version (cPanel)\n";
print slurpee( "/usr/local/csf/lib/csf.help", 'fatal' => 1, 'wantarray' => 0 );
return;
}
sub dopacketfilters {
if ( $config{PACKET_FILTER} and $config{LF_SPI} ) {
if ( $config{FASTSTART} ) { $faststart = 1 }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N INVDROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N INVALID" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVALID $statemodule INVALID -j INVDROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags ALL NONE -j INVDROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags ALL ALL -j INVDROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags SYN,FIN SYN,FIN -j INVDROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags SYN,RST SYN,RST -j INVDROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags FIN,RST FIN,RST -j INVDROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags ACK,FIN FIN -j INVDROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags ACK,PSH PSH -j INVDROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags ACK,URG URG -j INVDROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp ! --syn $statemodulenew -j INVDROP" );
if ( $config{IPV6} and $config{IPV6_SPI} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N INVDROP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -N INVALID" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVALID $statemodule INVALID -j INVDROP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags ALL NONE -j INVDROP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags ALL ALL -j INVDROP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags SYN,FIN SYN,FIN -j INVDROP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags SYN,RST SYN,RST -j INVDROP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags FIN,RST FIN,RST -j INVDROP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags ACK,FIN FIN -j INVDROP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags ACK,PSH PSH -j INVDROP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp --tcp-flags ACK,URG URG -j INVDROP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVALID -p tcp ! --syn $statemodule6new -j INVDROP" );
}
if ( $config{FASTSTART} ) { faststart("Packet Filter") }
if ( $config{DROP_PF_LOGGING} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVDROP $statemodule INVALID -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INVALID* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags ALL NONE -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_AN* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags ALL ALL -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_AA* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_SFSF* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags SYN,RST SYN,RST -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_SRSR* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags FIN,RST FIN,RST -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_FRFR* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags ACK,FIN FIN -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_AFF* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags ACK,PSH PSH -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_APP* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags ACK,URG URG -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_AUU* '" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp ! --syn $statemodulenew -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_NOSYN* '" );
if ( $config{IPV6} and $config{IPV6_SPI} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVDROP $statemodule INVALID -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INVALID* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags ALL NONE -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_AN* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags ALL ALL -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_AA* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_SFSF* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags SYN,RST SYN,RST -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_SRSR* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags FIN,RST FIN,RST -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_FRFR* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags ACK,FIN FIN -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_AFF* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags ACK,PSH PSH -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_APP* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp --tcp-flags ACK,URG URG -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_AUU* '" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -p tcp ! --syn $statemodule6new -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *INV_NOSYN* '" );
}
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -j $config{DROP}" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -p tcp -j INVALID" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $ethdevout -p tcp -j INVALID" );
if ( $config{IPV6} and $config{IPV6_SPI} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INVDROP -j $config{DROP}" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT $eth6devin -p tcp -j INVALID" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I OUTPUT $eth6devout -p tcp -j INVALID" );
}
}
return;
}
sub doportfilters {
my $dropin = $config{DROP};
my $dropout = $config{DROP_OUT};
if ( $config{DROP_LOGGING} ) { $dropin = "LOGDROPIN" }
if ( $config{DROP_LOGGING} ) { $dropout = "LOGDROPOUT" }
my @entries = slurp("/etc/csf/csf.sips");
foreach my $line (@entries) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @entries, @incfile;
}
}
foreach my $line (@entries) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $ip, $comment ) = split( /\s/, $line, 2 );
my $iptype = checkip( \$ip );
if ( $iptype == 4 ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -d $ip -j $dropin" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALOUTPUT $ethdevout -s $ip -j $dropout" );
}
elsif ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $eth6devin -d $ip -j $dropin" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALOUTPUT $eth6devout -s $ip -j $dropout" );
}
}
if ( $config{GLOBAL_DENY} ) {
if ( $config{LF_IPSET} ) {
my $pktin = $config{DROP};
my $pktout = $config{DROP_OUT};
if ( $config{DROP_IP_LOGGING} ) { $pktin = "LOGDROPIN" }
if ( $config{DROP_OUT_LOGGING} ) { $pktout = "LOGDROPOUT" }
ipsetcreate("chain_GDENY");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A GDENYIN -m set --match-set chain_GDENY src -j $pktin" );
unless ( $config{LF_BLOCKINONLY} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A GDENYOUT -m set --match-set chain_GDENY dst -j $pktout" ) }
if ( $config{IPV6} ) {
ipsetcreate("chain_6_GDENY");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A GDENYIN -m set --match-set chain_6_GDENY src -j $pktin" );
unless ( $config{LF_BLOCKINONLY} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A GDENYOUT -m set --match-set chain_6_GDENY dst -j $pktout" ) }
}
}
if ( -e "/var/lib/csf/csf.gdeny" ) {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/csf.gdeny") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, $comment ) = split( /\s/, $line, 2 );
linefilter( $ip, "deny", "GDENY" );
}
if ( $config{FASTSTART} ) { faststart("Global Deny") }
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j GDENYIN" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALOUTPUT $ethdevout -j GDENYOUT" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $eth6devin -j GDENYIN" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALOUTPUT $eth6devout -j GDENYOUT" );
}
}
my @deny = slurp("/etc/csf/csf.deny");
foreach my $line (@deny) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @deny, @incfile;
}
}
if ( $config{FASTSTART} ) { $faststart = 1 }
if ( $config{LF_IPSET} ) {
my $pktin = $config{DROP};
my $pktout = $config{DROP_OUT};
if ( $config{DROP_IP_LOGGING} ) { $pktin = "LOGDROPIN" }
if ( $config{DROP_OUT_LOGGING} ) { $pktout = "LOGDROPOUT" }
ipsetcreate("chain_DENY");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A DENYIN -m set --match-set chain_DENY src -j $pktin" );
unless ( $config{LF_BLOCKINONLY} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A DENYOUT -m set --match-set chain_DENY dst -j $pktout" ) }
if ( $config{IPV6} ) {
ipsetcreate("chain_6_DENY");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A DENYIN -m set --match-set chain_6_DENY src -j $pktin" );
unless ( $config{LF_BLOCKINONLY} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A DENYOUT -m set --match-set chain_6_DENY dst -j $pktout" ) }
}
}
foreach my $line (@deny) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $ip, $comment ) = split( /\s/, $line, 2 );
linefilter( $ip, "deny" );
}
if ( $config{FASTSTART} ) { faststart("csf.deny") }
if ( !-z "/var/lib/csf/csf.tempban" ) {
my $dropin = $config{DROP};
my $dropout = $config{DROP_OUT};
if ( $config{DROP_IP_LOGGING} ) { $dropin = "LOGDROPIN" }
if ( $config{DROP_OUT_LOGGING} ) { $dropout = "LOGDROPOUT" }
sysopen( my $TEMPBAN, "/var/lib/csf/csf.tempban", O_RDWR | O_CREAT );
flock( $TEMPBAN, LOCK_EX );
my @data = <$TEMPBAN>;
chomp @data;
my @newdata;
foreach my $line (@data) {
my ( $time, $ip, $port, $inout, $timeout, $message ) = split( /\|/, $line );
my $iptype = checkip( \$ip );
if ( $iptype == 6 and !$config{IPV6} ) { next }
if ( ( ( ( time - $time ) < $timeout ) and $iptype ) or ( $message =~ /\(CF:([^\)]+)\)/ ) ) {
if ( $inout =~ /in/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A DENYIN $eth6devin -p $proto --dport $dport -s $ip -j $dropin" );
if ( $messengerports{$dport} and $config{MESSENGER6} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "A", $dport ) }
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A DENYIN $ethdevin -p $proto --dport $dport -s $ip -j $dropin" );
if ( $messengerports{$dport} and $config{MESSENGER} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "A", $dport ) }
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A DENYIN $eth6devin -s $ip -j $dropin" );
if ( $config{MESSENGER6} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "A" ) }
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A DENYIN $ethdevin -s $ip -j $dropin" );
if ( $config{MESSENGER} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "A" ) }
}
}
}
if ( $inout =~ /out/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A DENYOUT $eth6devout -p $proto --dport $dport -d $ip -j $dropout" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A DENYOUT $ethdevout -p $proto --dport $dport -d $ip -j $dropout" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A DENYOUT $eth6devout -d $ip -j $dropout" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A DENYOUT $ethdevout -d $ip -j $dropout" );
}
}
}
push @newdata, $line;
}
}
seek( $TEMPBAN, 0, 0 );
truncate( $TEMPBAN, 0 );
foreach my $line (@newdata) { print $TEMPBAN "$line\n" }
close($TEMPBAN);
}
if ( !-z "/var/lib/csf/csf.tempallow" ) {
sysopen( my $TEMPALLOW, "/var/lib/csf/csf.tempallow", O_RDWR | O_CREAT );
flock( $TEMPALLOW, LOCK_EX );
my @data = <$TEMPALLOW>;
chomp @data;
my @newdata;
foreach my $line (@data) {
my ( $time, $ip, $port, $inout, $timeout, $message ) = split( /\|/, $line );
my $iptype = checkip( \$ip );
if ( $iptype == 6 and !$config{IPV6} ) { next }
if ( ( ( ( time - $time ) < $timeout ) and $iptype ) or ( $message =~ /\(CF:([^\)]+)\)/ ) ) {
if ( $inout =~ /in/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I ALLOWIN $eth6devin -p $proto --dport $dport -s $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I ALLOWIN $ethdevin -p $proto --dport $dport -s $ip -j $accept" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I ALLOWIN $eth6devin -s $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I ALLOWIN $ethdevin -s $ip -j $accept" );
}
}
}
if ( $inout =~ /out/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I ALLOWOUT $eth6devout -p $proto --dport $dport -d $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I ALLOWOUT $ethdevout -p $proto --dport $dport -d $ip -j $accept" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I ALLOWOUT $eth6devout -d $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I ALLOWOUT $ethdevout -d $ip -j $accept" );
}
}
}
push @newdata, $line;
}
}
seek( $TEMPALLOW, 0, 0 );
truncate( $TEMPALLOW, 0 );
foreach my $line (@newdata) { print $TEMPALLOW "$line\n" }
close($TEMPALLOW);
}
if ( $config{GLOBAL_ALLOW} ) {
if ( $config{LF_IPSET} ) {
ipsetcreate("chain_GALLOW");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A GALLOWIN -m set --match-set chain_GALLOW src -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A GALLOWOUT -m set --match-set chain_GALLOW dst -j $accept" );
if ( $config{IPV6} ) {
ipsetcreate("chain_6_GALLOW");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A GALLOWIN -m set --match-set chain_6_GALLOW src -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A GALLOWOUT -m set --match-set chain_6_GALLOW dst -j $accept" );
}
}
if ( -e "/var/lib/csf/csf.gallow" ) {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/csf.gallow") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, $comment ) = split( /\s/, $line, 2 );
linefilter( $ip, "allow", "GALLOW" );
}
if ( $config{FASTSTART} ) { faststart("Global Allow") }
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I LOCALINPUT $ethdevin -j GALLOWIN" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I LOCALOUTPUT $ethdevout -j GALLOWOUT" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I LOCALINPUT $eth6devin -j GALLOWIN" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I LOCALOUTPUT $eth6devout -j GALLOWOUT" );
}
}
$config{CC_ALLOW} //= "";
$config{CC_ALLOW} =~ s/\s//g;
if ( $config{CC_ALLOW} ) {
foreach my $cc ( split( /\,/, $config{CC_ALLOW} ) ) {
$cc = lc $cc;
if ( $config{LF_IPSET} ) {
ipsetcreate("cc_$cc");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOW -m set --match-set cc_$cc src -j $accept" );
if ( $config{CC6_LOOKUPS} and $config{IPV6} ) {
ipsetcreate("cc_6_$cc");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOW -m set --match-set cc_6_$cc src -j $accept" );
}
}
if ( -e "/var/lib/csf/zone/$cc.zone" ) {
if ( $config{LF_IPSET} ) {
undef @ipset;
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( $config{CC_DROP_CIDR} > 0 and $config{CC_DROP_CIDR} < 33 ) {
my ( $drop_ip, $drop_cidr ) = split( /\//, $ip );
if ( !length $drop_cidr ) { $drop_cidr = "32" }
if ( $drop_cidr > $config{CC_DROP_CIDR} ) { next }
}
if ( cccheckip( \$ip ) ) { push @ipset, "add -exist cc_$cc $ip" }
}
ipsetrestore("cc_$cc");
}
else {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) {
if ( $config{CC_DROP_CIDR} > 0 and $config{CC_DROP_CIDR} < 33 ) {
my ( $drop_ip, $drop_cidr ) = split( /\//, $ip );
if ( !length $drop_cidr ) { $drop_cidr = "32" }
if ( $drop_cidr > $config{CC_DROP_CIDR} ) { next }
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOW -s $ip -j $accept" );
}
}
if ( $config{FASTSTART} ) { faststart("CC_ALLOW [$cc]") }
}
}
if ( $config{CC6_LOOKUPS} and -e "/var/lib/csf/zone/$cc.zone6" ) {
if ( $config{LF_IPSET} ) {
undef @ipset;
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone6") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) { push @ipset, "add -exist cc_6_$cc $ip" }
}
ipsetrestore("cc_6_$cc");
}
else {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone6") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOW -s $ip -j $accept" );
}
}
if ( $config{FASTSTART} ) { faststart("CC_ALLOW [$cc]") }
}
}
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I LOCALINPUT $ethdevin -j CC_ALLOW" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I LOCALINPUT $ethdevin -j CC_ALLOW" );
}
}
if ( $config{DYNDNS} ) {
if ( $config{LF_IPSET} ) {
ipsetcreate("chain_ALLOWDYN");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A ALLOWDYNIN -m set --match-set chain_ALLOWDYN src -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A ALLOWDYNOUT -m set --match-set chain_ALLOWDYN dst -j $accept" );
if ( $config{IPV6} ) {
ipsetcreate("chain_6_ALLOWDYN");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A ALLOWDYNIN -m set --match-set chain_6_ALLOWDYN src -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A ALLOWDYNOUT -m set --match-set chain_6_ALLOWDYN dst -j $accept" );
}
}
if ( -e "/var/lib/csf/csf.tempdyn" ) {
foreach my $line ( slurp("/var/lib/csf/csf.tempdyn") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, $comment ) = split( /\s/, $line, 2 );
linefilter( $ip, "allow", "ALLOWDYN" );
}
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I LOCALINPUT $ethdevin -j ALLOWDYNIN" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I LOCALOUTPUT $ethdevout -j ALLOWDYNOUT" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I LOCALINPUT $ethdevin -j ALLOWDYNIN" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I LOCALOUTPUT $ethdevout -j ALLOWDYNOUT" );
}
}
if ( $config{GLOBAL_DYNDNS} ) {
if ( $config{LF_IPSET} ) {
ipsetcreate("chain_GDYN");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A GDYNIN -m set --match-set chain_GDYN src -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A GDYNOUT -m set --match-set chain_GDYN dst -j $accept" );
if ( $config{IPV6} ) {
ipsetcreate("chain_6_GDYN");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A GDYNIN -m set --match-set chain_6_GDYN src -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A GDYNOUT -m set --match-set chain_6_GDYN dst -j $accept" );
}
}
if ( -e "/var/lib/csf/csf.tempgdyn" ) {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/csf.tempgdyn") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, $comment ) = split( /\s/, $line, 2 );
linefilter( $ip, "allow", "GDYN" );
}
if ( $config{FASTSTART} ) { faststart("Global Dynamic DNS") }
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I LOCALINPUT $ethdevin -j GDYNIN" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I LOCALOUTPUT $ethdevout -j GDYNOUT" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I LOCALINPUT $ethdevin -j GDYNIN" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I LOCALOUTPUT $ethdevout -j GDYNOUT" );
}
}
my @allow = slurp("/etc/csf/csf.allow");
foreach my $line (@allow) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @allow, @incfile;
}
}
if ( $config{FASTSTART} ) { $faststart = 1 }
if ( $config{LF_IPSET} ) {
ipsetcreate("chain_ALLOW");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A ALLOWIN -m set --match-set chain_ALLOW src -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A ALLOWOUT -m set --match-set chain_ALLOW dst -j $accept" );
if ( $config{IPV6} ) {
ipsetcreate("chain_6_ALLOW");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A ALLOWIN -m set --match-set chain_6_ALLOW src -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A ALLOWOUT -m set --match-set chain_6_ALLOW dst -j $accept" );
}
}
foreach my $line (@allow) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $ip, $comment ) = split( /\s/, $line, 2 );
linefilter( $ip, "allow" );
}
if ( $config{FASTSTART} ) { faststart("csf.allow") }
foreach my $name ( keys %blocklists ) {
my $drop = $config{DROP};
if ( $config{DROP_IP_LOGGING} ) { $drop = "BLOCKDROP" }
if ( $config{LF_IPSET} ) {
ipsetcreate("bl_$name");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A $name -m set --match-set bl_$name src -j $drop" );
if ( $config{IPV6} ) {
ipsetcreate("bl_6_$name");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A $name -m set --match-set bl_6_$name src -j $drop" );
}
}
if ( -e "/var/lib/csf/csf.block.$name" ) {
if ( $config{LF_IPSET} ) {
undef @ipset;
my @ipset6;
foreach my $line ( slurp("/var/lib/csf/csf.block.$name") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, $comment ) = split( /\s/, $line, 2 );
my $iptype = checkip( \$ip );
if ( $iptype == 4 ) {
push @ipset, "add -exist bl_$name $ip";
}
elsif ( $iptype == 6 and $config{IPV6} ) {
push @ipset6, "add -exist bl_6_$name $ip";
}
}
ipsetrestore("bl_$name");
if ( $config{IPV6} ) {
@ipset = @ipset6;
ipsetrestore("bl_6_$name");
}
}
else {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/csf.block.$name") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, $comment ) = split( /\s/, $line, 2 );
my $iptype = checkip( \$ip );
if ( $iptype == 4 ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A $name -s $ip -j $drop" );
}
elsif ( $iptype == 6 and $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A $name -s $ip -j $drop" );
}
}
if ( $config{FASTSTART} ) { faststart("Blocklist $name") }
}
}
$config{LF_BOGON_SKIP} =~ s/\s//g;
if ( $name eq "BOGON" and $config{LF_BOGON_SKIP} ne "" ) {
foreach my $device ( split( /\,/, $config{LF_BOGON_SKIP} ) ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I BOGON -i $device -j RETURN" );
}
}
if ( $cxsreputation and $name =~ /^CXS_/ and $name ne "CXS_ALL" and $cxsports{$name} ne "" ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT -p tcp -m multiport --dport $cxsports{$name} $ethdevin -j $name" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT -p tcp -m multiport --dport $cxsports{$name} $ethdevin -j $name" );
}
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j $name" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j $name" );
}
}
}
$config{CC_ALLOW_SMTPAUTH} //= "";
$config{CC_ALLOW_SMTPAUTH} =~ s/\s//g;
if ( $config{SMTPAUTH_RESTRICT} ) {
if ($verbose) { print "csf: Generating /etc/exim.smtpauth\n" }
sysopen( my $SMTPAUTH, "/etc/exim.smtpauth", O_WRONLY | O_CREAT );
flock( $SMTPAUTH, LOCK_EX );
seek( $SMTPAUTH, 0, 0 );
truncate( $SMTPAUTH, 0 );
print $SMTPAUTH "# DO NOT EDIT THIS FILE\n#\n";
print $SMTPAUTH "# Modify /etc/csf/csf.smtpauth and then restart csf and then lfd\n\n";
print $SMTPAUTH "127.0.0.0/8\n";
print $SMTPAUTH "\"::1\"\n";
print $SMTPAUTH "\"::1/128\"\n";
if ( -e "/etc/csf/csf.smtpauth" ) {
my @entries = slurp("/etc/csf/csf.smtpauth");
foreach my $line (@entries) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @entries, @incfile;
}
}
foreach my $line (@entries) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
my $status = checkip( \$ip );
if ( $status == 4 ) { print $SMTPAUTH "$ip\n" }
elsif ( $status == 6 ) { print $SMTPAUTH "\"$ip\"\n" }
}
}
foreach my $cc ( split( /\,/, $config{CC_ALLOW_SMTPAUTH} ) ) {
$cc = lc $cc;
if ( -e "/var/lib/csf/zone/$cc.zone" ) {
print $SMTPAUTH "\n# IPv4 addresses for [" . uc($cc) . "]:\n";
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( $config{CC_DROP_CIDR} > 0 and $config{CC_DROP_CIDR} < 33 ) {
my ( $drop_ip, $drop_cidr ) = split( /\//, $ip );
if ( !length $drop_cidr ) { $drop_cidr = "32" }
if ( $drop_cidr > $config{CC_DROP_CIDR} ) { next }
}
my $status = cccheckip( \$ip );
if ( $status == 4 ) { print $SMTPAUTH "$ip\n" }
elsif ( $status == 6 ) { print $SMTPAUTH "\"$ip\"\n" }
}
}
if ( $config{CC6_LOOKUPS} and -e "/var/lib/csf/zone/$cc.zone6" ) {
print $SMTPAUTH "\n# IPv6 addresses for [" . uc($cc) . "]:\n";
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone6") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
my $status = cccheckip( \$ip );
if ( $status == 4 ) { print $SMTPAUTH "$ip\n" }
elsif ( $status == 6 ) { print $SMTPAUTH "\"$ip\"\n" }
}
}
}
close($SMTPAUTH);
chmod( 0644, "/etc/exim.smtpauth" );
}
$config{CC_DENY} //= "";
$config{CC_DENY} =~ s/\s//g;
if ( $config{CC_DENY} ) {
foreach my $cc ( split( /\,/, $config{CC_DENY} ) ) {
$cc = lc $cc;
my $drop = $config{DROP};
if ( $config{DROP_IP_LOGGING} ) { $drop = "CCDROP" }
if ( $config{LF_IPSET} ) {
ipsetcreate("cc_$cc");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I CC_DENY -m set --match-set cc_$cc src -j $drop" );
if ( $config{CC6_LOOKUPS} and $config{IPV6} ) {
ipsetcreate("cc_6_$cc");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I CC_DENY -m set --match-set cc_6_$cc src -j $drop" );
}
}
if ( -e "/var/lib/csf/zone/$cc.zone" ) {
if ( $config{LF_IPSET} ) {
undef @ipset;
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( $config{CC_DROP_CIDR} > 0 and $config{CC_DROP_CIDR} < 33 ) {
my ( $drop_ip, $drop_cidr ) = split( /\//, $ip );
if ( !length $drop_cidr ) { $drop_cidr = "32" }
if ( $drop_cidr > $config{CC_DROP_CIDR} ) { next }
}
if ( cccheckip( \$ip ) ) { push @ipset, "add -exist cc_$cc $ip" }
}
ipsetrestore("cc_$cc");
}
else {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( $config{CC_DROP_CIDR} > 0 and $config{CC_DROP_CIDR} < 33 ) {
my ( $drop_ip, $drop_cidr ) = split( /\//, $ip );
if ( !length $drop_cidr ) { $drop_cidr = "32" }
if ( $drop_cidr > $config{CC_DROP_CIDR} ) { next }
}
if ( cccheckip( \$ip ) ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I CC_DENY -s $ip -j $drop" );
}
}
if ( $config{FASTSTART} ) { faststart("CC_DENY [$cc]") }
}
}
if ( $config{CC6_LOOKUPS} and -e "/var/lib/csf/zone/$cc.zone6" ) {
if ( $config{LF_IPSET} ) {
undef @ipset;
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone6") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) { push @ipset, "add -exist cc_6_$cc $ip" }
}
ipsetrestore("cc_6_$cc");
}
else {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone6") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I CC_DENY -s $ip -j $drop" );
}
}
if ( $config{FASTSTART} ) { faststart("CC_DENY [$cc]") }
}
}
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j CC_DENY" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j CC_DENY" );
}
}
$config{CC_ALLOW_FILTER} //= "";
$config{CC_ALLOW_FILTER} =~ s/\s//g;
if ( $config{CC_ALLOW_FILTER} ) {
my $cnt = 0;
my $cnt6 = 0;
foreach my $cc ( split( /\,/, $config{CC_ALLOW_FILTER} ) ) {
$cc = lc $cc;
if ( $config{LF_IPSET} ) {
ipsetcreate("cc_$cc");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWF -m set --match-set cc_$cc src -j RETURN" );
if ( $config{CC6_LOOKUPS} and $config{IPV6} ) {
ipsetcreate("cc_6_$cc");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWF -m set --match-set cc_6_$cc src -j RETURN" );
}
}
if ( -e "/var/lib/csf/zone/$cc.zone" ) {
if ( $config{LF_IPSET} ) {
undef @ipset;
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( $config{CC_DROP_CIDR} > 0 and $config{CC_DROP_CIDR} < 33 ) {
my ( $drop_ip, $drop_cidr ) = split( /\//, $ip );
if ( !length $drop_cidr ) { $drop_cidr = "32" }
if ( $drop_cidr > $config{CC_DROP_CIDR} ) { next }
}
if ( cccheckip( \$ip ) ) {
push @ipset, "add -exist cc_$cc $ip";
$cnt++;
}
}
ipsetrestore("cc_$cc");
}
else {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) {
if ( $config{CC_DROP_CIDR} > 0 and $config{CC_DROP_CIDR} < 33 ) {
my ( $drop_ip, $drop_cidr ) = split( /\//, $ip );
if ( !length $drop_cidr ) { $drop_cidr = "32" }
if ( $drop_cidr > $config{CC_DROP_CIDR} ) { next }
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWF -s $ip -j RETURN" );
$cnt++;
}
}
if ( $config{FASTSTART} ) { faststart("CC_ALLOW_FILTER [$cc]") }
}
}
if ( $config{CC6_LOOKUPS} and -e "/var/lib/csf/zone/$cc.zone6" ) {
if ( $config{LF_IPSET} ) {
undef @ipset;
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone6") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) {
push @ipset, "add -exist cc_6_$cc $ip";
$cnt6++;
}
}
ipsetrestore("cc_6_$cc");
}
else {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone6") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWF -s $ip -j RETURN" );
$cnt6++;
}
}
if ( $config{FASTSTART} ) { faststart("CC_ALLOW_FILTER [$cc]") }
}
}
}
my $drop = $config{DROP};
if ( $config{DROP_IP_LOGGING} ) { $drop = "CCDROP" }
if ( $cnt > 0 ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWF -j $drop" ) }
if ( $config{LF_SPI} ) {
if ( $config{USE_FTPHELPER} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I CC_ALLOWF $ethdevin $statemodule RELATED -m helper --helper ftp -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I CC_ALLOWF $ethdevin $statemodule ESTABLISHED -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I CC_ALLOWF $ethdevin $statemodule ESTABLISHED,RELATED -j $accept" );
}
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j CC_ALLOWF" );
if ( $config{IPV6} ) {
if ( $cnt6 > 0 ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWF -j $drop" ) }
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j CC_ALLOWF" );
if ( $config{IPV6_SPI} ) {
if ( $config{USE_FTPHELPER} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I CC_ALLOWF $ethdevin $statemodule RELATED -m helper --helper ftp -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I CC_ALLOWF $ethdevin $statemodule ESTABLISHED -j $accept" );
}
else {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I CC_ALLOWF $ethdevin $statemodule ESTABLISHED,RELATED -j $accept" );
}
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I CC_ALLOWF $eth6devin -p icmpv6 -j $accept" );
}
}
}
$config{CC_ALLOW_PORTS} //= "";
$config{CC_ALLOW_PORTS} =~ s/\s//g;
if ( $config{CC_ALLOW_PORTS} ) {
$config{CC_ALLOW_PORTS_TCP} //= "";
$config{CC_ALLOW_PORTS_TCP} =~ s/\s//g;
$config{CC_ALLOW_PORTS_UDP} //= "";
$config{CC_ALLOW_PORTS_UDP} =~ s/\s//g;
if ( $config{CC_ALLOW_PORTS_TCP} ne "" ) {
foreach my $port ( split( /\,/, $config{CC_ALLOW_PORTS_TCP} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid CC_ALLOW_PORTS_TCP port [$port]" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWPORTS $ethdevin -p tcp $statemodulenew --dport $port -j $accept" );
if ( $config{CC6_LOOKUPS} and $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWPORTS $ethdevin -p tcp $statemodulenew --dport $port -j $accept" );
}
}
}
if ( $config{CC_ALLOW_PORTS_UDP} ne "" ) {
foreach my $port ( split( /\,/, $config{CC_ALLOW_PORTS_UDP} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid CC_ALLOW_PORTS_UDP port [$port]" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWPORTS $ethdevin -p udp $statemodulenew --dport $port -j $accept" );
if ( $config{CC6_LOOKUPS} and $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWPORTS $ethdevin -p udp $statemodulenew --dport $port -j $accept" );
}
}
}
my $cnt = 0;
foreach my $cc ( split( /\,/, $config{CC_ALLOW_PORTS} ) ) {
$cc = lc $cc;
if ( $config{LF_IPSET} ) {
ipsetcreate("cc_$cc");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWP -m set --match-set cc_$cc src -j CC_ALLOWPORTS" );
if ( $config{CC6_LOOKUPS} and $config{IPV6} ) {
ipsetcreate("cc_6_$cc");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWP -m set --match-set cc_6_$cc src -j CC_ALLOWPORTS" );
}
}
if ( -e "/var/lib/csf/zone/$cc.zone" ) {
if ( $config{LF_IPSET} ) {
undef @ipset;
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( $config{CC_DROP_CIDR} > 0 and $config{CC_DROP_CIDR} < 33 ) {
my ( $drop_ip, $drop_cidr ) = split( /\//, $ip );
if ( !length $drop_cidr ) { $drop_cidr = "32" }
if ( $drop_cidr > $config{CC_DROP_CIDR} ) { next }
}
if ( cccheckip( \$ip ) ) { push @ipset, "add -exist cc_$cc $ip" }
}
ipsetrestore("cc_$cc");
}
else {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) {
if ( $config{CC_DROP_CIDR} > 0 and $config{CC_DROP_CIDR} < 33 ) {
my ( $drop_ip, $drop_cidr ) = split( /\//, $ip );
if ( !length $drop_cidr ) { $drop_cidr = "32" }
if ( $drop_cidr > $config{CC_DROP_CIDR} ) { next }
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWP -s $ip -j CC_ALLOWPORTS" );
$cnt++;
}
}
if ( $config{FASTSTART} ) { faststart("CC_ALLOW_PORTS [$cc]") }
}
}
if ( $config{CC6_LOOKUPS} and -e "/var/lib/csf/zone/$cc.zone6" ) {
if ( $config{LF_IPSET} ) {
undef @ipset;
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone6") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) { push @ipset, "add -exist cc_6_$cc $ip" }
}
ipsetrestore("cc_6_$cc");
}
else {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone6") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_ALLOWP -s $ip -j CC_ALLOWPORTS" );
$cnt++;
}
}
if ( $config{FASTSTART} ) { faststart("CC_ALLOW_PORTS [$cc]") }
}
}
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j CC_ALLOWP" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j CC_ALLOWP" );
}
}
$config{CC_DENY_PORTS} //= "";
$config{CC_DENY_PORTS} =~ s/\s//g;
if ( $config{CC_DENY_PORTS} ) {
$config{CC_DENY_PORTS_TCP} //= "";
$config{CC_DENY_PORTS_TCP} =~ s/\s//g;
$config{CC_DENY_PORTS_UDP} //= "";
$config{CC_DENY_PORTS_UDP} =~ s/\s//g;
if ( $config{CC_DENY_PORTS_TCP} ne "" ) {
foreach my $port ( split( /\,/, $config{CC_DENY_PORTS_TCP} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid CC_DENY_PORTS_TCP port [$port]" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_DENYPORTS $ethdevin -p tcp --dport $port -j $config{DROP}" );
if ( $config{CC6_LOOKUPS} and $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_DENYPORTS $ethdevin -p tcp --dport $port -j $config{DROP}" );
}
}
}
if ( $config{CC_DENY_PORTS_UDP} ne "" ) {
foreach my $port ( split( /\,/, $config{CC_DENY_PORTS_UDP} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid CC_DENY_PORTS_UDP port [$port]" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_DENYPORTS $ethdevin -p udp --dport $port -j $config{DROP}" );
if ( $config{CC6_LOOKUPS} and $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_DENYPORTS $ethdevin -p udp --dport $port -j $config{DROP}" );
}
}
}
my $cnt = 0;
foreach my $cc ( split( /\,/, $config{CC_DENY_PORTS} ) ) {
$cc = lc $cc;
if ( $config{LF_IPSET} ) {
ipsetcreate("cc_$cc");
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I CC_DENYP -m set --match-set cc_$cc src -j CC_DENYPORTS" );
if ( $config{CC6_LOOKUPS} and $config{IPV6} ) {
ipsetcreate("cc_6_$cc");
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I CC_DENYP -m set --match-set cc_6_$cc src -j CC_DENYPORTS" );
}
}
if ( -e "/var/lib/csf/zone/$cc.zone" ) {
if ( $config{LF_IPSET} ) {
undef @ipset;
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( $config{CC_DROP_CIDR} > 0 and $config{CC_DROP_CIDR} < 33 ) {
my ( $drop_ip, $drop_cidr ) = split( /\//, $ip );
if ( !length $drop_cidr ) { $drop_cidr = "32" }
if ( $drop_cidr > $config{CC_DROP_CIDR} ) { next }
}
if ( cccheckip( \$ip ) ) { push @ipset, "add -exist cc_$cc $ip" }
}
ipsetrestore("cc_$cc");
}
else {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) {
if ( $config{CC_DROP_CIDR} > 0 and $config{CC_DROP_CIDR} < 33 ) {
my ( $drop_ip, $drop_cidr ) = split( /\//, $ip );
if ( !length $drop_cidr ) { $drop_cidr = "32" }
if ( $drop_cidr > $config{CC_DROP_CIDR} ) { next }
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CC_DENYP -s $ip -j CC_DENYPORTS" );
$cnt++;
}
}
if ( $config{FASTSTART} ) { faststart("CC_DENY_PORTS [$cc]") }
}
}
if ( $config{CC6_LOOKUPS} and -e "/var/lib/csf/zone/$cc.zone6" ) {
if ( $config{LF_IPSET} ) {
undef @ipset;
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone6") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) { push @ipset, "add -exist cc_6_$cc $ip" }
}
ipsetrestore("cc_6_$cc");
}
else {
if ( $config{FASTSTART} ) { $faststart = 1 }
foreach my $line ( slurp("/var/lib/csf/zone/$cc.zone6") ) {
$line =~ s/$cleanreg//g;
if ( $line =~ /^(\s|\#|$)/ ) { next }
my ( $ip, undef ) = split( /\s/, $line, 2 );
if ( cccheckip( \$ip ) ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CC_DENYP -s $ip -j CC_DENYPORTS" );
$cnt++;
}
}
if ( $config{FASTSTART} ) { faststart("CC_DENY_PORTS [$cc]") }
}
}
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j CC_DENYP" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALINPUT $ethdevin -j CC_DENYP" );
}
}
if ( $config{CLUSTER_SENDTO} ) {
foreach my $ip ( split( /\,/, $config{CLUSTER_SENDTO} ) ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I LOCALOUTPUT $ethdevout -p tcp -d $ip --dport $config{CLUSTER_PORT} -j $accept" );
}
}
if ( $config{CLUSTER_RECVFROM} ) {
foreach my $ip ( split( /\,/, $config{CLUSTER_RECVFROM} ) ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I LOCALINPUT $ethdevin -p tcp -s $ip --dport $config{CLUSTER_PORT} -j $accept" );
}
}
if ( $config{SYNFLOOD} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A SYNFLOOD -m limit --limit $config{SYNFLOOD_RATE} --limit-burst $config{SYNFLOOD_BURST} -j RETURN" );
if ( $config{DROP_LOGGING} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A SYNFLOOD -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *SYNFLOOD Blocked* '" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A SYNFLOOD -j DROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -p tcp --syn -j SYNFLOOD" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A SYNFLOOD -m limit --limit $config{SYNFLOOD_RATE} --limit-burst $config{SYNFLOOD_BURST} -j RETURN" );
if ( $config{DROP_LOGGING} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A SYNFLOOD -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *SYNFLOOD Blocked* '" ) }
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A SYNFLOOD -j DROP" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I INPUT $ethdevin -p tcp --syn -j SYNFLOOD" );
}
}
$config{PORTFLOOD} =~ s/\s//g;
if ( $config{PORTFLOOD} ) {
my $maxrecent = 20;
if ( -e "/sys/module/ipt_recent/parameters/ip_pkt_list_tot" ) {
my @new = slurp("/sys/module/ipt_recent/parameters/ip_pkt_list_tot");
if ( $new[0] > 1 ) { $maxrecent = $new[0] }
}
if ( -e "/sys/module/xt_recent/parameters/ip_pkt_list_tot" ) {
my @new = slurp("/sys/module/xt_recent/parameters/ip_pkt_list_tot");
if ( $new[0] > 1 ) { $maxrecent = $new[0] }
}
foreach my $portflood ( split( /\,/, $config{PORTFLOOD} ) ) {
my ( $port, $proto, $count, $seconds ) = split( /\;/, $portflood );
if ( ( ( $port < 0 ) or ( $port > 65535 ) ) or ( $proto !~ /icmp|tcp|udp/ ) or ( $seconds !~ /\d+/ ) ) { error( __LINE__, "csf: Incorrect PORTFLOOD setting: [$portflood]" ) }
if ( ( $count < 1 ) or ( $count > $maxrecent ) ) {
print "WARNING: count in PORTFLOOD setting must be between 1 and $maxrecent: [$portflood]\n";
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p $proto --dport $port $statemodulenew -m recent --set --name $port" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p $proto --dport $port $statemodulenew -m recent --update --seconds $seconds --hitcount $count --name $port -j PORTFLOOD" );
if ( $config{PORTFLOOD6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p $proto --dport $port $statemodulenew -m recent --set --name $port" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p $proto --dport $port $statemodulenew -m recent --update --seconds $seconds --hitcount $count --name $port -j PORTFLOOD" );
}
}
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A PORTFLOOD -j $config{DROP}" );
if ( $config{PORTFLOOD6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A PORTFLOOD -j $config{DROP}" );
}
}
$config{CONNLIMIT} =~ s/\s//g;
if ( $config{CONNLIMIT} ) {
foreach my $connlimit ( split( /\,/, $config{CONNLIMIT} ) ) {
my ( $port, $limit ) = split( /\;/, $connlimit );
if ( ( $port < 0 ) or ( $port > 65535 ) or ( $limit < 1 ) or ( $limit !~ /\d+/ ) ) { error( __LINE__, "csf: Incorrect CONNLIMIT setting: [$connlimit]" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p tcp --syn --dport $port -m connlimit --connlimit-above $limit -j CONNLIMIT" );
if ( $config{CONNLIMIT6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p tcp --syn --dport $port -m connlimit --connlimit-above $limit -j CONNLIMIT" );
}
}
if ( $config{CONNLIMIT_LOGGING} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CONNLIMIT -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *ConnLimit* '" ); }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A CONNLIMIT -p tcp -j REJECT --reject-with tcp-reset" );
if ( $config{CONNLIMIT6} ) {
if ( $config{CONNLIMIT_LOGGING} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CONNLIMIT -m limit --limit 30/m --limit-burst 5 -j $logintarget 'Firewall: *ConnLimit* '" ); }
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A CONNLIMIT -p tcp -j REJECT --reject-with tcp-reset" );
}
}
if ( $config{UDPFLOOD} ) {
foreach my $item ( split( /\,/, $config{UDPFLOOD_ALLOWUSER} ) ) {
$item =~ s/\s//g;
my $uid = ( getpwnam($item) )[2];
if ($uid) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A UDPFLOOD -p udp -m owner --uid-owner $uid -j RETURN", 1 );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A UDPFLOOD -p udp -m owner --uid-owner $uid -j RETURN", 1 );
}
}
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A UDPFLOOD -p udp -m owner --uid-owner 0 -j RETURN", 1 );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A UDPFLOOD $ethdevout -p udp -m limit --limit $config{UDPFLOOD_LIMIT} --limit-burst $config{UDPFLOOD_BURST} -j RETURN" );
if ( $config{UDPFLOOD_LOGGING} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A UDPFLOOD -m limit --limit 30/m --limit-burst 5 -j $logouttarget 'Firewall: *UDPFLOOD* '" ); }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A UDPFLOOD $ethdevout -p udp -j $config{DROP_OUT}" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A LOCALOUTPUT $ethdevout -p udp -j UDPFLOOD" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A UDPFLOOD -p udp -m owner --uid-owner 0 -j RETURN", 1 );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A UDPFLOOD $ethdevout -p udp -m limit --limit $config{UDPFLOOD_LIMIT} --limit-burst $config{UDPFLOOD_BURST} -j RETURN" );
if ( $config{UDPFLOOD_LOGGING} ) { syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A UDPFLOOD -m limit --limit 30/m --limit-burst 5 -j $logouttarget 'Firewall: *UDPFLOOD* '" ); }
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A UDPFLOOD $ethdevout -p udp -j $config{DROP_OUT}" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A LOCALOUTPUT $ethdevout -p udp -j UDPFLOOD" );
}
}
my $icmp_in_rate = "";
my $icmp_out_rate = "";
if ( $config{ICMP_IN_RATE} ) { $icmp_in_rate = "-m limit --limit $config{ICMP_IN_RATE}" }
if ( $config{ICMP_OUT_RATE} ) { $icmp_out_rate = "-m limit --limit $config{ICMP_OUT_RATE}" }
if ( $config{ICMP_IN} ) {
if ( $config{ICMP_IN_RATE} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p icmp --icmp-type echo-request $icmp_in_rate -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p icmp --icmp-type echo-request -j $dropin" );
}
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p icmp --icmp-type echo-request -j $dropin" );
}
if ( $config{ICMP_TIMESTAMPDROP} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p icmp --icmp-type timestamp-request -j $dropin" );
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p icmp -j $accept" );
if ( $config{ICMP_OUT} ) {
if ( $config{ICMP_OUT_RATE} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -p icmp --icmp-type echo-request $icmp_out_rate -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -p icmp --icmp-type echo-request -j $dropout" );
}
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -p icmp --icmp-type echo-request -j $dropout" );
}
if ( $config{ICMP_TIMESTAMPDROP} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -p icmp --icmp-type timestamp-reply -j $dropout" );
}
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -p icmp -j $accept" );
if ( $config{IPV6} ) {
if ( $config{IPV6_ICMP_STRICT} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type destination-unreachable -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type packet-too-big -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type time-exceeded -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type parameter-problem -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type echo-request -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type echo-reply -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j $accept" );
}
else {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 -j $accept" );
}
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 -j $accept" );
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type destination-unreachable -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type packet-too-big -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type time-exceeded -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type parameter-problem -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type echo-request -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type echo-reply -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j $accept");
}
if ( $config{LF_SPI} ) {
if ( $config{USE_FTPHELPER} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t raw -A PREROUTING -p tcp --dport $config{USE_FTPHELPER} -j CT --helper ftp" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t raw -A OUTPUT -p tcp --dport $config{USE_FTPHELPER} -j CT --helper ftp" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin $statemodule RELATED -m helper --helper ftp -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout $statemodule RELATED -m helper --helper ftp -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin $statemodule ESTABLISHED -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout $statemodule ESTABLISHED -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin $statemodule ESTABLISHED,RELATED -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout $statemodule ESTABLISHED,RELATED -j $accept" );
}
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p udp -m udp --dport 32768:61000 -j $accept" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p tcp -m tcp --dport 32768:61000 ! --syn -j $accept" );
}
if ( $config{IPV6} ) {
if ( $config{IPV6_SPI} ) {
if ( $config{USE_FTPHELPER} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t raw -A PREROUTING -p tcp --dport $config{USE_FTPHELPER} -j CT --helper ftp" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t raw -A OUTPUT -p tcp --dport $config{USE_FTPHELPER} -j CT --helper ftp" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin $statemodule RELATED -m helper --helper ftp -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout $statemodule RELATED -m helper --helper ftp -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin $statemodule ESTABLISHED -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout $statemodule ESTABLISHED -j $accept" );
}
else {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin $statemodule ESTABLISHED,RELATED -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout $statemodule ESTABLISHED,RELATED -j $accept" );
}
}
else {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p udp -m udp --dport 32768:61000 -j $accept" );
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p tcp -m tcp --dport 32768:61000 ! --syn -j $accept" );
}
}
$config{PORTKNOCKING} =~ s/\s//g;
if ( $config{PORTKNOCKING} ) {
foreach my $portknock ( split( /\,/, $config{PORTKNOCKING} ) ) {
my ( $port, $proto, $timeout, $knocks ) = split( /\;/, $portknock, 4 );
my @steps = split( /\;/, $knocks );
my $nsteps = @steps;
if ( $nsteps < 3 ) {
print "csf: Error - not enough Port Knocks for port $port [$knocks]\n";
next;
}
for ( my $step = 1; $step < $nsteps + 1; $step++ ) {
my $ar = $step - 1;
if ( $step == 1 ) {
if ( $config{PORTKNOCKING_LOG} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p $proto --dport $steps[$ar] $statemodulenew -m limit --limit 30/m --limit-burst 5 -j LOG --log-prefix 'Knock: *$port\_S$step* '" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p $proto --dport $steps[$ar] $statemodulenew -m recent --set --name PK\_$port\_S$step" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p $proto --dport $steps[$ar] $statemodulenew -j DROP" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -N PK\_$port\_S$step\_IN" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A PK\_$port\_S$step\_IN -m recent --name PK\_$port\_S" . ( $step - 1 ) . " --remove" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A PK\_$port\_S$step\_IN -m recent --name PK\_$port\_S$step --set" );
if ( $config{PORTKNOCKING_LOG} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A PK\_$port\_S$step\_IN -m limit --limit 30/m --limit-burst 5 -j LOG --log-prefix 'Knock: *$port\_S$step* '" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A PK\_$port\_S$step\_IN -j DROP" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p $proto --dport $steps[$ar] $statemodulenew -m recent --rcheck --seconds $timeout --name PK\_$port\_S" . ( $step - 1 ) . " -j PK\_$port\_S$step\_IN" );
}
}
if ( $config{PORTKNOCKING_LOG} ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p $proto --dport $port $statemodulenew -m recent --rcheck --seconds $timeout --name PK\_$port\_S$nsteps -m limit --limit 30/m --limit-burst 5 -j LOG --log-prefix 'Knock: *$port\_IN* '" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p $proto --dport $port $statemodulenew -m recent --rcheck --seconds $timeout --name PK\_$port\_S$nsteps -j ACCEPT" );
}
}
if ( $config{FASTSTART} ) { $faststart = 1 }
$config{TCP_IN} =~ s/\s//g;
if ( $config{TCP_IN} ne "" ) {
foreach my $port ( split( /\,/, $config{TCP_IN} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid TCP_IN port [$port]" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p tcp $statemodulenew --dport $port -j $accept" );
}
}
if ( $config{FASTSTART} ) { faststart("TCP_IN") }
if ( $config{FASTSTART} ) { $faststart = 1 }
$config{TCP6_IN} =~ s/\s//g;
if ( $config{IPV6} and $config{TCP6_IN} ne "" ) {
foreach my $port ( split( /\,/, $config{TCP6_IN} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid TCP6_IN port [$port]" ) }
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p tcp $statemodule6new --dport $port -j $accept" );
}
}
if ( $config{FASTSTART} ) { faststart("TCP6_IN") }
if ( $config{FASTSTART} ) { $faststart = 1 }
$config{TCP_OUT} =~ s/\s//g;
if ( $config{TCP_OUT} ne "" ) {
foreach my $port ( split( /\,/, $config{TCP_OUT} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid TCP_OUT port [$port]" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -p tcp $statemodulenew --dport $port -j $accept" );
}
}
if ( $config{FASTSTART} ) { faststart("TCP_OUT") }
if ( $config{FASTSTART} ) { $faststart = 1 }
$config{TCP6_OUT} =~ s/\s//g;
if ( $config{IPV6} and $config{TCP6_OUT} ne "" ) {
foreach my $port ( split( /\,/, $config{TCP6_OUT} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid TCP6_OUT port [$port]" ) }
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p tcp $statemodule6new --dport $port -j $accept" );
}
}
if ( $config{FASTSTART} ) { faststart("TCP6_OUT") }
if ( $config{FASTSTART} ) { $faststart = 1 }
$config{UDP_IN} =~ s/\s//g;
if ( $config{UDP_IN} ne "" ) {
foreach my $port ( split( /\,/, $config{UDP_IN} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid UDP_IN port [$port]" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p udp $statemodulenew --dport $port -j $accept" );
}
}
if ( $config{FASTSTART} ) { faststart("UDP_IN") }
if ( $config{FASTSTART} ) { $faststart = 1 }
$config{UDP6_IN} =~ s/\s//g;
if ( $config{IPV6} and $config{UDP6_IN} ne "" ) {
foreach my $port ( split( /\,/, $config{UDP6_IN} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid UDP6_IN port [$port]" ) }
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p udp $statemodule6new --dport $port -j $accept" );
}
}
if ( $config{FASTSTART} ) { faststart("UDP6_IN") }
if ( $config{FASTSTART} ) { $faststart = 1 }
$config{UDP_OUT} =~ s/\s//g;
if ( $config{UDP_OUT} ne "" ) {
foreach my $port ( split( /\,/, $config{UDP_OUT} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid UDP_OUT port [$port]" ) }
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -p udp $statemodulenew --dport $port -j $accept" );
}
}
if ( $config{FASTSTART} ) { faststart("UDP_OUT") }
if ( $config{FASTSTART} ) { $faststart = 1 }
$config{UDP6_OUT} =~ s/\s//g;
if ( $config{IPV6} and $config{UDP6_OUT} ne "" ) {
foreach my $port ( split( /\,/, $config{UDP6_OUT} ) ) {
if ( $port eq "" ) { next }
if ( $port !~ /^[\d:]*$/ ) { error( __LINE__, "Invalid UDP6_OUT port [$port]" ) }
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p udp $statemodule6new --dport $port -j $accept" );
}
}
if ( $config{FASTSTART} ) { faststart("UDP6_OUT") }
# if ($config{IPV6}) {
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p udp -m frag --fraglast -j $accept");
# }
# my $icmp_in_rate = "";
# my $icmp_out_rate = "";
# if ($config{ICMP_IN_RATE}) {$icmp_in_rate = "-m limit --limit $config{ICMP_IN_RATE}"}
# if ($config{ICMP_OUT_RATE}) {$icmp_out_rate = "-m limit --limit $config{ICMP_OUT_RATE}"}
#
# if ($config{ICMP_IN}) {
# syscommand(__LINE__,"$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p icmp --icmp-type echo-request $icmp_in_rate -j $accept");
# syscommand(__LINE__,"$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -p icmp --icmp-type echo-reply $icmp_out_rate -j $accept");
# }
#
# if ($config{ICMP_OUT}) {
# syscommand(__LINE__,"$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -p icmp --icmp-type echo-request $icmp_out_rate -j $accept");
# syscommand(__LINE__,"$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p icmp --icmp-type echo-reply $icmp_in_rate -j $accept");
# }
#
# syscommand(__LINE__,"$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p icmp --icmp-type time-exceeded -j $accept");
# syscommand(__LINE__,"$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A INPUT $ethdevin -p icmp --icmp-type destination-unreachable -j $accept");
#
# syscommand(__LINE__,"$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -p icmp --icmp-type time-exceeded -j $accept");
# syscommand(__LINE__,"$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $ethdevout -p icmp --icmp-type destination-unreachable -j $accept");
#
# if ($config{IPV6}) {
# if ($config{IPV6_ICMP_STRICT}) {
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type destination-unreachable -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type packet-too-big -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type time-exceeded -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type parameter-problem -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type echo-request -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type echo-reply -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j $accept");
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j $accept");
# } else {
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A INPUT $eth6devin -p icmpv6 -j $accept");
# }
#
# syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 -j $accept");
## syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type destination-unreachable -j $accept");
## syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type packet-too-big -j $accept");
## syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type time-exceeded -j $accept");
## syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type parameter-problem -j $accept");
## syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type echo-request -j $accept");
## syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type echo-reply -j $accept");
## syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j $accept");
## syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j $accept");
## syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j $accept");
## syscommand(__LINE__,"$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A OUTPUT $eth6devout -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j $accept");
# }
if ( -e "/etc/csf/csf.redirect" ) {
my $dnat = 0;
my @entries = slurp("/etc/csf/csf.redirect");
foreach my $line (@entries) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @entries, @incfile;
}
}
foreach my $line (@entries) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $redirect, $comment ) = split( /\s/, $line, 2 );
my ( $ipx, $porta, $ipy, $portb, $proto ) = split( /\|/, $redirect );
unless ( $proto eq "tcp" or $proto eq "udp" ) { error( __LINE__, "csf: Incorrect csf.redirect setting ([$proto]): [$line]" ) }
unless ( $ipx eq "*" or checkip( \$ipx ) ) { error( __LINE__, "csf: Incorrect csf.redirect setting ([$ipx]): [$line]" ) }
unless ( $porta eq "*" or $porta > 0 or $porta < 65536 ) { error( __LINE__, "csf: Incorrect csf.redirect setting ([$porta]): [$line]" ) }
unless ( $ipy eq "*" or checkip( \$ipy ) ) { error( __LINE__, "csf: Incorrect csf.redirect setting ([$ipy]): [$line]" ) }
unless ( $portb eq "*" or $portb > 0 or $portb < 65536 ) { error( __LINE__, "csf: Incorrect csf.redirect setting ([$portb]): [$line]" ) }
if ( $ipy eq "*" ) {
if ( $ipx eq "*" ) { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -A PREROUTING $ethdevin -p $proto --dport $porta -j REDIRECT --to-ports $portb" ) }
else { syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -A PREROUTING $ethdevin -p $proto -d $ipx --dport $porta -j REDIRECT --to-ports $portb" ) }
}
else {
unless ($dnat) {
open( my $OUT, ">", "/proc/sys/net/ipv4/ip_forward" );
flock( $OUT, LOCK_EX );
print $OUT "1";
close($OUT);
$dnat = 1;
}
if ( $ipx ne "*" and $porta eq "*" ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -A PREROUTING $ethdevin -p $proto -d $ipx -j DNAT --to-destination $ipy" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -A POSTROUTING $ethdevout -p $proto -d $ipy -j SNAT --to-source $ipx" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A FORWARD $ethdevin -p $proto -d $ipy $statemodulenew -j ACCEPT" );
}
elsif ( $ipx ne "*" and $porta ne "*" and $portb ne "*" ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -A PREROUTING $ethdevin -p $proto -d $ipx --dport $porta -j DNAT --to-destination $ipy:$portb" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -A POSTROUTING $ethdevout -p $proto -d $ipy -j SNAT --to-source $ipx" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A FORWARD $ethdevin -p $proto -d $ipy --dport $portb $statemodulenew -j ACCEPT" );
}
else { error( __LINE__, "csf: Invalid csf.redirect format [$line]" ) }
}
}
if ( $dnat and $config{LF_SPI} ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A FORWARD $ethdevin $statemodule ESTABLISHED,RELATED -j ACCEPT" );
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A FORWARD $ethdevin -j LOGDROPIN" );
}
}
return;
}
sub dodisable {
open( my $OUT, ">", "/etc/csf/csf.disable" );
flock( $OUT, LOCK_EX );
close($OUT);
sysopen( my $CONF, "/etc/chkserv.d/chkservd.conf", O_RDWR | O_CREAT ) or error( __LINE__, "Could not open /etc/chkserv.d/chkservd.conf: $!" );
flock( $CONF, LOCK_EX ) or error( __LINE__, "Could not lock /etc/chkserv.d/chkservd.conf: $!" );
my $text = join( "", <$CONF> );
my @conf = split( /$slurpreg/, $text );
chomp @conf;
seek( $CONF, 0, 0 );
truncate( $CONF, 0 );
foreach my $line (@conf) {
if ( $line =~ /^lfd:/ ) { $line = "lfd:0" }
print $CONF $line . "\n";
}
close($CONF) or error( __LINE__, "Could not close /etc/conf: $!" );
ConfigServer::Service::stoplfd();
dostop(0);
print "csf and lfd have been disabled\n";
return;
}
sub doenable {
unless ( -e "/etc/csf/csf.disable" ) {
print "csf and lfd are not disabled!\n";
exit 0; ## no critic (Cpanel::NoExitsFromSubroutines) - CLI command early termination
}
unlink("/etc/csf/csf.disable");
dostart();
ConfigServer::Service::startlfd();
sysopen( my $CONF, "/etc/chkserv.d/chkservd.conf", O_RDWR | O_CREAT ) or error( __LINE__, "Could not open /etc/chkserv.d/chkservd.conf: $!" );
flock( $CONF, LOCK_EX ) or error( __LINE__, "Could not lock /etc/chkserv.d/chkservd.conf: $!" );
my $text = join( "", <$CONF> );
my @conf = split( /$slurpreg/, $text );
chomp @conf;
seek( $CONF, 0, 0 );
truncate( $CONF, 0 );
foreach my $line (@conf) {
if ( $line =~ /^lfd:/ ) { $line = "lfd:1" }
print $CONF $line . "\n";
}
close($CONF) or error( __LINE__, "Could not close /etc/conf: $!" );
open( my $OUT, ">", "/etc/chkserv.d/lfd" );
flock( $OUT, LOCK_EX );
print $OUT "service[lfd]=x,x,x,service lfd restart,lfd,root\n";
close($OUT);
print "csf and lfd have been enabled\n";
return;
}
sub crontab {
my $act = shift;
my @crontab = slurp("/etc/crontab");
my $hit = 0;
my @newcrontab;
foreach my $line (@crontab) {
if ( $line =~ /csf(\.pl)? -f/ ) {
$hit = 1;
if ( $act eq "add" ) {
push @newcrontab, $line;
}
}
else {
push @newcrontab, $line;
}
}
if ( ( $act eq "add" ) and !($hit) ) {
push @newcrontab, "*/$config{TESTING_INTERVAL} * * * * root /usr/sbin/csf -f > /dev/null 2>&1";
}
if ( ( $act eq "remove" ) and !($hit) ) {
# don't do anything
}
else {
sysopen( my $CRONTAB, "/etc/crontab", O_RDWR | O_CREAT ) or die "Could not open /etc/crontab: $!";
flock( $CRONTAB, LOCK_EX ) or die "Could not lock /etc/crontab: $!";
seek( $CRONTAB, 0, 0 );
truncate( $CRONTAB, 0 );
foreach my $line (@newcrontab) {
print $CRONTAB $line . "\n";
}
close($CRONTAB) or die "Could not close /etc/crontab: $!";
}
return;
}
sub error {
my $line = shift;
my $error = shift;
my $verbose;
if ( $config{DEBUG} >= 1 ) { $verbose = "--verbose" }
system("$config{IPTABLES} $verbose --policy INPUT ACCEPT");
system("$config{IPTABLES} $verbose --policy OUTPUT ACCEPT");
system("$config{IPTABLES} $verbose --policy FORWARD ACCEPT");
system("$config{IPTABLES} $verbose --flush");
system("$config{IPTABLES} $verbose --delete-chain");
if ( $config{NAT} ) {
syscommand( __LINE__, "$config{IPTABLES} $verbose -t nat --flush" );
syscommand( __LINE__, "$config{IPTABLES} $verbose -t nat --delete-chain" );
}
if ( $config{RAW} ) {
syscommand( __LINE__, "$config{IPTABLES} $verbose -t raw --flush" );
syscommand( __LINE__, "$config{IPTABLES} $verbose -t raw --delete-chain" );
}
if ( $config{MANGLE} ) {
syscommand( __LINE__, "$config{IPTABLES} $verbose -t mangle --flush" );
syscommand( __LINE__, "$config{IPTABLES} $verbose -t mangle --delete-chain" );
}
if ( $config{IPV6} ) {
system("$config{IP6TABLES} $verbose --policy INPUT ACCEPT");
system("$config{IP6TABLES} $verbose --policy OUTPUT ACCEPT");
system("$config{IP6TABLES} $verbose --policy FORWARD ACCEPT");
system("$config{IP6TABLES} $verbose --flush");
system("$config{IP6TABLES} $verbose --delete-chain");
if ( $config{NAT6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t nat --flush" );
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t nat --delete-chain" );
}
if ( $config{RAW6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t raw --flush" );
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t raw --delete-chain" );
}
if ( $config{MANGLE6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t mangle --flush" );
syscommand( __LINE__, "$config{IP6TABLES} $verbose -t mangle --delete-chain" );
}
}
if ( $config{LF_IPSET} ) {
system("$config{IPSET} flush");
system("$config{IPSET} destroy");
}
print "Error: $error, at line $line\n";
open( my $OUT, ">", "/etc/csf/csf.error" );
flock( $OUT, LOCK_EX );
print $OUT "Error: $error, at line $line in /usr/sbin/csf\n";
close($OUT);
if ( $config{TESTING} ) { crontab("remove") }
exit 1; ## no critic (Cpanel::NoExitsFromSubroutines) - Fatal error termination
}
sub version {
my ($myv) = slurpee( "/etc/csf/version.txt", 'fatal' => 1 );
chomp $myv;
return $myv;
}
sub getethdev {
my $ethdev = ConfigServer::GetEthDev->new();
my %g_ifaces = $ethdev->ifaces;
my %g_ipv4 = $ethdev->ipv4;
my %g_ipv6 = $ethdev->ipv6;
foreach my $key ( keys %g_ifaces ) {
$ifaces{$key} = 1;
}
foreach my $key ( keys %g_ipv4 ) {
$ips{$key} = 1;
}
if ( $config{IPV6} ) {
foreach my $key ( keys %g_ipv6 ) {
eval {
local $SIG{__DIE__} = undef;
$ipscidr6->add($key);
};
}
}
$config{ETH_DEVICE} //= "";
$config{ETH_DEVICE} =~ s/:.*//; # Strip everything after the first colon.
if ( $config{ETH_DEVICE} eq "" ) {
$ethdevin = "! -i lo";
$ethdevout = "! -o lo";
}
else {
$ethdevin = "-i $config{ETH_DEVICE}";
$ethdevout = "-o $config{ETH_DEVICE}";
}
$config{ETH6_DEVICE} //= "";
if ( $config{ETH6_DEVICE} eq "" ) {
$eth6devin = $ethdevin;
$eth6devout = $ethdevout;
}
else {
$eth6devin = "-i $config{ETH6_DEVICE}";
$eth6devout = "-o $config{ETH6_DEVICE}";
}
return;
}
sub linefilter {
my $line = shift;
my $ad = shift;
my $chain = shift // "";
my $delete = shift;
my $pktin = "$accept";
my $pktout = "$accept";
my $localin = "ALLOWIN";
my $localout = "ALLOWOUT";
my $inadd = "-I";
if ( $ad eq "deny" ) {
$inadd = "-A";
$pktin = $config{DROP};
$pktout = $config{DROP_OUT};
if ( $config{DROP_IP_LOGGING} ) { $pktin = "LOGDROPIN" }
if ( $config{DROP_OUT_LOGGING} ) { $pktout = "LOGDROPOUT" }
$localin = "DENYIN";
$localout = "DENYOUT";
}
my $chainin = $chain . "IN";
my $chainout = $chain . "OUT";
$line =~ s/[\n\r]//g;
$line = lc $line;
if ( $line =~ /^\#/ ) { return }
if ( $line =~ /^Include/ ) { return }
if ( $line eq "" ) { return }
my $checkip = checkip( \$line );
my $iptables = $config{IPTABLES};
my $ipv4 = 1;
my $ipv6 = 0;
my $linein = $ethdevin;
my $lineout = $ethdevout;
if ( $checkip == 6 ) {
if ( $config{IPV6} ) {
$iptables = $config{IP6TABLES};
$linein = $eth6devin;
$lineout = $eth6devout;
$ipv4 = 0;
$ipv6 = 1;
}
else { return }
}
if ($checkip) {
if ($chain) {
if ( $config{LF_IPSET} ) {
if ($ipv4) { ipsetadd( "chain_$chainin", $line ) }
else { ipsetadd( "chain_6_${chainin}", $line ) }
}
else {
syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose -A $chainin $linein -s $line -j $pktin" );
if ( ( $ad eq "deny" and !$config{LF_BLOCKINONLY} ) or ( $ad ne "deny" ) ) { syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose -A $chainout $lineout -d $line -j $pktout" ) }
}
}
else {
if ($delete) {
if ( $config{LF_IPSET} ) {
if ($ipv4) { ipsetdel( "chain_$localin", $line ) }
else { ipsetdel( "chain_6_${localin}", $line ) }
}
else {
syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose -D $localin $linein -s $line -j $pktin" );
if ( ( $ad eq "deny" and !$config{LF_BLOCKINONLY} ) or ( $ad ne "deny" ) ) { syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose -D $localout $lineout -d $line -j $pktout" ) }
}
if ( ( $ad eq "deny" ) and ( $ipv4 and $config{MESSENGER} and $config{MESSENGER_PERM} ) ) { domessenger( $line, "D" ) }
if ( ( $ad eq "deny" ) and ( $ipv6 and $config{MESSENGER6} and $config{MESSENGER_PERM} ) ) { domessenger( $line, "D" ) }
}
else {
if ( $config{LF_IPSET} ) {
if ($ipv4) { ipsetadd( "chain_$localin", $line ) }
else { ipsetadd( "chain_6_${localin}", $line ) }
}
else {
syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose $inadd $localin $linein -s $line -j $pktin" );
if ( ( $ad eq "deny" and !$config{LF_BLOCKINONLY} ) or ( $ad ne "deny" ) ) { syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose $inadd $localout $lineout -d $line -j $pktout" ) }
}
if ( ( $ad eq "deny" ) and ( $ipv4 and $config{MESSENGER} and $config{MESSENGER_PERM} ) ) { domessenger( $line, "A" ) }
if ( ( $ad eq "deny" ) and ( $ipv6 and $config{MESSENGER6} and $config{MESSENGER_PERM} ) ) { domessenger( $line, "A" ) }
}
}
}
elsif ( $line =~ /[:|]/ ) {
if ( $line !~ /\|/ ) { $line =~ s/\:/\|/g }
my $sip = "";
my $dip = "";
my $sport = "";
my $dport = "";
my $protocol = "-p tcp";
my $inout;
my $from = 0;
my $uid = "";
my $gid = "";
my $iptype;
my @ll = split( /\|/, $line );
if ( $ll[0] eq "tcp" ) {
$protocol = "-p tcp";
$from = 1;
}
elsif ( $ll[0] eq "udp" ) {
$protocol = "-p udp";
$from = 1;
}
elsif ( $ll[0] eq "icmp" ) {
$protocol = "-p icmp";
$from = 1;
}
for ( my $x = $from; $x < 2; $x++ ) {
next unless defined $ll[$x];
if ( ( $ll[$x] eq "out" ) ) {
$inout = "out";
$from = $x + 1;
last;
}
elsif ( ( $ll[$x] eq "in" ) ) {
$inout = "in";
$from = $x + 1;
last;
}
}
for ( my $x = $from; $x < 3; $x++ ) {
next unless defined $ll[$x];
if ( ( $ll[$x] =~ /d=(.*)/ ) ) {
$dport = "--dport $1";
$dport =~ s/_/:/g;
if ( $protocol eq "-p icmp" ) { $dport = "--icmp-type $1" }
if ( $dport =~ /,/ ) { $dport = "-m multiport " . $dport }
$from = $x + 1;
last;
}
elsif ( ( $ll[$x] =~ /s=(.*)/ ) ) {
$sport = "--sport $1";
$sport =~ s/_/:/g;
if ( $protocol eq "-p icmp" ) { $sport = "--icmp-type $1" }
if ( $sport =~ /,/ ) { $sport = "-m multiport " . $sport }
$from = $x + 1;
last;
}
}
for ( my $x = $from; $x < 4; $x++ ) {
next unless defined $ll[$x];
if ( ( $ll[$x] =~ /d=(.*)/ ) ) {
my $ip = $1;
my $status = checkip( \$ip );
if ($status) {
$iptype = $status;
$dip = "-d $1";
}
last;
}
elsif ( ( $ll[$x] =~ /s=(.*)/ ) ) {
my $ip = $1;
my $status = checkip( \$ip );
if ($status) {
$iptype = $status;
$sip = "-s $1";
}
last;
}
}
for ( my $x = $from; $x < 5; $x++ ) {
next unless defined $ll[$x];
if ( ( $ll[$x] =~ /u=(.*)/ ) ) {
$uid = "--uid-owner $1";
last;
}
elsif ( ( $ll[$x] =~ /g=(.*)/ ) ) {
$gid = "--gid-owner $1";
last;
}
}
if ( $uid or $gid ) {
if ( $config{VPS} and $noowner ) {
print "Cannot use UID or GID rules [$ad: $line] on this VPS as the Monolithic kernel does not support the iptables module ipt_owner/xt_owner - rule skipped\n";
}
else {
if ($chain) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A $chainout $lineout $protocol $dport -m owner $uid $gid -j $pktout" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A $chainout $lineout $protocol $dport -m owner $uid $gid -j $pktout" );
}
}
else {
if ($delete) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D $localout $lineout $protocol $dport -m owner $uid $gid -j $pktout" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D $localout $lineout $protocol $dport -m owner $uid $gid -j $pktout" );
}
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose $inadd $localout $lineout $protocol $dport -m owner $uid $gid -j $pktout" );
if ( $config{IPV6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose $inadd $localout $lineout $protocol $dport -m owner $uid $gid -j $pktout" );
}
}
}
}
}
elsif ( ( $sip or $dip ) and ( $dport or $sport ) ) {
my $iptables = $config{IPTABLES};
if ( $iptype == 6 ) {
if ( $config{IPV6} ) {
$iptables = $config{IP6TABLES};
}
else {
return;
}
}
if ( ( $inout eq "" ) or ( $inout eq "in" ) ) {
my $bport = $dport;
$bport =~ s/--dport //o;
my $bip = $sip;
$bip =~ s/-s //o;
if ($chain) {
syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose -A $chainin $linein $protocol $dip $sip $dport $sport -j $pktin" );
}
else {
if ($delete) {
syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose -D $localin $linein $protocol $dip $sip $dport $sport -j $pktin" );
if ( $messengerports{$bport} and ( $ad eq "deny" ) and ( $ipv4 and $config{MESSENGER} and $config{MESSENGER_PERM} ) ) { domessenger( $bip, "D", "$bport" ) }
if ( $messengerports{$bport} and ( $ad eq "deny" ) and ( $ipv6 and $config{MESSENGER6} and $config{MESSENGER_PERM} ) ) { domessenger( $bip, "D", "$bport" ) }
}
else {
syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose $inadd $localin $linein $protocol $dip $sip $dport $sport -j $pktin" );
if ( $messengerports{$bport} and ( $ad eq "deny" ) and ( $ipv4 and $config{MESSENGER} and $config{MESSENGER_PERM} ) ) { domessenger( $bip, "A", "$bport" ) }
if ( $messengerports{$bport} and ( $ad eq "deny" ) and ( $ipv6 and $config{MESSENGER6} and $config{MESSENGER_PERM} ) ) { domessenger( $bip, "A", "$bport" ) }
}
}
}
if ( $inout eq "out" ) {
if ($chain) {
syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose -A $chainout $lineout $protocol $dip $sip $dport $sport -j $pktout" );
}
else {
if ($delete) {
syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose -D $localout $lineout $protocol $dip $sip $dport $sport -j $pktout" );
}
else {
syscommand( __LINE__, "$iptables $config{IPTABLESWAIT} $verbose $inadd $localout $lineout $protocol $dip $sip $dport $sport -j $pktout" );
}
}
}
}
}
return;
}
sub docheck {
# Auto-updates have been deprecated. This command now performs a local installation check.
print "Checking CSF installation...\n";
print "CSF version: v$version\n";
# Verify critical files exist
my @critical_files = (
'/usr/sbin/csf',
'/usr/sbin/lfd',
'/etc/csf/csf.conf',
);
my $all_ok = 1;
foreach my $file (@critical_files) {
if ( -e $file ) {
print " ✓ $file exists\n";
}
else {
print " ✗ $file missing\n";
$all_ok = 0;
}
}
if ($all_ok) {
print "\nCSF installation check passed\n";
print "Note: Auto-updates are no longer supported. Please use your package manager to update CSF.\n";
}
else {
print "\nCSF installation check failed - some files are missing\n";
exit 1; ## no critic (Cpanel::NoExitsFromSubroutines) - Installation check failure
}
return;
}
sub doiplookup {
my $ip = $input{argument}[0];
if ( checkip( \$ip ) ) {
print iplookup($ip) . "\n";
}
else {
print "lookup failed: [$ip] is not a valid PUBLIC IP\n";
}
$input{argument}[0] = $ip;
return;
}
sub dogrep {
my $ipmatch = $input{argument}[0];
checkip( \$ipmatch );
my $ipstring = quotemeta($ipmatch);
my $mhit = 0;
my $head = 0;
my $oldchain = "INPUT";
my $table = "filter";
my $chain = "";
my $rest = "";
format GREP =
@<<<<< @<<<<<<<<<<<<<<< @*
$table, $chain, $rest
.
local $~ = "GREP";
my $command = "echo 'filter table:\n' ; $config{IPTABLES} $config{IPTABLESWAIT} -v -L -n --line-numbers";
if ( $config{NAT} ) { $command .= " ; echo 'nat table:\n' ; $config{IPTABLES} $config{IPTABLESWAIT} -v -t nat -L -n --line-numbers" }
if ( $config{MANGLE} ) { $command .= " ;echo 'mangle table:\n' ; $config{IPTABLES} $config{IPTABLESWAIT} -v -t mangle -L -n --line-numbers" }
if ( $config{RAW} ) { $command .= " ; echo 'raw table:\n' ; $config{IPTABLES} $config{IPTABLESWAIT} -v -t raw -L -n --line-numbers" }
my ( $childin, $childout );
my $pid = IPC::Open3::open3( $childin, $childout, $childout, $command );
my @output = <$childout>;
waitpid( $pid, 0 );
chomp @output;
if ( $output[0] =~ /# Warning: iptables-legacy tables present/ ) { shift @output }
foreach my $line (@output) {
if ( $line =~ /^Chain\s([\w\_]*)\s/ ) { $chain = $1 }
if ( $line =~ /^(\S+) table:$/ ) { $table = $1 }
if ( defined $chain && $chain eq "acctboth" ) { next }
if ( !$head and ( $line =~ /^num/ ) ) { print "\nTable Chain $line\n"; $head = 1 }
if ( $line !~ /\d+/ ) { next }
my ( undef, undef, undef, $action, undef, undef, undef, undef, $source, $destination, $options ) = split( /\s+/, $line, 11 );
my $hit = 0;
if ( $line =~ /\b$ipstring\b/i ) {
$hit = 1;
}
else {
if ( defined $source and ( $source =~ /\// ) and ( $source ne "0.0.0.0/0" ) ) {
if ( checkip( \$source ) ) {
my $cidr = Net::CIDR::Lite->new;
eval { local $SIG{__DIE__} = undef; $cidr->add($source) };
if ( $cidr->find($ipmatch) ) { $hit = 1 }
}
}
if ( !$hit and defined $destination and ( $destination =~ /\// ) and ( $destination ne "0.0.0.0/0" ) ) {
if ( checkip( \$destination ) ) {
my $cidr = Net::CIDR::Lite->new;
eval { local $SIG{__DIE__} = undef; $cidr->add($destination) };
if ( $cidr->find($ipmatch) ) { $hit = 1 }
}
}
}
if ($hit) {
$rest = $line;
if ( $oldchain ne $chain ) { print "\n" }
write;
$oldchain = $chain;
$mhit = 1;
}
}
unless ($mhit) {
print "No matches found for $ipmatch in iptables\n";
}
if ( $config{LF_IPSET} and checkip( \$ipmatch ) ) {
print "\n";
my $mhit = 0;
my $head = 0;
my $oldchain = "INPUT";
my ( $childin, $childout );
my $pid = IPC::Open3::open3( $childin, $childout, $childout, $config{IPSET}, "-n", "list" );
my @output = <$childout>;
waitpid( $pid, 0 );
chomp @output;
my %sets;
foreach my $line (@output) { $sets{$line} = 1 }
foreach my $chain ( keys %sets ) {
my $option;
my $cc;
my $country;
if ( $chain =~ /^cc_(\w+)$/ ) {
$cc = $1;
$country = uc $cc;
if ( $config{CC_DENY} =~ /$cc/i ) { $option = "CC_DENY" }
if ( $config{CC_ALLOW} =~ /$cc/i ) { $option = "CC_ALLOW" }
if ( $config{CC_ALLOW_FILTER} =~ /$cc/i ) { $option = "CC_ALLOW_FILTER" }
if ( $config{CC_ALLOW_PORTS} =~ /$cc/i ) { $option = "CC_ALLOW_PORTS" }
if ( $config{CC_DENY_PORTS} =~ /$cc/i ) { $option = "CC_DENY_PORTS" }
}
if ( $chain =~ /^cc_6_(\w+)$/ ) {
$cc = $1;
$country = uc $cc;
if ( $config{CC_DENY} =~ /$cc/i ) { $option = "CC_DENY" }
if ( $config{CC_ALLOW} =~ /$cc/i ) { $option = "CC_ALLOW" }
if ( $config{CC_ALLOW_FILTER} =~ /$cc/i ) { $option = "CC_ALLOW_FILTER" }
if ( $config{CC_ALLOW_PORTS} =~ /$cc/i ) { $option = "CC_ALLOW_PORTS" }
if ( $config{CC_DENY_PORTS} =~ /$cc/i ) { $option = "CC_DENY_PORTS" }
}
if ( $chain =~ /^bl_(\w+)$/ ) {
$cc = $1;
$option = "$cc file:/etc/csf/csf.blocklists";
}
if ( $chain =~ /^bl_6_(\w+)$/ ) {
$cc = $1;
$option = "$cc file:/etc/csf/csf.blocklists";
}
if ( $chain =~ /^chain_(\w+)$/ ) {
$cc = $1;
if ( $cc eq "DENY" ) { $option = " File:/etc/csf/csf.deny" }
if ( $cc eq "ALLOW" ) { $option = " File:/etc/csf/csf.allow" }
if ( $cc eq "GDENY" ) { $option = "GLOBAL_DENY" }
if ( $cc eq "GALLOW" ) { $option = "GLOBAL_ALLOW" }
if ( $cc eq "ALLOWDYN" ) { $option = "DYNDNS" }
if ( $cc eq "GDYN" ) { $option = "GLOBAL_DYNDNS" }
}
if ( $chain =~ /^chain_6_(\w+)$/ ) {
$cc = $1;
if ( $cc eq "DENY" ) { $option = " File:/etc/csf/csf.deny" }
if ( $cc eq "ALLOW" ) { $option = " File:/etc/csf/csf.allow" }
if ( $cc eq "GDENY" ) { $option = "GLOBAL_DENY" }
if ( $cc eq "GALLOW" ) { $option = "GLOBAL_ALLOW" }
if ( $cc eq "ALLOWDYN" ) { $option = "DYNDNS" }
if ( $cc eq "GDYN" ) { $option = "GLOBAL_DYNDNS" }
}
my $hit = 0;
my ( $childin, $childout );
my $pid = IPC::Open3::open3( $childin, $childout, $childout, $config{IPSET}, "test", "$chain", "$ipmatch" );
my @output = <$childout>;
waitpid( $pid, 0 );
chomp @output;
my $line = $output[0];
if ( $line =~ /is in set/ ) { $hit = 1 }
if ($hit) {
$rest = $line;
if ( $oldchain ne $chain ) { print "\n" }
print "IPSET: Set:$chain Match:$ipmatch";
if ($option) {
print " Setting:$option";
if ($country) { print " Country:$country" }
}
print "\n";
$oldchain = $chain;
$mhit = 1;
}
}
unless ($mhit) {
print "IPSET: No matches found for $ipmatch\n";
}
}
if ( $config{IPV6} ) {
my $mhit = 0;
my $head = 0;
$table = "filter";
my $oldchain = "INPUT";
print "\n\nip6tables:\n";
my $command = "echo 'filter table:\n' ; $config{IP6TABLES} $config{IPTABLESWAIT} -v -L -n --line-numbers";
if ( $config{NAT6} ) { $command .= " ; echo 'nat table:\n' ; $config{IP6TABLES} $config{IPTABLESWAIT} -v -t nat -L -n --line-numbers" }
if ( $config{MANGLE6} ) { $command .= " ; echo 'mangle table:\n' ; $config{IP6TABLES} $config{IPTABLESWAIT} -v -t mangle -L -n --line-numbers" }
if ( $config{RAW6} ) { $command .= " ; echo 'raw table:\n' ; $config{IP6TABLES} $config{IPTABLESWAIT} -v -t raw -L -n --line-numbers" }
my ( $childin, $childout );
my $pid = IPC::Open3::open3( $childin, $childout, $childout, $command );
my @output = <$childout>;
waitpid( $pid, 0 );
chomp @output;
if ( $output[0] =~ /# Warning: iptables-legacy tables present/ ) { shift @output }
foreach my $line (@output) {
if ( $line =~ /^Chain\s([\w\_]*)\s/ ) { $chain = $1 }
if ( $line =~ /^(\S+) table:$/ ) { $table = $1 }
if ( defined $chain and $chain eq "acctboth" ) { next }
if ( !$head and ( $line =~ /^num/ ) ) { print "\nTable Chain $line\n"; $head = 1 }
if ( $line !~ /\d+/ ) { next }
my ( undef, undef, undef, $action, undef, undef, undef, $source, $destination, $options ) = split( /\s+/, $line, 11 );
my $hit = 0;
if ( $line =~ /\b$ipstring\b/i ) {
$hit = 1;
}
else {
if ( defined $source and ( $source =~ /\// ) and ( $source ne "::/0" ) ) {
if ( checkip( \$source ) ) {
my $cidr = Net::CIDR::Lite->new;
eval { local $SIG{__DIE__} = undef; $cidr->add($source) };
if ( $cidr->find($ipmatch) ) { $hit = 1 }
}
}
if ( !$hit and defined $destination and ( $destination =~ /\// ) and ( $destination ne "::/0" ) ) {
if ( checkip( \$destination ) ) {
my $cidr = Net::CIDR::Lite->new;
eval { local $SIG{__DIE__} = undef; $cidr->add($destination) };
if ( $cidr->find($ipmatch) ) { $hit = 1 }
}
}
}
if ($hit) {
$rest = $line;
if ( $oldchain ne $chain ) { print "\n" }
write;
$oldchain = $chain;
$mhit = 1;
}
}
unless ($mhit) {
print "No matches found for $ipmatch in ip6tables\n";
}
}
my @tempallow = slurpee( "/var/lib/csf/csf.tempallow", 'fatal' => 1 );
chomp @tempallow;
foreach my $line (@tempallow) {
next unless $line =~ /\S/; # Skip blank lines
my ( $time, $ipd, $port, $inout, $timeout, $message ) = split( /\|/, $line );
checkip( \$ipd );
if ( $ipd eq $ipmatch ) {
print "\nTemporary Allows: IP:$ipd Port:$port Dir:$inout TTL:$timeout ($message)\n";
}
elsif ( $ipd =~ /(.*\/\d+)/ ) {
my $cidrhit = $1;
if ( checkip( \$cidrhit ) ) {
my $cidr = Net::CIDR::Lite->new;
eval { local $SIG{__DIE__} = undef; $cidr->add($cidrhit) };
if ( $cidr->find($ipmatch) ) {
print "\nTemporary Allows: IP:$ipd Port:$port Dir:$inout TTL:$timeout ($message)\n";
}
}
}
}
my @allow = slurp("/etc/csf/csf.allow");
foreach my $line (@allow) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @allow, @incfile;
}
}
foreach my $line (@allow) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $ipd, $commentd ) = split( /\s/, $line, 2 );
$ipd //= '';
checkip( \$ipd );
if ( $ipd eq $ipmatch ) {
print "\ncsf.allow: $line\n";
}
elsif ( $ipd =~ /(.*\/\d+)/ ) {
my $cidrhit = $1;
if ( checkip( \$cidrhit ) ) {
my $cidr = Net::CIDR::Lite->new;
eval { local $SIG{__DIE__} = undef; $cidr->add($cidrhit) };
if ( $cidr->find($ipmatch) ) {
print "\nPermanent Allows (csf.allow): $line\n";
}
}
}
}
my @tempdeny = slurpee( "/var/lib/csf/csf.tempban", 'fatal' => 1 );
chomp @tempdeny;
foreach my $line (@tempdeny) {
next unless $line =~ /\S/; # Skip blank lines
my ( $time, $ipd, $port, $inout, $timeout, $message ) = split( /\|/, $line );
checkip( \$ipd );
if ( $ipd eq $ipmatch ) {
print "\nTemporary Blocks: IP:$ipd Port:$port Dir:$inout TTL:$timeout ($message)\n";
}
elsif ( $ipd =~ /(.*\/\d+)/ ) {
my $cidrhit = $1;
if ( checkip( \$cidrhit ) ) {
my $cidr = Net::CIDR::Lite->new;
eval { local $SIG{__DIE__} = undef; $cidr->add($cidrhit) };
if ( $cidr->find($ipmatch) ) {
print "\nTemporary Blocks: IP:$ipd Port:$port Dir:$inout TTL:$timeout ($message)\n";
}
}
}
}
my @deny = slurp("/etc/csf/csf.deny");
foreach my $line (@deny) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @deny, @incfile;
}
}
foreach my $line (@deny) {
$line =~ s/$cleanreg//g;
if ( $line eq "" ) { next }
if ( $line =~ /^\s*\#|Include/ ) { next }
my ( $ipd, $commentd ) = split( /\s/, $line, 2 );
$ipd //= '';
checkip( \$ipd );
if ( $ipd eq $ipmatch ) {
print "\ncsf.deny: $line\n";
}
elsif ( $ipd =~ /(.*\/\d+)/ ) {
my $cidrhit = $1;
if ( checkip( \$cidrhit ) ) {
my $cidr = Net::CIDR::Lite->new;
eval { local $SIG{__DIE__} = undef; $cidr->add($cidrhit) };
if ( $cidr->find($ipmatch) ) {
print "\nPermanent Blocks (csf.deny): $line\n";
}
}
}
}
return;
}
sub dotempban {
my ( $ip, $deny, $ports, $inout, $time, $timeout, $message );
format TEMPBAN =
@<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @|||||| @<<<< @<<<<<<<<<<<<<<< @*
$deny, $ip, $ports, $inout,$time,$message
.
local $~ = "TEMPBAN";
if ( ( !-z "/var/lib/csf/csf.tempban" ) or ( !-z "/var/lib/csf/csf.tempallow" ) ) {
print "\nA/D IP address Port Dir Time To Live Comment\n";
if ( !-z "/var/lib/csf/csf.tempban" ) {
sysopen( my $IN, "/var/lib/csf/csf.tempban", O_RDWR );
flock( $IN, LOCK_SH );
my @data = <$IN>;
chomp @data;
close($IN);
foreach my $line (@data) {
if ( $line eq "" ) { next }
( $time, $ip, $ports, $inout, $timeout, $message ) = split( /\|/, $line );
$time = $timeout - ( time - $time );
if ( $ports eq "" ) { $ports = "*" }
if ( $inout eq "" ) { $inout = " *" }
if ( $time < 1 ) {
$time = "<1";
}
else {
my $days = int( $time / ( 24 * 60 * 60 ) );
my $hours = ( $time / ( 60 * 60 ) ) % 24;
my $mins = ( $time / 60 ) % 60;
my $secs = $time % 60;
$days = $days < 1 ? '' : $days . 'd ';
$hours = $hours < 1 ? '' : $hours . 'h ';
$mins = $mins < 1 ? '' : $mins . 'm ';
$time = $days . $hours . $mins . $secs . 's';
}
$deny = "DENY";
foreach ( split( /,/, $ports ) ) { write }
}
}
if ( !-z "/var/lib/csf/csf.tempallow" ) {
sysopen( my $IN, "/var/lib/csf/csf.tempallow", O_RDWR );
flock( $IN, LOCK_SH );
my @data = <$IN>;
chomp @data;
close($IN);
foreach my $line (@data) {
if ( $line eq "" ) { next }
( $time, $ip, $ports, $inout, $timeout, $message ) = split( /\|/, $line );
$time = $timeout - ( time - $time );
if ( $ports eq "" ) { $ports = "*" }
if ( $inout eq "" ) { $inout = " *" }
if ( $time < 1 ) {
$time = "<1";
}
else {
my $days = int( $time / ( 24 * 60 * 60 ) );
my $hours = ( $time / ( 60 * 60 ) ) % 24;
my $mins = ( $time / 60 ) % 60;
my $secs = $time % 60;
$days = $days < 1 ? '' : $days . 'd ';
$hours = $hours < 1 ? '' : $hours . 'h ';
$mins = $mins < 1 ? '' : $mins . 'm ';
$time = $days . $hours . $mins . $secs . 's';
}
$deny = "ALLOW";
foreach ( split( /,/, $ports ) ) { write }
}
}
}
else {
print "csf: There are no temporary IP entries\n";
}
return;
}
sub dotempdeny {
my $cftemp = shift;
my ( $ip, $timeout, $portdir ) = @{ $input{argument} }[ 0 .. 2 ];
my $inout = "in";
my $port = "";
if ( $timeout =~ /^(\d*)([mhd])/i ) {
my $secs = $1;
my $dur = lc $2;
if ( $dur eq "m" ) { $timeout = $secs * 60 }
elsif ( $dur eq "h" ) { $timeout = $secs * 60 * 60 }
elsif ( $dur eq "d" ) { $timeout = $secs * 60 * 60 * 24 }
else { $timeout = $secs }
}
my $iptype = checkip( \$ip );
if ( !$iptype ) {
print "csf: [$ip] is not a valid PUBLIC IP\n";
return;
}
if ( $iptype == 6 and !$config{IPV6} ) {
print "failed: [$ip] is valid IPv6 but IPV6 is not enabled in csf.conf\n";
}
getethdev();
if ( $ips{$ip} or $ipscidr->find($ip) or $ipscidr6->find($ip) ) {
print "deny failed: [$ip] is one of this servers addresses!\n";
return;
}
if ( $timeout =~ /\D/ ) {
$portdir = join( " ", $timeout, $portdir );
$timeout = 0;
}
if ( $portdir =~ /\-d\s*out/i ) { $inout = "out" }
if ( $portdir =~ /\-d\s*inout/i ) { $inout = "inout" }
if ( $portdir =~ /\-p\s*([\w\,\*\;]+)/ ) { $port = $1 }
my $comment = $portdir;
$comment =~ s/\-d\s*out//ig;
$comment =~ s/\-d\s*inout//ig;
$comment =~ s/\-d\s*in//ig;
$comment =~ s/\-p\s*[\w\,\*\;]+//ig;
$comment =~ s/^\s*|\s*$//g;
if ( $comment eq "" ) { $comment = "Manually added: " . iplookup($ip) }
my @deny = slurp("/etc/csf/csf.deny");
foreach my $line (@deny) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @deny, @incfile;
}
}
my $ipstring = quotemeta($ip);
if ( grep { $_ =~ /^$ipstring\b/ } @deny ) {
print "csf: $ip is already permanently blocked\n";
exit 0; ## no critic (Cpanel::NoExitsFromSubroutines) - CLI command early termination
}
@deny = slurpee( "/var/lib/csf/csf.tempban", 'fatal' => 1 );
chomp @deny;
if ( grep { $_ =~ /\b$ip\|$port\|\b/ } @deny ) {
print "csf: $ip is already temporarily blocked\n";
exit 0;
}
my $dropin = $config{DROP};
my $dropout = $config{DROP_OUT};
if ( $config{DROP_IP_LOGGING} ) { $dropin = "LOGDROPIN" }
if ( $config{DROP_OUT_LOGGING} ) { $dropout = "LOGDROPOUT" }
if ( !length $timeout || $timeout < 2 ) { $timeout = 3600 }
if ( $port =~ /\*/ ) { $port = "" }
if ( $inout =~ /in/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A DENYIN $eth6devin -p $proto --dport $dport -s $ip -j $dropin" );
if ( $messengerports{$dport} and $config{MESSENGER6} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "A", $dport ) }
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A DENYIN $ethdevin -p $proto --dport $dport -s $ip -j $dropin" );
if ( $messengerports{$dport} and $config{MESSENGER} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "A", $dport ) }
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A DENYIN $eth6devin -s $ip -j $dropin" );
if ( $config{MESSENGER6} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "A" ) }
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A DENYIN $ethdevin -s $ip -j $dropin" );
if ( $config{MESSENGER} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "A" ) }
}
}
}
if ( $inout =~ /out/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A DENYOUT $eth6devout -p $proto --dport $dport -d $ip -j $dropout" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A DENYOUT $ethdevout -p $proto --dport $dport -d $ip -j $dropout" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -A DENYOUT $eth6devout -d $ip -j $dropout" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -A DENYOUT $ethdevout -d $ip -j $dropout" );
}
}
}
if ( $config{CF_ENABLE} and $cftemp ) { $comment .= " (CF_ENABLE)" }
sysopen( my $OUT, "/var/lib/csf/csf.tempban", O_WRONLY | O_APPEND | O_CREAT ) or error( __LINE__, "Error: Can't append out file: $!" );
flock( $OUT, LOCK_EX );
print $OUT time . "|$ip|$port|$inout|$timeout|$comment\n";
close($OUT);
if ( $port eq "" ) { $port = "*" }
if ( $inout eq "in" ) { $inout = "inbound" }
if ( $inout eq "out" ) { $inout = "outbound" }
if ( $inout eq "inout" ) { $inout = "in and outbound" }
print "csf: $ip blocked on port $port for $timeout seconds $inout\n";
return;
}
sub dotempallow {
my $cftemp = shift;
my ( $ip, $timeout, $portdir ) = @{ $input{argument} }[ 0 .. 2 ];
my $inout = "inout";
my $port = "";
if ( $timeout =~ /^(\d*)([mhd])/i ) {
my $secs = $1;
my $dur = lc $2;
if ( $dur eq "m" ) { $timeout = $secs * 60 }
elsif ( $dur eq "h" ) { $timeout = $secs * 60 * 60 }
elsif ( $dur eq "d" ) { $timeout = $secs * 60 * 60 * 24 }
else { $timeout = $secs }
}
my $iptype = checkip( \$ip );
if ( !$iptype ) {
print "csf: [$ip] is not a valid PUBLIC IP\n";
return;
}
if ( $iptype == 6 and !$config{IPV6} ) {
print "failed: [$ip] is valid IPv6 but IPV6 is not enabled in csf.conf\n";
}
if ( $timeout =~ /\D/ ) {
$portdir = join( " ", $timeout, $portdir );
$timeout = 0;
}
if ( $portdir =~ /\-d\s*in/i ) { $inout = "in" }
if ( $portdir =~ /\-d\s*out/i ) { $inout = "out" }
if ( $portdir =~ /\-d\s*inout/i ) { $inout = "inout" }
if ( $portdir =~ /\-p\s*([\w\,\*\;]+)/ ) { $port = $1 }
my $comment = $portdir;
$comment =~ s/\-d\s*out//ig;
$comment =~ s/\-d\s*inout//ig;
$comment =~ s/\-d\s*in//ig;
$comment =~ s/\-p\s*[\w\,\*\;]+//ig;
$comment =~ s/^\s*|\s*$//g;
if ( $comment eq "" ) { $comment = "Manually added: " . iplookup($ip) }
my @allow = slurp("/etc/csf/csf.allow");
foreach my $line (@allow) {
if ( $line =~ /^Include\s*(.*)$/ ) {
my @incfile = slurp($1);
push @allow, @incfile;
}
}
if ( grep { $_ =~ /^$ip\b/ } @allow ) {
print "csf: $ip is already permanently allowed\n";
exit 0; ## no critic (Cpanel::NoExitsFromSubroutines) - CLI command early termination
}
@allow = slurpee( "/var/lib/csf/csf.tempallow", 'fatal' => 1 );
chomp @allow;
if ( grep { $_ =~ /\b$ip\|$port\|\b/ } @allow ) {
print "csf: $ip is already temporarily allowed\n";
exit 0;
}
if ( !length $timeout || $timeout < 2 ) { $timeout = 3600 }
if ( $port =~ /\*/ ) { $port = "" }
getethdev();
if ( $inout =~ /in/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I ALLOWIN $eth6devin -p $proto --dport $dport -s $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I ALLOWIN $ethdevin -p $proto --dport $dport -s $ip -j $accept" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I ALLOWIN $eth6devin -s $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I ALLOWIN $ethdevin -s $ip -j $accept" );
}
}
}
if ( $inout =~ /out/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I ALLOWOUT $eth6devout -p $proto --dport $dport -d $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I ALLOWOUT $ethdevout -p $proto --dport $dport -d $ip -j $accept" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -I ALLOWOUT $eth6devout -d $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -I ALLOWOUT $ethdevout -d $ip -j $accept" );
}
}
}
if ( $config{CF_ENABLE} and $cftemp ) { $comment .= " (CF_ENABLE)" }
sysopen( my $OUT, "/var/lib/csf/csf.tempallow", O_WRONLY | O_APPEND | O_CREAT ) or error( __LINE__, "Error: Can't append out file: $!" );
flock( $OUT, LOCK_EX );
print $OUT time . "|$ip|$port|$inout|$timeout|$comment\n";
close($OUT);
if ( $port eq "" ) { $port = "*" }
if ( $inout eq "in" ) { $inout = "inbound" }
if ( $inout eq "out" ) { $inout = "outbound" }
if ( $inout eq "inout" ) { $inout = "in and outbound" }
print "csf: $ip allowed on port $port for $timeout seconds $inout\n";
return;
}
sub dotemprm {
my $ip = $input{argument}[0];
if ( $ip eq "" ) {
print "csf: No IP specified\n";
return;
}
my $iptype = checkip( \$ip );
if ( $iptype == 6 and !$config{IPV6} ) {
print "failed: [$ip] is valid IPv6 but IPV6 is not enabled in csf.conf\n";
}
unless ($iptype) {
print "csf: [$ip] is not a valid PUBLIC IP\n";
return;
}
getethdev();
if ( !-z "/var/lib/csf/csf.tempban" ) {
my $unblock = 0;
sysopen( my $TEMPBAN, "/var/lib/csf/csf.tempban", O_RDWR | O_CREAT );
flock( $TEMPBAN, LOCK_EX );
my @data = <$TEMPBAN>;
chomp @data;
my @newdata;
foreach my $line (@data) {
my ( $time, $thisip, $port, $inout, $timeout, $message ) = split( /\|/, $line );
if ( $thisip eq $ip ) {
my $dropin = $config{DROP};
my $dropout = $config{DROP_OUT};
if ( $config{DROP_IP_LOGGING} ) { $dropin = "LOGDROPIN" }
if ( $config{DROP_OUT_LOGGING} ) { $dropout = "LOGDROPOUT" }
if ( $inout =~ /in/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $eth6devin -p $proto --dport $dport -s $ip -j $dropin" );
if ( $messengerports{$dport} and $config{MESSENGER6} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D", $dport ) }
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $ethdevin -p $proto --dport $dport -s $ip -j $dropin" );
if ( $messengerports{$dport} and $config{MESSENGER} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D", $dport ) }
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $eth6devin -s $ip -j $dropin" );
if ( $config{MESSENGER6} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D" ) }
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $ethdevin -s $ip -j $dropin" );
if ( $config{MESSENGER} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D" ) }
}
}
}
if ( $inout =~ /out/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $eth6devout -p $proto --dport $dport -d $ip -j $dropout" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $ethdevout -p $proto --dport $dport -d $ip -j $dropout" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $eth6devout -d $ip -j $dropout" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $ethdevout -d $ip -j $dropout" );
}
}
}
if ( $config{CF_ENABLE} and $message =~ /\(CF_ENABLE\)/ ) { ConfigServer::CloudFlare::action( "remove", $ip, $config{CF_BLOCK} ) }
print "csf: $ip temporary block removed\n";
$unblock = 1;
}
else {
push @newdata, $line;
}
}
seek( $TEMPBAN, 0, 0 );
truncate( $TEMPBAN, 0 );
foreach my $line (@newdata) { print $TEMPBAN "$line\n" }
close($TEMPBAN);
unless ($unblock) {
print "csf: $ip not found in temporary bans\n";
}
}
else {
print "csf: There are no temporary IP bans\n";
}
if ( !-z "/var/lib/csf/csf.tempallow" ) {
my $unblock = 0;
sysopen( my $TEMPALLOW, "/var/lib/csf/csf.tempallow", O_RDWR | O_CREAT );
flock( $TEMPALLOW, LOCK_EX );
my @data = <$TEMPALLOW>;
chomp @data;
my @newdata;
foreach my $line (@data) {
my ( $time, $thisip, $port, $inout, $timeout, $message ) = split( /\|/, $line );
if ( $thisip eq $ip ) {
if ( $inout =~ /in/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $eth6devin -p $proto --dport $dport -s $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $ethdevin -p $proto --dport $dport -s $ip -j $accept" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $eth6devin -s $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $ethdevin -s $ip -j $accept" );
}
}
}
if ( $inout =~ /out/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $eth6devout -p $proto --dport $dport -d $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $ethdevout -p $proto --dport $dport -d $ip -j $accept" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $eth6devout -d $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $ethdevout -d $ip -j $accept" );
}
}
}
if ( $config{CF_ENABLE} and $message =~ /\(CF_ENABLE\)/ ) { ConfigServer::CloudFlare::action( "remove", $ip, "whitelist" ) }
print "csf: $ip temporary allow removed\n";
$unblock = 1;
}
else {
push @newdata, $line;
}
}
seek( $TEMPALLOW, 0, 0 );
truncate( $TEMPALLOW, 0 );
foreach my $line (@newdata) { print $TEMPALLOW "$line\n" }
close($TEMPALLOW);
unless ($unblock) {
print "csf: $ip not found in temporary allows\n";
}
}
else {
print "csf: There are no temporary IP allows\n";
}
return;
}
sub dotemprmd {
my $ip = $input{argument}[0];
if ( $ip eq "" ) {
print "csf: No IP specified\n";
return;
}
my $iptype = checkip( \$ip );
if ( $iptype == 6 and !$config{IPV6} ) {
print "failed: [$ip] is valid IPv6 but IPV6 is not enabled in csf.conf\n";
}
unless ($iptype) {
print "csf: [$ip] is not a valid PUBLIC IP\n";
return;
}
getethdev();
if ( !-z "/var/lib/csf/csf.tempban" ) {
my $unblock = 0;
sysopen( my $TEMPBAN, "/var/lib/csf/csf.tempban", O_RDWR | O_CREAT );
flock( $TEMPBAN, LOCK_EX );
my @data = <$TEMPBAN>;
chomp @data;
my @newdata;
foreach my $line (@data) {
my ( $time, $thisip, $port, $inout, $timeout, $message ) = split( /\|/, $line );
if ( $thisip eq $ip ) {
my $dropin = $config{DROP};
my $dropout = $config{DROP_OUT};
if ( $config{DROP_IP_LOGGING} ) { $dropin = "LOGDROPIN" }
if ( $config{DROP_OUT_LOGGING} ) { $dropout = "LOGDROPOUT" }
if ( $inout =~ /in/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $eth6devin -p $proto --dport $dport -s $ip -j $dropin" );
if ( $messengerports{$dport} and $config{MESSENGER6} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D", $dport ) }
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $ethdevin -p $proto --dport $dport -s $ip -j $dropin" );
if ( $messengerports{$dport} and $config{MESSENGER} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D", $dport ) }
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $eth6devin -s $ip -j $dropin" );
if ( $config{MESSENGER6} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D" ) }
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $ethdevin -s $ip -j $dropin" );
if ( $config{MESSENGER} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D" ) }
}
}
}
if ( $inout =~ /out/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $eth6devout -p $proto --dport $dport -d $ip -j $dropout" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $ethdevout -p $proto --dport $dport -d $ip -j $dropout" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $eth6devout -d $ip -j $dropout" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $ethdevout -d $ip -j $dropout" );
}
}
}
if ( $config{CF_ENABLE} and $message =~ /\(CF_ENABLE\)/ ) { ConfigServer::CloudFlare::action( "remove", $ip, $config{CF_BLOCK} ) }
print "csf: $ip temporary block removed\n";
$unblock = 1;
}
else {
push @newdata, $line;
}
}
seek( $TEMPBAN, 0, 0 );
truncate( $TEMPBAN, 0 );
foreach my $line (@newdata) { print $TEMPBAN "$line\n" }
close($TEMPBAN);
unless ($unblock) {
print "csf: $ip not found in temporary bans\n";
}
}
else {
print "csf: There are no temporary IP bans\n";
}
return;
}
sub dotemprma {
my $ip = $input{argument}[0];
if ( $ip eq "" ) {
print "csf: No IP specified\n";
return;
}
my $iptype = checkip( \$ip );
if ( $iptype == 6 and !$config{IPV6} ) {
print "failed: [$ip] is valid IPv6 but IPV6 is not enabled in csf.conf\n";
}
unless ($iptype) {
print "csf: [$ip] is not a valid PUBLIC IP\n";
return;
}
getethdev();
if ( !-z "/var/lib/csf/csf.tempallow" ) {
my $unblock = 0;
sysopen( my $TEMPALLOW, "/var/lib/csf/csf.tempallow", O_RDWR | O_CREAT );
flock( $TEMPALLOW, LOCK_EX );
my @data = <$TEMPALLOW>;
chomp @data;
my @newdata;
foreach my $line (@data) {
my ( $time, $thisip, $port, $inout, $timeout, $message ) = split( /\|/, $line );
if ( $thisip eq $ip ) {
if ( $inout =~ /in/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $eth6devin -p $proto --dport $dport -s $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $ethdevin -p $proto --dport $dport -s $ip -j $accept" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $eth6devin -s $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $ethdevin -s $ip -j $accept" );
}
}
}
if ( $inout =~ /out/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $eth6devout -p $proto --dport $dport -d $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $ethdevout -p $proto --dport $dport -d $ip -j $accept" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $eth6devout -d $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $ethdevout -d $ip -j $accept" );
}
}
}
if ( $config{CF_ENABLE} and $message =~ /\(CF_ENABLE\)/ ) { ConfigServer::CloudFlare::action( "remove", $ip, "whitelist" ) }
print "csf: $ip temporary allow removed\n";
$unblock = 1;
}
else {
push @newdata, $line;
}
}
seek( $TEMPALLOW, 0, 0 );
truncate( $TEMPALLOW, 0 );
foreach my $line (@newdata) { print $TEMPALLOW "$line\n" }
close($TEMPALLOW);
unless ($unblock) {
print "csf: $ip not found in temporary allows\n";
}
}
else {
print "csf: There are no temporary IP allows\n";
}
return;
}
sub dotempf {
getethdev();
if ( !-z "/var/lib/csf/csf.tempban" ) {
sysopen( my $TEMPBAN, "/var/lib/csf/csf.tempban", O_RDWR | O_CREAT );
flock( $TEMPBAN, LOCK_EX );
my @data = <$TEMPBAN>;
chomp @data;
foreach my $line (@data) {
if ( $line eq "" ) { next }
my ( $time, $ip, $port, $inout, $timeout, $message ) = split( /\|/, $line );
my $iptype = checkip( \$ip );
if ( $iptype == 6 and !$config{IPV6} ) { next }
my $dropin = $config{DROP};
my $dropout = $config{DROP_OUT};
if ( $config{DROP_IP_LOGGING} ) { $dropin = "LOGDROPIN" }
if ( $config{DROP_OUT_LOGGING} ) { $dropout = "LOGDROPOUT" }
if ( $inout =~ /in/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $eth6devin -p $proto --dport $dport -s $ip -j $dropin" );
if ( $messengerports{$dport} and $config{MESSENGER6} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D", $dport ) }
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $ethdevin -p $proto --dport $dport -s $ip -j $dropin" );
if ( $messengerports{$dport} and $config{MESSENGER} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D", $dport ) }
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $eth6devin -s $ip -j $dropin" );
if ( $config{MESSENGER6} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D" ) }
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYIN $ethdevin -s $ip -j $dropin" );
if ( $config{MESSENGER} and $config{MESSENGER_TEMP} ) { domessenger( $ip, "D" ) }
}
}
}
if ( $inout =~ /out/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $eth6devout -p $proto --dport $dport -d $ip -j $dropout" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $ethdevout -p $proto --dport $dport -d $ip -j $dropout" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $eth6devout -d $ip -j $dropout" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D DENYOUT $ethdevout -d $ip -j $dropout" );
}
}
}
if ( $config{CF_ENABLE} and $message =~ /\(CF_ENABLE\)/ ) { ConfigServer::CloudFlare::action( "remove", $ip, $config{CF_BLOCK} ) }
print "csf: $ip temporary block removed\n";
}
seek( $TEMPBAN, 0, 0 );
truncate( $TEMPBAN, 0 );
close($TEMPBAN);
}
else {
print "csf: There are no temporary IP bans\n";
}
if ( !-z "/var/lib/csf/csf.tempallow" ) {
sysopen( my $TEMPALLOW, "/var/lib/csf/csf.tempallow", O_RDWR | O_CREAT );
flock( $TEMPALLOW, LOCK_EX );
my @data = <$TEMPALLOW>;
chomp @data;
foreach my $line (@data) {
if ( $line eq "" ) { next }
my ( $time, $ip, $port, $inout, $timeout, $message ) = split( /\|/, $line );
my $iptype = checkip( \$ip );
if ( $iptype == 6 and !$config{IPV6} ) { next }
if ( $inout =~ /in/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $eth6devin -p $proto --dport $dport -s $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $ethdevin -p $proto --dport $dport -s $ip -j $accept" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $eth6devin -s $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWIN $ethdevin -s $ip -j $accept" );
}
}
}
if ( $inout =~ /out/ ) {
if ($port) {
foreach my $dport ( split( /\,/, $port ) ) {
my ( $tport, $proto ) = split( /\;/, $dport );
$dport = $tport;
if ( !length $proto ) { $proto = "tcp" }
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $eth6devout -p $proto --dport $dport -d $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $ethdevout -p $proto --dport $dport -d $ip -j $accept" );
}
}
}
else {
if ( $iptype == 6 ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $eth6devout -d $ip -j $accept" );
}
else {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -D ALLOWOUT $ethdevout -d $ip -j $accept" );
}
}
}
if ( $config{CF_ENABLE} and $message =~ /\(CF_ENABLE\)/ ) { ConfigServer::CloudFlare::action( "remove", $ip, "whitelist" ) }
print "csf: $ip temporary allow removed\n";
}
seek( $TEMPALLOW, 0, 0 );
truncate( $TEMPALLOW, 0 );
close($TEMPALLOW);
}
else {
print "csf: There are no temporary IP allows\n";
}
return;
}
sub dowatch {
print "csf: --watch, -w is no longer supported. Use --trace instead\n";
return;
}
sub dotrace {
my $cmd = $ARGV[1];
my $ip = $ARGV[2];
if ( $ip eq "" ) {
print "csf: No IP specified\n";
return;
}
my $checkip = checkip( \$ip );
unless ($checkip) {
print "csf: [$ip] is not a valid PUBLIC IP\n";
return;
}
if ( $cmd eq "add" ) {
if ( $checkip == 4 ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t raw -I PREROUTING -p tcp --syn --source $ip -j TRACE" );
}
else {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t raw -I PREROUTING -p tcp --syn --source $ip -j TRACE" );
}
print "csf: Added trace for $ip\n";
}
elsif ( $cmd eq "remove" ) {
if ( $checkip == 4 ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t raw -D PREROUTING -p tcp --syn --source $ip -j TRACE" );
}
else {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t raw -D PREROUTING -p tcp --syn --source $ip -j TRACE" );
}
print "csf: Removed trace for $ip\n";
}
else {
print "csf: Error, use [add|remove] [ip]\n";
}
return;
}
sub dologrun {
if ( $config{LOGSCANNER} ) {
open( my $OUT, ">", "/var/lib/csf/csf.logrun" ) or error( __LINE__, "Could not create /var/lib/csf/csf.logrun: $!" );
flock( $OUT, LOCK_EX );
close($OUT);
}
else {
print "Option LOGSCANNER needs to be enabled in csf.conf for this feature\n";
}
return;
}
sub domessenger {
my $ip = shift;
my $delete = shift;
my $ports = shift;
if ( $ports eq "" ) { $ports = "$config{MESSENGER_HTTPS_IN},$config{MESSENGER_HTML_IN},$config{MESSENGER_TEXT_IN}" }
my $iptype = checkip( \$ip );
if ( $config{CC_MESSENGER_ALLOW} or $config{CC_MESSENGER_DENY} ) {
my ( $cc, $asn ) = iplookup( $ip, 1 );
( $asn, undef ) = split( /\s+/, $asn );
if ( $config{CC_MESSENGER_ALLOW} ) {
my $allow = 0;
if ( $cc ne "" and $config{CC_MESSENGER_ALLOW} =~ /$cc/i ) { $allow = 1 }
if ( $asn ne "" and $config{CC_MESSENGER_ALLOW} =~ /$asn/i ) { $allow = 1 }
unless ($allow) { return 1 }
}
if ( $config{CC_MESSENGER_DENY} ) {
if ( $cc ne "" and $config{CC_MESSENGER_DENY} =~ /$cc/i ) { return 1 }
if ( $asn ne "" and $config{CC_MESSENGER_DENY} =~ /$asn/i ) { return 1 }
}
}
my $del = "-A";
if ( $delete eq "D" ) { $del = "-D" }
my %textin;
my %htmlin;
my %httpsin;
foreach my $port ( split( /\,/, $config{MESSENGER_HTTPS_IN} ) ) { $httpsin{$port} = 1 }
foreach my $port ( split( /\,/, $config{MESSENGER_HTML_IN} ) ) { $htmlin{$port} = 1 }
foreach my $port ( split( /\,/, $config{MESSENGER_TEXT_IN} ) ) { $textin{$port} = 1 }
my $textports;
my $htmlports;
my $httpsports;
foreach my $port ( split( /\,/, $ports ) ) {
if ( $httpsin{$port} ) {
if ( $httpsports eq "" ) { $httpsports = "$port" }
else { $httpsports .= ",$port" }
}
if ( $htmlin{$port} ) {
if ( $htmlports eq "" ) { $htmlports = "$port" }
else { $htmlports .= ",$port" }
}
if ( $textin{$port} ) {
if ( $textports eq "" ) { $textports = "$port" }
else { $textports .= ",$port" }
}
}
if ( $config{LF_IPSET} ) {
if ( $ip =~ /^-m set/ ) {
my $ip6 = $ip;
$ip6 =~ s/MESSENGER src/MESSENGER_6 src/g;
if ( $httpsports ne "" ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -A PREROUTING $ethdevin -p tcp $ip -m multiport --dports $httpsports -j REDIRECT --to-ports $config{MESSENGER_HTTPS}" );
if ( $config{MESSENGER6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t nat -A PREROUTING $ethdevin -p tcp $ip6 -m multiport --dports $httpsports -j REDIRECT --to-ports $config{MESSENGER_HTTPS}" );
}
}
if ( $htmlports ne "" ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -A PREROUTING $ethdevin -p tcp $ip -m multiport --dports $htmlports -j REDIRECT --to-ports $config{MESSENGER_HTML}" );
if ( $config{MESSENGER6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t nat -A PREROUTING $ethdevin -p tcp $ip6 -m multiport --dports $htmlports -j REDIRECT --to-ports $config{MESSENGER_HTML}" );
}
}
if ( $textports ne "" ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat -A PREROUTING $ethdevin -p tcp $ip -m multiport --dports $textports -j REDIRECT --to-ports $config{MESSENGER_TEXT}" );
if ( $config{MESSENGER6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t nat -A PREROUTING $ethdevin -p tcp $ip6 -m multiport --dports $textports -j REDIRECT --to-ports $config{MESSENGER_TEXT}" );
}
}
}
else {
if ( $delete eq "D" ) {
if ( $iptype == 4 ) {
ipsetdel( "MESSENGER", $ip );
}
if ( $iptype == 6 and $config{MESSENGER6} ) {
ipsetdel( "MESSENGER_6", $ip );
}
}
else {
if ( $iptype == 4 ) {
ipsetadd( "MESSENGER", $ip );
}
if ( $iptype == 6 and $config{MESSENGER6} ) {
ipsetadd( "MESSENGER_6", $ip );
}
}
}
}
else {
if ( $httpsports ne "" ) {
if ( $iptype == 4 ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} -t nat $del PREROUTING $ethdevin -p tcp -s $ip -m multiport --dports $httpsports -j REDIRECT --to-ports $config{MESSENGER_HTTPS}" );
}
if ( $iptype == 6 and $config{MESSENGER6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} -t nat $del PREROUTING $ethdevin -p tcp -s $ip -m multiport --dports $httpsports -j REDIRECT --to-ports $config{MESSENGER_HTTPS}" );
}
}
if ( $htmlports ne "" ) {
if ( $iptype == 4 ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat $del PREROUTING $ethdevin -p tcp -s $ip -m multiport --dports $htmlports -j REDIRECT --to-ports $config{MESSENGER_HTML}" );
}
if ( $iptype == 6 and $config{MESSENGER6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t nat $del PREROUTING $ethdevin -p tcp -s $ip -m multiport --dports $htmlports -j REDIRECT --to-ports $config{MESSENGER_HTML}" );
}
}
if ( $textports ne "" ) {
if ( $iptype == 4 ) {
syscommand( __LINE__, "$config{IPTABLES} $config{IPTABLESWAIT} $verbose -t nat $del PREROUTING $ethdevin -p tcp -s $ip -m multiport --dports $textports -j REDIRECT --to-ports $config{MESSENGER_TEXT}" );
}
if ( $iptype == 6 and $config{MESSENGER6} ) {
syscommand( __LINE__, "$config{IP6TABLES} $config{IPTABLESWAIT} $verbose -t nat $del PREROUTING $ethdevin -p tcp -s $ip -m multiport --dports $textports -j REDIRECT --to-ports $config{MESSENGER_TEXT}" );
}
}
}
return;
}
sub domail {
my $output = ConfigServer::ServerCheck::report();
if ( $input{argument}[0] ) {
my $message = "From: root\n";
$message .= "To: root\n";
$message .= "Subject: Server Check on [hostname]\n";
$message .= "MIME-Version: 1.0\n";
$message .= "Content-Type: text/html\n";
$message .= "\n";
$message .= $output;
my @message = split( /\n/, $message );
ConfigServer::Sendmail::relay( $input{argument}[0], "", @message );
}
else {
print $output;
print "\n";
}
return;
}
sub dorbls {
my ( $failures, $output ) = ConfigServer::RBLCheck::report( 1, "", 0 );
my $failure_s = "failure";
if ( $failures ne 1 ) { $failure_s .= "s" }
if ( $failures eq "" ) { $failures = 0 }
if ( $input{argument}[0] ) {
my $message = "From: root\n";
$message .= "To: root\n";
$message .= "Subject: RBL Check on [hostname]: [$failures] $failure_s\n";
$message .= "MIME-Version: 1.0\n";
$message .= "Content-Type: text/html\n";
$message .= "\n";
$message .= $output;
my @message = split( /\n/, $message );
ConfigServer::Sendmail::relay( $input{argument}[0], "", @message );
}
else {
print $output;
print "\n";
}
return;
}
sub doprofile {
my $cmd = $ARGV[1];
my $profile1 = $ARGV[2];
my $profile2 = $ARGV[3];
my $stamp = time;
$profile1 =~ s/\W/_/g;
$profile2 =~ s/\W/_/g;
if ( $cmd eq "list" ) {
my @profiles = sort glob("/usr/local/csf/profiles/*");
my @backups = reverse glob("/var/lib/csf/backup/*");
print "\n";
print "Configuration Profiles\n";
print "======================\n";
foreach my $profile (@profiles) {
my ( $file, undef ) = File::Basename::fileparse($profile);
$file =~ s/\.conf$//;
print "$file\n";
}
print "\n";
print "Configuration Backups\n";
print "=====================\n";
foreach my $backup (@backups) {
my ( $file, undef ) = File::Basename::fileparse($backup);
my ( $stamp, undef ) = split( /_/, $file );
print $file. " (" . localtime($stamp) . ")\n";
}
print "\n";
}
elsif ( $cmd eq "backup" ) {
unless ($profile1) { $profile1 = "backup" }
print "Creating backup...\n";
system( "/bin/cp", "-avf", "/etc/csf/csf.conf", "/var/lib/csf/backup/${stamp}_${profile1}" );
}
elsif ( $cmd eq "restore" ) {
if ( -e "/var/lib/csf/backup/$profile1" ) {
print "Restoring backup...\n";
system( "/bin/cp", "-avf", "/var/lib/csf/backup/${profile1}", "/etc/csf/csf.conf" );
print "You should now restart csf and then lfd\n";
}
else {
print "File [$profile1] not found in /var/lib/csf/backup/\n";
}
}
elsif ( $cmd eq "apply" ) {
if ( -e "/usr/local/csf/profiles/${profile1}.conf" ) {
my %apply;
print "Creating backup...\n";
system( "/bin/cp", "-avf", "/etc/csf/csf.conf", "/var/lib/csf/backup/${stamp}_pre_${profile1}" );
print "Applying profile...\n";
my @applyconfig = slurpee( "/usr/local/csf/profiles/${profile1}.conf", 'fatal' => 1 );
chomp @applyconfig;
foreach my $line (@applyconfig) {
if ( $line =~ /^\#/ ) { next }
if ( $line !~ /=/ ) { next }
my ( $name, $value ) = split( /=/, $line, 2 );
$name =~ s/\s//g;
if ( $value =~ /\"(.*)\"/ ) { $value = $1 }
$apply{$name} = $value;
}
sysopen( my $CONF, "/etc/csf/csf.conf", O_RDWR | O_CREAT ) or die "Unable to open file: $!";
flock( $CONF, LOCK_SH );
my @confdata = <$CONF>;
close($CONF);
chomp @confdata;
sysopen( my $OUT, "/etc/csf/csf.conf", O_WRONLY | O_CREAT ) or die "Unable to open file: $!";
flock( $OUT, LOCK_EX );
seek( $OUT, 0, 0 );
truncate( $OUT, 0 );
for ( my $x = 0; $x < @confdata; $x++ ) {
if ( ( $confdata[$x] !~ /^\#/ ) and ( $confdata[$x] =~ /=/ ) ) {
my ( $name, $value ) = split( /=/, $confdata[$x], 2 );
$name =~ s/\s//g;
if ( $value =~ /\"(.*)\"/ ) { $value = $1 }
if ( defined $apply{$name} and ( $apply{$name} ne $value ) ) { $value = $apply{$name} }
print $OUT "$name = \"$value\"\n";
}
else {
print $OUT "$confdata[$x]\n";
}
}
close($OUT);
print "[$profile1] has been applied. You should now restart csf and then lfd\n";
}
else {
print "[$profile1] is not a valid profile\n";
}
}
elsif ( $cmd eq "keep" ) {
if ( $profile1 =~ /^\d+$/ ) {
my @backups = reverse glob("/var/lib/csf/backup/*");
for ( $profile1 .. ( @backups - 1 ) ) {
system( "/bin/rm", "-fv", $backups[$_] );
}
}
else {
print "You must specify the number of backups to keep\n";
}
}
elsif ( $cmd eq "diff" ) {
my $firstfile = "/var/lib/csf/backup/$profile1";
my $secondfile = "/var/lib/csf/backup/$profile2";
if ( -e "/usr/local/csf/profiles/${profile1}.conf" ) {
$firstfile = "/usr/local/csf/profiles/${profile1}.conf";
}
if ( -e "/usr/local/csf/profiles/${profile2}.conf" ) {
$secondfile = "/usr/local/csf/profiles/${profile2}.conf";
}
if ( -e $firstfile ) {
if ( -e $secondfile or $profile2 eq "" or $profile2 eq "current" ) {
my %config1;
my @configdata = slurpee( $firstfile, 'fatal' => 1 );
chomp @configdata;
foreach my $line (@configdata) {
if ( $line =~ /^\#/ ) { next }
if ( $line !~ /=/ ) { next }
my ( $name, $value ) = split( /=/, $line, 2 );
$name =~ s/\s//g;
if ( $value =~ /\"(.*)\"/ ) { $value = $1 }
$config1{$name} = $value;
}
if ( $profile2 eq "" or $profile2 eq "current" ) {
$profile2 = "current";
@configdata = slurpee( "/etc/csf/csf.conf", 'fatal' => 1 );
}
else {
@configdata = slurpee( $secondfile, 'fatal' => 1 );
}
@configdata = sort @configdata;
chomp @configdata;
print "[SETTING]\t[$profile1]\t[$profile2]\n\n";
foreach my $line (@configdata) {
if ( $line =~ /^\#/ ) { next }
if ( $line !~ /=/ ) { next }
my ( $name, $value ) = split( /=/, $line, 2 );
$name =~ s/\s//g;
if ( $value =~ /\"(.*)\"/ ) { $value = $1 }
if ( defined $config1{$name} and ( $config1{$name} ne $value ) ) {
print "[$name]\t[$config1{$name}]\t[$value]\n";
}
}
}
else {
print "File [$profile2] not found in /var/lib/csf/backup/\n";
}
}
else {
print "File [$profile1] not found in /var/lib/csf/backup/\n";
}
}
else {
print "Incorrect syntax for command\n";
}
return;
}
sub doports {
my ( $fport, $fopen, $fconn, $fpid, $fexe, $fcmd );
format PORTS =
@<<<<<<<<< @<<< @<<<< @<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @*
$fport, $fopen,$fconn,$fpid, $fcmd, $fexe
.
local $~ = "PORTS";
print "Ports listening for external connections and the executables running behind them:\n";
print "Port/Proto Open Conn PID/User Command Line Executable\n";
my %listen = ConfigServer::Ports->listening;
my %ports = ConfigServer::Ports->openports;
foreach my $protocol ( sort keys %listen ) {
foreach my $port ( sort { $a <=> $b } keys %{ $listen{$protocol} } ) {
foreach my $pid ( sort { $a <=> $b } keys %{ $listen{$protocol}{$port} } ) {
$fport = "$port/$protocol";
if ( $ports{$protocol}{$port} ) { $fopen = "4" }
else { $fopen = "-" }
if ( $config{IPV6} and $ports{ $protocol . "6" }{$port} ) { $fopen .= "/6" }
else { $fopen .= "/-" }
$fpid = "($pid/" . $listen{$protocol}{$port}{$pid}{user} . ")";
$fexe = $listen{$protocol}{$port}{$pid}{exe};
$fcmd = $listen{$protocol}{$port}{$pid}{cmd};
$fconn = $listen{$protocol}{$port}{$pid}{conn};
write;
}
}
}
return;
}
sub domessengerv2 {
print "csf - MESSENGERV2 /etc/apache2/conf.d/csf_messenger.conf regeneration:\n\n";
ConfigServer::Messenger::messengerv2();
print "\n...Done.\n";
return;
}
sub docloudflare {
my $cmd = $ARGV[1];
my $setting = $ARGV[2];
my $value = $ARGV[3];
my $valuemore = $ARGV[4];
my $valuelist;
my $valuemorelist;
foreach my $i ( 3 .. $#ARGV ) { $valuelist .= $ARGV[$i] }
foreach my $i ( 4 .. $#ARGV ) { $valuemorelist .= $ARGV[$i] }
unless ( $config{CF_ENABLE} ) {
print "csf - CF_ENABLE must be enabled and CloudFlare access details configured to use these commands\n";
exit 1; ## no critic (Cpanel::NoExitsFromSubroutines) - CLI command precondition failure
}
if ( $cmd eq "list" ) {
unless ( $setting eq "all" or $setting eq "block" or $setting eq "challenge" or $setting eq "whitelist" ) {
print "Invalid list type, must be: [block], [challenge], [whitelist] or [all]\n";
exit 1;
}
my ( $ip, $domain, $mode, $date, $comment );
format CLOUDFLARE =
@<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<< @<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<< @*
$ip, $domain, $mode, $date, $comment
.
local $~ = "CLOUDFLARE";
print "Target Local User Mode Date Notes\n";
print "====== ========== ==== ==== =====\n";
my @domains = ConfigServer::CloudFlare::action( "getlist", "", "", "", $valuelist );
foreach my $domainkey (@domains) {
foreach my $key ( sort { $domainkey->{$a}{created_on} <=> $domainkey->{$b}{created_on} } keys %{$domainkey} ) {
if ( $domainkey->{$key}{success} ) {
if ( $setting eq "all" or $domainkey->{$key}{mode} eq $setting ) {
$ip = $key;
$date = localtime( $domainkey->{$key}{created_on} );
$comment = $domainkey->{$key}{notes};
$domain = $domainkey->{$key}{domain};
$mode = $domainkey->{$key}{mode};
write;
}
}
else {
print $domainkey->{$key}{domain} . "\n";
}
}
}
}
elsif ( $cmd eq "add" ) {
my $mode;
if ( $setting eq "block" ) { $mode = "block" }
elsif ( $setting eq "challenge" ) { $mode = "challenge" }
elsif ( $setting eq "whitelist" ) { $mode = "whitelist" }
else {
print "Invalid add type, must be: [block], [challenge] or [whitelist]\n";
exit 1;
}
my $status = ConfigServer::CloudFlare::action( "add", $value, $mode, "", $valuemorelist );
}
elsif ( $cmd eq "del" ) {
my $status = ConfigServer::CloudFlare::action( "del", $setting, "whitelist", "", $valuelist );
}
elsif ( $cmd eq "tempadd" ) {
my $mode;
if ( $setting eq "deny" ) { $mode = "block" }
elsif ( $setting eq "allow" ) { $mode = "whitelist" }
else {
print "Invalid tempadd type, must be: [deny], or [allow]\n";
exit 1;
}
$input{argument} = [ $value, $config{CF_TEMP} ];
if ( $setting eq "deny" ) {
my $status = ConfigServer::CloudFlare::action( "deny", $value, $mode, "", $valuemorelist, 1 );
dotempdeny("cf");
}
elsif ( $setting eq "allow" ) {
my $status = ConfigServer::CloudFlare::action( "allow", $value, $mode, "", $valuemorelist, 1 );
dotempallow("cf");
}
}
else {
print "Invalid command, must be: [list], [remove], [add], or [tempadd]\n";
exit 1;
}
return;
}
sub dographs {
my ( $type, $dir ) = @{ $input{argument} }[ 0, 1 ];
my %types = (
"load" => 1,
"cpu" => 1,
"mem" => 1,
"net" => 1,
"disk" => 1,
"diskw" => 1,
"email" => 1,
"temp" => 1,
"mysqldata" => 1,
"mysqlqueries" => 1,
"mysqlslowqueries" => 1,
"mysqlconns" => 1,
"apachecpu" => 1,
"apacheconn" => 1,
"apachework" => 1
);
if ( $dir !~ /\/$/ ) { $dir .= "/" }
unless ( $config{ST_ENABLE} ) {
print "ST_ENABLE is disabled\n";
exit 1; ## no critic (Cpanel::NoExitsFromSubroutines) - CLI command precondition failure
}
unless ( $config{ST_SYSTEM} ) {
print "ST_SYSTEM is disabled\n";
exit 1;
}
# GD::Graph availability is now verified at ServerStats compile time
if ( $type eq "" and $dir eq "" ) {
print "Valid graph types:\n";
foreach my $key ( keys %types ) { print "$key " }
print "\n";
print "Usage: csf [graph type] [directory]\n";
exit 1;
}
if ( $type eq "" or !$types{$type} ) {
print "Invalid graph type. Choose one of:\n";
foreach my $key ( keys %types ) { print "$key " }
print "\n";
print "Usage: csf [graph type] [directory]\n";
exit 1;
}
if ( $dir eq "" or !( -d $dir ) ) {
print "You must specify a valid directory in which to create the graphs and html pages\n";
print "Usage: csf [graph type] [directory]\n";
exit 1;
}
print "Creating html pages and images...\n";
ConfigServer::ServerStats::charts( $config{CC_LOOKUPS}, $dir );
open( my $CHARTS, ">", $dir . "/charts.html" );
flock( $CHARTS, LOCK_EX );
print $CHARTS ConfigServer::ServerStats::charts_html( $config{CC_LOOKUPS}, "" );
close($CHARTS);
ConfigServer::ServerStats::graphs( $type, $config{ST_SYSTEM_MAXDAYS}, $dir );
open( my $GRAPHS, ">", $dir . "/graphs.html" );
flock( $GRAPHS, LOCK_EX );
print $GRAPHS ConfigServer::ServerStats::graphs_html("");
close($GRAPHS);
print "Created charts.html, graphs.html and their images in $dir\n";
return;
}
sub loadmodule {
my $module = shift;
my @output;
eval {
local $SIG{__DIE__} = undef;
local $SIG{'ALRM'} = sub { die };
alarm(5);
my ( $childin, $childout );
my $pid = IPC::Open3::open3( $childin, $childout, $childout, $config{MODPROBE}, $module );
@output = <$childout>;
waitpid( $pid, 0 );
alarm(0);
};
alarm(0);
return @output;
}
sub syscommand {
my $line = shift;
my $command = shift;
my $force = shift;
my $status = 0;
my $iptableslock = 0;
if ( $command =~ /^($config{IPTABLES}|$config{IP6TABLES})/ ) { $iptableslock = 1 }
if ($faststart) {
if ( $command =~ /^$config{IPTABLES}\s+(.*)$/ ) {
my $fastcmd = $1;
$fastcmd =~ s/-v//;
$fastcmd =~ s/--wait//;
if ( $fastcmd =~ /-t\s+nat/ ) {
$fastcmd =~ s/-t\s+nat//;
push @faststart4nat, $fastcmd;
}
else {
push @faststart4, $fastcmd;
}
}
if ( $command =~ /^$config{IP6TABLES}\s+(.*)$/ ) {
my $fastcmd = $1;
$fastcmd =~ s/-v//;
$fastcmd =~ s/--wait//;
if ( $fastcmd =~ /-t\s+nat/ ) {
$fastcmd =~ s/-t\s+nat//;
push @faststart6nat, $fastcmd;
}
else {
push @faststart6, $fastcmd;
}
}
return;
}
if ( $config{VPS} ) { $status = checkvps() }
if ($status) {
error( $line, $status );
}
else {
if ( $config{DEBUG} >= 1 ) { print "debug[$line]: Command:$command\n"; }
if ($iptableslock) { iptableslock("lock") }
my @output;
if ( $iptableslock and $config{WAITLOCK} ) {
eval {
local $SIG{__DIE__} = undef;
local $SIG{'ALRM'} = sub { die "alarm\n" };
alarm( $config{WAITLOCK_TIMEOUT} );
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $command );
@output = <$childout>;
waitpid( $cmdpid, 0 );
alarm(0);
};
alarm(0);
if ( $@ eq "alarm\n" ) {
error( __LINE__, "*Error* timeout after iptables --wait for $config{WAITLOCK_TIMEOUT} seconds - WAITLOCK" );
}
}
else {
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $command );
@output = <$childout>;
waitpid( $cmdpid, 0 );
}
if ($iptableslock) { iptableslock("unlock") }
chomp @output;
if ( defined $output[0] && $output[0] =~ /# Warning: iptables-legacy tables present/ ) { shift @output }
foreach my $line (@output) {
if ( $line =~ /^Using intrapositioned negation/ ) { next }
print $line. "\n";
}
if ( defined $output[0] && $output[0] =~ /(^iptables: Unknown error 4294967295)|(xtables lock)/ and !$config{WAITLOCK} ) {
my $cnt = 0;
my $repeat = 6;
while ( $cnt < $repeat ) {
sleep 1;
if ( $config{DEBUG} >= 1 ) { print "debug[$line]: Retry (" . ( $cnt + 1 ) . ") [$command] due to [$output[0]]" }
if ($iptableslock) { iptableslock("lock") }
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $command );
my @output = <$childout>;
waitpid( $cmdpid, 0 );
if ($iptableslock) { iptableslock("unlock") }
chomp @output;
if ( defined $output[0] && $output[0] =~ /# Warning: iptables-legacy tables present/ ) { shift @output }
$cnt++;
if ( defined $output[0] && $output[0] =~ /(^iptables: Unknown error 4294967295)|(xtables lock)/ and $cnt == $repeat ) { error( $line, "Error processing command for line [$line] ($repeat times): [$output[0]]" ); }
unless ( defined $output[0] && $output[0] =~ /(^iptables: Unknown error 4294967295)|(xtables lock)/ ) { $cnt = $repeat }
}
}
if ( defined $output[0] && $output[0] =~ /^(iptables|xtables|Bad|Another)/ and ( $config{TESTING} or $force ) ) {
if ( $output[0] =~ /iptables: No chain\/target\/match by that name/ ) {
error( $line, "iptables command [$command] failed, you appear to be missing a required iptables module" );
}
else {
error( $line, "iptables command [$command] failed" );
}
}
if ( defined $output[0] && $output[0] =~ /^(ip6tables|Bad|Another)/ and ( $config{TESTING} or $force ) ) {
if ( $output[0] =~ /ip6tables: No chain\/target\/match by that name/ ) {
error( $line, "ip6tables command [$command] failed, you appear to be missing a required ip6tables module" );
}
else {
error( $line, "ip6tables command [$command] failed" );
}
}
if ( defined $output[0] && $output[0] =~ /xtables lock/ ) {
$warning .= "iptables command [$command] failed due to xtables lock, enable WAITLOCK in csf.conf\n\n";
}
if ( defined $output[0] && $output[0] =~ /^(iptables|xtables|ip6tables|Bad|Another)/ ) {
$warning .= "*ERROR* line:[$line]\nCommand:[$command]\nError:[$output[0]]\nYou should check through the main output carefully\n\n";
}
}
return;
}
sub iptableslock {
my $lock = shift;
my $iptablesx = shift;
if ( $lock eq "lock" ) {
if ( sysopen( $iptableslock_fh, "/var/lib/csf/command.lock", O_RDWR | O_CREAT ) ) {
flock( $iptableslock_fh, LOCK_EX );
autoflush $iptableslock_fh 1;
seek( $iptableslock_fh, 0, 0 );
truncate( $iptableslock_fh, 0 );
print $iptableslock_fh $$;
}
}
elsif ( $lock eq "unlock" && defined $iptableslock_fh ) {
close($iptableslock_fh);
undef $iptableslock_fh;
}
return;
}
sub checkvps {
if ( -e "/proc/user_beancounters" and !( -e "/proc/vz/version" ) ) {
my @data = slurp("/proc/user_beancounters");
chomp @data;
foreach my $line (@data) {
if ( $line =~ /^\s*numiptent\s+(\d*)\s+(\d*)\s+(\d*)\s+(\d*)/ ) {
if ( $1 > $4 - 10 ) { return "The VPS iptables rule limit (numiptent) is too low ($1/$4) - stopping firewall to prevent iptables blocking all connections" }
}
}
}
return 0;
}
sub modprobe {
if ( -e $config{MODPROBE} ) {
my @modules = ( "ip_tables", "ipt_multiport", "iptable_filter", "ipt_limit", "ipt_LOG", "ipt_REJECT", "ipt_conntrack", "ip_conntrack", "ip_conntrack_ftp", "iptable_mangle", "ipt_REDIRECT", "iptable_nat" );
unless ( loadmodule("xt_multiport") ) {
@modules = ( "ip_tables", "xt_multiport", "iptable_filter", "xt_limit", "ipt_LOG", "ipt_REJECT", "ip_conntrack_ftp", "iptable_mangle", "xt_conntrack", "ipt_REDIRECT", "iptable_nat", "nf_conntrack_ftp", "nf_nat_ftp" );
}
if ( $config{SMTP_BLOCK} ) {
push @modules, "ipt_owner";
push @modules, "xt_owner";
}
if ( $config{PORTFLOOD} or $config{PORTFLOOD6} or $config{PORTKNOCKING} ) {
push @modules, "ipt_recent ip_list_tot=1000 ip_list_hash_size=0";
}
if ( $config{CONNLIMIT} ) {
push @modules, "xt_connlimit";
}
foreach my $module (@modules) { loadmodule($module) }
}
return;
}
sub faststart {
my $text = shift;
if (@faststart4) {
if ($verbose) { print "csf: FASTSTART loading $text (IPv4)\n" }
my $status;
if ( $config{VPS} ) { $status = fastvps( scalar @faststart4 ) }
if ($status) { error( __LINE__, $status ) }
if ( $config{DEBUG} >= 2 ) { print join( "\n", @faststart4 ) . "\n" }
iptableslock("lock");
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, "$config{IPTABLES_RESTORE} $config{IPTABLESWAIT} -n" );
print $childin "*filter\n" . join( "\n", @faststart4 ) . "\nCOMMIT\n";
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
if ( length $results[0] && $results[0] =~ /# Warning: iptables-legacy tables present/ ) { shift @results }
if ( length $results[0] && $results[0] =~ /^(iptables|ip6tables|xtables|Bad|Another)/ ) {
my $cmd;
if ( $results[1] =~ /^Error occurred at line: (\d+)$/ ) { $cmd = $faststart4[ $1 - 1 ] }
error( __LINE__, "FASTSTART: ($text IPv4) [$cmd] [$results[0]]. Try restarting csf with FASTSTART disabled" );
}
iptableslock( "unlock", 1 );
}
if (@faststart4nat) {
if ($verbose) { print "csf: FASTSTART loading $text (IPv4 nat)\n" }
my $status;
if ( $config{VPS} ) { $status = fastvps( scalar @faststart4nat ) }
if ($status) { error( __LINE__, $status ) }
if ( $config{DEBUG} >= 2 ) { print join( "\n", @faststart4nat ) . "\n" }
iptableslock("lock");
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, "$config{IPTABLES_RESTORE} $config{IPTABLESWAIT} -n" );
print $childin "*nat\n" . join( "\n", @faststart4nat ) . "\nCOMMIT\n";
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
if ( length $results[0] && $results[0] =~ /# Warning: iptables-legacy tables present/ ) { shift @results }
if ( length $results[0] && $results[0] =~ /^(iptables|ip6tables|xtables|Bad|Another)/ ) {
my $cmd;
if ( $results[1] =~ /^Error occurred at line: (\d+)$/ ) { $cmd = $faststart4[ $1 - 1 ] }
error( __LINE__, "FASTSTART: ($text IPv4nat) [$cmd] [$results[0]]. Try restarting csf with FASTSTART disabled" );
}
iptableslock( "unlock", 1 );
}
if ( @faststart6 and $config{IPV6} ) {
if ($verbose) { print "csf: FASTSTART loading $text (IPv6)\n" }
my $status;
if ( $config{VPS} ) { $status = fastvps( scalar @faststart6 ) }
if ($status) { error( __LINE__, $status ) }
if ( $config{DEBUG} >= 2 ) { print join( "\n", @faststart6 ) . "\n" }
iptableslock("lock");
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, "$config{IP6TABLES_RESTORE} $config{IPTABLESWAIT} -n" );
print $childin "*filter\n" . join( "\n", @faststart6 ) . "\nCOMMIT\n";
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
if ( length $results[0] && $results[0] =~ /# Warning: iptables-legacy tables present/ ) { shift @results }
if ( length $results[0] && $results[0] =~ /^(iptables|ip6tables|xtables|Bad|Another)/ ) {
my $cmd;
if ( $results[1] =~ /^Error occurred at line: (\d+)$/ ) { $cmd = $faststart4[ $1 - 1 ] }
error( __LINE__, "FASTSTART: ($text IPv6) [$cmd] [$results[0]]. Try restarting csf with FASTSTART disabled" );
}
iptableslock( "unlock", 1 );
}
if ( @faststart6nat and $config{IPV6} ) {
if ($verbose) { print "csf: FASTSTART loading $text (IPv6 nat)\n" }
my $status;
if ( $config{VPS} ) { $status = fastvps( scalar @faststart6nat ) }
if ($status) { error( __LINE__, $status ) }
if ( $config{DEBUG} >= 2 ) { print join( "\n", @faststart6nat ) . "\n" }
iptableslock("lock");
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, "$config{IP6TABLES_RESTORE} $config{IPTABLESWAIT} -n" );
print $childin "*nat\n" . join( "\n", @faststart6nat ) . "\nCOMMIT\n";
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
if ( length $results[0] && $results[0] =~ /# Warning: iptables-legacy tables present/ ) { shift @results }
if ( length $results[0] && $results[0] =~ /^(iptables|ip6tables|xtables|Bad|Another)/ ) {
my $cmd;
if ( $results[1] =~ /^Error occurred at line: (\d+)$/ ) { $cmd = $faststart6[ $1 - 1 ] }
error( __LINE__, "FASTSTART: ($text IPv6nat) [$cmd] [$results[0]]. Try restarting csf with FASTSTART disabled" );
}
iptableslock( "unlock", 1 );
}
if (@faststartipset) {
if ($verbose) { print "csf: FASTSTART loading $text (IPSET)\n" }
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{IPSET}, "restore" );
print $childin join( "\n", @faststartipset ) . "\n";
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
if ( length $results[0] && $results[0] =~ /^ipset/ ) {
print "FASTSTART: (IPSET) Error:[$results[0]]. Try restarting csf with FASTSTART disabled";
}
}
undef @faststart4;
undef @faststart4nat;
undef @faststart6;
undef @faststart6nat;
undef @faststartipset;
$faststart = 0;
return;
}
sub fastvps {
my $size = shift;
if ( -e "/proc/user_beancounters" and !( -e "/proc/vz/version" ) ) {
my @data = slurp("/proc/user_beancounters");
chomp @data;
foreach my $line (@data) {
if ( $line =~ /^\s*numiptent\s+(\d*)\s+(\d*)\s+(\d*)\s+(\d*)/ ) {
if ( $1 > $4 - ( $size + 10 ) ) { return "The VPS iptables rule limit (numiptent) is too low to add $size rules ($1/$4) - *IPs not added*" }
}
}
}
return 0;
}
sub ipsetcreate {
my $set = shift;
$SIG{PIPE} = 'IGNORE';
my $family = "inet";
if ( $set =~ /_6/ ) { $family = "inet6" }
if ($verbose) { print "csf: IPSET creating set $set\n" }
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{IPSET}, "create", "-exist", $set, "hash:net", "family", $family, "hashsize", $config{LF_IPSET_HASHSIZE}, "maxelem", $config{LF_IPSET_MAXELEM} );
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
if ( length $results[0] && $results[0] =~ /^ipset/ ) {
print "IPSET: [$results[0]]\n";
$warning .= "*ERROR* IPSET: [$results[0]]\n";
}
return;
}
sub ipsetrestore {
my $set = shift;
$SIG{PIPE} = 'IGNORE';
if ($verbose) { print "csf: IPSET loading set $set with " . scalar(@ipset) . " entries\n" }
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{IPSET}, "restore" );
print $childin join( "\n", @ipset ) . "\n";
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
if ( length $results[0] && $results[0] =~ /^ipset/ ) {
print "IPSET: [$results[0]]\n";
$warning .= "*ERROR* IPSET: [$results[0]]\n";
}
undef @ipset;
return;
}
sub ipsetadd {
my $set = shift;
my $ip = shift;
$SIG{PIPE} = 'IGNORE';
if ( $set =~ /^chain(_6)?_NEW(\w+)$/ ) { $set = "chain" . $1 . "_" . $2 }
if ( $set =~ /^(\w+)(IN|OUT)$/ ) { $set = $1 }
if ( $set =~ /^bl(_6)?_NEW(\w+)$/ ) { $set = "bl" . $1 . "_" . $2 }
if ( $set eq "" or $ip eq "" ) { return }
if ($faststart) {
push @faststartipset, "add -exist $set $ip";
return;
}
if ($verbose) { print "csf: IPSET adding [$ip] to set [$set]\n" }
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{IPSET}, "add", "-exist", $set, $ip );
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
if ( length $results[0] && $results[0] =~ /^ipset/ ) {
print "IPSET: [$results[0]]\n";
$warning .= "*ERROR* IPSET: [$results[0]]\n";
}
return;
}
sub ipsetdel {
my $set = shift;
my $ip = shift;
$SIG{PIPE} = 'IGNORE';
if ( $set =~ /^chain(_6)?_NEW(\w+)$/ ) { $set = "chain" . $1 . "_" . $2 }
if ( $set =~ /^(\w+)(IN|OUT)$/ ) { $set = $1 }
if ( $set =~ /^bl(_6)?_NEW(\w+)$/ ) { $set = "bl" . $1 . "_" . $2 }
if ( $set eq "" or $ip eq "" ) { return }
if ($verbose) { print "csf: IPSET deleting [$ip] from set [$set]\n" }
my ( $childin, $childout );
my $cmdpid = IPC::Open3::open3( $childin, $childout, $childout, $config{IPSET}, "del", $set, $ip );
close $childin;
my @results = <$childout>;
waitpid( $cmdpid, 0 );
chomp @results;
if ( length $results[0] && $results[0] =~ /^ipset/ ) {
print "IPSET: [$results[0]]\n";
$warning .= "*ERROR* IPSET: [$results[0]]\n";
}
return;
}
1;