mirror of
https://github.com/waytotheweb/scripts.git
synced 2026-03-29 14:17:07 +00:00
GPL v3 Release
This commit is contained in:
100
csf/ConfigServer/AbuseIP.pm
Normal file
100
csf/ConfigServer/AbuseIP.pm
Normal file
@@ -0,0 +1,100 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::AbuseIP;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Carp;
|
||||
use IPC::Open3;
|
||||
use Net::IP;
|
||||
use ConfigServer::Config;
|
||||
use ConfigServer::CheckIP qw(checkip);
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.03;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(abuseip);
|
||||
|
||||
my $abusemsg = 'Abuse Contact for [ip]: [[contact]]
|
||||
|
||||
The Abuse Contact of this report was provided by the Abuse Contact DB by abusix.com. abusix.com does not maintain the content of the database. All information which we pass out, derives from the RIR databases and is processed for ease of use. If you want to change or report non working abuse contacts please contact the appropriate RIR. If you have any further question, contact abusix.com directly via email (info@abusix.com). Information about the Abuse Contact Database can be found here:
|
||||
|
||||
https://abusix.com/global-reporting/abuse-contact-db
|
||||
|
||||
abusix.com is neither responsible nor liable for the content or accuracy of this message.';
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start abuseip
|
||||
sub abuseip {
|
||||
my $ip = shift;
|
||||
my $abuse = "";
|
||||
my $netip;
|
||||
my $reversed_ip;
|
||||
|
||||
if (checkip(\$ip)) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
$netip = Net::IP->new($ip);
|
||||
$reversed_ip = $netip->reverse_ip();
|
||||
};
|
||||
|
||||
if ($reversed_ip =~ /^(\S+)\.in-addr\.arpa/) {$reversed_ip = $1}
|
||||
if ($reversed_ip =~ /^(\S+)\s+(\S+)\.in-addr\.arpa/) {$reversed_ip = $2}
|
||||
if ($reversed_ip =~ /^(\S+)\.ip6\.arpa/) {$reversed_ip = $1}
|
||||
if ($reversed_ip =~ /^(\S+)\s+(\S+)\.ip6\.arpa/) {$reversed_ip = $2}
|
||||
|
||||
if ($reversed_ip ne "") {
|
||||
$reversed_ip .= ".abuse-contacts.abusix.org";
|
||||
|
||||
my $cmdpid;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die};
|
||||
alarm(10);
|
||||
my ($childin, $childout);
|
||||
$cmdpid = open3($childin, $childout, $childout, $config{HOST},"-W","5","-t","TXT",$reversed_ip);
|
||||
close $childin;
|
||||
my @results = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @results;
|
||||
if ($results[0] =~ /^${reversed_ip}.+"(.*)"$/) {$abuse = $1}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($cmdpid =~ /\d+/ and $cmdpid > 1 and kill(0,$cmdpid)) {kill(9,$cmdpid)}
|
||||
|
||||
if ($abuse ne "") {
|
||||
my $msg = $abusemsg;
|
||||
$msg =~ s/\[ip\]/$ip/g;
|
||||
$msg =~ s/\[contact\]/$abuse/g;
|
||||
return $abuse, $msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# end abuseip
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
160
csf/ConfigServer/CheckIP.pm
Normal file
160
csf/ConfigServer/CheckIP.pm
Normal file
@@ -0,0 +1,160 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::CheckIP;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Carp;
|
||||
use Net::IP;
|
||||
use ConfigServer::Config;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.03;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(checkip cccheckip);
|
||||
|
||||
my $ipv4reg = ConfigServer::Config->ipv4reg;
|
||||
my $ipv6reg = ConfigServer::Config->ipv6reg;
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start checkip
|
||||
sub checkip {
|
||||
my $ipin = shift;
|
||||
my $ret = 0;
|
||||
my $ipref = 0;
|
||||
my $ip;
|
||||
my $cidr;
|
||||
if (ref $ipin) {
|
||||
($ip,$cidr) = split(/\//,${$ipin});
|
||||
$ipref = 1;
|
||||
} else {
|
||||
($ip,$cidr) = split(/\//,$ipin);
|
||||
}
|
||||
my $testip = $ip;
|
||||
|
||||
if ($cidr ne "") {
|
||||
unless ($cidr =~ /^\d+$/) {return 0}
|
||||
}
|
||||
|
||||
if ($ip =~ /^$ipv4reg$/) {
|
||||
$ret = 4;
|
||||
if ($cidr) {
|
||||
unless ($cidr >= 1 && $cidr <= 32) {return 0}
|
||||
}
|
||||
if ($ip eq "127.0.0.1") {return 0}
|
||||
}
|
||||
|
||||
if ($ip =~ /^$ipv6reg$/) {
|
||||
$ret = 6;
|
||||
if ($cidr) {
|
||||
unless ($cidr >= 1 && $cidr <= 128) {return 0}
|
||||
}
|
||||
$ip =~ s/://g;
|
||||
$ip =~ s/^0*//g;
|
||||
if ($ip == 1) {return 0}
|
||||
if ($ipref) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
my $netip = Net::IP->new($testip);
|
||||
my $myip = $netip->short();
|
||||
if ($myip ne "") {
|
||||
if ($cidr eq "") {
|
||||
${$ipin} = $myip;
|
||||
} else {
|
||||
${$ipin} = $myip."/".$cidr;
|
||||
}
|
||||
}
|
||||
};
|
||||
if ($@) {return 0}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
# end checkip
|
||||
###############################################################################
|
||||
# start cccheckip
|
||||
sub cccheckip {
|
||||
my $ipin = shift;
|
||||
my $ret = 0;
|
||||
my $ipref = 0;
|
||||
my $ip;
|
||||
my $cidr;
|
||||
if (ref $ipin) {
|
||||
($ip,$cidr) = split(/\//,${$ipin});
|
||||
$ipref = 1;
|
||||
} else {
|
||||
($ip,$cidr) = split(/\//,$ipin);
|
||||
}
|
||||
my $testip = $ip;
|
||||
|
||||
if ($cidr ne "") {
|
||||
unless ($cidr =~ /^\d+$/) {return 0}
|
||||
}
|
||||
|
||||
if ($ip =~ /^$ipv4reg$/) {
|
||||
$ret = 4;
|
||||
if ($cidr) {
|
||||
unless ($cidr >= 1 && $cidr <= 32) {return 0}
|
||||
}
|
||||
if ($ip eq "127.0.0.1") {return 0}
|
||||
my $type;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
my $netip = Net::IP->new($testip);
|
||||
$type = $netip->iptype();
|
||||
};
|
||||
if ($@) {return 0}
|
||||
if ($type ne "PUBLIC") {return 0}
|
||||
}
|
||||
|
||||
if ($ip =~ /^$ipv6reg$/) {
|
||||
$ret = 6;
|
||||
if ($cidr) {
|
||||
unless ($cidr >= 1 && $cidr <= 128) {return 0}
|
||||
}
|
||||
$ip =~ s/://g;
|
||||
$ip =~ s/^0*//g;
|
||||
if ($ip == 1) {return 0}
|
||||
if ($ipref) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
my $netip = Net::IP->new($testip);
|
||||
my $myip = $netip->short();
|
||||
if ($myip ne "") {
|
||||
if ($cidr eq "") {
|
||||
${$ipin} = $myip;
|
||||
} else {
|
||||
${$ipin} = $myip."/".$cidr;
|
||||
}
|
||||
}
|
||||
};
|
||||
if ($@) {return 0}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
# end cccheckip
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
533
csf/ConfigServer/CloudFlare.pm
Normal file
533
csf/ConfigServer/CloudFlare.pm
Normal file
@@ -0,0 +1,533 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::CloudFlare;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Carp;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use JSON::Tiny();
|
||||
use LWP::UserAgent;
|
||||
use Time::Local();
|
||||
use ConfigServer::Config;
|
||||
use ConfigServer::Slurp qw(slurp);
|
||||
use ConfigServer::Logger qw(logfile);
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.00;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
|
||||
my $slurpreg = ConfigServer::Slurp->slurpreg;
|
||||
my $cleanreg = ConfigServer::Slurp->cleanreg;
|
||||
|
||||
my %args;
|
||||
$args{"content-type"} = "application/json";
|
||||
|
||||
if ($config{DEBUG} >= 2) {
|
||||
require Data::Dumper;
|
||||
import Data::Dumper;
|
||||
}
|
||||
|
||||
if (-e "/usr/local/cpanel/version") {
|
||||
require YAML::Tiny;
|
||||
}
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start action
|
||||
sub action {
|
||||
my $action = shift;
|
||||
my $ip = shift;
|
||||
my $mode = shift;
|
||||
my $id = shift;
|
||||
my $domainlist = shift;
|
||||
my $allowany = shift;
|
||||
|
||||
my $status;
|
||||
my $return;
|
||||
|
||||
if ($config{DEBUG} == 1) {logfile("Debug: CloudFlare - [$action] [$ip] [$mode] [$id] [$domainlist] [$allowany]")}
|
||||
unless ($config{URLGET}) {
|
||||
logfile("CloudFlare: URLGET must be set to 1 to use LWP for this feature");
|
||||
return;
|
||||
}
|
||||
|
||||
if ($action eq "remove") {
|
||||
my @newfile;
|
||||
sysopen (my $TEMP, "/var/lib/csf/cloudflare.temp", O_RDWR | O_CREAT);
|
||||
flock($TEMP, LOCK_EX);
|
||||
my $hit;
|
||||
while (my $line = <$TEMP>) {
|
||||
chomp $line;
|
||||
my ($rip,$mode,$user,$raccount,$rapikey,$rid,$time) = split(/\|/,$line);
|
||||
|
||||
if ($ip eq $rip) {
|
||||
$args{"X-Auth-Email"} = $raccount;
|
||||
$args{"X-Auth-Key"} = $rapikey;
|
||||
|
||||
$status = &remove($ip,$mode,$rid);
|
||||
logfile($status." ($user)");
|
||||
$hit = 1;
|
||||
} else {
|
||||
push @newfile, $line;
|
||||
}
|
||||
}
|
||||
if ($hit) {
|
||||
seek ($TEMP, 0, 0);
|
||||
truncate ($TEMP, 0);
|
||||
foreach my $line (@newfile) {
|
||||
print $TEMP $line."\n";
|
||||
}
|
||||
}
|
||||
close ($TEMP);
|
||||
} else {
|
||||
my %authlist;
|
||||
my %domains;
|
||||
foreach my $domain (split(/\,/,$domainlist)) {
|
||||
$domain =~ s/\s//g;
|
||||
if ($domain eq "") {next}
|
||||
$domain =~ s/^www\.//;
|
||||
$domains{$domain} = 1;
|
||||
}
|
||||
|
||||
my $scope = &getscope();
|
||||
|
||||
foreach my $user (keys %{$scope->{user}}) {
|
||||
if ($allowany and ($scope->{user}{$user}{domain} eq "any" or $scope->{user}{$user}{any})) {
|
||||
$authlist{$scope->{user}{$user}{account}}{apikey} = $scope->{user}{$user}{apikey};
|
||||
$authlist{$scope->{user}{$user}{account}}{user} = $user;
|
||||
}
|
||||
|
||||
foreach my $domain (keys %domains) {
|
||||
if ($scope->{domain}{$domain}{user} eq $user) {
|
||||
$authlist{$scope->{domain}{$domain}{account}}{apikey} = $scope->{domain}{$domain}{apikey};
|
||||
$authlist{$scope->{domain}{$domain}{account}}{user} = $scope->{domain}{$domain}{user};
|
||||
}
|
||||
foreach my $userdomain (keys %{$scope->{user}{$user}{domain}}) {
|
||||
if ($user eq $domain and $scope->{user}{$user}{domain}{$userdomain} ne "") {
|
||||
$authlist{$scope->{user}{$user}{account}}{apikey} = $scope->{user}{$user}{apikey};
|
||||
$authlist{$scope->{user}{$user}{account}}{user} = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my @list;
|
||||
foreach my $account (sort keys %authlist) {
|
||||
$args{"X-Auth-Email"} = $account;
|
||||
$args{"X-Auth-Key"} = $authlist{$account}{apikey};
|
||||
my $user = $authlist{$account}{user};
|
||||
|
||||
if ($action eq "deny") {
|
||||
my ($id,$status) = &block($ip);
|
||||
logfile($status." ($user)");
|
||||
sysopen (my $TEMP, "/var/lib/csf/cloudflare.temp", O_WRONLY | O_APPEND | O_CREAT);
|
||||
flock($TEMP, LOCK_EX);
|
||||
print $TEMP "$ip|$mode|$user|$account|$authlist{$account}{apikey}|$id|".time."\n";
|
||||
close ($TEMP);
|
||||
}
|
||||
elsif ($action eq "allow") {
|
||||
my ($id,$status) = &whitelist($ip);
|
||||
logfile($status." ($user)");
|
||||
sysopen (my $TEMP, "/var/lib/csf/cloudflare.temp", O_WRONLY | O_APPEND | O_CREAT);
|
||||
flock($TEMP, LOCK_EX);
|
||||
print $TEMP "$ip|$mode|$user|$account|$authlist{$account}{apikey}|$id|".time."\n";
|
||||
close ($TEMP);
|
||||
}
|
||||
elsif ($action eq "del") {
|
||||
my $status = &remove($ip,$mode);
|
||||
print "csf - $status ($user)\n";
|
||||
}
|
||||
elsif ($action eq "add") {
|
||||
my $id;
|
||||
my $status;
|
||||
if ($mode eq "block") {($id,$status) = &block($ip)}
|
||||
if ($mode eq "challenge") {($id,$status) = &challenge($ip)}
|
||||
if ($mode eq "whitelist") {($id,$status) = &whitelist($ip)}
|
||||
print "csf - $status ($user)\n";
|
||||
}
|
||||
elsif ($action eq "getlist") {
|
||||
push @list, &getlist($user);
|
||||
}
|
||||
}
|
||||
if ($action eq "getlist") {return @list}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
# end action
|
||||
###############################################################################
|
||||
# start block
|
||||
sub block {
|
||||
my $ip = shift;
|
||||
my $target = &checktarget($ip);
|
||||
|
||||
my $block->{mode} = $config{CF_BLOCK};
|
||||
$block->{configuration}->{target} = $target;
|
||||
$block->{configuration}->{value} = $ip;
|
||||
$block->{notes} = "csf $config{CF_BLOCK}";
|
||||
|
||||
my $content;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
$content = JSON::Tiny::encode_json($block);
|
||||
};
|
||||
|
||||
my $ua = LWP::UserAgent->new;
|
||||
my $res = $ua->post('https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules', %args, Content => $content);
|
||||
|
||||
if ($res->is_success) {
|
||||
my $id = JSON::Tiny::decode_json($res->content);
|
||||
return $id->{result}->{id},"CloudFlare: $config{CF_BLOCK} $target $ip";
|
||||
} else {
|
||||
if ($config{DEBUG} == 1) {print "Debug: ".$res->content."\n"}
|
||||
elsif ($config{DEBUG} >= 2) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
print Dumper(JSON::Tiny::decode_json($res->content));
|
||||
};
|
||||
}
|
||||
return "CloudFlare: [$ip] $config{CF_BLOCK} failed: ".$res->status_line;
|
||||
}
|
||||
}
|
||||
# end block
|
||||
###############################################################################
|
||||
# start whitelist
|
||||
sub whitelist {
|
||||
my $ip = shift;
|
||||
my $target = &checktarget($ip);
|
||||
|
||||
my $whitelist->{mode} = "whitelist";
|
||||
$whitelist->{configuration}->{target} = $target;
|
||||
$whitelist->{configuration}->{value} = $ip;
|
||||
$whitelist->{notes} = "csf whitelist";
|
||||
|
||||
my $content;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
$content = JSON::Tiny::encode_json($whitelist);
|
||||
};
|
||||
|
||||
my $ua = LWP::UserAgent->new;
|
||||
my $res = $ua->post('https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules', %args, Content => $content);
|
||||
|
||||
if ($res->is_success) {
|
||||
my $id = JSON::Tiny::decode_json($res->content);
|
||||
return $id->{result}->{id}, "CloudFlare: whitelisted $target $ip";
|
||||
} else {
|
||||
if ($config{DEBUG} == 1) {print "Debug: ".$res->content."\n"}
|
||||
elsif ($config{DEBUG} >= 2) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
print Dumper(JSON::Tiny::decode_json($res->content));
|
||||
};
|
||||
}
|
||||
return "CloudFlare: [$ip] whitelist failed: ".$res->status_line;
|
||||
}
|
||||
}
|
||||
# end whitelist
|
||||
###############################################################################
|
||||
# start challenge
|
||||
sub challenge {
|
||||
my $ip = shift;
|
||||
my $target = &checktarget($ip);
|
||||
|
||||
my $challenge->{mode} = "challenge";
|
||||
$challenge->{configuration}->{target} = $target;
|
||||
$challenge->{configuration}->{value} = $ip;
|
||||
$challenge->{notes} = "csf challenge";
|
||||
|
||||
my $content;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
$content = JSON::Tiny::encode_json($challenge);
|
||||
};
|
||||
|
||||
my $ua = LWP::UserAgent->new;
|
||||
my $res = $ua->post('https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules', %args, Content => $content);
|
||||
|
||||
if ($res->is_success) {
|
||||
my $id = JSON::Tiny::decode_json($res->content);
|
||||
return $id->{result}->{id}, "CloudFlare: challenged $target $ip";
|
||||
} else {
|
||||
if ($config{DEBUG} == 1) {print "Debug: ".$res->content."\n"}
|
||||
elsif ($config{DEBUG} >= 2) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
print Dumper(JSON::Tiny::decode_json($res->content));
|
||||
};
|
||||
}
|
||||
return "CloudFlare: [$ip] challenge failed: ".$res->status_line;
|
||||
}
|
||||
}
|
||||
# end challenge
|
||||
###############################################################################
|
||||
# start add
|
||||
sub add {
|
||||
my $ip = shift;
|
||||
my $mode = shift;
|
||||
my $target = &checktarget($ip);
|
||||
|
||||
my $add->{mode} = $mode;
|
||||
$add->{configuration}->{target} = $target;
|
||||
$add->{configuration}->{value} = $ip;
|
||||
|
||||
my $content;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
$content = JSON::Tiny::encode_json($add);
|
||||
};
|
||||
|
||||
my $ua = LWP::UserAgent->new;
|
||||
my $res = $ua->post('https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules', %args, Content => $content);
|
||||
|
||||
if ($res->is_success) {
|
||||
my $id = JSON::Tiny::decode_json($res->content);
|
||||
return $id->{result}->{id}, "CloudFlare: $mode added $target $ip";
|
||||
} else {
|
||||
if ($config{DEBUG} == 1) {print "Debug: ".$res->content."\n"}
|
||||
elsif ($config{DEBUG} >= 2) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
print Dumper(JSON::Tiny::decode_json($res->content));
|
||||
};
|
||||
}
|
||||
return "CloudFlare: [$ip] $mode failed: ".$res->status_line;
|
||||
}
|
||||
}
|
||||
# end whitelist
|
||||
###############################################################################
|
||||
# start remove
|
||||
sub remove {
|
||||
my $ip = shift;
|
||||
my $mode = shift;
|
||||
my $id = shift;
|
||||
my $target = &checktarget($ip);
|
||||
|
||||
if ($id eq "") {
|
||||
$id = getid($ip,$mode);
|
||||
if ($id =~ /CloudFlare:/) {return $id}
|
||||
if ($id eq "") {return "CloudFlare: [$ip] remove failed: id not found"}
|
||||
}
|
||||
|
||||
my $ua = LWP::UserAgent->new;
|
||||
my $res = $ua->delete('https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules/'.$id, %args);
|
||||
|
||||
if ($res->is_success) {
|
||||
return "CloudFlare: removed $target $ip";
|
||||
} else {
|
||||
if ($config{DEBUG} == 1) {print "Debug: ".$res->content."\n"}
|
||||
elsif ($config{DEBUG} >= 2) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
print Dumper(JSON::Tiny::decode_json($res->content));
|
||||
};
|
||||
}
|
||||
return "CloudFlare: [$ip] [$id] remove failed: ".$res->status_line;
|
||||
}
|
||||
}
|
||||
# end remove
|
||||
###############################################################################
|
||||
# start getid
|
||||
sub getid {
|
||||
my $ip = shift;
|
||||
my $mode = shift;
|
||||
my $target = &checktarget($ip);
|
||||
|
||||
my $ua = LWP::UserAgent->new;
|
||||
my $res = $ua->get('https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules?page=1&per_page=100&configuration.target='.$target.'&configuration.value='.$ip.'&match=all&order=mode&direction=desc', %args);
|
||||
|
||||
if ($res->is_success) {
|
||||
my $result = JSON::Tiny::decode_json($res->content);
|
||||
my $entry = @{$result->{result}}[0];
|
||||
return $entry->{id};
|
||||
} else {
|
||||
if ($config{DEBUG} == 1) {print "Debug: ".$res->content."\n"}
|
||||
elsif ($config{DEBUG} >= 2) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
print Dumper(JSON::Tiny::decode_json($res->content));
|
||||
};
|
||||
}
|
||||
return "CloudFlare: [$ip] id [$mode] failed: ".$res->status_line;
|
||||
}
|
||||
}
|
||||
# end getid
|
||||
###############################################################################
|
||||
# start getlist
|
||||
sub getlist {
|
||||
my $domain = shift;
|
||||
|
||||
my %ips;
|
||||
my $page = 1;
|
||||
my $pages = 1;
|
||||
my $result;
|
||||
|
||||
my $ua = LWP::UserAgent->new;
|
||||
|
||||
while (1) {
|
||||
my $res = $ua->get('https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules?page='.$page.'&per_page=100&order=created_on&direction=asc&match=all', %args);
|
||||
if ($res->is_success) {
|
||||
my $result = JSON::Tiny::decode_json($res->content);
|
||||
|
||||
$pages = $result->{result_info}->{total_pages};
|
||||
foreach my $entry (@{$result->{result}}) {
|
||||
if ($entry->{configuration}->{target} eq "ip" or $entry->{configuration}->{target} eq "country" or $entry->{configuration}->{target} eq "ip_range") {
|
||||
my ($date, $time) = split /T/ => $entry->{created_on};
|
||||
my ($year, $mon, $mday) = split /-/ => $date;
|
||||
$year -= 1900;
|
||||
$mon -= 1;
|
||||
my ($hour, $min, $sec) = split /:/ => $time;
|
||||
my $timelocal = Time::Local::timelocal($sec, $min, $hour, $mday, $mon, $year);
|
||||
|
||||
$ips{$entry->{configuration}->{value}}{notes} = $entry->{notes};
|
||||
$ips{$entry->{configuration}->{value}}{mode} = $entry->{mode};
|
||||
$ips{$entry->{configuration}->{value}}{created_on} = $timelocal;
|
||||
$ips{$entry->{configuration}->{value}}{domain} = $domain;
|
||||
$ips{$entry->{configuration}->{value}}{success} = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($config{DEBUG} >= 2) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
print Dumper(JSON::Tiny::decode_json($res->content));
|
||||
};
|
||||
}
|
||||
$ips{$domain}{success} = 0;
|
||||
$ips{$domain}{domain} = "CloudFlare: list failed for ($domain): ".$res->status_line;
|
||||
return \%ips;
|
||||
}
|
||||
$page++;
|
||||
if ($pages < $page) {last}
|
||||
}
|
||||
return \%ips;
|
||||
}
|
||||
# end getlist
|
||||
###############################################################################
|
||||
# start getscope
|
||||
sub getscope {
|
||||
my %scope;
|
||||
my %disabled;
|
||||
my %any;
|
||||
my @entries = slurp("/etc/csf/csf.cloudflare");
|
||||
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 @setting = split(/\:/,$line);
|
||||
|
||||
if ($setting[0] eq "DOMAIN") {
|
||||
my $domain = $setting[1];
|
||||
my $user = $setting[3];
|
||||
my $account = $setting[5];
|
||||
my $apikey = $setting[7];
|
||||
|
||||
$scope{domain}{$domain}{account} = $account;
|
||||
$scope{domain}{$domain}{apikey} = $apikey;
|
||||
$scope{domain}{$domain}{user} = $user;
|
||||
$scope{user}{$user}{account} = $account;
|
||||
$scope{user}{$user}{apikey} = $apikey;
|
||||
$scope{user}{$user}{domain}{$domain} = $domain;
|
||||
if ($domain eq "any") {$scope{user}{$user}{any} = 1}
|
||||
}
|
||||
if ($setting[0] eq "DISABLE") {
|
||||
$disabled{$setting[1]} = 1;
|
||||
}
|
||||
if ($setting[0] eq "ANY") {
|
||||
$any{$setting[1]} = 1;
|
||||
}
|
||||
}
|
||||
if ($config{CF_CPANEL}) {
|
||||
my %userdomains;
|
||||
my %accounts;
|
||||
my %creds;
|
||||
|
||||
open (my $IN, "<","/etc/userdomains");
|
||||
flock ($IN, LOCK_SH);
|
||||
my @localusers = <$IN>;
|
||||
close ($IN);
|
||||
chomp @localusers;
|
||||
foreach my $line (@localusers) {
|
||||
my ($domain,$user) = split(/\:\s*/,$line,2);
|
||||
$userdomains{$domain} = $user;
|
||||
$accounts{$user} = 1;
|
||||
}
|
||||
|
||||
foreach my $user (keys %accounts) {
|
||||
if ($disabled{$user}) {next}
|
||||
my $userhome = (getpwnam($user))[7];
|
||||
|
||||
if (-e "$userhome/.cpanel/datastore/cloudflare_data.yaml") {
|
||||
my $yaml = YAML::Tiny->read("$userhome/.cpanel/datastore/cloudflare_data.yaml");
|
||||
if ($yaml->[0]->{client_api_key} ne "") {
|
||||
$creds{$user}{account} = $yaml->[0]->{cloudflare_email};
|
||||
$creds{$user}{apikey} = $yaml->[0]->{client_api_key};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $domain (keys %userdomains) {
|
||||
my $user = $userdomains{$domain};
|
||||
if ($disabled{$user}) {next}
|
||||
if ($creds{$user}{apikey} ne "") {
|
||||
$scope{domain}{$domain}{account} = $creds{$user}{account};
|
||||
$scope{domain}{$domain}{apikey} = $creds{$user}{apikey};
|
||||
$scope{domain}{$domain}{user} = $user;
|
||||
$scope{user}{$user}{account} = $creds{$user}{account};
|
||||
$scope{user}{$user}{apikey} = $creds{$user}{apikey};
|
||||
$scope{user}{$user}{domain}{$domain} = $domain;
|
||||
if ($any{$user}) {
|
||||
$scope{domain}{any}{account} = $creds{$user}{account};
|
||||
$scope{domain}{any}{apikey} = $creds{$user}{apikey};
|
||||
$scope{domain}{any}{user} = $user;
|
||||
$scope{user}{$user}{domain}{any} = "any";
|
||||
$scope{user}{$user}{any} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return \%scope;
|
||||
}
|
||||
# end getscope
|
||||
###############################################################################
|
||||
# start checktarget
|
||||
sub checktarget {
|
||||
my $arg = shift;
|
||||
if ($arg =~ /^\w\w$/) {return "country"}
|
||||
elsif ($arg =~ /\/16$/) {return "ip_range"}
|
||||
elsif ($arg =~ /\/24$/) {return "ip_range"}
|
||||
else {return "ip"}
|
||||
}
|
||||
# end checktarget
|
||||
###############################################################################
|
||||
1;
|
||||
457
csf/ConfigServer/Config.pm
Normal file
457
csf/ConfigServer/Config.pm
Normal file
@@ -0,0 +1,457 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::Config;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use version;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use Carp;
|
||||
use IPC::Open3;
|
||||
use ConfigServer::Slurp qw(slurp);
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.05;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
our $ipv4reg = qr/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/;
|
||||
our $ipv6reg = qr/((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?/;
|
||||
|
||||
my %config;
|
||||
my %configsetting;
|
||||
my $warning;
|
||||
my $version;
|
||||
|
||||
my $slurpreg = ConfigServer::Slurp->slurpreg;
|
||||
my $cleanreg = ConfigServer::Slurp->cleanreg;
|
||||
my $configfile = "/etc/csf/csf.conf";
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start loadconfig
|
||||
sub loadconfig {
|
||||
my $class = shift;
|
||||
my $self = {};
|
||||
bless $self,$class;
|
||||
|
||||
if (%config) {
|
||||
$self->{warning} = $warning;
|
||||
return $self;
|
||||
}
|
||||
|
||||
undef %configsetting;
|
||||
undef %config;
|
||||
undef $warning;
|
||||
|
||||
my @file = slurp($configfile);
|
||||
foreach my $line (@file) {
|
||||
$line =~ s/$cleanreg//g;
|
||||
if ($line =~ /^(\s|\#|$)/) {next}
|
||||
if ($line !~ /=/) {next}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
croak "*Error* Invalid configuration line [$line] in $configfile";
|
||||
}
|
||||
if ($configsetting{$name}) {
|
||||
croak "*Error* Setting $name is repeated in $configfile - you must remove the duplicates and then restart csf and lfd";
|
||||
}
|
||||
$config{$name} = $value;
|
||||
$configsetting{$name} = 1;
|
||||
}
|
||||
|
||||
if ($config{LF_IPSET}) {
|
||||
unless ($config{LF_IPSET_HASHSIZE}) {
|
||||
$config{LF_IPSET_HASHSIZE} = "1024";
|
||||
$configsetting{LF_IPSET_HASHSIZE} = 1;
|
||||
}
|
||||
unless ($config{LF_IPSET_MAXELEM}) {
|
||||
$config{LF_IPSET_MAXELEM} = "65536";
|
||||
$configsetting{LF_IPSET_MAXELEM} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($config{USE_FTPHELPER} eq "1") {
|
||||
$warning .= "USE_FTPHELPER should be set to your FTP server port (21), not 1. USE_FTPHELPER has been disabled\n";
|
||||
$config{USE_FTPHELPER} = 0;
|
||||
}
|
||||
|
||||
if ($config{IPTABLES} eq "" or !(-x $config{IPTABLES})) {
|
||||
croak "*Error* The path to iptables is either not set or incorrect for IPTABLES [$config{IPTABLES}] in /etc/csf/csf.conf";
|
||||
}
|
||||
|
||||
if (-e "/proc/sys/net/netfilter/nf_conntrack_helper" and !$config{USE_FTPHELPER}) {
|
||||
my $setting = slurp("/proc/sys/net/netfilter/nf_conntrack_helper");
|
||||
chomp $setting;
|
||||
|
||||
if ($setting == 0) {
|
||||
open (my $PROC, ">", "/proc/sys/net/netfilter/nf_conntrack_helper");
|
||||
print $PROC "1\n";
|
||||
close $PROC;
|
||||
}
|
||||
}
|
||||
|
||||
if ($config{WAITLOCK}) {$config{IPTABLESWAIT} = "--wait";}
|
||||
my @results = &systemcmd("$config{IPTABLES} $config{IPTABLESWAIT} --version");
|
||||
if ($results[0] =~ /iptables v(\d+\.\d+\.\d+)/) {
|
||||
$version = $1;
|
||||
|
||||
$config{IPTABLESWAIT} = "";
|
||||
if ($config{WAITLOCK}) {
|
||||
my @ipdata;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die "alarm\n"};
|
||||
alarm($config{WAITLOCK_TIMEOUT});
|
||||
my ($childin, $childout);
|
||||
my $cmdpid = open3($childin, $childout, $childout, "$config{IPTABLES} --wait -L OUTPUT -nv");
|
||||
@ipdata = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ipdata;
|
||||
if ($ipdata[0] =~ /# Warning: iptables-legacy tables present/) {shift @ipdata}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($@ eq "alarm\n") {
|
||||
croak "*ERROR* Timeout after $config{WAITLOCK_TIMEOUT} seconds for iptables --wait - WAITLOCK\n";
|
||||
}
|
||||
if ($ipdata[0] =~ /^Chain OUTPUT/) {
|
||||
$config{IPTABLESWAIT} = "--wait";
|
||||
} else {
|
||||
$warning .= "*WARNING* This version of iptables does not support the --wait option - disabling WAITLOCK\n";
|
||||
$config{WAITLOCK} = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$warning .= "*WARNING* Unable to detect iptables version [$results[0]]\n";
|
||||
}
|
||||
|
||||
if ($config{CC_LOOKUPS} and $config{CC_LOOKUPS} != 4 and $config{CC_SRC} eq "1") {
|
||||
if ($config{MM_LICENSE_KEY} eq "") {
|
||||
$warning .= "*ERROR*: Country Code Lookups setting MM_LICENSE_KEY must be set in /etc/csf/csf.conf to continue using the MaxMind databases\n";
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $cclist ("CC_DENY","CC_ALLOW","CC_ALLOW_FILTER","CC_ALLOW_PORTS","CC_DENY_PORTS","CC_ALLOW_SMTPAUTH") {
|
||||
$config{$cclist} =~ s/\s//g;
|
||||
my $newcclist;
|
||||
foreach my $cc (split(/\,/,$config{$cclist})) {
|
||||
if ($cc ne "" and ((length($cc) == 2 and $cc =~ /^[a-zA-Z][a-zA-Z]$/i) or (length($cc) > 2 and $cc =~ /^AS\d+$/i))) {
|
||||
$cc = lc $cc;
|
||||
if ($newcclist eq "") {$newcclist = "$cc"} else {$newcclist .= ",$cc"}
|
||||
} else {
|
||||
$warning .= "*WARNING* $cclist contains an invalid entry [$cc]\n";
|
||||
}
|
||||
}
|
||||
$config{$cclist} = $newcclist;
|
||||
}
|
||||
|
||||
if ($config{CC_DENY} or $config{CC_ALLOW} or $config{CC_ALLOW_FILTER} or $config{CC_ALLOW_PORTS} or $config{CC_DENY_PORTS} or $config{CC_ALLOW_SMTPAUTH}) {
|
||||
if ($config{MM_LICENSE_KEY} eq "" and $config{CC_SRC} eq "1") {
|
||||
$warning .= "*ERROR*: Country Code Filters setting MM_LICENSE_KEY must be set in /etc/csf/csf.conf to continue updating the MaxMind databases\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($config{DROP_OUT} ne "DROP") {
|
||||
my @data = &systemcmd("$config{IPTABLES} $config{IPTABLESWAIT} -N TESTDENY");
|
||||
unless ($data[0] =~ /^iptables/) {
|
||||
my @ipdata = &systemcmd("$config{IPTABLES} $config{IPTABLESWAIT} -I TESTDENY -j $config{DROP_OUT}");
|
||||
if ($ipdata[0] =~ /^iptables/) {
|
||||
$warning .= "*WARNING* Cannot use DROP_OUT value of [$config{DROP_OUT}] on this server, set to DROP\n";
|
||||
$config{DROP_OUT} = "DROP";
|
||||
}
|
||||
&systemcmd("$config{IPTABLES} $config{IPTABLESWAIT} -F TESTDENY");
|
||||
&systemcmd("$config{IPTABLES} $config{IPTABLESWAIT} -X TESTDENY");
|
||||
}
|
||||
}
|
||||
my @raw = &systemcmd("$config{IPTABLES} $config{IPTABLESWAIT} -L PREROUTING -t raw");
|
||||
if ($raw[0] =~ /^Chain PREROUTING/) {$config{RAW} = 1} else {$config{RAW} = 0}
|
||||
my @mangle = &systemcmd("$config{IPTABLES} $config{IPTABLESWAIT} -L PREROUTING -t mangle");
|
||||
if ($mangle[0] =~ /^Chain PREROUTING/) {$config{MANGLE} = 1} else {$config{MANGLE} = 0}
|
||||
|
||||
if ($config{IPV6} and -x $config{IP6TABLES} and $version) {
|
||||
if ($config{USE_CONNTRACK} and version->parse($version) <= version->parse("1.3.5")) {$config{USE_CONNTRACK} = 0}
|
||||
if ($config{PORTFLOOD} and version->parse($version) >= version->parse("1.4.3")) {$config{PORTFLOOD6} = 1}
|
||||
if ($config{CONNLIMIT} and version->parse($version) >= version->parse("1.4.3")) {$config{CONNLIMIT6} = 1}
|
||||
if ($config{MESSENGER} and version->parse($version) >= version->parse("1.4.17")) {$config{MESSENGER6} = 1}
|
||||
if ($config{SMTP_REDIRECT} and version->parse($version) >= version->parse("1.4.17")) {$config{SMTP_REDIRECT6} = 1}
|
||||
my @ipdata = &systemcmd("$config{IP6TABLES} $config{IPTABLESWAIT} -t nat -L POSTROUTING -nv");
|
||||
if ($ipdata[0] =~ /^Chain POSTROUTING/) {
|
||||
$config{NAT6} = 1;
|
||||
}
|
||||
elsif (version->parse($version) >= version->parse("1.4.17")) {
|
||||
if ($config{SMTP_REDIRECT}) {
|
||||
$warning .= "*WARNING* ip6tables nat table not present - disabling SMTP_REDIRECT for IPv6\n";
|
||||
$config{SMTP_REDIRECT6} = 0;
|
||||
}
|
||||
if ($config{MESSENGER}) {
|
||||
$warning .= "*WARNING* ip6tables nat table not present - disabling MESSENGER Service for IPv6\n";
|
||||
$config{MESSENGER6} = 0;
|
||||
}
|
||||
if ($config{DOCKER} and $config{DOCKER_NETWORK6} ne "") {
|
||||
$warning .= "*WARNING* ip6tables nat table not present - disabling DOCKER for IPv6\n";
|
||||
}
|
||||
}
|
||||
my @raw = &systemcmd("$config{IP6TABLES} $config{IPTABLESWAIT} -L PREROUTING -t raw");
|
||||
if ($raw[0] =~ /^Chain PREROUTING/) {$config{RAW6} = 1} else {$config{RAW6} = 0}
|
||||
my @mangle = &systemcmd("$config{IP6TABLES} $config{IPTABLESWAIT} -L PREROUTING -t mangle");
|
||||
if ($mangle[0] =~ /^Chain PREROUTING/) {$config{MANGLE6} = 1} else {$config{MANGLE6} = 0}
|
||||
}
|
||||
elsif ($config{IPV6}) {
|
||||
$warning .= "*WARNING* incorrect ip6tables binary location [$config{IP6TABLES}] - IPV6 disabled\n";
|
||||
$config{IPV6} = 0;
|
||||
}
|
||||
|
||||
if (!$config{GENERIC} and -e "/var/cpanel/dnsonly") {$config{DNSONLY} = 1}
|
||||
|
||||
if (-e "/var/cpanel/smtpgidonlytweak" and !$config{GENERIC}) {
|
||||
if ($config{DNSONLY}) {
|
||||
$warning .= "*WARNING* The cPanel option to 'Restrict outgoing SMTP to root, exim, and mailman' is incompatible with this firewall. The option must be disabled using \"/usr/local/cpanel/scripts/smtpmailgidonly off\" and the SMTP_BLOCK alternative in csf used instead\n";
|
||||
} else {
|
||||
$warning .= "*WARNING* The option \"WHM > Tweak Settings > Restrict outgoing SMTP to root, exim, and mailman (FKA SMTP Tweak)\" is incompatible with this firewall. The option must be disabled in WHM and the SMTP_BLOCK alternative in csf used instead\n";
|
||||
}
|
||||
}
|
||||
if (-e "/proc/vz/veinfo") {$config{VPS} = 1}
|
||||
else {
|
||||
foreach my $line (slurp("/proc/self/status")) {
|
||||
$line =~ s/$cleanreg//g;
|
||||
if ($line =~ /^envID:\s*(\d+)\s*$/) {
|
||||
if ($1 > 0) {
|
||||
$config{VPS} = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($config{DROP_IP_LOGGING} and $config{PS_INTERVAL}) {
|
||||
$warning .= "*WARNING* Cannot use PS_INTERVAL with DROP_IP_LOGGING enabled. DROP_IP_LOGGING disabled\n";
|
||||
$config{DROP_IP_LOGGING} = 0;
|
||||
}
|
||||
|
||||
if ($config{FASTSTART}) {
|
||||
unless (-x $config{IPTABLES_RESTORE}) {
|
||||
$warning .= "*WARNING* Unable to use FASTSTART as [$config{IPTABLES_RESTORE}] is not executable or does not exist\n";
|
||||
$config{FASTSTART} = 0;
|
||||
}
|
||||
if ($config{IPV6}) {
|
||||
unless (-x $config{IP6TABLES_RESTORE}) {
|
||||
$warning .= "*WARNING* Unable to use FASTSTART as (IPv6) [$config{IP6TABLES_RESTORE}] is not executable or does not exist\n";
|
||||
$config{FASTSTART} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($config{MESSENGER}) {
|
||||
if ($config{MESSENGERV2}) {
|
||||
if (!-e "/etc/cpanel/ea4/is_ea4") {
|
||||
$warning .= "*WARNING* EA4 is not in use - disabling MESSENGERV2 and MESSENGER HTTPS Service\n";
|
||||
$config{MESSENGERV2} = "0";
|
||||
$config{MESSENGER_HTTPS_IN} = "";
|
||||
$config{MESSENGER_HTTPS_DISABLED} = "*WARNING* EA4 is not in use - disabling MESSENGERV2 and MESSENGER HTTPS Service";
|
||||
}
|
||||
}
|
||||
if ($config{MESSENGER_HTTPS_IN} and (!$config{MESSENGERV2} or $config{MESSENGER_HTTPS_DISABLED})) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
require IO::Socket::SSL;
|
||||
};
|
||||
if ($@) {
|
||||
$warning .= "*WARNING* Perl module IO::Socket::SSL missing - disabling MESSENGER HTTPS Service\n";
|
||||
$config{MESSENGER_HTTPS_IN} = "";
|
||||
$config{MESSENGER_HTTPS_DISABLED} = "*WARNING* Perl module IO::Socket::SSL missing - disabling MESSENGER HTTPS Service";
|
||||
}
|
||||
elsif (version->parse($IO::Socket::SSL::VERSION) < version->parse("1.83")) {
|
||||
$warning .= "*WARNING* Perl module IO::Socket::SSL v$IO::Socket::SSL::VERSION does not support SNI - disabling MESSENGER HTTPS Service\n";
|
||||
$config{MESSENGER_HTTPS_IN} = "";
|
||||
$config{MESSENGER_HTTPS_DISABLED} = "*WARNING* Perl module IO::Socket::SSL v$IO::Socket::SSL::VERSION does not support SNI - disabling MESSENGER HTTPS Service";
|
||||
}
|
||||
}
|
||||
my $pcnt = 0;
|
||||
foreach my $port (split(/\,/,$config{MESSENGER_HTML_IN})) {
|
||||
$pcnt++;
|
||||
}
|
||||
if ($pcnt > 15) {
|
||||
$warning .= "*WARNING* MESSENGER_HTML_IN contains more than 15 ports - disabling MESSENGER Service\n";
|
||||
$config{MESSENGER} = 0;
|
||||
} else {
|
||||
$pcnt = 0;
|
||||
foreach my $port (split(/\,/,$config{MESSENGER_TEXT_IN})) {
|
||||
$pcnt++;
|
||||
}
|
||||
if ($pcnt > 15) {
|
||||
$warning .= "*WARNING* MESSENGER_TEXT_IN contains more than 15 ports - disabling MESSENGER Service\n";
|
||||
$config{MESSENGER} = 0;
|
||||
} else {
|
||||
$pcnt = 0;
|
||||
foreach my $port (split(/\,/,$config{MESSENGER_HTTPS_IN})) {
|
||||
$pcnt++;
|
||||
}
|
||||
if ($pcnt > 15) {
|
||||
$warning .= "*WARNING* MESSENGER_HTTPS_IN contains more than 15 ports - disabling MESSENGER Service\n";
|
||||
$config{MESSENGER} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($config{IPV6} and $config{IPV6_SPI}) {
|
||||
open (my $FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock ($FH, LOCK_SH);
|
||||
my @data = <$FH>;
|
||||
close ($FH);
|
||||
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 > 6)) or (($maj > 1) and ($mid > 5) and ($min > 19))) {
|
||||
} else {
|
||||
$warning .= "*WARNING* Kernel $data[0] may not support an ip6tables SPI firewall. You should set IPV6_SPI to \"0\" in /etc/csf/csf.conf\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (($config{CLUSTER_SENDTO} or $config{CLUSTER_RECVFROM})) {
|
||||
if (-f $config{CLUSTER_SENDTO}) {
|
||||
if ($config{DEBUG} >= 1) {$warning .= "*DEBUG* CLUSTER_SENDTO retrieved from $config{CLUSTER_SENDTO} and set to: "}
|
||||
$config{CLUSTER_SENDTO} = join(",", slurp($config{CLUSTER_SENDTO}));
|
||||
if ($config{DEBUG} >= 1) {$warning .= "[$config{CLUSTER_SENDTO}]\n"}
|
||||
}
|
||||
if (-f $config{CLUSTER_RECVFROM}) {
|
||||
if ($config{DEBUG} >= 1) {$warning .= "*DEBUG* CLUSTER_RECVFROM retrieved from $config{CLUSTER_RECVFROM} and set to: "}
|
||||
$config{CLUSTER_RECVFROM} = join(",", slurp($config{CLUSTER_RECVFROM}));
|
||||
if ($config{DEBUG} >= 1) {$warning .= "[$config{CLUSTER_RECVFROM}]\n"}
|
||||
}
|
||||
}
|
||||
|
||||
my @ipdata = &systemcmd("$config{IPTABLES} $config{IPTABLESWAIT} -t nat -L POSTROUTING -nv");
|
||||
if ($ipdata[0] =~ /^Chain POSTROUTING/) {
|
||||
$config{NAT} = 1;
|
||||
} else {
|
||||
if ($config{MESSENGER}) {
|
||||
$warning .= "*WARNING* iptables nat table not present - disabling MESSENGER Service\n";
|
||||
$config{MESSENGER} = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($config{PT_USERKILL}) {
|
||||
$warning .= "*WARNING* PT_USERKILL should not normally be enabled as it can easily lead to legitimate processes being terminated, use csf.pignore instead\n";
|
||||
}
|
||||
|
||||
$config{cc_src} = "MaxMind";
|
||||
$config{asn_src} = "MaxMind";
|
||||
$config{cc_country} = "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country-CSV&suffix=zip&license_key=$config{MM_LICENSE_KEY}";
|
||||
$config{cc_city} = "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City-CSV&suffix=zip&license_key=$config{MM_LICENSE_KEY}";
|
||||
$config{cc_asn} = "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-ASN-CSV&suffix=zip&license_key=$config{MM_LICENSE_KEY}";
|
||||
if ($config{CC_SRC} eq "2") {
|
||||
$config{cc_src} = "DB-IP";
|
||||
$config{asn_src} = "iptoasn.com";
|
||||
$config{ccl_src} = "ipdeny.com";
|
||||
my ($month,$year) = sub{ 1+shift, 1900+shift }->((localtime time)[4,5]);
|
||||
$month = sprintf("%02d", $month);
|
||||
$config{cc_country} = "http://download.db-ip.com/free/dbip-country-lite-$year-$month.csv.gz";
|
||||
$config{cc_city} = "http://download.db-ip.com/free/dbip-city-lite-$year-$month.csv.gz";
|
||||
$config{cc_asn} = "http://iptoasn.com/data/ip2asn-combined.tsv.gz";
|
||||
$config{cc_cc} = "http://download.geonames.org/export/dump/countryInfo.txt";
|
||||
}
|
||||
|
||||
$config{DOWNLOADSERVER} = &getdownloadserver;
|
||||
|
||||
$self->{warning} = $warning;
|
||||
|
||||
return $self;
|
||||
}
|
||||
# end loadconfig
|
||||
###############################################################################
|
||||
# start config
|
||||
sub config {
|
||||
return %config;
|
||||
}
|
||||
# end config
|
||||
###############################################################################
|
||||
# start resetconfig
|
||||
sub resetconfig {
|
||||
undef %config;
|
||||
undef %configsetting;
|
||||
undef $warning;
|
||||
|
||||
return;
|
||||
}
|
||||
# end resetconfig
|
||||
###############################################################################
|
||||
# start configsetting
|
||||
sub configsetting {
|
||||
return %configsetting;
|
||||
}
|
||||
# end configsetting
|
||||
###############################################################################
|
||||
# start ipv4reg
|
||||
sub ipv4reg {
|
||||
return $ipv4reg;
|
||||
}
|
||||
# end ipv4reg
|
||||
###############################################################################
|
||||
# start ipv6reg
|
||||
sub ipv6reg {
|
||||
return $ipv6reg;
|
||||
}
|
||||
# end ipv6reg
|
||||
###############################################################################
|
||||
# start systemcmd
|
||||
sub systemcmd {
|
||||
my @command = @_;
|
||||
my @result;
|
||||
|
||||
eval {
|
||||
my ($childin, $childout);
|
||||
my $pid = open3($childin, $childout, $childout, @command);
|
||||
@result = <$childout>;
|
||||
waitpid ($pid, 0);
|
||||
chomp @result;
|
||||
if ($result[0] =~ /# Warning: iptables-legacy tables present/) {shift @result}
|
||||
};
|
||||
|
||||
return @result;
|
||||
}
|
||||
# end systemcmd
|
||||
###############################################################################
|
||||
## start getdownloadserver
|
||||
sub getdownloadserver {
|
||||
my @servers;
|
||||
my $downloadservers = "/etc/csf/downloadservers";
|
||||
my $chosen;
|
||||
if (-e $downloadservers) {
|
||||
foreach my $line (slurp($downloadservers)) {
|
||||
$line =~ s/$cleanreg//g;
|
||||
if ($line =~ /^download/) {push @servers, $line}
|
||||
}
|
||||
$chosen = $servers[rand @servers];
|
||||
}
|
||||
## if ($chosen eq "") {$chosen = "download.configserver.com"}
|
||||
return $chosen;
|
||||
}
|
||||
## end getdownloadserver
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
241
csf/ConfigServer/DisplayResellerUI.pm
Normal file
241
csf/ConfigServer/DisplayResellerUI.pm
Normal file
@@ -0,0 +1,241 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
package ConfigServer::DisplayResellerUI;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use POSIX qw(:sys_wait_h sysconf strftime);
|
||||
use File::Basename;
|
||||
use Net::CIDR::Lite;
|
||||
use IPC::Open3;
|
||||
|
||||
use ConfigServer::Config;
|
||||
use ConfigServer::CheckIP qw(checkip);
|
||||
use ConfigServer::Sendmail;
|
||||
use ConfigServer::Logger;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.01;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
umask(0177);
|
||||
|
||||
our ($chart, $ipscidr6, $ipv6reg, $ipv4reg, %config, %ips, $mobile,
|
||||
%FORM, $script, $script_da, $images, $myv, %rprivs, $hostname,
|
||||
$hostshort, $tz, $panel);
|
||||
|
||||
#
|
||||
###############################################################################
|
||||
# start main
|
||||
sub main {
|
||||
my $form_ref = shift;
|
||||
%FORM = %{$form_ref};
|
||||
$script = shift;
|
||||
$script_da = shift;
|
||||
$images = shift;
|
||||
$myv = shift;
|
||||
|
||||
open (my $IN,"<","/etc/csf/csf.resellers");
|
||||
flock ($IN, LOCK_SH);
|
||||
while (my $line = <$IN>) {
|
||||
my ($user,$alert,$privs) = split(/\:/,$line);
|
||||
$privs =~ s/\s//g;
|
||||
foreach my $priv (split(/\,/,$privs)) {
|
||||
$rprivs{$user}{$priv} = 1;
|
||||
}
|
||||
$rprivs{$user}{ALERT} = $alert;
|
||||
}
|
||||
close ($IN);
|
||||
|
||||
open (my $HOSTNAME, "<","/proc/sys/kernel/hostname");
|
||||
flock ($HOSTNAME, LOCK_SH);
|
||||
$hostname = <$HOSTNAME>;
|
||||
chomp $hostname;
|
||||
close ($HOSTNAME);
|
||||
$hostshort = (split(/\./,$hostname))[0];
|
||||
$tz = strftime("%z", localtime);
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
%config = $config->config();
|
||||
|
||||
$panel = "cPanel";
|
||||
if ($config{GENERIC}) {$panel = "Generic"}
|
||||
if ($config{INTERWORX}) {$panel = "InterWorx"}
|
||||
if ($config{DIRECTADMIN}) {$panel = "DirectAdmin"}
|
||||
|
||||
if ($FORM{ip} ne "") {$FORM{ip} =~ s/(^\s+)|(\s+$)//g}
|
||||
|
||||
if ($FORM{action} ne "" and !checkip(\$FORM{ip})) {
|
||||
print "<table class='table table-bordered table-striped'>\n";
|
||||
print "<tr><td>";
|
||||
print "[$FORM{ip}] is not a valid IP address\n";
|
||||
print "</td></tr></table>\n";
|
||||
print "<p><form action='$script' method='post'><input type='submit' class='btn btn-default' value='Return'></form></p>\n";
|
||||
} else {
|
||||
if ($FORM{action} eq "qallow" and $rprivs{$ENV{REMOTE_USER}}{ALLOW}) {
|
||||
if ($FORM{comment} eq "") {
|
||||
print "<table class='table table-bordered table-striped'>\n";
|
||||
print "<tr><td>You must provide a Comment for this option</td></tr></table>\n";
|
||||
} else {
|
||||
$FORM{comment} =~ s/"//g;
|
||||
print "<table class='table table-bordered table-striped'>\n";
|
||||
print "<tr><td>";
|
||||
print "<p>Allowing $FORM{ip}...</p>\n<p><pre style='font-family: Courier New, Courier; font-size: 12px'>\n";
|
||||
my $text = &printcmd("/usr/sbin/csf","-a",$FORM{ip},"ALLOW by Reseller $ENV{REMOTE_USER} ($FORM{comment})");
|
||||
print "</p>\n<p>...<b>Done</b>.</p>\n";
|
||||
print "</td></tr></table>\n";
|
||||
if ($rprivs{$ENV{REMOTE_USER}}{ALERT}) {
|
||||
open (my $IN, "<", "/usr/local/csf/tpl/reselleralert.txt");
|
||||
flock ($IN, LOCK_SH);
|
||||
my @alert = <$IN>;
|
||||
close ($IN);
|
||||
chomp @alert;
|
||||
|
||||
my @message;
|
||||
foreach my $line (@alert) {
|
||||
$line =~ s/\[reseller\]/$ENV{REMOTE_USER}/ig;
|
||||
$line =~ s/\[action\]/ALLOW/ig;
|
||||
$line =~ s/\[ip\]/$FORM{ip}/ig;
|
||||
$line =~ s/\[rip\]/$ENV{REMOTE_HOST}/ig;
|
||||
$line =~ s/\[text\]/Result of ALLOW:\n\n$text/ig;
|
||||
push @message, $line;
|
||||
}
|
||||
ConfigServer::Sendmail::relay("", "", @message);
|
||||
}
|
||||
ConfigServer::Logger::logfile("$panel Reseller [$ENV{REMOTE_USER}]: ALLOW $FORM{ip}");
|
||||
}
|
||||
print "<p><form action='$script' method='post'><input type='hidden' name='mobi' value='$FORM{mobi}'><input type='submit' class='btn btn-default' value='Return'></form></p>\n";
|
||||
}
|
||||
elsif ($FORM{action} eq "qdeny" and $rprivs{$ENV{REMOTE_USER}}{DENY}) {
|
||||
if ($FORM{comment} eq "") {
|
||||
print "<table class='table table-bordered table-striped'>\n";
|
||||
print "<tr><td>You must provide a Comment for this option</td></tr></table>\n";
|
||||
} else {
|
||||
$FORM{comment} =~ s/"//g;
|
||||
print "<table class='table table-bordered table-striped'>\n";
|
||||
print "<tr><td>";
|
||||
print "<p>Blocking $FORM{ip}...</p>\n<p><pre style='font-family: Courier New, Courier; font-size: 12px'>\n";
|
||||
my $text = &printcmd("/usr/sbin/csf","-d",$FORM{ip},"DENY by Reseller $ENV{REMOTE_USER} ($FORM{comment})");
|
||||
print "</p>\n<p>...<b>Done</b>.</p>\n";
|
||||
print "</td></tr></table>\n";
|
||||
if ($rprivs{$ENV{REMOTE_USER}}{ALERT}) {
|
||||
open (my $IN, "<", "/usr/local/csf/tpl/reselleralert.txt");
|
||||
flock ($IN, LOCK_SH);
|
||||
my @alert = <$IN>;
|
||||
close ($IN);
|
||||
chomp @alert;
|
||||
|
||||
my @message;
|
||||
foreach my $line (@alert) {
|
||||
$line =~ s/\[reseller\]/$ENV{REMOTE_USER}/ig;
|
||||
$line =~ s/\[action\]/DENY/ig;
|
||||
$line =~ s/\[ip\]/$FORM{ip}/ig;
|
||||
$line =~ s/\[rip\]/$ENV{REMOTE_HOST}/ig;
|
||||
$line =~ s/\[text\]/Result of DENY:\n\n$text/ig;
|
||||
push @message, $line;
|
||||
}
|
||||
ConfigServer::Sendmail::relay("", "", @message);
|
||||
}
|
||||
ConfigServer::Logger::logfile("$panel Reseller [$ENV{REMOTE_USER}]: DENY $FORM{ip}");
|
||||
}
|
||||
print "<p><form action='$script' method='post'><input type='hidden' name='mobi' value='$FORM{mobi}'><input type='submit' class='btn btn-default' value='Return'></form></p>\n";
|
||||
}
|
||||
elsif ($FORM{action} eq "qkill" and $rprivs{$ENV{REMOTE_USER}}{UNBLOCK}) {
|
||||
my $text = "";
|
||||
if ($rprivs{$ENV{REMOTE_USER}}{ALERT}) {
|
||||
my ($childin, $childout);
|
||||
my $pid = open3($childin, $childout, $childout, "/usr/sbin/csf","-g",$FORM{ip});
|
||||
while (<$childout>) {$text .= $_}
|
||||
waitpid ($pid, 0);
|
||||
}
|
||||
print "<table class='table table-bordered table-striped'>\n";
|
||||
print "<tr><td>";
|
||||
print "<p>Unblock $FORM{ip}, trying permanent blocks...</p>\n<p><pre style='font-family: Courier New, Courier; font-size: 12px'>\n";
|
||||
my $text1 = &printcmd("/usr/sbin/csf","-dr",$FORM{ip});
|
||||
print "</p>\n<p>...<b>Done</b>.</p>\n";
|
||||
print "<p>Unblock $FORM{ip}, trying temporary blocks...</p>\n<p><pre style='font-family: Courier New, Courier; font-size: 12px'>\n";
|
||||
my $text2 = &printcmd("/usr/sbin/csf","-tr",$FORM{ip});
|
||||
print "</p>\n<p>...<b>Done</b>.</p>\n";
|
||||
print "</td></tr></table>\n";
|
||||
print "<p><form action='$script' method='post'><input type='hidden' name='mobi' value='$FORM{mobi}'><input type='submit' class='btn btn-default' value='Return'></form></p>\n";
|
||||
if ($rprivs{$ENV{REMOTE_USER}}{ALERT}) {
|
||||
open (my $IN, "<", "/usr/local/csf/tpl/reselleralert.txt");
|
||||
flock ($IN, LOCK_SH);
|
||||
my @alert = <$IN>;
|
||||
close ($IN);
|
||||
chomp @alert;
|
||||
|
||||
my @message;
|
||||
foreach my $line (@alert) {
|
||||
$line =~ s/\[reseller\]/$ENV{REMOTE_USER}/ig;
|
||||
$line =~ s/\[action\]/UNBLOCK/ig;
|
||||
$line =~ s/\[ip\]/$FORM{ip}/ig;
|
||||
$line =~ s/\[rip\]/$ENV{REMOTE_HOST}/ig;
|
||||
$line =~ s/\[text\]/Result of GREP before UNBLOCK:\n$text\n\nResult of UNBLOCK:\nPermanent:\n$text1\nTemporary:\n$text2\n/ig;
|
||||
push @message, $line;
|
||||
}
|
||||
ConfigServer::Sendmail::relay("", "", @message);
|
||||
}
|
||||
ConfigServer::Logger::logfile("$panel Reseller [$ENV{REMOTE_USER}]: UNBLOCK $FORM{ip}");
|
||||
}
|
||||
elsif ($FORM{action} eq "grep" and $rprivs{$ENV{REMOTE_USER}}{GREP}) {
|
||||
print "<table class='table table-bordered table-striped'>\n";
|
||||
print "<tr><td>";
|
||||
print "<p>Searching for $FORM{ip}...</p>\n<p><pre style='font-family: Courier New, Courier; font-size: 12px'>\n";
|
||||
&printcmd("/usr/sbin/csf","-g",$FORM{ip});
|
||||
print "</p>\n<p>...<b>Done</b>.</p>\n";
|
||||
print "</td></tr></table>\n";
|
||||
print "<p><form action='$script' method='post'><input type='submit' class='btn btn-default' value='Return'></form></p>\n";
|
||||
}
|
||||
else {
|
||||
print "<table class='table table-bordered table-striped'>\n";
|
||||
print "<thead><tr><th align='left' colspan='2'>csf - ConfigServer Firewall options for $ENV{REMOTE_USER}</th></tr></thead>";
|
||||
if ($rprivs{$ENV{REMOTE_USER}}{ALLOW}) {print "<tr><td><form action='$script' method='post'><input type='hidden' name='action' value='qallow'><input type='submit' class='btn btn-default' value='Quick Allow'></td><td width='100%'>Allow IP address <input type='text' name='ip' id='allowip' value='' size='18' style='background-color: lightgreen'> through the firewall and add to the allow file (csf.allow).<br>Comment for Allow: <input type='text' name='comment' value='' size='30'> (required)</form></td></tr>\n"}
|
||||
if ($rprivs{$ENV{REMOTE_USER}}{DENY}) {print "<tr><td><form action='$script' method='post'><input type='hidden' name='action' value='qdeny'><input type='submit' class='btn btn-default' value='Quick Deny'></td><td width='100%'>Block IP address <input type='text' name='ip' value='' size='18' style='background-color: pink'> in the firewall and add to the deny file (csf.deny).<br>Comment for Block: <input type='text' name='comment' value='' size='30'> (required)</form></td></tr>\n"}
|
||||
if ($rprivs{$ENV{REMOTE_USER}}{UNBLOCK}) {print "<tr><td><form action='$script' method='post'><input type='hidden' name='action' value='qkill'><input type='submit' class='btn btn-default' value='Quick Unblock'></td><td width='100%'>Remove IP address <input type='text' name='ip' value='' size='18'> from the firewall (temp and perm blocks)</form></td></tr>\n"}
|
||||
if ($rprivs{$ENV{REMOTE_USER}}{GREP}) {print "<tr><td><form action='$script' method='post'><input type='hidden' name='action' value='grep'><input type='submit' class='btn btn-default' value='Search for IP'></td><td width='100%'>Search iptables for IP address <input type='text' name='ip' value='' size='18'></form></td></tr>\n"}
|
||||
print "</table><br>\n";
|
||||
}
|
||||
}
|
||||
|
||||
print "<br>\n";
|
||||
print "<pre>csf: v$myv</pre>";
|
||||
print "<p>©2006-2023, <a href='http://www.configserver.com' target='_blank'>ConfigServer Services</a> (Jonathan Michaelson)</p>\n";
|
||||
|
||||
return;
|
||||
}
|
||||
# end main
|
||||
###############################################################################
|
||||
# start printcmd
|
||||
sub printcmd {
|
||||
my @command = @_;
|
||||
my $text;
|
||||
my ($childin, $childout);
|
||||
my $pid = open3($childin, $childout, $childout, @command);
|
||||
while (<$childout>) {print $_ ; $text .= $_}
|
||||
waitpid ($pid, 0);
|
||||
return $text;
|
||||
}
|
||||
# end printcmd
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
2954
csf/ConfigServer/DisplayUI.pm
Normal file
2954
csf/ConfigServer/DisplayUI.pm
Normal file
File diff suppressed because it is too large
Load Diff
170
csf/ConfigServer/GetEthDev.pm
Normal file
170
csf/ConfigServer/GetEthDev.pm
Normal file
@@ -0,0 +1,170 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::GetEthDev;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Carp;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use IPC::Open3;
|
||||
use POSIX qw(locale_h);
|
||||
use ConfigServer::Config;
|
||||
use ConfigServer::CheckIP qw(checkip);
|
||||
use ConfigServer::Logger;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.01;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
my (%ifaces, %ipv4, %ipv6, %brd);
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start new
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = {};
|
||||
bless $self,$class;
|
||||
|
||||
my $status;
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
my $ipv4reg = $config->ipv4reg;
|
||||
my $ipv6reg = $config->ipv6reg;
|
||||
$brd{"255.255.255.255"} = 1;
|
||||
setlocale(LC_ALL, "POSIX");
|
||||
|
||||
if (-e $config{IP}) {
|
||||
my ($childin, $childout);
|
||||
my $pid = open3($childin, $childout, $childout, $config{IP}, "-oneline", "addr");
|
||||
my @ifconfig = <$childout>;
|
||||
waitpid ($pid, 0);
|
||||
chomp @ifconfig;
|
||||
|
||||
foreach my $line (@ifconfig) {
|
||||
if ($line =~ /^\d+:\s+([\w\.\-]+)/ ) {
|
||||
$ifaces{$1} = 1;
|
||||
}
|
||||
if ($line =~ /inet.*?($ipv4reg)/) {
|
||||
my ($ip,undef) = split(/\//,$1);
|
||||
if (checkip(\$ip)) {
|
||||
$ipv4{$ip} = 1;
|
||||
}
|
||||
}
|
||||
if ($line =~ /brd\s+($ipv4reg)/) {
|
||||
my ($ip,undef) = split(/\//,$1);
|
||||
if (checkip(\$ip)) {
|
||||
$brd{$ip} = 1;
|
||||
}
|
||||
}
|
||||
if ($line =~ /inet6.*?($ipv6reg)/) {
|
||||
my ($ip,undef) = split(/\//,$1);
|
||||
$ip .= "/128";
|
||||
if (checkip(\$ip)) {
|
||||
$ipv6{$ip} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
$status = 0;
|
||||
}
|
||||
elsif (-e $config{IFCONFIG}) {
|
||||
my ($childin, $childout);
|
||||
my $pid = open3($childin, $childout, $childout, $config{IFCONFIG});
|
||||
my @ifconfig = <$childout>;
|
||||
waitpid ($pid, 0);
|
||||
chomp @ifconfig;
|
||||
|
||||
foreach my $line (@ifconfig) {
|
||||
if ($line =~ /^([\w\.\-]+)/ ) {
|
||||
$ifaces{$1} = 1;
|
||||
}
|
||||
if ($line =~ /inet.*?($ipv4reg)/) {
|
||||
my ($ip,undef) = split(/\//,$1);
|
||||
if (checkip(\$ip)) {
|
||||
$ipv4{$ip} = 1;
|
||||
}
|
||||
}
|
||||
if ($line =~ /Bcast:($ipv4reg)/) {
|
||||
my ($ip,undef) = split(/\//,$1);
|
||||
if (checkip(\$ip)) {
|
||||
$brd{$ip} = 1;
|
||||
}
|
||||
}
|
||||
if ($line =~ /inet6.*?($ipv6reg)/) {
|
||||
my ($ip,undef) = split(/\//,$1);
|
||||
$ip .= "/128";
|
||||
if (checkip(\$ip)) {
|
||||
$ipv6{$ip} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
$status = 0;
|
||||
}
|
||||
else {
|
||||
$status = 1;
|
||||
}
|
||||
|
||||
if (-e "/var/cpanel/cpnat") {
|
||||
open (my $NAT, "<", "/var/cpanel/cpnat");
|
||||
flock ($NAT, LOCK_SH);
|
||||
while (my $line = <$NAT>) {
|
||||
chomp $line;
|
||||
if ($line =~ /^(\#|\n|\r)/) {next}
|
||||
my ($internal,$external) = split(/\s+/,$line);
|
||||
if (checkip(\$internal) and checkip(\$external)) {
|
||||
$ipv4{$external} = 1;
|
||||
}
|
||||
}
|
||||
close ($NAT);
|
||||
}
|
||||
|
||||
$self->{status} = $status;
|
||||
return $self;
|
||||
}
|
||||
# end main
|
||||
###############################################################################
|
||||
# start ifaces
|
||||
sub ifaces {
|
||||
return %ifaces;
|
||||
}
|
||||
# end ifaces
|
||||
###############################################################################
|
||||
# start ipv4
|
||||
sub ipv4 {
|
||||
return %ipv4;
|
||||
}
|
||||
# end ipv4
|
||||
###############################################################################
|
||||
# start ipv6
|
||||
sub ipv6 {
|
||||
return %ipv6;
|
||||
}
|
||||
# end ipv6
|
||||
###############################################################################
|
||||
# start brd
|
||||
sub brd {
|
||||
return %brd;
|
||||
}
|
||||
# end brd
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
95
csf/ConfigServer/GetIPs.pm
Normal file
95
csf/ConfigServer/GetIPs.pm
Normal file
@@ -0,0 +1,95 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::GetIPs;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Carp;
|
||||
use Socket;
|
||||
use IPC::Open3;
|
||||
use ConfigServer::Config;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.03;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(getips);
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
my $ipv4reg = ConfigServer::Config->ipv4reg;
|
||||
my $ipv6reg = ConfigServer::Config->ipv6reg;
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start getips
|
||||
sub getips {
|
||||
my $hostname = shift;
|
||||
my @ips;
|
||||
|
||||
if (-e $config{HOST} and -x $config{HOST}) {
|
||||
my $cmdpid;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die};
|
||||
alarm(10);
|
||||
my ($childin, $childout);
|
||||
$cmdpid = open3($childin, $childout, $childout, $config{HOST},"-W","5",$hostname);
|
||||
close $childin;
|
||||
my @results = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @results;
|
||||
|
||||
foreach my $line (@results) {
|
||||
if ($line =~ /($ipv4reg|$ipv6reg)/) {push @ips, $1}
|
||||
}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($cmdpid =~ /\d+/ and $cmdpid > 1 and kill(0,$cmdpid)) {kill(9,$cmdpid)}
|
||||
} else {
|
||||
local $SIG{__DIE__} = undef;
|
||||
eval ('use Socket6;');
|
||||
if ($@) {
|
||||
my @iplist;
|
||||
my (undef, undef, undef, undef, @addrs) = gethostbyname($hostname);
|
||||
foreach (@addrs) {push(@iplist,join(".",unpack("C4", $_)))}
|
||||
push @ips,$_ foreach(@iplist);
|
||||
} else {
|
||||
eval ('
|
||||
use Socket6;
|
||||
my @res = getaddrinfo($hostname, undef, AF_UNSPEC, SOCK_STREAM);
|
||||
while(scalar(@res)>=5){
|
||||
my $saddr;
|
||||
(undef, undef, undef, $saddr, undef, @res) = @res;
|
||||
my ($host, undef) = getnameinfo($saddr,NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
push @ips,$host;
|
||||
|
||||
}
|
||||
');
|
||||
}
|
||||
}
|
||||
|
||||
return @ips;
|
||||
}
|
||||
# end getips
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
107
csf/ConfigServer/KillSSH.pm
Normal file
107
csf/ConfigServer/KillSSH.pm
Normal file
@@ -0,0 +1,107 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::KillSSH;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use ConfigServer::Logger;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.00;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start iplookup
|
||||
sub find {
|
||||
my $ip = shift;
|
||||
my $ports = shift;
|
||||
|
||||
my %inodes;
|
||||
|
||||
if ($ports eq "" or $ip eq "") {return}
|
||||
|
||||
foreach my $proto ("tcp","tcp6") {
|
||||
open (my $IN, "<", "/proc/net/$proto");
|
||||
flock ($IN, LOCK_SH);
|
||||
while (<$IN>) {
|
||||
my @rec = split();
|
||||
if ($rec[9] =~ /uid/) {next}
|
||||
|
||||
my ($dip,$dport) = split(/:/,$rec[2]);
|
||||
$dport = hex($dport);
|
||||
|
||||
my ($sip,$sport) = split(/:/,$rec[1]);
|
||||
$sport = hex($sport);
|
||||
|
||||
$dip = &hex2ip($dip);
|
||||
$sip = &hex2ip($sip);
|
||||
|
||||
if ($sip eq '0.0.0.1') {next}
|
||||
if ($dip eq $ip) {
|
||||
foreach my $port (split(/\,/, $ports)) {
|
||||
if ($port eq $sport) {
|
||||
$inodes{$rec[9]} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
close ($IN);
|
||||
}
|
||||
|
||||
opendir (my $PROCDIR, "/proc");
|
||||
while (my $pid = readdir($PROCDIR)) {
|
||||
if ($pid !~ /^\d+$/) {next}
|
||||
opendir (DIR, "/proc/$pid/fd") or next;
|
||||
while (my $file = readdir (DIR)) {
|
||||
if ($file =~ /^\./) {next}
|
||||
my $fd = readlink("/proc/$pid/fd/$file");
|
||||
if ($fd =~ /^socket:\[?([0-9]+)\]?$/) {
|
||||
if ($inodes{$1} and readlink("/proc/$pid/exe") =~ /sshd/) {
|
||||
kill (9,$pid);
|
||||
ConfigServer::Logger::logfile("*PT_SSHDKILL*: Process PID:[$pid] killed for blocked IP:[$ip]");
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir (DIR);
|
||||
}
|
||||
closedir ($PROCDIR);
|
||||
return;
|
||||
}
|
||||
# end find
|
||||
###############################################################################
|
||||
## start hex2ip
|
||||
sub hex2ip {
|
||||
my $bin = pack "C*" => map hex, $_[0] =~ /../g;
|
||||
my @l = unpack "L*", $bin;
|
||||
if (@l == 4) {
|
||||
return join ':', map { sprintf "%x:%x", $_ >> 16, $_ & 0xffff } @l;
|
||||
}
|
||||
elsif (@l == 1) {
|
||||
return join '.', map { $_ >> 24, ($_ >> 16 ) & 0xff, ($_ >> 8) & 0xff, $_ & 0xff } @l;
|
||||
}
|
||||
}
|
||||
## end hex2ip
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
83
csf/ConfigServer/Logger.pm
Normal file
83
csf/ConfigServer/Logger.pm
Normal file
@@ -0,0 +1,83 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::Logger;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Carp;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use ConfigServer::Config;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.02;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(logfile);
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
my $hostname;
|
||||
if (-e "/proc/sys/kernel/hostname") {
|
||||
open (my $IN, "<", "/proc/sys/kernel/hostname");
|
||||
flock ($IN, LOCK_SH);
|
||||
$hostname = <$IN>;
|
||||
chomp $hostname;
|
||||
close ($IN);
|
||||
} else {
|
||||
$hostname = "unknown";
|
||||
}
|
||||
my $hostshort = (split(/\./,$hostname))[0];
|
||||
|
||||
my $sys_syslog;
|
||||
if ($config{SYSLOG}) {
|
||||
eval('use Sys::Syslog;'); ##no critic
|
||||
unless ($@) {$sys_syslog = 1}
|
||||
}
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start logfile
|
||||
sub logfile {
|
||||
my $line = shift;
|
||||
my @ts = split(/\s+/,scalar localtime);
|
||||
if ($ts[2] < 10) {$ts[2] = " ".$ts[2]}
|
||||
|
||||
my $logfile = "/var/log/lfd.log";
|
||||
if ($< != 0) {$logfile = "/var/log/lfd_messenger.log"}
|
||||
|
||||
sysopen (my $LOGFILE, $logfile, O_WRONLY | O_APPEND | O_CREAT);
|
||||
flock ($LOGFILE, LOCK_EX);
|
||||
print $LOGFILE "$ts[1] $ts[2] $ts[3] $hostshort lfd[$$]: $line\n";
|
||||
close ($LOGFILE);
|
||||
|
||||
if ($config{SYSLOG} and $sys_syslog) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
openlog('lfd', 'ndelay,pid', 'user');
|
||||
syslog('info', $line);
|
||||
closelog();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
# end logfile
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
439
csf/ConfigServer/LookUpIP.pm
Normal file
439
csf/ConfigServer/LookUpIP.pm
Normal file
@@ -0,0 +1,439 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::LookUpIP;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Carp;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use IPC::Open3;
|
||||
use JSON::Tiny;
|
||||
use Net::IP;
|
||||
use Socket;
|
||||
use ConfigServer::CheckIP qw(checkip);
|
||||
use ConfigServer::Config;
|
||||
use ConfigServer::URLGet;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 2.00;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(iplookup);
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
|
||||
my $urlget;
|
||||
if ($config{CC_LOOKUPS} == 4) {
|
||||
$urlget = ConfigServer::URLGet->new($config{URLGET}, "", $config{URLPROXY});
|
||||
unless (defined $urlget) {
|
||||
$config{URLGET} = 1;
|
||||
$urlget = ConfigServer::URLGet->new($config{URLGET}, "", $config{URLPROXY});
|
||||
}
|
||||
}
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start iplookup
|
||||
sub iplookup {
|
||||
my $ip = shift;
|
||||
my $cconly = shift;
|
||||
my $host = "-";
|
||||
my $iptype = checkip(\$ip);
|
||||
|
||||
if ($config{LF_LOOKUPS} and !$cconly) {
|
||||
my $dnsip;
|
||||
my $dnsrip;
|
||||
my $dnshost;
|
||||
my $cachehit;
|
||||
open (my $DNS, "<", "/var/lib/csf/csf.dnscache");
|
||||
flock ($DNS, LOCK_SH);
|
||||
while (my $line = <$DNS>) {
|
||||
chomp $line;
|
||||
($dnsip,$dnsrip,$dnshost) = split(/\|/,$line);
|
||||
if ($ip eq $dnsip) {
|
||||
$cachehit = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close ($DNS);
|
||||
if ($cachehit) {
|
||||
$host = $dnshost;
|
||||
} else {
|
||||
if (-e $config{HOST} and -x $config{HOST}) {
|
||||
my $cmdpid;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die};
|
||||
alarm(10);
|
||||
my ($childin, $childout);
|
||||
$cmdpid = open3($childin, $childout, $childout, $config{HOST},"-W","5",$ip);
|
||||
close $childin;
|
||||
my @results = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @results;
|
||||
if ($results[0] =~ /(\S+)\.$/) {$host = $1}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($cmdpid =~ /\d+/ and $cmdpid > 1 and kill(0,$cmdpid)) {kill(9,$cmdpid)}
|
||||
} else {
|
||||
if ($iptype == 4) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die};
|
||||
alarm(10);
|
||||
my $ipaddr = inet_aton($ip);
|
||||
$host = gethostbyaddr($ipaddr, AF_INET);
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
}
|
||||
elsif ($iptype == 6) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die};
|
||||
alarm(10);
|
||||
eval('use Socket6;'); ##no critic
|
||||
my $ipaddr = inet_pton(AF_INET6, $ip);
|
||||
$host = gethostbyaddr($ipaddr, AF_INET6);
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
}
|
||||
}
|
||||
sysopen (DNS, "/var/lib/csf/csf.dnscache", O_WRONLY | O_APPEND | O_CREAT);
|
||||
flock (DNS, LOCK_EX);
|
||||
print DNS "$ip|$ip|$host\n";
|
||||
close (DNS);
|
||||
}
|
||||
if ($host eq "") {$host = "-"}
|
||||
}
|
||||
|
||||
if (($config{CC_LOOKUPS} and $iptype == 4) or ($config{CC_LOOKUPS} and $config{CC6_LOOKUPS} and $iptype == 6)) {
|
||||
my @result;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
@result = &geo_binary($ip,$iptype);
|
||||
};
|
||||
my $asn = $result[4];
|
||||
if ($result[0] eq "") {$result[0] = "-"}
|
||||
if ($result[1] eq "") {$result[1] = "-"}
|
||||
if ($result[2] eq "") {$result[2] = "-"}
|
||||
if ($result[3] eq "") {$result[3] = "-"}
|
||||
if ($result[4] eq "") {$result[4] = "-"} else {$result[4] = "[$result[4]]"}
|
||||
if ($config{CC_LOOKUPS} == 3) {
|
||||
if ($cconly) {return ($result[0],$asn)}
|
||||
my $return = "$ip ($result[0]/$result[1]/$result[2]/$result[3]/$host/$result[4])";
|
||||
if ($result[0] eq "-") {$return = "$ip ($host)"}
|
||||
$return =~ s/'|"//g;
|
||||
return $return;
|
||||
}
|
||||
elsif ($config{CC_LOOKUPS} == 2 or $config{CC_LOOKUPS} == 4) {
|
||||
if ($cconly) {return $result[0]}
|
||||
my $return = "$ip ($result[0]/$result[1]/$result[2]/$result[3]/$host)";
|
||||
if ($result[0] eq "-") {$return = "$ip ($host)"}
|
||||
$return =~ s/'|"//g;
|
||||
return $return;
|
||||
}
|
||||
else {
|
||||
if ($cconly) {return $result[0]}
|
||||
my $return = "$ip ($result[0]/$result[1]/$host)";
|
||||
if ($result[0] eq "-") {$return = "$ip ($host)"}
|
||||
$return =~ s/'|"//g;
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
if ($config{LF_LOOKUPS}) {
|
||||
if ($host eq "-") {$host = "Unknown"}
|
||||
my $return = "$ip ($host)";
|
||||
$return =~ s/'//g;
|
||||
return $return;
|
||||
} else {
|
||||
return $ip;
|
||||
}
|
||||
}
|
||||
# end iplookup
|
||||
###############################################################################
|
||||
# start geo_binary
|
||||
sub geo_binary {
|
||||
my $myip = shift;
|
||||
my $ipv = shift;
|
||||
my @return;
|
||||
|
||||
my $netip = Net::IP->new($myip);
|
||||
my $ip = $netip->binip();
|
||||
my $type = $netip->iptype();
|
||||
if ($type eq "PRIVATE") {return}
|
||||
|
||||
if ($config{CC_LOOKUPS} == 4) {
|
||||
my ($status, $text) = $urlget->urlget("http://api.db-ip.com/v2/free/$myip");
|
||||
if ($status) {$text = ""}
|
||||
if ($text ne "") {
|
||||
my $json = JSON::Tiny::decode_json($text);
|
||||
return ($json->{countryCode},$json->{countryName},$json->{stateProv},$json->{city});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ($config{CC_SRC} eq "" or $config{CC_SRC} eq "1") {
|
||||
my $file = "/var/lib/csf/Geo/GeoLite2-Country-Blocks-IPv${ipv}.csv";
|
||||
if ($config{CC_LOOKUPS} == 2 or $config{CC_LOOKUPS} == 3) {
|
||||
$file = "/var/lib/csf/Geo/GeoLite2-City-Blocks-IPv${ipv}.csv";
|
||||
}
|
||||
my $start = 0;
|
||||
my $end = -s $file;
|
||||
$end += 4;
|
||||
my $cnt = 0;
|
||||
my $last;
|
||||
my $range;
|
||||
my $geoid;
|
||||
open (my $CSV, "<", $file);
|
||||
flock ($CSV, LOCK_SH);
|
||||
while (1) {
|
||||
my $mid = int (($end + $start) / 2);
|
||||
seek ($CSV, $mid, 0);
|
||||
my $a = <$CSV>;
|
||||
my $b = <$CSV>;
|
||||
chomp $b;
|
||||
($range,$geoid,undef) = split(/\,/,$b);
|
||||
if ($range !~ /^\d/ or $range eq $last or $range eq "") {return}
|
||||
$last = $range;
|
||||
my $netip = Net::IP->new($range);
|
||||
my $lastip = $netip->last_ip();
|
||||
$lastip = Net::IP::ip_iptobin($lastip,$ipv);
|
||||
my $firstip = $netip->ip();
|
||||
$firstip = Net::IP::ip_iptobin($firstip,$ipv);
|
||||
if (Net::IP::ip_bincomp($ip,'lt',$firstip) == 1) {
|
||||
$end = $mid;
|
||||
}
|
||||
elsif (Net::IP::ip_bincomp($ip,'gt',$lastip) == 1) {
|
||||
$start = $mid;
|
||||
} else {
|
||||
last;
|
||||
}
|
||||
$cnt++;
|
||||
if ($cnt > 200) {return}
|
||||
}
|
||||
close ($CSV);
|
||||
|
||||
if ($geoid > 0) {
|
||||
my $file = "/var/lib/csf/Geo/GeoLite2-Country-Locations-en.csv";
|
||||
if ($config{CC_LOOKUPS} == 2 or $config{CC_LOOKUPS} == 3) {
|
||||
$file = "/var/lib/csf/Geo/GeoLite2-City-Locations-en.csv";
|
||||
}
|
||||
my $start = 0;
|
||||
my $end = -s $file;
|
||||
$end += 4;
|
||||
my $cnt = 0;
|
||||
my $last;
|
||||
open (my $CSV, "<", $file);
|
||||
flock ($CSV, LOCK_SH);
|
||||
while (1) {
|
||||
my $mid = int (($end + $start) / 2);
|
||||
seek ($CSV, $mid, 0);
|
||||
my $a = <$CSV>;
|
||||
my $b = <$CSV>;
|
||||
chomp $b;
|
||||
my @bits = split(/\,/,$b);
|
||||
if ($range !~ /^\d/ or $bits[0] eq $last or $bits[0] eq "") {last}
|
||||
$last = $bits[0];
|
||||
if ($geoid < $bits[0]) {
|
||||
$end = $mid;
|
||||
}
|
||||
elsif ($geoid > $bits[0]) {
|
||||
$start = $mid + 1;
|
||||
} else {
|
||||
$b =~ s/\"//g;
|
||||
my ($geoname_id, $locale_code, $continent_code, $continent_name, $country_iso_code, $country_name, $subdivision_1_iso_code, $subdivision_1_name, $subdivision_2_iso_code, $subdivision_2_name, $city_name, $metro_code, $time_zone) = split(/\,/,$b);
|
||||
my $region = $subdivision_2_name;
|
||||
if ($region eq "" or $region eq $city_name) {$region = $subdivision_1_name}
|
||||
$return[0] = $country_iso_code;
|
||||
$return[1] = $country_name;
|
||||
$return[2] = $region;
|
||||
$return[3] = $city_name;
|
||||
last;
|
||||
}
|
||||
$cnt++;
|
||||
if ($cnt > 200) {return}
|
||||
}
|
||||
close ($CSV);
|
||||
}
|
||||
|
||||
if ($config{CC_LOOKUPS} == 3) {
|
||||
my $file = "/var/lib/csf/Geo/GeoLite2-ASN-Blocks-IPv${ipv}.csv";
|
||||
my $start = 0;
|
||||
my $end = -s $file;
|
||||
$end += 4;
|
||||
my $cnt = 0;
|
||||
my $last;
|
||||
my $range;
|
||||
my $asn;
|
||||
my $asnorg;
|
||||
open (my $CSV, "<", $file);
|
||||
flock ($CSV, LOCK_SH);
|
||||
while (1) {
|
||||
my $mid = int (($end + $start) / 2);
|
||||
seek ($CSV, $mid, 0);
|
||||
my $a = <$CSV>;
|
||||
my $b = <$CSV>;
|
||||
chomp $b;
|
||||
($range,$asn,$asnorg) = split(/\,/,$b,3);
|
||||
if ($range !~ /^\d/ or $range eq $last or $range eq "") {last}
|
||||
$last = $range;
|
||||
my $netip = Net::IP->new($range);
|
||||
my $lastip = $netip->last_ip();
|
||||
$lastip = Net::IP::ip_iptobin($lastip,$ipv);
|
||||
my $firstip = $netip->ip();
|
||||
$firstip = Net::IP::ip_iptobin($firstip,$ipv);
|
||||
if (Net::IP::ip_bincomp($ip,'lt',$firstip) == 1) {
|
||||
$end = $mid;
|
||||
}
|
||||
elsif (Net::IP::ip_bincomp($ip,'gt',$lastip) == 1) {
|
||||
$start = $mid + 1;
|
||||
} else {
|
||||
$return[4] = "AS$asn $asnorg";
|
||||
last;
|
||||
}
|
||||
$cnt++;
|
||||
if ($cnt > 200) {last}
|
||||
}
|
||||
close ($CSV);
|
||||
}
|
||||
} elsif ($config{CC_SRC} eq "2") {
|
||||
my %country_name;
|
||||
open (my $CC, "<", "/var/lib/csf/Geo/countryInfo.txt");
|
||||
flock ($CC, LOCK_SH);
|
||||
foreach my $line (<$CC>) {
|
||||
if ($line eq "" or $line =~ /^\#/ or $line =~ /^\s/) {next}
|
||||
my ($cc,undef,undef,undef,$country,undef) = split(/\t/, $line);
|
||||
if ($cc ne "" and $country ne "") {$country_name{$cc} = $country}
|
||||
}
|
||||
close ($CC);
|
||||
|
||||
my $file = "/var/lib/csf/Geo/dbip-country-lite.csv";
|
||||
if ($config{CC_LOOKUPS} == 2 or $config{CC_LOOKUPS} == 3) {
|
||||
$file = "/var/lib/csf/Geo/dbip-city-lite.csv";
|
||||
}
|
||||
my $start = 0;
|
||||
my $end = -s $file;
|
||||
$end += 4;
|
||||
my $cnt = 0;
|
||||
my $last;
|
||||
my $range;
|
||||
my $geoid;
|
||||
open (my $CSV, "<", $file);
|
||||
flock ($CSV, LOCK_SH);
|
||||
while (1) {
|
||||
my $mid = int (($end + $start) / 2);
|
||||
seek ($CSV, $mid, 0);
|
||||
my $a = <$CSV>;
|
||||
my $b = <$CSV>;
|
||||
chomp $b;
|
||||
my ($firstip,$lastip,$cc_lookups1,$country_iso_code,$region,$city_name,undef) = split(/\,/,$b);
|
||||
if ($firstip eq $lastip or $firstip eq "") {return}
|
||||
if (checkip(\$firstip) ne $ipv) {
|
||||
if ($ipv eq "6") {
|
||||
$start = $mid;
|
||||
} else {
|
||||
$end = $mid;
|
||||
}
|
||||
} else {
|
||||
my $netfirstip = Net::IP->new($firstip);
|
||||
my $firstip = $netfirstip->binip();
|
||||
my $netlastip = Net::IP->new($lastip);
|
||||
my $lastip = $netlastip->binip();
|
||||
if (Net::IP::ip_bincomp($ip,'lt',$firstip) == 1) {
|
||||
$end = $mid;
|
||||
}
|
||||
elsif (Net::IP::ip_bincomp($ip,'gt',$lastip) == 1) {
|
||||
$start = $mid + 1;
|
||||
} else {
|
||||
if ($config{CC_LOOKUPS} == 1) {$country_iso_code = $cc_lookups1}
|
||||
if ($country_iso_code eq "ZZ") {last}
|
||||
$return[0] = $country_iso_code;
|
||||
$return[1] = $country_name{$country_iso_code};
|
||||
$return[2] = $region;
|
||||
$return[3] = $city_name;
|
||||
last;
|
||||
}
|
||||
}
|
||||
$cnt++;
|
||||
if ($cnt > 200) {return}
|
||||
}
|
||||
close ($CSV);
|
||||
|
||||
if ($config{CC_LOOKUPS} == 3) {
|
||||
my $file = "/var/lib/csf/Geo/ip2asn-combined.tsv";
|
||||
my $start = 0;
|
||||
my $end = -s $file;
|
||||
$end += 4;
|
||||
my $cnt = 0;
|
||||
my $last;
|
||||
my $range;
|
||||
my $asn;
|
||||
my $asnorg;
|
||||
open (my $CSV, "<", $file);
|
||||
flock ($CSV, LOCK_SH);
|
||||
while (1) {
|
||||
my $mid = int (($end + $start) / 2);
|
||||
seek ($CSV, $mid, 0);
|
||||
my $a = <$CSV>;
|
||||
my $b = <$CSV>;
|
||||
chomp $b;
|
||||
my ($firstip,$lastip,$asn,undef,$asnorg) = split(/\t/,$b);
|
||||
if ($firstip eq $lastip or $firstip eq "") {last}
|
||||
if (checkip(\$firstip) ne $ipv) {
|
||||
if ($ipv eq "6") {
|
||||
$start = $mid;
|
||||
} else {
|
||||
$end = $mid;
|
||||
}
|
||||
} else {
|
||||
my $netfirstip = Net::IP->new($firstip);
|
||||
my $firstip = $netfirstip->binip();
|
||||
my $netlastip = Net::IP->new($lastip);
|
||||
my $lastip = $netlastip->binip();
|
||||
if (Net::IP::ip_bincomp($ip,'lt',$firstip) == 1) {
|
||||
$end = $mid;
|
||||
}
|
||||
elsif (Net::IP::ip_bincomp($ip,'gt',$lastip) == 1) {
|
||||
$start = $mid + 1;
|
||||
} else {
|
||||
if ($asn eq "0") {last}
|
||||
$return[4] = "AS$asn $asnorg";
|
||||
last;
|
||||
}
|
||||
}
|
||||
$cnt++;
|
||||
if ($cnt > 200) {last}
|
||||
}
|
||||
close ($CSV);
|
||||
}
|
||||
}
|
||||
return @return;
|
||||
}
|
||||
# end geo_binary
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
1290
csf/ConfigServer/Messenger.pm
Normal file
1290
csf/ConfigServer/Messenger.pm
Normal file
File diff suppressed because it is too large
Load Diff
226
csf/ConfigServer/Ports.pm
Normal file
226
csf/ConfigServer/Ports.pm
Normal file
@@ -0,0 +1,226 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::Ports;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use ConfigServer::Config;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.02;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
my %printable = ( ( map { chr($_), unpack('H2', chr($_)) } (0..255) ), "\\"=>'\\', "\r"=>'r', "\n"=>'n', "\t"=>'t', "\""=>'"' ); ##no critic
|
||||
my %tcpstates = ("01" => "ESTABLISHED",
|
||||
"02" => "SYN_SENT",
|
||||
"03" => "SYN_RECV",
|
||||
"04" => "FIN_WAIT1",
|
||||
"05" => "FIN_WAIT2",
|
||||
"06" => "TIME_WAIT",
|
||||
"07" => "CLOSE",
|
||||
"08" => "CLOSE_WAIT",
|
||||
"09" => "LAST_ACK",
|
||||
"0A" => "LISTEN",
|
||||
"0B" => "CLOSING");
|
||||
# end main
|
||||
###############################################################################
|
||||
# start listening
|
||||
sub listening {
|
||||
my %net;
|
||||
my %conn;
|
||||
my %listen;
|
||||
|
||||
foreach my $proto ("tcp","udp","tcp6","udp6") {
|
||||
open (my $IN, "<","/proc/net/$proto");
|
||||
flock ($IN, LOCK_SH);
|
||||
while (<$IN>) {
|
||||
my @rec = split();
|
||||
if ($rec[9] =~ /uid/) {next}
|
||||
|
||||
my ($dip,$dport) = split(/:/,$rec[1]);
|
||||
$dport = hex($dport);
|
||||
|
||||
my ($sip,$sport) = split(/:/,$rec[2]);
|
||||
$sport = hex($sport);
|
||||
|
||||
$dip = &hex2ip($dip);
|
||||
$sip = &hex2ip($sip);
|
||||
|
||||
my $inode = $rec[9];
|
||||
my $state = $tcpstates{$rec[3]};
|
||||
my $protocol = $proto;
|
||||
$protocol =~ s/6//;
|
||||
if ($protocol eq "udp" and $state eq "CLOSE") {$state = "LISTEN"}
|
||||
|
||||
if ($state eq "ESTABLISHED") {$conn{$dport}{$protocol}++}
|
||||
|
||||
if ($dip =~ /^127\./) {next}
|
||||
if ($dip =~ /^0\.0\.0\.1/) {next}
|
||||
if ($state eq "LISTEN") {$net{$inode}{$protocol} = $dport}
|
||||
}
|
||||
close ($IN);
|
||||
}
|
||||
|
||||
opendir (PROCDIR, "/proc");
|
||||
while (my $pid = readdir(PROCDIR)) {
|
||||
if ($pid !~ /^\d+$/) {next}
|
||||
my $exe = readlink("/proc/$pid/exe") || "";
|
||||
my $cwd = readlink("/proc/$pid/cwd") || "";
|
||||
my $uid;
|
||||
my $user;
|
||||
|
||||
if (defined $exe) {$exe =~ s/([\r\n\t\"\\\x00-\x1f\x7F-\xFF])/\\$printable{$1}/sg}
|
||||
open (my $CMDLINE,"<","/proc/$pid/cmdline");
|
||||
flock ($CMDLINE, LOCK_SH);
|
||||
my $cmdline = <$CMDLINE>;
|
||||
close ($CMDLINE);
|
||||
if (defined $cmdline) {
|
||||
chomp $cmdline;
|
||||
$cmdline =~ s/\0$//g;
|
||||
$cmdline =~ s/\0/ /g;
|
||||
$cmdline =~ s/([\r\n\t\"\\\x00-\x1f\x7F-\xFF])/\\$printable{$1}/sg;
|
||||
$cmdline =~ s/\s+$//;
|
||||
$cmdline =~ s/^\s+//;
|
||||
}
|
||||
if ($exe eq "") {next}
|
||||
my @fd;
|
||||
opendir (DIR, "/proc/$pid/fd") or next;
|
||||
while (my $file = readdir (DIR)) {
|
||||
if ($file =~ /^\./) {next}
|
||||
push (@fd, readlink("/proc/$pid/fd/$file"));
|
||||
}
|
||||
closedir (DIR);
|
||||
open (my $STATUS,"<", "/proc/$pid/status") or next;
|
||||
flock ($STATUS, LOCK_SH);
|
||||
my @status = <$STATUS>;
|
||||
close ($STATUS);
|
||||
chomp @status;
|
||||
foreach my $line (@status) {
|
||||
if ($line =~ /^Uid:(.*)/) {
|
||||
my $uidline = $1;
|
||||
my @uids;
|
||||
foreach my $bit (split(/\s/,$uidline)) {
|
||||
if ($bit =~ /^(\d*)$/) {push @uids, $1}
|
||||
}
|
||||
$uid = $uids[-1];
|
||||
$user = getpwuid($uid);
|
||||
if ($user eq "") {$user = $uid}
|
||||
}
|
||||
}
|
||||
|
||||
my $files;
|
||||
my $sockets;
|
||||
foreach my $file (@fd) {
|
||||
if ($file =~ /^socket:\[?([0-9]+)\]?$/) {
|
||||
my $ino = $1;
|
||||
if ($net{$ino}) {
|
||||
foreach my $protocol (keys %{$net{$ino}}) {
|
||||
$listen{$protocol}{$net{$ino}{$protocol}}{$pid}{user} = $user;
|
||||
$listen{$protocol}{$net{$ino}{$protocol}}{$pid}{exe} = $exe;
|
||||
$listen{$protocol}{$net{$ino}{$protocol}}{$pid}{cmd} = $cmdline;
|
||||
$listen{$protocol}{$net{$ino}{$protocol}}{$pid}{cmd} = $cmdline;
|
||||
$listen{$protocol}{$net{$ino}{$protocol}}{$pid}{conn} = $conn{$net{$ino}{$protocol}}{$protocol} | "-";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
closedir (PROCDIR);
|
||||
return %listen;
|
||||
}
|
||||
# end listening
|
||||
###############################################################################
|
||||
# start openports
|
||||
sub openports {
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
my %ports;
|
||||
|
||||
$config{TCP_IN} =~ s/\s//g;
|
||||
foreach my $entry (split(/,/,$config{TCP_IN})) {
|
||||
if ($entry =~ /^(\d+):(\d+)$/) {
|
||||
my $from = $1;
|
||||
my $to = $2;
|
||||
for (my $port = $from; $port < $to ; $port++) {
|
||||
$ports{tcp}{$port} = 1;
|
||||
}
|
||||
} else {
|
||||
$ports{tcp}{$entry} = 1;
|
||||
}
|
||||
}
|
||||
$config{TCP6_IN} =~ s/\s//g;
|
||||
foreach my $entry (split(/,/,$config{TCP6_IN})) {
|
||||
if ($entry =~ /^(\d+):(\d+)$/) {
|
||||
my $from = $1;
|
||||
my $to = $2;
|
||||
for (my $port = $from; $port < $to ; $port++) {
|
||||
$ports{tcp6}{$port} = 1;
|
||||
}
|
||||
} else {
|
||||
$ports{tcp6}{$entry} = 1;
|
||||
}
|
||||
}
|
||||
$config{UDP_IN} =~ s/\s//g;
|
||||
foreach my $entry (split(/,/,$config{UDP_IN})) {
|
||||
if ($entry =~ /^(\d+):(\d+)$/) {
|
||||
my $from = $1;
|
||||
my $to = $2;
|
||||
for (my $port = $from; $port < $to ; $port++) {
|
||||
$ports{udp}{$port} = 1;
|
||||
}
|
||||
} else {
|
||||
$ports{udp}{$entry} = 1;
|
||||
}
|
||||
}
|
||||
$config{UDP6_IN} =~ s/\s//g;
|
||||
foreach my $entry (split(/,/,$config{UDP6_IN})) {
|
||||
if ($entry =~ /^(\d+):(\d+)$/) {
|
||||
my $from = $1;
|
||||
my $to = $2;
|
||||
for (my $port = $from; $port < $to ; $port++) {
|
||||
$ports{udp6}{$port} = 1;
|
||||
}
|
||||
} else {
|
||||
$ports{udp6}{$entry} = 1;
|
||||
}
|
||||
}
|
||||
return %ports;
|
||||
}
|
||||
# end openports
|
||||
###############################################################################
|
||||
## start hex2ip
|
||||
sub hex2ip {
|
||||
my $bin = pack "C*" => map hex, $_[0] =~ /../g;
|
||||
my @l = unpack "L*", $bin;
|
||||
if (@l == 4) {
|
||||
return join ':', map { sprintf "%x:%x", $_ >> 16, $_ & 0xffff } @l;
|
||||
}
|
||||
elsif (@l == 1) {
|
||||
return join '.', map { $_ >> 24, ($_ >> 16 ) & 0xff, ($_ >> 8) & 0xff, $_ & 0xff } @l;
|
||||
}
|
||||
}
|
||||
## end hex2ip
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
255
csf/ConfigServer/RBLCheck.pm
Normal file
255
csf/ConfigServer/RBLCheck.pm
Normal file
@@ -0,0 +1,255 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::RBLCheck;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use ConfigServer::Config;
|
||||
use ConfigServer::CheckIP qw(checkip);
|
||||
use ConfigServer::Slurp qw(slurp);
|
||||
use ConfigServer::GetIPs qw(getips);
|
||||
use ConfigServer::RBLLookup qw(rbllookup);
|
||||
use IPC::Open3;
|
||||
use Net::IP;
|
||||
use ConfigServer::GetEthDev;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.01;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
my ($ui, $failures, $verbose, $cleanreg, $status, %ips, $images, %config,
|
||||
$ipresult, $output);
|
||||
|
||||
my $ipv4reg = ConfigServer::Config->ipv4reg;
|
||||
my $ipv6reg = ConfigServer::Config->ipv6reg;
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start report
|
||||
sub report {
|
||||
$verbose = shift;
|
||||
$images = shift;
|
||||
$ui = shift;
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
%config = $config->config();
|
||||
$cleanreg = ConfigServer::Slurp->cleanreg;
|
||||
$failures = 0;
|
||||
|
||||
$| = 1;
|
||||
|
||||
&startoutput;
|
||||
|
||||
&getethdev;
|
||||
|
||||
my @RBLS = slurp("/usr/local/csf/lib/csf.rbls");
|
||||
|
||||
if (-e "/etc/csf/csf.rblconf") {
|
||||
my @entries = slurp("/etc/csf/csf.rblconf");
|
||||
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}
|
||||
if ($line =~ /^enablerbl:(.*)$/) {
|
||||
push @RBLS, $1;
|
||||
}
|
||||
elsif ($line =~ /^disablerbl:(.*)$/) {
|
||||
my $hit = $1;
|
||||
for (0..@RBLS) {
|
||||
my $x = $_;
|
||||
my ($rbl,$rblurl) = split(/:/,$RBLS[$x],2);
|
||||
if ($rbl eq $hit) {$RBLS[$x] = ""}
|
||||
}
|
||||
}
|
||||
if ($line =~ /^enableip:(.*)$/) {
|
||||
if (checkip(\$1)) {$ips{$1} = 1}
|
||||
}
|
||||
elsif ($line =~ /^disableip:(.*)$/) {
|
||||
if (checkip(\$1)) {delete $ips{$1}}
|
||||
}
|
||||
}
|
||||
}
|
||||
@RBLS = sort @RBLS;
|
||||
|
||||
foreach my $ip (sort keys %ips) {
|
||||
my $netip = Net::IP->new($ip);
|
||||
my $type = $netip->iptype();
|
||||
if ($type eq "PUBLIC") {
|
||||
|
||||
if ($verbose and -e "/var/lib/csf/${ip}.rbls") {
|
||||
unlink "/var/lib/csf/${ip}.rbls";
|
||||
}
|
||||
|
||||
if (-e "/var/lib/csf/${ip}.rbls") {
|
||||
my $text = join("\n",slurp("/var/lib/csf/${ip}.rbls"));
|
||||
if ($ui) {print $text} else {$output .= $text}
|
||||
} else {
|
||||
if ($verbose) {
|
||||
$ipresult = "";
|
||||
my $hits = 0;
|
||||
&addtitle("Checked $ip ($type) on ".localtime());
|
||||
|
||||
foreach my $line (@RBLS) {
|
||||
my ($rbl,$rblurl) = split(/:/,$line,2);
|
||||
if ($rbl eq "") {next}
|
||||
|
||||
my ($rblhit,$rbltxt) = rbllookup($ip,$rbl);
|
||||
my @tmptxt = $rbltxt;
|
||||
$rbltxt = "";
|
||||
foreach my $line (@tmptxt) {
|
||||
$line =~ s/(http(\S+))/<a target="_blank" href="$1">$1<\/a>/g;
|
||||
$rbltxt .= "${line}\n";
|
||||
}
|
||||
$rbltxt =~ s/\n/<br>\n/g;
|
||||
|
||||
if ($rblhit eq "timeout") {
|
||||
&addline(0,$rbl,$rblurl,"TIMEOUT");
|
||||
}
|
||||
elsif ($rblhit eq "") {
|
||||
if ($verbose == 2) {
|
||||
&addline(0,$rbl,$rblurl,"OK");
|
||||
}
|
||||
}
|
||||
else {
|
||||
&addline(1,$rbl,$rblurl,$rbltxt);
|
||||
$hits++;
|
||||
}
|
||||
}
|
||||
unless ($hits) {
|
||||
my $text;
|
||||
$text .= "<div style='clear: both;background: #BDECB6;padding: 8px;border: 1px solid #DDDDDD;'>OK</div>\n";
|
||||
if ($ui) {print $text} else {$output .= $text}
|
||||
$ipresult .= $text;
|
||||
}
|
||||
sysopen (my $OUT, "/var/lib/csf/${ip}.rbls", O_WRONLY | O_CREAT);
|
||||
flock($OUT, LOCK_EX);
|
||||
print $OUT $ipresult;
|
||||
close ($OUT);
|
||||
} else {
|
||||
&addtitle("New $ip ($type)");
|
||||
my $text;
|
||||
$text .= "<div style='clear: both;background: #FFD1DC;padding: 8px;border: 1px solid #DDDDDD;'>Not Checked</div>\n";
|
||||
if ($ui) {print $text} else {$output .= $text}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($verbose == 2) {
|
||||
&addtitle("Skipping $ip ($type)");
|
||||
my $text;
|
||||
$text .= "<div style='clear: both;background: #BDECB6;padding: 8px;border: 1px solid #DDDDDD;'>OK</div>\n";
|
||||
if ($ui) {print $text} else {$output .= $text}
|
||||
}
|
||||
}
|
||||
}
|
||||
&endoutput;
|
||||
|
||||
return ($failures,$output);
|
||||
}
|
||||
# end report
|
||||
###############################################################################
|
||||
# start startoutput
|
||||
sub startoutput {
|
||||
return;
|
||||
}
|
||||
# end startoutput
|
||||
###############################################################################
|
||||
# start addline
|
||||
sub addline {
|
||||
my $status = shift;
|
||||
my $rbl = shift;
|
||||
my $rblurl = shift;
|
||||
my $comment = shift;
|
||||
my $text;
|
||||
my $check = $rbl;
|
||||
if ($rblurl ne "") {$check = "<a href='$rblurl' target='_blank'>$rbl</a>"}
|
||||
|
||||
if ($status) {
|
||||
$text .= "<div style='display: flex;width: 100%;clear: both;'>\n";
|
||||
$text .= "<div style='width: 250px;background: #FFD1DC;padding: 8px;border-bottom: 1px solid #DDDDDD;border-left: 1px solid #DDDDDD;border-right: 1px solid #DDDDDD;'>$check</div>\n";
|
||||
$text .= "<div style='flex: 1;padding: 8px;border-bottom: 1px solid #DDDDDD;border-right: 1px solid #DDDDDD;'>$comment</div>\n";
|
||||
$text .= "</div>\n";
|
||||
$failures ++;
|
||||
$ipresult .= $text;
|
||||
}
|
||||
elsif ($verbose) {
|
||||
$text .= "<div style='display: flex;width: 100%;clear: both;'>\n";
|
||||
$text .= "<div style='width: 250px;background: #BDECB6;padding: 8px;border-bottom: 1px solid #DDDDDD;border-left: 1px solid #DDDDDD;border-right: 1px solid #DDDDDD;'>$check</div>\n";
|
||||
$text .= "<div style='flex: 1;padding: 8px;border-bottom: 1px solid #DDDDDD;border-right: 1px solid #DDDDDD;'>$comment</div>\n";
|
||||
$text .= "</div>\n";
|
||||
}
|
||||
if ($ui) {print $text} else {$output .= $text}
|
||||
|
||||
return;
|
||||
}
|
||||
# end addline
|
||||
###############################################################################
|
||||
# start addtitle
|
||||
sub addtitle {
|
||||
my $title = shift;
|
||||
my $text;
|
||||
|
||||
$text .= "<br><div style='clear: both;padding: 8px;background: #F4F4EA;border: 1px solid #DDDDDD;border-top-right-radius: 5px;border-top-left-radius: 5px;'><strong>$title</strong></div>\n";
|
||||
|
||||
$ipresult .= $text;
|
||||
if ($ui) {print $text} else {$output .= $text}
|
||||
|
||||
return;
|
||||
}
|
||||
# end addtitle
|
||||
###############################################################################
|
||||
# start endoutput
|
||||
sub endoutput {
|
||||
if ($ui) {print "<br>\n"} else {$output .= "<br>\n"}
|
||||
|
||||
return;
|
||||
}
|
||||
# end endoutput
|
||||
###############################################################################
|
||||
# start getethdev
|
||||
sub getethdev {
|
||||
my $ethdev = ConfigServer::GetEthDev->new();
|
||||
my %g_ipv4 = $ethdev->ipv4;
|
||||
my %g_ipv6 = $ethdev->ipv6;
|
||||
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);
|
||||
# };
|
||||
# }
|
||||
# }
|
||||
|
||||
return;
|
||||
}
|
||||
# end getethdev
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
116
csf/ConfigServer/RBLLookup.pm
Normal file
116
csf/ConfigServer/RBLLookup.pm
Normal file
@@ -0,0 +1,116 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::RBLLookup;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use IPC::Open3;
|
||||
use Net::IP;
|
||||
use ConfigServer::Config;
|
||||
use ConfigServer::CheckIP qw(checkip);
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.01;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(rbllookup);
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
my $ipv4reg = ConfigServer::Config->ipv4reg;
|
||||
my $ipv6reg = ConfigServer::Config->ipv6reg;
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start rbllookup
|
||||
sub rbllookup {
|
||||
my $ip = shift;
|
||||
my $rbl = shift;
|
||||
my %rblhits;
|
||||
my $netip;
|
||||
my $reversed_ip;
|
||||
my $timeout = 4;
|
||||
my $rblhit;
|
||||
my $rblhittxt;
|
||||
|
||||
if (checkip(\$ip)) {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
$netip = Net::IP->new($ip);
|
||||
$reversed_ip = $netip->reverse_ip();
|
||||
};
|
||||
|
||||
if ($reversed_ip =~ /^(\S+)\.in-addr\.arpa/) {$reversed_ip = $1}
|
||||
if ($reversed_ip =~ /^(\S+)\s+(\S+)\.in-addr\.arpa/) {$reversed_ip = $2}
|
||||
if ($reversed_ip =~ /^(\S+)\.ip6\.arpa/) {$reversed_ip = $1}
|
||||
if ($reversed_ip =~ /^(\S+)\s+(\S+)\.ip6\.arpa/) {$reversed_ip = $2}
|
||||
|
||||
if ($reversed_ip ne "") {
|
||||
my $lookup_ip = $reversed_ip.".".$rbl;
|
||||
|
||||
my $cmdpid;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die};
|
||||
alarm($timeout);
|
||||
my ($childin, $childout);
|
||||
$cmdpid = open3($childin, $childout, $childout, $config{HOST},"-t","A",$lookup_ip);
|
||||
close $childin;
|
||||
my @results = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @results;
|
||||
if ($results[0] =~ /^${reversed_ip}.+ ($ipv4reg|$ipv6reg)$/) {$rblhit = $1}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($@) {$rblhit = "timeout"}
|
||||
if ($cmdpid =~ /\d+/ and $cmdpid > 1 and kill(0,$cmdpid)) {kill(9,$cmdpid)}
|
||||
|
||||
if ($rblhit ne "") {
|
||||
if ($rblhit ne "timeout") {
|
||||
my $cmdpid;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die};
|
||||
alarm($timeout);
|
||||
my ($childin, $childout);
|
||||
$cmdpid = open3($childin, $childout, $childout, $config{HOST},"-t","TXT",$lookup_ip);
|
||||
close $childin;
|
||||
my @results = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @results;
|
||||
foreach my $line (@results) {
|
||||
if ($line =~ /^${reversed_ip}.+ "([^\"]+)"$/) {$rblhittxt .= "$1\n"}
|
||||
}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($cmdpid =~ /\d+/ and $cmdpid > 1 and kill(0,$cmdpid)) {kill(9,$cmdpid)}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ($rblhit,$rblhittxt);
|
||||
}
|
||||
# end rbllookup
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
1028
csf/ConfigServer/RegexMain.pm
Normal file
1028
csf/ConfigServer/RegexMain.pm
Normal file
File diff suppressed because it is too large
Load Diff
86
csf/ConfigServer/Sanity.pm
Normal file
86
csf/ConfigServer/Sanity.pm
Normal file
@@ -0,0 +1,86 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::Sanity;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use Carp;
|
||||
use ConfigServer::Config;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.02;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(sanity);
|
||||
|
||||
my %sanity;
|
||||
my %sanitydefault;
|
||||
my $sanityfile = "/usr/local/csf/lib/sanity.txt";
|
||||
|
||||
open (my $IN, "<", $sanityfile);
|
||||
flock ($IN, LOCK_SH);
|
||||
my @data = <$IN>;
|
||||
close ($IN);
|
||||
chomp @data;
|
||||
foreach my $line (@data) {
|
||||
my ($name,$value,$def) = split(/\=/,$line);
|
||||
$sanity{$name} = $value;
|
||||
$sanitydefault{$name} = $def;
|
||||
}
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
|
||||
if ($config{IPSET}) {
|
||||
delete $sanity{"DENY_IP_LIMIT"};
|
||||
delete $sanitydefault{"DENY_IP_LIMIT"};
|
||||
}
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start sanity
|
||||
sub sanity {
|
||||
my $sanity_item = shift;
|
||||
my $sanity_value = shift;
|
||||
my $insane = 0;
|
||||
|
||||
$sanity_item =~ s/\s//g;
|
||||
$sanity_value =~ s/\s//g;
|
||||
|
||||
if (defined $sanity{$sanity_item}) {
|
||||
$insane = 1;
|
||||
foreach my $check (split(/\|/,$sanity{$sanity_item})) {
|
||||
if ($check =~ /-/) {
|
||||
my ($from,$to) = split(/\-/,$check);
|
||||
if (($sanity_value >= $from) and ($sanity_value <= $to)) {$insane = 0}
|
||||
|
||||
} else {
|
||||
if ($sanity_value eq $check) {$insane = 0}
|
||||
}
|
||||
}
|
||||
$sanity{$sanity_item} =~ s/\|/ or /g;
|
||||
}
|
||||
return ($insane,$sanity{$sanity_item},$sanitydefault{$sanity_item});
|
||||
}
|
||||
# end sanity
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
179
csf/ConfigServer/Sendmail.pm
Normal file
179
csf/ConfigServer/Sendmail.pm
Normal file
@@ -0,0 +1,179 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::Sendmail;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Carp;
|
||||
use POSIX qw(strftime);
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use ConfigServer::Config;
|
||||
use ConfigServer::CheckIP qw(checkip);
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.02;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
my $tz = strftime("%z", localtime);
|
||||
my $hostname;
|
||||
if (-e "/proc/sys/kernel/hostname") {
|
||||
open (my $IN, "<", "/proc/sys/kernel/hostname");
|
||||
flock ($IN, LOCK_SH);
|
||||
$hostname = <$IN>;
|
||||
chomp $hostname;
|
||||
close ($IN);
|
||||
} else {
|
||||
$hostname = "unknown";
|
||||
}
|
||||
|
||||
if ($config{LF_ALERT_SMTP}) {
|
||||
require Net::SMTP;
|
||||
import Net::SMTP;
|
||||
}
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start sendmail
|
||||
sub relay {
|
||||
my ($to, $from, @message) = @_;
|
||||
my $time = localtime(time);
|
||||
if ($to eq "") {$to = $config{LF_ALERT_TO}} else {$config{LF_ALERT_TO} = $to}
|
||||
if ($from eq "") {$from = $config{LF_ALERT_FROM}} else {$config{LF_ALERT_FROM} = $from}
|
||||
my $data;
|
||||
|
||||
if ($from =~ /([\w\.\=\-\_]+\@[\w\.\-\_]+)/) {$from = $1}
|
||||
if ($from eq "") {$from = "root"}
|
||||
if ($to =~ /([\w\.\=\-\_]+\@[\w\.\-\_]+)/) {$to = $1}
|
||||
if ($to eq "") {$to = "root"}
|
||||
|
||||
my $header = 1;
|
||||
foreach my $line (@message) {
|
||||
$line =~ s/\r//;
|
||||
if ($line eq "") {$header = 0}
|
||||
$line =~ s/\[time\]/$time $tz/ig;
|
||||
$line =~ s/\[hostname\]/$hostname/ig;
|
||||
if ($header) {
|
||||
if ($line =~ /^To:\s*(.*)\s*$/i) {
|
||||
my $totxt = $1;
|
||||
if ($config{LF_ALERT_TO} ne "") {
|
||||
$line =~ s/^To:.*$/To: $config{LF_ALERT_TO}/i;
|
||||
} else {
|
||||
$to = $totxt;
|
||||
}
|
||||
}
|
||||
if ($line =~ /^From:\s*(.*)\s*$/i) {
|
||||
my $fromtxt = $1;
|
||||
if ($config{LF_ALERT_FROM} ne "") {
|
||||
$line =~ s/^From:.*$/From: $config{LF_ALERT_FROM}/i;
|
||||
} else {
|
||||
$from = $1;
|
||||
}
|
||||
}
|
||||
}
|
||||
$data .= $line."\n";
|
||||
}
|
||||
|
||||
$data = &wraptext($data, 990);
|
||||
|
||||
if ($config{LF_ALERT_SMTP}) {
|
||||
if ($from !~ /\@/) {$from .= '@'.$hostname}
|
||||
if ($to !~ /\@/) {$to .= '@'.$hostname}
|
||||
my $smtp = Net::SMTP->new($config{LF_ALERT_SMTP}, Timeout => 10) or carp("Unable to send SMTP alert via [$config{LF_ALERT_SMTP}]: $!");
|
||||
if (defined $smtp) {
|
||||
$smtp->mail($from);
|
||||
$smtp->to($to);
|
||||
$smtp->data();
|
||||
$smtp->datasend($data);
|
||||
$smtp->dataend();
|
||||
$smtp->quit();
|
||||
}
|
||||
} else {
|
||||
local $SIG{CHLD} = 'DEFAULT';
|
||||
my $error = 0;
|
||||
open (my $MAIL, "|-", "$config{SENDMAIL} -f $from -t") or carp("Unable to send SENDMAIL alert via [$config{SENDMAIL}]: $!");
|
||||
print $MAIL $data;
|
||||
close ($MAIL) or $error = 1;
|
||||
if ($error and $config{DEBUG}) {
|
||||
logfile("Failed to send message via sendmail binary: $?");
|
||||
logfile("Failed message: [$data]");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
# end sendmail
|
||||
###############################################################################
|
||||
# start wraptext
|
||||
sub wraptext {
|
||||
my $text = shift;
|
||||
my $column = shift;
|
||||
my $original = $text;
|
||||
my $return = "";
|
||||
my $hit = 1;
|
||||
my $loop = 0;
|
||||
while ($hit) {
|
||||
$hit = 0;
|
||||
$return = "";
|
||||
foreach my $line (split(/\n/, $text)) {
|
||||
if (length($line) > $column) {
|
||||
foreach ($line =~ /(.{1,$column})/g) {
|
||||
my $chunk = $_;
|
||||
my $newchunk = "";
|
||||
my $thishit = 0;
|
||||
my @chars = split(//,$chunk);
|
||||
for (my $x = length($chunk)-1;$x >= 0; $x--) {
|
||||
if ($chars[$x] =~ /\s/) {
|
||||
for (0..$x) {$newchunk .= $chars[$_]}
|
||||
$newchunk .= "\n";
|
||||
for ($x+1..length($chunk)-1) {$newchunk .= $chars[$_]}
|
||||
$thishit = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ($thishit) {
|
||||
$hit = 1;
|
||||
$thishit = 0;
|
||||
$return .= $newchunk;
|
||||
} else {
|
||||
$return .= $chunk."\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$return .= $line."\n";
|
||||
}
|
||||
}
|
||||
$text = $return;
|
||||
$loop++;
|
||||
if ($loop > 1000) {
|
||||
return $original;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if (length($return) < length($original)) {$return = $original}
|
||||
return $return;
|
||||
}
|
||||
# end wraptext
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
1775
csf/ConfigServer/ServerCheck.pm
Normal file
1775
csf/ConfigServer/ServerCheck.pm
Normal file
File diff suppressed because it is too large
Load Diff
3560
csf/ConfigServer/ServerStats.pm
Normal file
3560
csf/ConfigServer/ServerStats.pm
Normal file
File diff suppressed because it is too large
Load Diff
131
csf/ConfigServer/Service.pm
Normal file
131
csf/ConfigServer/Service.pm
Normal file
@@ -0,0 +1,131 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::Service;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Carp;
|
||||
use IPC::Open3;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use ConfigServer::Config;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.01;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
|
||||
open (my $IN, "<", "/proc/1/comm");
|
||||
flock ($IN, LOCK_SH);
|
||||
my $sysinit = <$IN>;
|
||||
close ($IN);
|
||||
chomp $sysinit;
|
||||
if ($sysinit ne "systemd") {$sysinit = "init"}
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start type
|
||||
sub type {
|
||||
return $sysinit;
|
||||
}
|
||||
# end type
|
||||
###############################################################################
|
||||
# start startlfd
|
||||
sub startlfd {
|
||||
if ($sysinit eq "systemd") {
|
||||
&printcmd($config{SYSTEMCTL},"start","lfd.service");
|
||||
&printcmd($config{SYSTEMCTL},"status","lfd.service");
|
||||
} else {
|
||||
&printcmd("/etc/init.d/lfd","start");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
# end startlfd
|
||||
###############################################################################
|
||||
# start stoplfd
|
||||
sub stoplfd {
|
||||
if ($sysinit eq "systemd") {
|
||||
&printcmd($config{SYSTEMCTL},"stop","lfd.service");
|
||||
}
|
||||
else {
|
||||
&printcmd("/etc/init.d/lfd","stop");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
# end stoplfd
|
||||
###############################################################################
|
||||
# start restartlfd
|
||||
sub restartlfd {
|
||||
if ($sysinit eq "systemd") {
|
||||
&printcmd($config{SYSTEMCTL},"restart","lfd.service");
|
||||
&printcmd($config{SYSTEMCTL},"status","lfd.service");
|
||||
}
|
||||
else {
|
||||
&printcmd("/etc/init.d/lfd","restart");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
# end restartlfd
|
||||
###############################################################################
|
||||
# start restartlfd
|
||||
sub statuslfd {
|
||||
if ($sysinit eq "systemd") {
|
||||
&printcmd($config{SYSTEMCTL},"status","lfd.service");
|
||||
}
|
||||
else {
|
||||
&printcmd("/etc/init.d/lfd","status");
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
# end restartlfd
|
||||
###############################################################################
|
||||
# start printcmd
|
||||
sub printcmd {
|
||||
my @command = @_;
|
||||
|
||||
if ($config{DIRECTADMIN}) {
|
||||
my $doublepid = fork;
|
||||
if ($doublepid == 0) {
|
||||
my ($childin, $childout);
|
||||
my $pid = open3($childin, $childout, $childout, @command);
|
||||
while (<$childout>) {print $_}
|
||||
waitpid ($pid, 0);
|
||||
exit;
|
||||
}
|
||||
waitpid ($doublepid, 0);
|
||||
} else {
|
||||
my ($childin, $childout);
|
||||
my $pid = open3($childin, $childout, $childout, @command);
|
||||
while (<$childout>) {print $_}
|
||||
waitpid ($pid, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
# end printcmd
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
68
csf/ConfigServer/Slurp.pm
Normal file
68
csf/ConfigServer/Slurp.pm
Normal file
@@ -0,0 +1,68 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::Slurp;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use Carp;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 1.02;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(slurp);
|
||||
|
||||
our $slurpreg = qr/(?>\x0D\x0A?|[\x0A-\x0C\x85\x{2028}\x{2029}])/;
|
||||
our $cleanreg = qr/(\r)|(\n)|(^\s+)|(\s+$)/;
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start slurp
|
||||
sub slurp {
|
||||
my $file = shift;
|
||||
if (-e $file) {
|
||||
sysopen (my $FILE, $file, O_RDONLY) or carp "*Error* Unable to open [$file]: $!";
|
||||
flock ($FILE, LOCK_SH) or carp "*Error* Unable to lock [$file]: $!";
|
||||
my $text = do {local $/; <$FILE>};
|
||||
close ($FILE);
|
||||
return split(/$slurpreg/,$text);
|
||||
} else {
|
||||
carp "*Error* File does not exist: [$file]";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
# end slurp
|
||||
###############################################################################
|
||||
# start slurpreg
|
||||
sub slurpreg {
|
||||
return $slurpreg;
|
||||
}
|
||||
# end slurpreg
|
||||
###############################################################################
|
||||
# start cleanreg
|
||||
sub cleanreg {
|
||||
return $cleanreg;
|
||||
}
|
||||
# end cleanreg
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
305
csf/ConfigServer/URLGet.pm
Normal file
305
csf/ConfigServer/URLGet.pm
Normal file
@@ -0,0 +1,305 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
# start main
|
||||
package ConfigServer::URLGet;
|
||||
|
||||
use strict;
|
||||
use lib '/usr/local/csf/lib';
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use Carp;
|
||||
use IPC::Open3;
|
||||
use ConfigServer::Config;
|
||||
|
||||
use Exporter qw(import);
|
||||
our $VERSION = 2.00;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
my $agent = "ConfigServer";
|
||||
my $option = 1;
|
||||
my $proxy = "";
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config();
|
||||
$SIG{PIPE} = 'IGNORE';
|
||||
|
||||
# end main
|
||||
###############################################################################
|
||||
# start new
|
||||
sub new {
|
||||
my $class = shift;
|
||||
$option = shift;
|
||||
$agent = shift;
|
||||
$proxy = shift;
|
||||
my $self = {};
|
||||
bless $self,$class;
|
||||
|
||||
if ($option == 3) {
|
||||
return $self;
|
||||
}
|
||||
elsif ($option == 2) {
|
||||
eval ('use LWP::UserAgent;'); ##no critic
|
||||
if ($@) {return undef}
|
||||
}
|
||||
else {
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
eval ('use HTTP::Tiny;'); ##no critic
|
||||
};
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
# end new
|
||||
###############################################################################
|
||||
# start urlget
|
||||
sub urlget {
|
||||
my $self = shift;
|
||||
my $url = shift;
|
||||
my $file = shift;
|
||||
my $quiet = shift;
|
||||
my $status;
|
||||
my $text;
|
||||
|
||||
if (!defined $url) {carp "url not specified"; return}
|
||||
|
||||
if ($option == 3) {
|
||||
($status, $text) = &binget($url,$file,$quiet);
|
||||
}
|
||||
elsif ($option == 2) {
|
||||
($status, $text) = &urlgetLWP($url,$file,$quiet);
|
||||
}
|
||||
else {
|
||||
($status, $text) = &urlgetTINY($url,$file,$quiet);
|
||||
}
|
||||
return ($status, $text);
|
||||
}
|
||||
# end urlget
|
||||
###############################################################################
|
||||
# start urlgetTINY
|
||||
sub urlgetTINY {
|
||||
my $url = shift;
|
||||
my $file = shift;
|
||||
my $quiet = shift;
|
||||
my $status = 0;
|
||||
my $timeout = 1200;
|
||||
if ($proxy eq "") {undef $proxy}
|
||||
my $ua = HTTP::Tiny->new(
|
||||
'agent' => $agent,
|
||||
'timeout' => 300,
|
||||
'proxy' => $proxy
|
||||
);
|
||||
my $res;
|
||||
my $text;
|
||||
($status, $text) = eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die "Download timeout after $timeout seconds"};
|
||||
alarm($timeout);
|
||||
if ($file) {
|
||||
local $|=1;
|
||||
my $expected_length;
|
||||
my $bytes_received = 0;
|
||||
my $per = 0;
|
||||
my $oldper = 0;
|
||||
open (my $OUT, ">", "$file\.tmp") or return (1, "Unable to open $file\.tmp: $!");
|
||||
flock ($OUT, LOCK_EX);
|
||||
binmode ($OUT);
|
||||
$res = $ua->request('GET', $url, {
|
||||
data_callback => sub {
|
||||
my($chunk, $res) = @_;
|
||||
$bytes_received += length($chunk);
|
||||
unless (defined $expected_length) {$expected_length = $res->{headers}->{'content-length'} || 0}
|
||||
if ($expected_length) {
|
||||
my $per = int(100 * $bytes_received / $expected_length);
|
||||
if ((int($per / 5) == $per / 5) and ($per != $oldper) and !$quiet) {
|
||||
print "...$per\%\n";
|
||||
$oldper = $per;
|
||||
}
|
||||
} else {
|
||||
unless ($quiet) {print "."}
|
||||
}
|
||||
print $OUT $chunk;
|
||||
}
|
||||
});
|
||||
close ($OUT);
|
||||
unless ($quiet) {print "\n"}
|
||||
} else {
|
||||
$res = $ua->request('GET', $url);
|
||||
}
|
||||
alarm(0);
|
||||
if ($res->{success}) {
|
||||
if ($file) {
|
||||
rename ("$file\.tmp","$file") or return (1, "Unable to rename $file\.tmp to $file: $!");
|
||||
return (0, $file);
|
||||
} else {
|
||||
return (0, $res->{content});
|
||||
}
|
||||
} else {
|
||||
my $reason = $res->{reason};
|
||||
if ($res->{status} == 599) {$reason = $res->{content}}
|
||||
($status, $text) = &binget($url,$file,$quiet,$reason);
|
||||
return ($status, $text);
|
||||
}
|
||||
};
|
||||
alarm(0);
|
||||
if ($@) {return (1, $@)}
|
||||
return ($status,$text);
|
||||
}
|
||||
# end urlgetTINY
|
||||
###############################################################################
|
||||
# start urlgetLWP
|
||||
sub urlgetLWP {
|
||||
my $url = shift;
|
||||
my $file = shift;
|
||||
my $quiet = shift;
|
||||
my $status = 0;
|
||||
my $timeout = 300;
|
||||
my $ua = LWP::UserAgent->new;
|
||||
$ua->agent($agent);
|
||||
$ua->timeout(30);
|
||||
if ($proxy ne "") {$ua->proxy([ 'http', 'https' ], $proxy)}
|
||||
#use LWP::ConnCache;
|
||||
#my $cache = LWP::ConnCache->new;
|
||||
#$cache->total_capacity([1]);
|
||||
#$ua->conn_cache($cache);
|
||||
my $req = HTTP::Request->new(GET => $url);
|
||||
my $res;
|
||||
my $text;
|
||||
($status, $text) = eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die "Download timeout after $timeout seconds"};
|
||||
alarm($timeout);
|
||||
if ($file) {
|
||||
local $|=1;
|
||||
my $expected_length;
|
||||
my $bytes_received = 0;
|
||||
my $per = 0;
|
||||
my $oldper = 0;
|
||||
open (my $OUT, ">", "$file\.tmp") or return (1, "Unable to open $file\.tmp: $!");
|
||||
flock ($OUT, LOCK_EX);
|
||||
binmode ($OUT);
|
||||
$res = $ua->request($req,
|
||||
sub {
|
||||
my($chunk, $res) = @_;
|
||||
$bytes_received += length($chunk);
|
||||
unless (defined $expected_length) {$expected_length = $res->content_length || 0}
|
||||
if ($expected_length) {
|
||||
my $per = int(100 * $bytes_received / $expected_length);
|
||||
if ((int($per / 5) == $per / 5) and ($per != $oldper) and !$quiet) {
|
||||
print "...$per\%\n";
|
||||
$oldper = $per;
|
||||
}
|
||||
} else {
|
||||
unless ($quiet) {print "."}
|
||||
}
|
||||
print $OUT $chunk;
|
||||
});
|
||||
close ($OUT);
|
||||
unless ($quiet) {print "\n"}
|
||||
} else {
|
||||
$res = $ua->request($req);
|
||||
}
|
||||
alarm(0);
|
||||
if ($res->is_success) {
|
||||
if ($file) {
|
||||
rename ("$file\.tmp","$file") or return (1, "Unable to rename $file\.tmp to $file: $!");
|
||||
return (0, $file);
|
||||
} else {
|
||||
return (0, $res->content);
|
||||
}
|
||||
} else {
|
||||
($status, $text) = &binget($url,$file,$quiet,$res->message);
|
||||
return ($status, $text);
|
||||
}
|
||||
};
|
||||
alarm(0);
|
||||
if ($@) {
|
||||
return (1, $@);
|
||||
}
|
||||
if ($text) {
|
||||
return ($status,$text);
|
||||
} else {
|
||||
return (1, "Download timeout after $timeout seconds");
|
||||
}
|
||||
}
|
||||
# end urlget
|
||||
###############################################################################
|
||||
# start binget
|
||||
sub binget {
|
||||
my $url = shift;
|
||||
my $file = shift;
|
||||
my $quiet = shift;
|
||||
my $errormsg = shift;
|
||||
$url = "'$url'";
|
||||
|
||||
my $cmd;
|
||||
if (-e $config{CURL}) {
|
||||
$cmd = $config{CURL}." -skLf -m 120";
|
||||
if ($file) {$cmd = $config{CURL}." -kLf -m 120 -o";}
|
||||
}
|
||||
elsif (-e $config{WGET}) {
|
||||
$cmd = $config{WGET}." -qT 120 -O-";
|
||||
if ($file) {$cmd = $config{WGET}." -T 120 -O"}
|
||||
}
|
||||
if ($cmd ne "") {
|
||||
if ($file) {
|
||||
my ($childin, $childout);
|
||||
my $cmdpid = open3($childin, $childout, $childout, $cmd." $file\.tmp $url");
|
||||
my @output = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
unless ($quiet and $option != 3) {
|
||||
print "Using fallback [$cmd]\n";
|
||||
print @output;
|
||||
}
|
||||
if (-e "$file\.tmp") {
|
||||
rename ("$file\.tmp","$file") or return (1, "Unable to rename $file\.tmp to $file: $!");
|
||||
return (0, $file);
|
||||
} else {
|
||||
if ($option == 3) {
|
||||
return (1, "Unable to download: ".$cmd." $file\.tmp $url".join("",@output));
|
||||
} else {
|
||||
return (1, "Unable to download: ".$errormsg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
my ($childin, $childout);
|
||||
my $cmdpid = open3($childin, $childout, $childout, $cmd." $url");
|
||||
my @output = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
if (scalar @output > 0) {
|
||||
return (0, join("",@output));
|
||||
} else {
|
||||
if ($option == 3) {
|
||||
return (1, "Unable to download: [$cmd $url]".join("",@output));
|
||||
} else {
|
||||
return (1, "Unable to download: ".$errormsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($option == 3) {
|
||||
return (1, "Unable to download (CURL/WGET also not present, see csf.conf)");
|
||||
} else {
|
||||
return (1, "Unable to download (CURL/WGET also not present, see csf.conf): ".$errormsg);
|
||||
}
|
||||
}
|
||||
# end binget
|
||||
###############################################################################
|
||||
1;
|
||||
1042
csf/ConfigServer/cseUI.pm
Normal file
1042
csf/ConfigServer/cseUI.pm
Normal file
File diff suppressed because it is too large
Load Diff
519
csf/Crypt/Blowfish_PP.pm
Normal file
519
csf/Crypt/Blowfish_PP.pm
Normal file
@@ -0,0 +1,519 @@
|
||||
# This is Crypt/Blowfish_PP.pm which is an implementation of Bruce Schneier's
|
||||
# blowfish cryptographic algorithm. I will write some proper docs when I get
|
||||
# time....
|
||||
# code is (c) copyright Matthew Byng-Maddick <mbm@colondot.net> 2000-2023, and
|
||||
# some bits are copyright Bruce Schneier. For more information see his website
|
||||
# at http://www.counterpane.com/
|
||||
|
||||
=head1 NAME
|
||||
|
||||
B<Crypt::Blowfish_PP> - Blowfish encryption algorithm implemented purely in Perl
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
C<use Crypt::Blowfish_PP>;
|
||||
|
||||
$blowfish=new Crypt::Blowfish_PP($key);
|
||||
|
||||
$ciphertextBlock=$blowfish->encrypt($plaintextBlock);
|
||||
|
||||
$plaintextBlock=$blowfish->decrypt($ciphertextBlock);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<Crypt::Blowfish_PP> module provides for users to use the Blowfish encryption
|
||||
algorithm in perl. The implementation is entirely Object Oriented, as there is
|
||||
quite a lot of context inherent in making blowfish as fast as it is. The key is
|
||||
anywhere between 64 and 448 bits (8 and 56 bytes), and should be passed as a
|
||||
packed string. The transformation itself is a 16-round Feistel Network, and
|
||||
operates on a 64 bit block.
|
||||
|
||||
Object methods for the Crypt::Blowfish_PP module:
|
||||
|
||||
=cut
|
||||
package Crypt::Blowfish_PP;
|
||||
|
||||
use strict;
|
||||
use vars qw($VERSION);
|
||||
|
||||
$VERSION="1.12";
|
||||
|
||||
=head2 B<new>(I<key>)
|
||||
|
||||
The B<new>() method initialises a blowfish object with the key that is passed.
|
||||
This is the slow part of doing a blowfish encryption or decryption, as it
|
||||
initialises the 18 p-boxes and the 1024 s-boxes that are used for the algorithm.
|
||||
It will return undef if the key is not of a valid length.
|
||||
|
||||
=cut
|
||||
|
||||
sub new
|
||||
{
|
||||
my $pack=shift;
|
||||
my $key=shift;
|
||||
return undef if(!defined($key));
|
||||
my %h=(
|
||||
p_boxes =>
|
||||
[
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
|
||||
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
||||
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
||||
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
||||
0x9216d5d9, 0x8979fb1b
|
||||
],
|
||||
s_boxes =>
|
||||
[
|
||||
[
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
|
||||
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
||||
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
||||
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
||||
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
|
||||
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
|
||||
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
|
||||
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
||||
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
|
||||
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
|
||||
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
||||
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
|
||||
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
|
||||
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
||||
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
|
||||
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
|
||||
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
|
||||
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
|
||||
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
||||
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
|
||||
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
|
||||
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
||||
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
|
||||
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
|
||||
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
||||
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
|
||||
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
|
||||
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
||||
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
|
||||
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
|
||||
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
||||
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
|
||||
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
|
||||
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
|
||||
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
|
||||
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
||||
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
|
||||
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
|
||||
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
||||
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
|
||||
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
|
||||
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
||||
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
|
||||
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
|
||||
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
||||
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
|
||||
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
|
||||
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
||||
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
|
||||
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
|
||||
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
|
||||
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
|
||||
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
||||
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
|
||||
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
|
||||
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
||||
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
|
||||
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
|
||||
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
||||
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
|
||||
],
|
||||
[
|
||||
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
|
||||
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
||||
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
|
||||
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
|
||||
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
|
||||
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
||||
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
|
||||
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
||||
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
|
||||
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
|
||||
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
|
||||
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
||||
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
|
||||
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
||||
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
|
||||
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
|
||||
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
|
||||
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
|
||||
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
||||
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
|
||||
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
|
||||
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
|
||||
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
||||
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
|
||||
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
||||
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
|
||||
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
|
||||
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
|
||||
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
||||
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
|
||||
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
||||
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
|
||||
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
|
||||
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
|
||||
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
|
||||
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
||||
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
|
||||
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
|
||||
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
|
||||
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
||||
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
|
||||
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
||||
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
|
||||
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
|
||||
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
|
||||
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
||||
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
|
||||
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
||||
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
|
||||
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
|
||||
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
|
||||
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
|
||||
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
||||
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
|
||||
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
|
||||
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
|
||||
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
||||
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
|
||||
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
||||
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
|
||||
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
|
||||
],
|
||||
[
|
||||
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
|
||||
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
|
||||
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
|
||||
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
||||
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
|
||||
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
||||
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
|
||||
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
|
||||
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
|
||||
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
||||
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
|
||||
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
||||
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
|
||||
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
|
||||
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
|
||||
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
||||
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
|
||||
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
|
||||
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
|
||||
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
|
||||
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
||||
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
|
||||
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
||||
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
|
||||
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
|
||||
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
|
||||
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
||||
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
|
||||
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
||||
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
|
||||
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
|
||||
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
|
||||
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
||||
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
|
||||
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
|
||||
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
|
||||
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
|
||||
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
||||
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
|
||||
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
||||
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
|
||||
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
|
||||
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
|
||||
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
||||
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
|
||||
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
||||
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
|
||||
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
|
||||
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
|
||||
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
||||
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
|
||||
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
|
||||
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
|
||||
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
|
||||
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
||||
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
|
||||
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
||||
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
|
||||
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
|
||||
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
|
||||
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
|
||||
],
|
||||
[
|
||||
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
|
||||
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
|
||||
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
||||
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
|
||||
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
|
||||
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
||||
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
|
||||
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
|
||||
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
||||
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
|
||||
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
|
||||
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
||||
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
|
||||
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
|
||||
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
||||
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
|
||||
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
|
||||
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
|
||||
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
|
||||
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
||||
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
|
||||
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
|
||||
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
||||
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
|
||||
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
|
||||
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
||||
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
|
||||
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
|
||||
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
||||
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
|
||||
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
|
||||
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
||||
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
|
||||
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
|
||||
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
|
||||
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
|
||||
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
||||
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
|
||||
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
|
||||
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
||||
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
|
||||
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
|
||||
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
||||
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
|
||||
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
|
||||
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
||||
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
|
||||
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
|
||||
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
||||
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
|
||||
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
|
||||
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
|
||||
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
|
||||
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
||||
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
|
||||
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
|
||||
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
||||
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
|
||||
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
|
||||
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
||||
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
|
||||
]
|
||||
]
|
||||
);
|
||||
my $keylen=length($key);
|
||||
return undef if(($keylen < 8) || ($keylen > 56));
|
||||
my @keybytes=split//,$key;
|
||||
my $b;
|
||||
for $b (@keybytes)
|
||||
{
|
||||
$b=unpack("C",$b);
|
||||
}
|
||||
my $j=0;
|
||||
my $i=0;
|
||||
my($l,$r)=(0,0);
|
||||
|
||||
# BEGIN PROCESS OF SETTING UP S & P-BOXES FOR THE KEY
|
||||
for ($i=0;$i<18;$i++)
|
||||
{
|
||||
my $temp= ($keybytes[$j]<<24) +
|
||||
($keybytes[($j+1)%($keylen)]<<16) +
|
||||
($keybytes[($j+2)%($keylen)]<<8) +
|
||||
($keybytes[($j+3)%($keylen)]) ;
|
||||
$h{"p_boxes"}->[$i]^=$temp;
|
||||
$j=($j+4)%($keylen);
|
||||
}
|
||||
for ($i=0;$i<18;$i+=2)
|
||||
{
|
||||
($l,$r)=crypt_block(\%h,$l,$r,0);
|
||||
$h{"p_boxes"}->[$i]=$l;
|
||||
$h{"p_boxes"}->[$i+1]=$r;
|
||||
}
|
||||
for $i (0..3)
|
||||
{
|
||||
for($j=0;$j<256;$j+=2)
|
||||
{
|
||||
($l,$r)=crypt_block(\%h,$l,$r,0);
|
||||
$h{"s_boxes"}->[$i]->[$j]=$l;
|
||||
$h{"s_boxes"}->[$i]->[$j+1]=$r;
|
||||
}
|
||||
}
|
||||
# S-BOXES AND P-BOXES NOW SET UP, NEED NO LONGER CARE
|
||||
# ABOUT ACTUAL KEY
|
||||
return bless \%h, $pack;
|
||||
}
|
||||
|
||||
sub F
|
||||
{
|
||||
my $S0=$_[0]->{"s_boxes"}->[0]->[($_[1]&0xFF000000)>>24];
|
||||
my $S1=$_[0]->{"s_boxes"}->[1]->[($_[1]&0x00FF0000)>>16];
|
||||
my $S2=$_[0]->{"s_boxes"}->[2]->[($_[1]&0x0000FF00)>>8];
|
||||
my $S3=$_[0]->{"s_boxes"}->[3]->[($_[1]&0x000000FF)];
|
||||
# this is horrid, but otherwise Perl overflows. :(
|
||||
if($S0>$S1)
|
||||
{
|
||||
$S0=$S0-4294967296 if($S0>2147483647);
|
||||
}
|
||||
else
|
||||
{
|
||||
$S1=$S1-4294967296 if($S1>2147483647);
|
||||
}
|
||||
my $F=($S0+$S1);
|
||||
$F+=4294967296 if($F<0);
|
||||
$F^=$S2;
|
||||
if($F>$S3)
|
||||
{
|
||||
$F=$F-4294967296 if($F>2147483647);
|
||||
}
|
||||
else
|
||||
{
|
||||
$S3=$S3-4294967296 if($S3>2147483647);
|
||||
}
|
||||
$F+=$S3;
|
||||
$F&=0xFFFFFFFF;
|
||||
return $F;
|
||||
}
|
||||
|
||||
sub ROUND
|
||||
{
|
||||
return($_[1],($_[2]^($_[0]->{"p_boxes"}->[$_[3]]))^F($_[0],$_[1]));
|
||||
}
|
||||
|
||||
sub crypt_block
|
||||
{
|
||||
my $self=shift;
|
||||
my $l=shift;
|
||||
my $r=shift;
|
||||
my $d=shift;
|
||||
if(!$d)
|
||||
{
|
||||
$l^=$self->{"p_boxes"}->[0];
|
||||
my $i;
|
||||
for $i (1..16)
|
||||
{
|
||||
($r,$l)=ROUND($self,$l,$r,$i);
|
||||
}
|
||||
$r^=$self->{"p_boxes"}->[17];
|
||||
}
|
||||
else
|
||||
{
|
||||
$l^=$self->{"p_boxes"}->[17];
|
||||
my $i;
|
||||
for $i (1..16)
|
||||
{
|
||||
($r,$l)=ROUND($self,$l,$r,17-$i);
|
||||
}
|
||||
$r^=$self->{"p_boxes"}->[0];
|
||||
}
|
||||
return($r,$l);
|
||||
}
|
||||
|
||||
=head2 B<encrypt>(I<block>)
|
||||
|
||||
The B<encrypt>() method uses the initialised blowfish object to encrypt 8 bytes
|
||||
of data of the string passed to it. It returns the encrypted block.
|
||||
|
||||
=cut
|
||||
|
||||
sub encrypt
|
||||
{
|
||||
my($self)=shift;
|
||||
my($block)=shift;
|
||||
my(@block)=split//,$block;
|
||||
map{$_=unpack("C",$_)}@block;
|
||||
# I'm not sure what endianness these are.... so hey.
|
||||
my($l)=$block[3]|($block[2]<<8)|($block[1]<<16)|($block[0]<<24);
|
||||
my($r)=$block[7]|($block[6]<<8)|($block[5]<<16)|($block[4]<<24);
|
||||
|
||||
($l,$r)=crypt_block($self,$l,$r,0);
|
||||
|
||||
@block=(
|
||||
$l>>24,($l>>16)&0xFF,($l>>8)&0xFF,$l&0xFF,
|
||||
$r>>24,($r>>16)&0xFF,($r>>8)&0xFF,$r&0xFF
|
||||
);
|
||||
map{$_=pack("C",$_)}@block;
|
||||
return join"",@block;
|
||||
}
|
||||
|
||||
=head2 B<decrypt>(I<block>)
|
||||
|
||||
The B<decrypt>() method uses the initialised blowfish object to decrypt 8 bytes
|
||||
of data of the string passed to it. It returns the decrypted block.
|
||||
|
||||
=cut
|
||||
|
||||
sub decrypt
|
||||
{
|
||||
my($self)=shift;
|
||||
my($block)=shift;
|
||||
my(@block)=split//,$block;
|
||||
map{$_=unpack("C",$_)}@block;
|
||||
my($l)=$block[3]|($block[2]<<8)|($block[1]<<16)|($block[0]<<24);
|
||||
my($r)=$block[7]|($block[6]<<8)|($block[5]<<16)|($block[4]<<24);
|
||||
|
||||
($l,$r)=crypt_block($self,$l,$r,1);
|
||||
|
||||
@block=(
|
||||
$l>>24,($l>>16)&0xFF,($l>>8)&0xFF,$l&0xFF,
|
||||
$r>>24,($r>>16)&0xFF,($r>>8)&0xFF,$r&0xFF
|
||||
);
|
||||
map{$_=pack("C",$_)}@block;
|
||||
return join"",@block;
|
||||
}
|
||||
|
||||
sub blocksize
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
sub keysize
|
||||
{
|
||||
return 56;
|
||||
}
|
||||
|
||||
=head1 COMMENTS
|
||||
|
||||
This is probably crap software, but hey, its for general use. I'm happy to patch
|
||||
it with other people's code... :)
|
||||
|
||||
If you want speed, then see the Crypt::Blowfish module.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Matthew Byng-Maddick <C<mbm@colondot.net>>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
http://www.counterpane.com/,L<Crypt::CBC>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
1064
csf/Crypt/CBC.pm
Normal file
1064
csf/Crypt/CBC.pm
Normal file
File diff suppressed because it is too large
Load Diff
2425
csf/HTTP/Tiny.pm
Normal file
2425
csf/HTTP/Tiny.pm
Normal file
File diff suppressed because it is too large
Load Diff
306
csf/JSON/Tiny.pm
Normal file
306
csf/JSON/Tiny.pm
Normal file
@@ -0,0 +1,306 @@
|
||||
package JSON::Tiny;
|
||||
|
||||
# Minimalistic JSON. Adapted from Mojo::JSON. (c)2012-2023 David Oswald
|
||||
# License: Artistic 2.0 license.
|
||||
# http://www.perlfoundation.org/artistic_license_2_0
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Carp 'croak';
|
||||
use Exporter 'import';
|
||||
use Scalar::Util 'blessed';
|
||||
use Encode ();
|
||||
|
||||
our $VERSION = '0.56';
|
||||
our @EXPORT_OK = qw(decode_json encode_json false from_json j to_json true);
|
||||
|
||||
# Literal names
|
||||
# Users may override Booleans with literal 0 or 1 if desired.
|
||||
our($FALSE, $TRUE) = map { bless \(my $dummy = $_), 'JSON::Tiny::_Bool' } 0, 1;
|
||||
|
||||
# Escaped special character map with u2028 and u2029
|
||||
my %ESCAPE = (
|
||||
'"' => '"',
|
||||
'\\' => '\\',
|
||||
'/' => '/',
|
||||
'b' => "\x08",
|
||||
'f' => "\x0c",
|
||||
'n' => "\x0a",
|
||||
'r' => "\x0d",
|
||||
't' => "\x09",
|
||||
'u2028' => "\x{2028}",
|
||||
'u2029' => "\x{2029}"
|
||||
);
|
||||
my %REVERSE = map { $ESCAPE{$_} => "\\$_" } keys %ESCAPE;
|
||||
|
||||
for(0x00 .. 0x1f) {
|
||||
my $packed = pack 'C', $_;
|
||||
$REVERSE{$packed} = sprintf '\u%.4X', $_ unless defined $REVERSE{$packed};
|
||||
}
|
||||
|
||||
sub decode_json {
|
||||
my $err = _decode(\my $value, shift);
|
||||
return defined $err ? croak $err : $value;
|
||||
}
|
||||
|
||||
sub encode_json { Encode::encode 'UTF-8', _encode_value(shift) }
|
||||
|
||||
sub false () {$FALSE} ## no critic (prototypes)
|
||||
|
||||
sub from_json {
|
||||
my $err = _decode(\my $value, shift, 1);
|
||||
return defined $err ? croak $err : $value;
|
||||
}
|
||||
|
||||
sub j {
|
||||
return encode_json $_[0] if ref $_[0] eq 'ARRAY' || ref $_[0] eq 'HASH';
|
||||
return decode_json $_[0];
|
||||
}
|
||||
|
||||
sub to_json { _encode_value(shift) }
|
||||
|
||||
sub true () {$TRUE} ## no critic (prototypes)
|
||||
|
||||
sub _decode {
|
||||
my $valueref = shift;
|
||||
|
||||
eval {
|
||||
|
||||
# Missing input
|
||||
die "Missing or empty input\n" unless length( local $_ = shift );
|
||||
|
||||
# UTF-8
|
||||
$_ = eval { Encode::decode('UTF-8', $_, 1) } unless shift;
|
||||
die "Input is not UTF-8 encoded\n" unless defined $_;
|
||||
|
||||
# Value
|
||||
$$valueref = _decode_value();
|
||||
|
||||
# Leftover data
|
||||
return m/\G[\x20\x09\x0a\x0d]*\z/gc || _throw('Unexpected data');
|
||||
} ? return undef : chomp $@;
|
||||
|
||||
return $@;
|
||||
}
|
||||
|
||||
sub _decode_array {
|
||||
my @array;
|
||||
until (m/\G[\x20\x09\x0a\x0d]*\]/gc) {
|
||||
|
||||
# Value
|
||||
push @array, _decode_value();
|
||||
|
||||
# Separator
|
||||
redo if m/\G[\x20\x09\x0a\x0d]*,/gc;
|
||||
|
||||
# End
|
||||
last if m/\G[\x20\x09\x0a\x0d]*\]/gc;
|
||||
|
||||
# Invalid character
|
||||
_throw('Expected comma or right square bracket while parsing array');
|
||||
}
|
||||
|
||||
return \@array;
|
||||
}
|
||||
|
||||
sub _decode_object {
|
||||
my %hash;
|
||||
until (m/\G[\x20\x09\x0a\x0d]*\}/gc) {
|
||||
|
||||
# Quote
|
||||
m/\G[\x20\x09\x0a\x0d]*"/gc
|
||||
or _throw('Expected string while parsing object');
|
||||
|
||||
# Key
|
||||
my $key = _decode_string();
|
||||
|
||||
# Colon
|
||||
m/\G[\x20\x09\x0a\x0d]*:/gc
|
||||
or _throw('Expected colon while parsing object');
|
||||
|
||||
# Value
|
||||
$hash{$key} = _decode_value();
|
||||
|
||||
# Separator
|
||||
redo if m/\G[\x20\x09\x0a\x0d]*,/gc;
|
||||
|
||||
# End
|
||||
last if m/\G[\x20\x09\x0a\x0d]*\}/gc;
|
||||
|
||||
# Invalid character
|
||||
_throw('Expected comma or right curly bracket while parsing object');
|
||||
}
|
||||
|
||||
return \%hash;
|
||||
}
|
||||
|
||||
sub _decode_string {
|
||||
my $pos = pos;
|
||||
|
||||
# Extract string with escaped characters
|
||||
m!\G((?:(?:[^\x00-\x1f\\"]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4})){0,32766})*)!gc; # segfault on 5.8.x in t/20-mojo-json.t
|
||||
my $str = $1;
|
||||
|
||||
# Invalid character
|
||||
unless (m/\G"/gc) {
|
||||
_throw('Unexpected character or invalid escape while parsing string')
|
||||
if m/\G[\x00-\x1f\\]/;
|
||||
_throw('Unterminated string');
|
||||
}
|
||||
|
||||
# Unescape popular characters
|
||||
if (index($str, '\\u') < 0) {
|
||||
$str =~ s!\\(["\\/bfnrt])!$ESCAPE{$1}!gs;
|
||||
return $str;
|
||||
}
|
||||
|
||||
# Unescape everything else
|
||||
my $buffer = '';
|
||||
while ($str =~ m/\G([^\\]*)\\(?:([^u])|u(.{4}))/gc) {
|
||||
$buffer .= $1;
|
||||
|
||||
# Popular character
|
||||
if ($2) { $buffer .= $ESCAPE{$2} }
|
||||
|
||||
# Escaped
|
||||
else {
|
||||
my $ord = hex $3;
|
||||
|
||||
# Surrogate pair
|
||||
if (($ord & 0xf800) == 0xd800) {
|
||||
|
||||
# High surrogate
|
||||
($ord & 0xfc00) == 0xd800
|
||||
or pos($_) = $pos + pos($str), _throw('Missing high-surrogate');
|
||||
|
||||
# Low surrogate
|
||||
$str =~ m/\G\\u([Dd][C-Fc-f]..)/gc
|
||||
or pos($_) = $pos + pos($str), _throw('Missing low-surrogate');
|
||||
|
||||
$ord = 0x10000 + ($ord - 0xd800) * 0x400 + (hex($1) - 0xdc00);
|
||||
}
|
||||
|
||||
# Character
|
||||
$buffer .= pack 'U', $ord;
|
||||
}
|
||||
}
|
||||
|
||||
# The rest
|
||||
return $buffer . substr $str, pos $str, length $str;
|
||||
}
|
||||
|
||||
sub _decode_value {
|
||||
|
||||
# Leading whitespace
|
||||
m/\G[\x20\x09\x0a\x0d]*/gc;
|
||||
|
||||
# String
|
||||
return _decode_string() if m/\G"/gc;
|
||||
|
||||
# Object
|
||||
return _decode_object() if m/\G\{/gc;
|
||||
|
||||
# Array
|
||||
return _decode_array() if m/\G\[/gc;
|
||||
|
||||
# Number
|
||||
my ($i) = /\G([-]?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?)/gc;
|
||||
return 0 + $i if defined $i;
|
||||
|
||||
# True
|
||||
return $TRUE if m/\Gtrue/gc;
|
||||
|
||||
# False
|
||||
return $FALSE if m/\Gfalse/gc;
|
||||
|
||||
# Null
|
||||
return undef if m/\Gnull/gc; ## no critic (return)
|
||||
|
||||
# Invalid character
|
||||
_throw('Expected string, array, object, number, boolean or null');
|
||||
}
|
||||
|
||||
sub _encode_array {
|
||||
'[' . join(',', map { _encode_value($_) } @{$_[0]}) . ']';
|
||||
}
|
||||
|
||||
sub _encode_object {
|
||||
my $object = shift;
|
||||
my @pairs = map { _encode_string($_) . ':' . _encode_value($object->{$_}) }
|
||||
sort keys %$object;
|
||||
return '{' . join(',', @pairs) . '}';
|
||||
}
|
||||
|
||||
sub _encode_string {
|
||||
my $str = shift;
|
||||
$str =~ s!([\x00-\x1f\x{2028}\x{2029}\\"/])!$REVERSE{$1}!gs;
|
||||
return "\"$str\"";
|
||||
}
|
||||
|
||||
sub _encode_value {
|
||||
my $value = shift;
|
||||
|
||||
# Reference
|
||||
if (my $ref = ref $value) {
|
||||
|
||||
# Object
|
||||
return _encode_object($value) if $ref eq 'HASH';
|
||||
|
||||
# Array
|
||||
return _encode_array($value) if $ref eq 'ARRAY';
|
||||
|
||||
# True or false
|
||||
return $$value ? 'true' : 'false' if $ref eq 'SCALAR';
|
||||
return $value ? 'true' : 'false' if $ref eq 'JSON::Tiny::_Bool';
|
||||
|
||||
# Blessed reference with TO_JSON method
|
||||
if (blessed $value && (my $sub = $value->can('TO_JSON'))) {
|
||||
return _encode_value($value->$sub);
|
||||
}
|
||||
}
|
||||
|
||||
# Null
|
||||
return 'null' unless defined $value;
|
||||
|
||||
|
||||
# Number (bitwise operators change behavior based on the internal value type)
|
||||
|
||||
# "0" & $x will modify the flags on the "0" on perl < 5.14, so use a copy
|
||||
my $zero = "0";
|
||||
# "0" & $num -> 0. "0" & "" -> "". "0" & $string -> a character.
|
||||
# this maintains the internal type but speeds up the xor below.
|
||||
my $check = $zero & $value;
|
||||
return $value
|
||||
if length $check
|
||||
# 0 ^ itself -> 0 (false)
|
||||
# $character ^ itself -> "\0" (true)
|
||||
&& !($check ^ $check)
|
||||
# filter out "upgraded" strings whose numeric form doesn't strictly match
|
||||
&& 0 + $value eq $value
|
||||
# filter out inf and nan
|
||||
&& $value * 0 == 0;
|
||||
|
||||
# String
|
||||
return _encode_string($value);
|
||||
}
|
||||
|
||||
sub _throw {
|
||||
|
||||
# Leading whitespace
|
||||
m/\G[\x20\x09\x0a\x0d]*/gc;
|
||||
|
||||
# Context
|
||||
my $context = 'Malformed JSON: ' . shift;
|
||||
if (m/\G\z/gc) { $context .= ' before end of data' }
|
||||
else {
|
||||
my @lines = split "\n", substr($_, 0, pos);
|
||||
$context .= ' at line ' . @lines . ', offset ' . length(pop @lines || '');
|
||||
}
|
||||
|
||||
die "$context\n";
|
||||
}
|
||||
|
||||
# Emulate boolean type
|
||||
package JSON::Tiny::_Bool;
|
||||
use overload '""' => sub { ${$_[0]} }, fallback => 1;
|
||||
1;
|
||||
223
csf/Module/Installed/Tiny.pm
Normal file
223
csf/Module/Installed/Tiny.pm
Normal file
@@ -0,0 +1,223 @@
|
||||
package Module::Installed::Tiny;
|
||||
|
||||
our $DATE = '2016-08-04'; # DATE
|
||||
our $VERSION = '0.003'; # VERSION
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Exporter qw(import);
|
||||
our @EXPORT_OK = qw(module_installed module_source);
|
||||
|
||||
our $SEPARATOR;
|
||||
BEGIN {
|
||||
if ($^O =~ /^(dos|os2)/i) {
|
||||
$SEPARATOR = '\\';
|
||||
} elsif ($^O =~ /^MacOS/i) {
|
||||
$SEPARATOR = ':';
|
||||
} else {
|
||||
$SEPARATOR = '/';
|
||||
}
|
||||
}
|
||||
|
||||
sub _module_source {
|
||||
my $name_pm = shift;
|
||||
|
||||
for my $entry (@INC) {
|
||||
next unless defined $entry;
|
||||
my $ref = ref($entry);
|
||||
my ($is_hook, @hook_res);
|
||||
if ($ref eq 'ARRAY') {
|
||||
$is_hook++;
|
||||
@hook_res = $entry->[0]->($entry, $name_pm);
|
||||
} elsif (UNIVERSAL::can($entry, 'INC')) {
|
||||
$is_hook++;
|
||||
@hook_res = $entry->INC($name_pm);
|
||||
} elsif ($ref eq 'CODE') {
|
||||
$is_hook++;
|
||||
@hook_res = $entry->($entry, $name_pm);
|
||||
} else {
|
||||
my $path = "$entry$SEPARATOR$name_pm";
|
||||
if (-f $path) {
|
||||
open my($fh), "<", $path
|
||||
or die "Can't locate $name_pm: $path: $!";
|
||||
local $/;
|
||||
return scalar <$fh>;
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_hook) {
|
||||
next unless @hook_res;
|
||||
my $prepend_ref = shift @hook_res if ref($hook_res[0]) eq 'SCALAR';
|
||||
my $fh = shift @hook_res if ref($hook_res[0]) eq 'GLOB';
|
||||
my $code = shift @hook_res if ref($hook_res[0]) eq 'CODE';
|
||||
my $code_state = shift @hook_res if @hook_res;
|
||||
if ($fh) {
|
||||
my $src = "";
|
||||
local $_;
|
||||
while (!eof($fh)) {
|
||||
$_ = <$fh>;
|
||||
if ($code) {
|
||||
$code->($code, $code_state);
|
||||
}
|
||||
$src .= $_;
|
||||
}
|
||||
$src = $$prepend_ref . $src if $prepend_ref;
|
||||
return $src;
|
||||
} elsif ($code) {
|
||||
my $src = "";
|
||||
local $_;
|
||||
while ($code->($code, $code_state)) {
|
||||
$src .= $_;
|
||||
}
|
||||
$src = $$prepend_ref . $src if $prepend_ref;
|
||||
return $src;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
die "Can't locate $name_pm in \@INC (\@INC contains: ".join(" ", @INC).")";
|
||||
}
|
||||
|
||||
sub module_source {
|
||||
my $name = shift;
|
||||
|
||||
# convert Foo::Bar -> Foo/Bar.pm
|
||||
my $name_pm;
|
||||
if ($name =~ /\A\w+(?:::\w+)*\z/) {
|
||||
($name_pm = "$name.pm") =~ s!::!$SEPARATOR!g;
|
||||
} else {
|
||||
$name_pm = $name;
|
||||
}
|
||||
|
||||
_module_source $name_pm;
|
||||
}
|
||||
|
||||
sub module_installed {
|
||||
my $name = shift;
|
||||
|
||||
# convert Foo::Bar -> Foo/Bar.pm
|
||||
my $name_pm;
|
||||
if ($name =~ /\A\w+(?:::\w+)*\z/) {
|
||||
($name_pm = "$name.pm") =~ s!::!$SEPARATOR!g;
|
||||
} else {
|
||||
$name_pm = $name;
|
||||
}
|
||||
|
||||
return 1 if exists $INC{$name_pm};
|
||||
|
||||
if (eval { _module_source $name_pm; 1 }) {
|
||||
1;
|
||||
} else {
|
||||
0;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
# ABSTRACT: Check if a module is installed, with as little code as possible
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=encoding UTF-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Module::Installed::Tiny - Check if a module is installed, with as little code as possible
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
This document describes version 0.003 of Module::Installed::Tiny (from Perl distribution Module-Installed-Tiny), released on 2016-08-04.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Module::Installed::Tiny qw(module_installed module_source);
|
||||
|
||||
# check if a module is available
|
||||
if (module_installed "Foo::Bar") {
|
||||
# Foo::Bar is available
|
||||
} elsif (module_installed "Foo/Baz.pm") {
|
||||
# Foo::Baz is available
|
||||
}
|
||||
|
||||
# get a module's source code, dies on failure
|
||||
my $src = module_source("Foo/Baz.pm");
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
To check if a module is installed (available), generally the simplest way is to
|
||||
try to C<require()> it:
|
||||
|
||||
if (eval { require Foo::Bar; 1 }) {
|
||||
# Foo::Bar is available
|
||||
}
|
||||
|
||||
However, this actually loads the module. There are some cases where this is not
|
||||
desirable: 1) we have to check a lot of modules (actually loading the modules
|
||||
will take a lot of CPU time and memory; 2) some of the modules conflict with one
|
||||
another and cannot all be loaded; 3) the module is OS specific and might not
|
||||
load under another OS; 4) we simply do not want to execute the module, for
|
||||
security or other reasons.
|
||||
|
||||
C<Module::Installed::Tiny> provides a routine C<module_installed()> which works
|
||||
like Perl's C<require> but does not actually load the module.
|
||||
|
||||
This module does not require any other module except L<Exporter>.
|
||||
|
||||
=head1 FUNCTIONS
|
||||
|
||||
=head2 module_installed($name) => bool
|
||||
|
||||
Check that module named C<$name> is available to load. This means that: either
|
||||
the module file exists on the filesystem and searchable in C<@INC> and the
|
||||
contents of the file can be retrieved, or when there is a require hook in
|
||||
C<@INC>, the module's source can be retrieved from the hook.
|
||||
|
||||
Note that this does not guarantee that the module can eventually be loaded
|
||||
successfully, as there might be syntax or runtime errors in the module's source.
|
||||
To check for that, one would need to actually load the module using C<require>.
|
||||
|
||||
=head2 module_source($name) => str
|
||||
|
||||
Return module's source code, without actually loading it. Die on failure.
|
||||
|
||||
=head1 HOMEPAGE
|
||||
|
||||
Please visit the project's homepage at L<https://metacpan.org/release/Module-Installed-Tiny>.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
Source repository is at L<https://github.com/perlancar/perl-Module-Installed-Tiny>.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Module-Installed-Tiny>
|
||||
|
||||
When submitting a bug or request, please include a test-file or a
|
||||
patch to an existing test-file that illustrates the bug or desired
|
||||
feature.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Module::Load::Conditional> provides C<check_install> which also does what
|
||||
C<module_installed> does, plus can check module version. It also has a couple
|
||||
other knobs to customize its behavior. It's less tiny than
|
||||
Module::Installed::Tiny though.
|
||||
|
||||
L<Module::Path> and L<Module::Path::More>. These modules can also be used to
|
||||
check if a module on the filesystem is available. They do not handle require
|
||||
hooks, nor do they actually check that the module file is readable.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
perlancar <perlancar@cpan.org>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2016 by perlancar@cpan.org.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
685
csf/Net/CIDR/Lite.pm
Normal file
685
csf/Net/CIDR/Lite.pm
Normal file
@@ -0,0 +1,685 @@
|
||||
package Net::CIDR::Lite;
|
||||
|
||||
use strict;
|
||||
use vars qw($VERSION);
|
||||
use Carp qw(confess);
|
||||
|
||||
$VERSION = '0.21';
|
||||
|
||||
my %masks;
|
||||
my @fields = qw(PACK UNPACK NBITS MASKS);
|
||||
|
||||
# Preloaded methods go here.
|
||||
|
||||
sub new {
|
||||
my $proto = shift;
|
||||
my $class = ref($proto) || $proto;
|
||||
my $self = bless {}, $class;
|
||||
$self->add_any($_) for @_;
|
||||
$self;
|
||||
}
|
||||
|
||||
sub add_any {
|
||||
my $self = shift;
|
||||
for (@_) {
|
||||
tr|/|| && do { $self->add($_); next };
|
||||
tr|-|| && do { $self->add_range($_); next };
|
||||
UNIVERSAL::isa($_, 'Net::CIDR::Lite') && do {
|
||||
$self->add_cidr($_); next
|
||||
};
|
||||
$self->add_ip($_), next;
|
||||
}
|
||||
$self;
|
||||
}
|
||||
|
||||
sub add {
|
||||
my $self = shift;
|
||||
my ($ip, $mask) = split "/", shift;
|
||||
$self->_init($ip) || confess "Can't determine ip format" unless %$self;
|
||||
confess "Bad mask $mask"
|
||||
unless $mask =~ /^\d+$/ and $mask <= $self->{NBITS}-8;
|
||||
$mask += 8;
|
||||
my $start = $self->{PACK}->($ip) & $self->{MASKS}[$mask]
|
||||
or confess "Bad ip address: $ip";
|
||||
my $end = $self->_add_bit($start, $mask);
|
||||
++$$self{RANGES}{$start} || delete $$self{RANGES}{$start};
|
||||
--$$self{RANGES}{$end} || delete $$self{RANGES}{$end};
|
||||
$self;
|
||||
}
|
||||
|
||||
sub clean {
|
||||
my $self = shift;
|
||||
return $self unless $self->{RANGES};
|
||||
my $ranges = $$self{RANGES};
|
||||
my $total;
|
||||
$$self{RANGES} = {
|
||||
map { $total ? ($total+=$$ranges{$_})? () : ($_=>-1)
|
||||
: do { $total+=$$ranges{$_}; ($_=>1) }
|
||||
} sort keys %$ranges
|
||||
};
|
||||
$self;
|
||||
}
|
||||
|
||||
sub list {
|
||||
my $self = shift;
|
||||
return unless $self->{NBITS};
|
||||
my $nbits = $$self{NBITS};
|
||||
my ($start, $total);
|
||||
my @results;
|
||||
for my $ip (sort keys %{$$self{RANGES}}) {
|
||||
$start = $ip unless $total;
|
||||
$total += $$self{RANGES}{$ip};
|
||||
unless ($total) {
|
||||
while ($start lt $ip) {
|
||||
my ($end, $bits);
|
||||
my $sbit = $nbits-1;
|
||||
# Find the position of the last 1 bit
|
||||
$sbit-- while !vec($start, $sbit^7, 1) and $sbit>0;
|
||||
for my $pos ($sbit+1..$nbits) {
|
||||
$end = $self->_add_bit($start, $pos);
|
||||
$bits = $pos-8, last if $end le $ip;
|
||||
}
|
||||
push @results, $self->{UNPACK}->($start) . "/$bits";
|
||||
$start = $end;
|
||||
}
|
||||
}
|
||||
}
|
||||
wantarray ? @results : \@results;
|
||||
}
|
||||
|
||||
sub list_range {
|
||||
my $self = shift;
|
||||
my ($start, $total);
|
||||
my @results;
|
||||
for my $ip (sort keys %{$$self{RANGES}}) {
|
||||
$start = $ip unless $total;
|
||||
$total += $$self{RANGES}{$ip};
|
||||
unless ($total) {
|
||||
$ip = $self->_minus_one($ip);
|
||||
push @results,
|
||||
$self->{UNPACK}->($start) . "-" . $self->{UNPACK}->($ip);
|
||||
}
|
||||
}
|
||||
wantarray ? @results : \@results;
|
||||
}
|
||||
|
||||
sub list_short_range {
|
||||
my $self = shift;
|
||||
|
||||
my $start;
|
||||
my $total;
|
||||
my @results;
|
||||
|
||||
for my $ip (sort keys %{$$self{RANGES}}) {
|
||||
# we begin new range when $total is zero
|
||||
$start = $ip if not $total;
|
||||
|
||||
# add to total (1 for start of the range or -1 for end of the range)
|
||||
$total += $$self{RANGES}{$ip};
|
||||
|
||||
# in case of end of range
|
||||
if (not $total) {
|
||||
while ($ip gt $start) {
|
||||
$ip = $self->_minus_one($ip);
|
||||
|
||||
# in case of single ip not a range
|
||||
if ($ip eq $start) {
|
||||
push @results,
|
||||
$self->{UNPACK}->($start);
|
||||
next;
|
||||
}
|
||||
|
||||
# get the last ip octet number
|
||||
my $to_octet = ( unpack('C5', $ip) )[4];
|
||||
|
||||
# next ip end will be current end masked by c subnet mask 255.255.255.0 - /24
|
||||
$ip = $ip & $self->{MASKS}[32];
|
||||
|
||||
# if the ip range is in the same c subnet
|
||||
if ($ip eq ($start & $self->{MASKS}[32])) {
|
||||
push @results,
|
||||
$self->{UNPACK}->($start) . "-" . $to_octet;
|
||||
}
|
||||
# otherwise the range start is .0 (end of range masked by c subnet mask)
|
||||
else {
|
||||
push @results,
|
||||
$self->{UNPACK}->($ip & $self->{MASKS}[32]) . "-" . $to_octet;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
wantarray ? @results : \@results;
|
||||
}
|
||||
|
||||
sub _init {
|
||||
my $self = shift;
|
||||
my $ip = shift;
|
||||
my ($nbits, $pack, $unpack);
|
||||
if (_pack_ipv4($ip)) {
|
||||
$nbits = 40;
|
||||
$pack = \&_pack_ipv4;
|
||||
$unpack = \&_unpack_ipv4;
|
||||
} elsif (_pack_ipv6($ip)) {
|
||||
$nbits = 136;
|
||||
$pack = \&_pack_ipv6;
|
||||
$unpack = \&_unpack_ipv6;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
$$self{PACK} = $pack;
|
||||
$$self{UNPACK} = $unpack;
|
||||
$$self{NBITS} = $nbits;
|
||||
$$self{MASKS} = $masks{$nbits} ||= [
|
||||
map { pack("B*", substr("1" x $_ . "0" x $nbits, 0, $nbits))
|
||||
} 0..$nbits
|
||||
];
|
||||
$$self{RANGES} = {};
|
||||
$self;
|
||||
}
|
||||
|
||||
sub _pack_ipv4 {
|
||||
my @nums = split /\./, shift(), -1;
|
||||
return unless @nums == 4;
|
||||
for (@nums) {
|
||||
return unless /^\d{1,3}$/ and $_ <= 255;
|
||||
}
|
||||
pack("CC*", 0, @nums);
|
||||
}
|
||||
|
||||
sub _unpack_ipv4 {
|
||||
join(".", unpack("xC*", shift));
|
||||
}
|
||||
|
||||
sub _pack_ipv6 {
|
||||
my $ip = shift;
|
||||
$ip =~ s/^::$/::0/;
|
||||
return if $ip =~ /^:/ and $ip !~ s/^::/:/;
|
||||
return if $ip =~ /:$/ and $ip !~ s/::$/:/;
|
||||
my @nums = split /:/, $ip, -1;
|
||||
return unless @nums <= 8;
|
||||
my ($empty, $ipv4, $str) = (0,'','');
|
||||
for (@nums) {
|
||||
return if $ipv4;
|
||||
$str .= "0" x (4-length) . $_, next if /^[a-fA-F\d]{1,4}$/;
|
||||
do { return if $empty++ }, $str .= "X", next if $_ eq '';
|
||||
next if $ipv4 = _pack_ipv4($_);
|
||||
return;
|
||||
}
|
||||
return if $ipv4 and @nums > 6;
|
||||
$str =~ s/X/"0" x (($ipv4 ? 25 : 33)-length($str))/e if $empty;
|
||||
pack("H*", "00" . $str).$ipv4;
|
||||
}
|
||||
|
||||
sub _unpack_ipv6 {
|
||||
_compress_ipv6(join(":", unpack("xH*", shift) =~ /..../g)),
|
||||
}
|
||||
|
||||
# Replace longest run of null blocks with a double colon
|
||||
sub _compress_ipv6 {
|
||||
my $ip = shift;
|
||||
if (my @runs = $ip =~ /((?:(?:^|:)(?:0000))+:?)/g ) {
|
||||
my $max = $runs[0];
|
||||
for (@runs[1..$#runs]) {
|
||||
$max = $_ if length($max) < length;
|
||||
}
|
||||
$ip =~ s/$max/::/;
|
||||
}
|
||||
$ip =~ s/:0{1,3}/:/g;
|
||||
$ip;
|
||||
}
|
||||
|
||||
# Add a single IP address
|
||||
sub add_ip {
|
||||
my $self = shift;
|
||||
my $ip = shift;
|
||||
$self->_init($ip) || confess "Can't determine ip format" unless %$self;
|
||||
my $start = $self->{PACK}->($ip) or confess "Bad ip address: $ip";
|
||||
my $end = $self->_add_bit($start, $self->{NBITS});
|
||||
++$$self{RANGES}{$start} || delete $$self{RANGES}{$start};
|
||||
--$$self{RANGES}{$end} || delete $$self{RANGES}{$end};
|
||||
$self;
|
||||
}
|
||||
|
||||
# Add a hyphenated range of IP addresses
|
||||
sub add_range {
|
||||
my $self = shift;
|
||||
local $_ = shift;
|
||||
my ($ip_start, $ip_end, $crud) = split /\s*-\s*/;
|
||||
confess "Only one hyphen allowed in range" if defined $crud;
|
||||
$self->_init($ip_start) || confess "Can't determine ip format"
|
||||
unless %$self;
|
||||
my $start = $self->{PACK}->($ip_start)
|
||||
or confess "Bad ip address: $ip_start";
|
||||
my $end = $self->{PACK}->($ip_end)
|
||||
or confess "Bad ip address: $ip_end";
|
||||
confess "Start IP is greater than end IP" if $start gt $end;
|
||||
$end = $self->_add_bit($end, $$self{NBITS});
|
||||
++$$self{RANGES}{$start} || delete $$self{RANGES}{$start};
|
||||
--$$self{RANGES}{$end} || delete $$self{RANGES}{$end};
|
||||
$self;
|
||||
}
|
||||
|
||||
# Add ranges from another Net::CIDR::Lite object
|
||||
sub add_cidr {
|
||||
my $self = shift;
|
||||
my $cidr = shift;
|
||||
confess "Not a CIDR object" unless UNIVERSAL::isa($cidr, 'Net::CIDR::Lite');
|
||||
unless (%$self) {
|
||||
@$self{@fields} = @$cidr{@fields};
|
||||
}
|
||||
$$self{RANGES}{$_} += $$cidr{RANGES}{$_} for keys %{$$cidr{RANGES}};
|
||||
$self;
|
||||
}
|
||||
|
||||
# Increment the ip address at the given bit position
|
||||
# bit position is in range 1 to # of bits in ip
|
||||
# where 1 is high order bit, # of bits is low order bit
|
||||
sub _add_bit {
|
||||
my $self= shift;
|
||||
my $base= shift();
|
||||
my $bits= shift()-1;
|
||||
while (vec($base, $bits^7, 1)) {
|
||||
vec($base, $bits^7, 1) = 0;
|
||||
$bits--;
|
||||
return $base if $bits < 0;
|
||||
}
|
||||
vec($base, $bits^7, 1) = 1;
|
||||
return $base;
|
||||
}
|
||||
|
||||
# Subtract one from an ip address
|
||||
sub _minus_one {
|
||||
my $self = shift;
|
||||
my $nbits = $self->{NBITS};
|
||||
my $ip = shift;
|
||||
$ip = ~$ip;
|
||||
$ip = $self->_add_bit($ip, $nbits);
|
||||
$ip = $self->_add_bit($ip, $nbits);
|
||||
$self->_add_bit(~$ip, $nbits);
|
||||
}
|
||||
|
||||
sub find {
|
||||
my $self = shift;
|
||||
$self->prep_find unless $self->{FIND};
|
||||
return $self->bin_find(@_) unless @{$self->{FIND}} < $self->{PCT};
|
||||
return 0 unless $self->{PACK};
|
||||
my $this_ip = $self->{PACK}->(shift);
|
||||
my $ranges = $self->{RANGES};
|
||||
my $last = -1;
|
||||
for my $ip (@{$self->{FIND}}) {
|
||||
last if $this_ip lt $ip;
|
||||
$last = $ranges->{$ip};
|
||||
}
|
||||
$last > 0;
|
||||
}
|
||||
|
||||
sub bin_find {
|
||||
my $self = shift;
|
||||
my $ip = $self->{PACK}->(shift);
|
||||
$self->prep_find unless $self->{FIND};
|
||||
my $find = $self->{FIND};
|
||||
my ($start, $end) = (0, $#$find);
|
||||
return unless $ip ge $find->[$start] and $ip lt $find->[$end];
|
||||
while ($end - $start > 0) {
|
||||
my $mid = int(($start+$end)/2);
|
||||
if ($start == $mid) {
|
||||
if ($find->[$end] eq $ip) {
|
||||
$start = $end;
|
||||
} else { $end = $start }
|
||||
} else {
|
||||
($find->[$mid] lt $ip ? $start : $end) = $mid;
|
||||
}
|
||||
}
|
||||
$self->{RANGES}{$find->[$start]} > 0;
|
||||
}
|
||||
|
||||
sub prep_find {
|
||||
my $self = shift;
|
||||
$self->clean;
|
||||
$self->{PCT} = shift || 20;
|
||||
my $aref = $self->{FIND} = [];
|
||||
push @$aref, $_ for sort keys %{$self->{RANGES}};
|
||||
$self;
|
||||
}
|
||||
|
||||
sub spanner {
|
||||
Net::CIDR::Lite::Span->new(@_);
|
||||
}
|
||||
|
||||
sub _ranges {
|
||||
sort keys %{shift->{RANGES}};
|
||||
}
|
||||
|
||||
sub _packer { shift->{PACK} }
|
||||
sub _unpacker { shift->{UNPACK} }
|
||||
|
||||
package Net::CIDR::Lite::Span;
|
||||
use Carp qw(confess);
|
||||
|
||||
sub new {
|
||||
my $proto = shift;
|
||||
my $class = ref($proto) || $proto;
|
||||
my $self = bless {RANGES=>{}}, $class;
|
||||
$self->add(@_);
|
||||
}
|
||||
|
||||
sub add {
|
||||
my $self = shift;
|
||||
my $ranges = $self->{RANGES};
|
||||
if (@_ && !$self->{PACK}) {
|
||||
my $cidr = $_[0];
|
||||
$cidr = Net::CIDR::Lite->new($cidr) unless ref($cidr);
|
||||
$self->{PACK} = $cidr->_packer;
|
||||
$self->{UNPACK} = $cidr->_unpacker;
|
||||
}
|
||||
while (@_) {
|
||||
my ($cidr, $label) = (shift, shift);
|
||||
$cidr = Net::CIDR::Lite->new($cidr) unless ref($cidr);
|
||||
$cidr->clean;
|
||||
for my $ip ($cidr->_ranges) {
|
||||
push @{$ranges->{$ip}}, $label;
|
||||
}
|
||||
}
|
||||
$self;
|
||||
}
|
||||
|
||||
sub find {
|
||||
my $self = shift;
|
||||
my $pack = $self->{PACK};
|
||||
my $unpack = $self->{UNPACK};
|
||||
my %results;
|
||||
my $in_range;
|
||||
$self->prep_find unless $self->{FIND};
|
||||
return {} unless @_;
|
||||
return { map { $_ => {} } @_ } unless @{$self->{FIND}};
|
||||
return $self->bin_find(@_) if @_/@{$self->{FIND}} < $self->{PCT};
|
||||
my @ips = sort map { $pack->($_) || confess "Bad IP: $_" } @_;
|
||||
my $last;
|
||||
for my $ip (@{$self->{FIND}}) {
|
||||
if ($ips[0] lt $ip) {
|
||||
$results{$unpack->(shift @ips)} = $self->_in_range($last)
|
||||
while @ips and $ips[0] lt $ip;
|
||||
}
|
||||
last unless @ips;
|
||||
$last = $ip;
|
||||
}
|
||||
if (@ips) {
|
||||
my $no_range = $self->_in_range({});
|
||||
$results{$unpack->(shift @ips)} = $no_range while @ips;
|
||||
}
|
||||
\%results;
|
||||
}
|
||||
|
||||
sub bin_find {
|
||||
my $self = shift;
|
||||
return {} unless @_;
|
||||
$self->prep_find unless $self->{FIND};
|
||||
return { map { $_ => {} } @_ } unless @{$self->{FIND}};
|
||||
my $pack = $self->{PACK};
|
||||
my $unpack = $self->{UNPACK};
|
||||
my $find = $self->{FIND};
|
||||
my %results;
|
||||
for my $ip ( map { $pack->($_) || confess "Bad IP: $_" } @_) {
|
||||
my ($start, $end) = (0, $#$find);
|
||||
$results{$unpack->($ip)} = $self->_in_range, next
|
||||
unless $ip ge $find->[$start] and $ip lt $find->[$end];
|
||||
while ($start < $end) {
|
||||
my $mid = int(($start+$end)/2);
|
||||
if ($start == $mid) {
|
||||
if ($find->[$end] eq $ip) {
|
||||
$start = $end;
|
||||
} else { $end = $start }
|
||||
} else {
|
||||
($find->[$mid] lt $ip ? $start : $end) = $mid;
|
||||
}
|
||||
}
|
||||
$results{$unpack->($ip)} = $self->_in_range($find->[$start]);
|
||||
}
|
||||
\%results;
|
||||
}
|
||||
|
||||
sub _in_range {
|
||||
my $self = shift;
|
||||
my $ip = shift || '';
|
||||
my $aref = $self->{PREPPED}{$ip} || [];
|
||||
my $key = join "|", sort @$aref;
|
||||
$self->{CACHE}{$key} ||= { map { $_ => 1 } @$aref };
|
||||
}
|
||||
|
||||
sub prep_find {
|
||||
my $self = shift;
|
||||
my $pct = shift || 4;
|
||||
$self->{PCT} = $pct/100;
|
||||
$self->{FIND} = [ sort keys %{$self->{RANGES}} ];
|
||||
$self->{PREPPED} = {};
|
||||
$self->{CACHE} = {};
|
||||
my %cache;
|
||||
my %in_range;
|
||||
for my $ip (@{$self->{FIND}}) {
|
||||
my $keys = $self->{RANGES}{$ip};
|
||||
$_ = !$_ for @in_range{@$keys};
|
||||
my @keys = grep $in_range{$_}, keys %in_range;
|
||||
my $key_str = join "|", @keys;
|
||||
$self->{PREPPED}{$ip} = $cache{$key_str} ||= \@keys;
|
||||
}
|
||||
$self;
|
||||
}
|
||||
|
||||
sub clean {
|
||||
my $self = shift;
|
||||
unless ($self->{PACK}) {
|
||||
my $ip = shift;
|
||||
my $cidr = Net::CIDR::Lite->new($ip);
|
||||
return $cidr->clean($ip);
|
||||
}
|
||||
my $ip = $self->{PACK}->(shift) || return;
|
||||
$self->{UNPACK}->($ip);
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Net::CIDR::Lite - Perl extension for merging IPv4 or IPv6 CIDR addresses
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Net::CIDR::Lite;
|
||||
|
||||
my $cidr = Net::CIDR::Lite->new;
|
||||
$cidr->add($cidr_address);
|
||||
@cidr_list = $cidr->list;
|
||||
@ip_ranges = $cidr->list_range;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Faster alternative to Net::CIDR when merging a large number
|
||||
of CIDR address ranges. Works for IPv4 and IPv6 addresses.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=over 4
|
||||
|
||||
=item new()
|
||||
|
||||
$cidr = Net::CIDR::Lite->new
|
||||
$cidr = Net::CIDR::Lite->new(@args)
|
||||
|
||||
Creates an object to represent a list of CIDR address ranges.
|
||||
No particular format is set yet; once an add method is called
|
||||
with a IPv4 or IPv6 format, only that format may be added for this
|
||||
cidr object. Any arguments supplied are passed to add_any() (see below).
|
||||
|
||||
=item add()
|
||||
|
||||
$cidr->add($cidr_address)
|
||||
|
||||
Adds a CIDR address range to the list.
|
||||
|
||||
=item add_range()
|
||||
|
||||
$cidr->add_range($ip_range)
|
||||
|
||||
Adds a hyphenated IP address range to the list.
|
||||
|
||||
=item add_cidr()
|
||||
|
||||
$cidr1->add_cidr($cidr2)
|
||||
|
||||
Adds address ranges from one object to another object.
|
||||
|
||||
=item add_ip()
|
||||
|
||||
$cidr->add_ip($ip_address)
|
||||
|
||||
Adds a single IP address to the list.
|
||||
|
||||
=item add_any()
|
||||
|
||||
$cidr->add_any($cidr_or_range_or_address);
|
||||
|
||||
Determines format of range or single ip address and calls add(),
|
||||
add_range(), add_cidr(), or add_ip() as appropriate.
|
||||
|
||||
=item $cidr->clean()
|
||||
|
||||
$cidr->clean;
|
||||
|
||||
If you are going to call the list method more than once on the
|
||||
same data, then for optimal performance, you can call this to
|
||||
purge null nodes in overlapping ranges from the list. Boundary
|
||||
nodes in contiguous ranges are automatically purged during add().
|
||||
Only useful when ranges overlap or when contiguous ranges are added
|
||||
out of order.
|
||||
|
||||
=item $cidr->list()
|
||||
|
||||
@cidr_list = $cidr->list;
|
||||
$list_ref = $cidr->list;
|
||||
|
||||
Returns a list of the merged CIDR addresses. Returns an array if called
|
||||
in list context, an array reference if not.
|
||||
|
||||
=item $cidr->list_range()
|
||||
|
||||
@cidr_list = $cidr->list_range;
|
||||
$list_ref = $cidr->list_range;
|
||||
|
||||
Returns a list of the merged addresses, but in hyphenated range
|
||||
format. Returns an array if called in list context, an array reference
|
||||
if not.
|
||||
|
||||
=item $cidr->list_short_range()
|
||||
|
||||
@cidr_list = $cidr->list_short_range;
|
||||
$list_ref = $cidr->list_short_range;
|
||||
|
||||
Returns a list of the C subnet merged addresses, in short hyphenated range
|
||||
format. Returns an array if called in list context, an array reference
|
||||
if not.
|
||||
|
||||
Example:
|
||||
|
||||
1.1.1.1-2
|
||||
1.1.1.5-7
|
||||
1.1.1.254-255
|
||||
1.1.2.0-2
|
||||
1.1.3.5
|
||||
1.1.3.7
|
||||
|
||||
=item $cidr->find()
|
||||
|
||||
$found = $cidr->find($ip);
|
||||
|
||||
Returns true if the ip address is found in the CIDR range. False if not.
|
||||
Not extremely efficient, is O(n*log(n)) to sort the ranges in the
|
||||
cidr object O(n) to search through the ranges in the cidr object.
|
||||
The sort is cached on the first call and used in subsequent calls,
|
||||
but if more addresses are added to the cidr object, prep_find() must
|
||||
be called on the cidr object.
|
||||
|
||||
=item $cidr->bin_find()
|
||||
|
||||
Same as find(), but forces a binary search. See also prep_find.
|
||||
|
||||
=item $cidr->prep_find()
|
||||
|
||||
$cidr->prep_find($num);
|
||||
|
||||
Caches the result of sorting the ip addresses. Implicitly called on the first
|
||||
find call, but must be explicitly called if more addresses are added to
|
||||
the cidr object. find() will do a binary search if the number of ranges is
|
||||
greater than or equal to $num (default 20);
|
||||
|
||||
=item $cidr->spanner()
|
||||
|
||||
$spanner = $cidr1->spanner($label1, $cidr2, $label2, ...);
|
||||
|
||||
Creates a spanner object to find out if multiple ip addresses are within
|
||||
multiple labeled address ranges. May also be called as (with or without
|
||||
any arguments):
|
||||
|
||||
Net::CIDR::Lite::Span->new($cidr1, $label1, $cidr2, $label2, ...);
|
||||
|
||||
=item $spanner->add()
|
||||
|
||||
$spanner->add($cidr1, $label1, $cidr2, $label2,...);
|
||||
|
||||
Adds labeled address ranges to the spanner object. The 'address range' may
|
||||
be a Net::CIDR::Lite object, a single CIDR address range, a single
|
||||
hyphenated IP address range, or a single IP address.
|
||||
|
||||
=item $spanner->find()
|
||||
|
||||
$href = $spanner->find(@ip_addresses);
|
||||
|
||||
Look up which range(s) ip addresses are in, and return a lookup table
|
||||
of the results, with the keys being the ip addresses, and the value a
|
||||
hash reference of which address ranges the ip address is in.
|
||||
|
||||
=item $spanner->bin_find()
|
||||
|
||||
Same as find(), but forces a binary search. See also prep_find.
|
||||
|
||||
=item $spanner->prep_find()
|
||||
|
||||
$spanner->prep_find($num);
|
||||
|
||||
Called implicitly the first time $spanner->find(..) is called, must be called
|
||||
again if more cidr objects are added to the spanner object. Will do a
|
||||
binary search if ratio of the number of ip addresses to the number of ranges
|
||||
is less than $num percent (default 4).
|
||||
|
||||
=item $spanner->clean()
|
||||
|
||||
$clean_address = $spanner->clean($ip_address);
|
||||
|
||||
Validates and returns a cleaned up version of an ip address (which is
|
||||
what you will find as the key in the result from the $spanner->find(..),
|
||||
not necessarily what the original argument looked like). E.g. removes
|
||||
unnecessary leading zeros, removes null blocks from IPv6
|
||||
addresses, etc.
|
||||
|
||||
=back
|
||||
|
||||
=head1 CAVEATS
|
||||
|
||||
Garbage in/garbage out. This module does do validation, but maybe
|
||||
not enough to suit your needs.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Douglas Wilson, E<lt>dougw@cpan.orgE<gt>
|
||||
w/numerous hints and ideas borrowed from Tye McQueen.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This module is free software; you can redistribute it and/or
|
||||
modify it under the same terms as Perl itself.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Net::CIDR>.
|
||||
|
||||
=cut
|
||||
2679
csf/Net/IP.pm
Normal file
2679
csf/Net/IP.pm
Normal file
File diff suppressed because it is too large
Load Diff
9
csf/accounttracking.txt
Normal file
9
csf/accounttracking.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
From: root
|
||||
To: root
|
||||
Subject: lfd on [hostname]: Account modification alert
|
||||
|
||||
Time: [time]
|
||||
|
||||
Reported Modifications:
|
||||
|
||||
[report]
|
||||
13
csf/alert.txt
Normal file
13
csf/alert.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
From: root
|
||||
To: root
|
||||
Subject: lfd on [hostname]: blocked [ip]
|
||||
|
||||
Time: [time]
|
||||
IP: [ip]
|
||||
Failures: [ipcount]
|
||||
Interval: [iptick] seconds
|
||||
Blocked: [block]
|
||||
|
||||
Log entries:
|
||||
|
||||
[text]
|
||||
35
csf/apache.http.txt
Normal file
35
csf/apache.http.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
Listen 0.0.0.0:[PORT]
|
||||
Listen [::]:[PORT]
|
||||
|
||||
# Virtualhost start - do not remove this line
|
||||
<VirtualHost *:[PORT]>
|
||||
ServerName [SERVERNAME]
|
||||
DocumentRoot [DOCUMENTROOT]
|
||||
KeepAlive Off
|
||||
<Directory "[DIRECTORY]">
|
||||
AllowOverride All
|
||||
</Directory>
|
||||
<IfModule suphp_module>
|
||||
suPHP_Engine On
|
||||
suPHP_UserGroup [USER] [USER]
|
||||
</IfModule>
|
||||
<IfModule suexec_module>
|
||||
<IfModule !mod_ruid2.c>
|
||||
SuexecUserGroup [USER] [USER]
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
<IfModule ruid2_module>
|
||||
RMode config
|
||||
RUidGid [USER] [USER]
|
||||
</IfModule>
|
||||
<IfModule mpm_itk.c>
|
||||
AssignUserID [USER] [USER]
|
||||
</IfModule>
|
||||
<IfModule mod_lsapi.c>
|
||||
lsapi_user_group [USER] [USER]
|
||||
</IfModule>
|
||||
<FilesMatch "\.(inc|php)$">
|
||||
[PHPHANDLER]
|
||||
</FilesMatch>
|
||||
</VirtualHost>
|
||||
# Virtualhost end - do not remove this line
|
||||
43
csf/apache.https.txt
Normal file
43
csf/apache.https.txt
Normal file
@@ -0,0 +1,43 @@
|
||||
Listen 0.0.0.0:[SSLPORT]
|
||||
Listen [::]:[SSLPORT]
|
||||
|
||||
# Virtualhost start - do not remove this line
|
||||
<VirtualHost *:[SSLPORT]>
|
||||
ServerName [SERVERNAME]
|
||||
ServerAlias [SERVERALIAS]
|
||||
DocumentRoot [DOCUMENTROOT]
|
||||
UseCanonicalName Off
|
||||
KeepAlive Off
|
||||
<Directory "[DIRECTORY]">
|
||||
AllowOverride All
|
||||
</Directory>
|
||||
<IfModule suphp_module>
|
||||
suPHP_Engine On
|
||||
suPHP_UserGroup [USER] [USER]
|
||||
</IfModule>
|
||||
<IfModule suexec_module>
|
||||
<IfModule !mod_ruid2.c>
|
||||
SuexecUserGroup [USER] [USER]
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
<IfModule ruid2_module>
|
||||
RMode config
|
||||
RUidGid [USER] [USER]
|
||||
</IfModule>
|
||||
<IfModule mpm_itk.c>
|
||||
AssignUserID [USER] [USER]
|
||||
</IfModule>
|
||||
<IfModule mod_lsapi.c>
|
||||
lsapi_user_group [USER] [USER]
|
||||
</IfModule>
|
||||
ScriptAlias /local-bin /usr/bin
|
||||
<FilesMatch "\.(inc|php)$">
|
||||
[PHPHANDLER]
|
||||
</FilesMatch>
|
||||
SSLEngine on
|
||||
SSLCertificateFile [SSLCERTIFICATEFILE]
|
||||
SSLCertificateKeyFile [SSLCERTIFICATEKEYFILE]
|
||||
SSLCACertificateFile [SSLCACERTIFICATEFILE]
|
||||
SSLUseStapling off
|
||||
</VirtualHost>
|
||||
# Virtualhost end - do not remove this line
|
||||
0
csf/apache.main.txt
Normal file
0
csf/apache.main.txt
Normal file
43
csf/apf_stub.pl
Normal file
43
csf/apf_stub.pl
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my @cmd = @ARGV;
|
||||
|
||||
if ($cmd[0] eq "-a" or $cmd[0] eq "--allow") {
|
||||
$cmd[0] = "--add";
|
||||
system("csf",@cmd);
|
||||
}
|
||||
elsif ($cmd[0] eq "-d" or $cmd[0] eq "--deny") {
|
||||
$cmd[0] = "--deny";
|
||||
system("csf",@cmd);
|
||||
}
|
||||
elsif ($cmd[0] eq "-u" or $cmd[0] eq "--remove" or $cmd[0] eq "--unban") {
|
||||
$cmd[1] =~ s/\^|\$//g;
|
||||
$cmd[0] = "--addrm";
|
||||
system("csf",@cmd);
|
||||
$cmd[0] = "--denyrm";
|
||||
system("csf",@cmd);
|
||||
$cmd[0] = "--temprm";
|
||||
system("csf",@cmd);
|
||||
}
|
||||
elsif ($cmd[0] eq "-s" or $cmd[0] eq "--start") {
|
||||
$cmd[0] = "--start";
|
||||
system("csf",@cmd);
|
||||
}
|
||||
elsif ($cmd[0] eq "-f" or $cmd[0] eq "--flush" or $cmd[0] eq "--stop") {
|
||||
$cmd[0] = "--stop";
|
||||
system("csf",@cmd);
|
||||
}
|
||||
elsif ($cmd[0] eq "-r" or $cmd[0] eq "--restart") {
|
||||
$cmd[0] = "--restart";
|
||||
system("csf",@cmd);
|
||||
}
|
||||
elsif ($cmd[0] eq "-l" or $cmd[0] eq "--list") {
|
||||
$cmd[0] = "--status";
|
||||
system("csf",@cmd);
|
||||
} else {
|
||||
print "Unknown command, please use csf directly instead of this apf stub\n";
|
||||
}
|
||||
|
||||
exit;
|
||||
605
csf/auto.cwp.pl
Normal file
605
csf/auto.cwp.pl
Normal file
@@ -0,0 +1,605 @@
|
||||
#!/usr/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>.
|
||||
###############################################################################
|
||||
## no critic (ProhibitBarewordFileHandles, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
use strict;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use IPC::Open3;
|
||||
|
||||
umask(0177);
|
||||
|
||||
our (%config, %configsetting, $vps, $oldversion);
|
||||
|
||||
$oldversion = $ARGV[0];
|
||||
|
||||
open (VERSION, "<","/etc/csf/version.txt");
|
||||
flock (VERSION, LOCK_SH);
|
||||
my $version = <VERSION>;
|
||||
close (VERSION);
|
||||
chomp $version;
|
||||
$version =~ s/\W/_/g;
|
||||
system("/bin/cp","-avf","/etc/csf/csf.conf","/var/lib/csf/backup/".time."_pre_v${version}_upgrade");
|
||||
|
||||
&loadcsfconfig;
|
||||
|
||||
foreach my $alertfile ("sshalert.txt","sualert.txt","sudoalert.txt","webminalert.txt","cpanelalert.txt") {
|
||||
if (-e "/usr/local/csf/tpl/".$alertfile) {
|
||||
sysopen (my $IN, "/usr/local/csf/tpl/".$alertfile, O_RDWR | O_CREAT);
|
||||
flock ($IN, LOCK_EX);
|
||||
my @data = <$IN>;
|
||||
chomp @data;
|
||||
my $hit = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /\[text\]/) {$hit = 1}
|
||||
}
|
||||
unless ($hit) {
|
||||
print $IN "\nLog line:\n\n[text]\n";
|
||||
}
|
||||
close ($IN);
|
||||
}
|
||||
}
|
||||
|
||||
if (-e "/proc/vz/veinfo") {
|
||||
$vps = 1;
|
||||
} else {
|
||||
open (IN, "<","/proc/self/status");
|
||||
flock (IN, LOCK_SH);
|
||||
while (my $line = <IN>) {
|
||||
chomp $line;
|
||||
if ($line =~ /^envID:\s*(\d+)\s*$/) {
|
||||
if ($1 > 0) {
|
||||
$vps = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/usr/local/cwpsrv") {
|
||||
sysopen (my $CWP, "/usr/local/cwpsrv/htdocs/resources/admin/include/3rdparty.php", O_RDWR | O_CREAT);
|
||||
flock ($CWP, LOCK_EX);
|
||||
my @data = <$CWP>;
|
||||
chomp @data;
|
||||
if (!(grep {$_ =~ /configserver/} @data)) {
|
||||
|
||||
seek ($CWP, 0, 0);
|
||||
truncate ($CWP, 0);
|
||||
foreach my $line (@data) {
|
||||
print $CWP $line."\n";
|
||||
}
|
||||
print $CWP "<?php include('/usr/local/cwpsrv/htdocs/resources/admin/include/configserver.php'); ?>\n";
|
||||
}
|
||||
close ($CWP);
|
||||
}
|
||||
|
||||
if (&checkversion("10.11") and !-e "/var/lib/csf/auto1011") {
|
||||
if (-e "/var/lib/csf/stats/lfdstats") {
|
||||
sysopen (STATS,"/var/lib/csf/stats/lfdstats", O_RDWR | O_CREAT);
|
||||
flock (STATS, LOCK_EX);
|
||||
my @stats = <STATS>;
|
||||
chomp @stats;
|
||||
my %ccs;
|
||||
my @line = split(/\,/,$stats[69]);
|
||||
for (my $x = 0; $x < @line; $x+=2) {$ccs{$line[$x]} = $line[$x+1]}
|
||||
$stats[69] = "";
|
||||
foreach my $key (keys %ccs) {$stats[69] .= "$key,$ccs{$key},"}
|
||||
seek (STATS, 0, 0);
|
||||
truncate (STATS, 0);
|
||||
foreach my $line (@stats) {
|
||||
print STATS "$line\n";
|
||||
}
|
||||
close (STATS);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1011");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("10.23") and !-e "/var/lib/csf/auto1023") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
my $SPAMDROPV6 = 0;
|
||||
my $STOPFORUMSPAMV6 = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^(\#)?SPAMDROPV6/) {$SPAMDROPV6 = 1}
|
||||
if ($line =~ /^(\#)?STOPFORUMSPAMV6/) {$STOPFORUMSPAMV6 = 1}
|
||||
print IN "$line\n";
|
||||
}
|
||||
unless ($SPAMDROPV6) {
|
||||
print IN "\n# Spamhaus IPv6 Don't Route Or Peer List (DROPv6)\n";
|
||||
print IN "# Details: http://www.spamhaus.org/drop/\n";
|
||||
print IN "#SPAMDROPV6|86400|0|https://www.spamhaus.org/drop/dropv6.txt\n";
|
||||
}
|
||||
unless ($STOPFORUMSPAMV6) {
|
||||
print IN "\n# Stop Forum Spam IPv6\n";
|
||||
print IN "# Details: http://www.stopforumspam.com/downloads/\n";
|
||||
print IN "# Many of the lists available contain a vast number of IP addresses so special\n";
|
||||
print IN "# care needs to be made when selecting from their lists\n";
|
||||
print IN "#STOPFORUMSPAMV6|86400|0|http://www.stopforumspam.com/downloads/listed_ip_1_ipv6.zip\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1023");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("12.02") and !-e "/var/lib/csf/auto1202") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /greensnow/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1202");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("14.03") and !-e "/var/lib/csf/auto1403") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /dshield/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1403");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
|
||||
if (-e "/etc/csf/csf.allow") {
|
||||
sysopen (IN,"/etc/csf/csf.allow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.allow/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.ignore") {
|
||||
sysopen (IN,"/etc/csf/csf.ignore", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.ignore/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/usr/local/csf/bin/regex.custom.pm") {
|
||||
sysopen (IN,"/usr/local/csf/bin/regex.custom.pm", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^use strict;/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /feeds\.dshield\.org/) {$line =~ s/feeds\.dshield\.org/www\.dshield\.org/g}
|
||||
if ($line =~ /openbl\.org/i) {next}
|
||||
if ($line =~ /autoshun/i) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempban") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempban", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempallow") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempallow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
if ($config{TESTING}) {
|
||||
|
||||
open (IN, "<", "/etc/ssh/sshd_config") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @sshconfig = <IN>;
|
||||
close (IN);
|
||||
chomp @sshconfig;
|
||||
|
||||
my $sshport = "22";
|
||||
foreach my $line (@sshconfig) {
|
||||
if ($line =~ /^Port (\d+)/) {$sshport = $1}
|
||||
}
|
||||
|
||||
$config{TCP_IN} =~ s/\s//g;
|
||||
if ($config{TCP_IN} ne "") {
|
||||
foreach my $port (split(/\,/,$config{TCP_IN})) {
|
||||
if ($port eq $sshport) {$sshport = "22"}
|
||||
}
|
||||
}
|
||||
|
||||
if ($sshport ne "22") {
|
||||
$config{TCP_IN} .= ",$sshport";
|
||||
$config{TCP6_IN} .= ",$sshport";
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^TCP6_IN/) {
|
||||
print OUT "TCP6_IN = \"$config{TCP6_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP6_IN port list\n\n";
|
||||
}
|
||||
elsif ($line =~ /^TCP_IN/) {
|
||||
print OUT "TCP_IN = \"$config{TCP_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP_IN port list\n\n";
|
||||
}
|
||||
else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
|
||||
}
|
||||
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (IN, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
chomp @data;
|
||||
if ($data[0] =~ /^(\d+)\.(\d+)\.(\d+)/) {
|
||||
my $maj = $1;
|
||||
my $mid = $2;
|
||||
my $min = $3;
|
||||
if ($maj == 3 and $mid > 6) {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^USE_CONNTRACK =/) {
|
||||
print OUT "USE_CONNTRACK = \"1\"\n";
|
||||
print "\n*** USE_CONNTRACK Enabled\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
|
||||
my @ipdata;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die "alarm\n"};
|
||||
alarm(3);
|
||||
my ($childin, $childout);
|
||||
my $cmdpid = open3($childin, $childout, $childout, "$config{IPTABLES} --wait -L OUTPUT -nv");
|
||||
@ipdata = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ipdata;
|
||||
if ($ipdata[0] =~ /# Warning: iptables-legacy tables present/) {shift @ipdata}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($@ ne "alarm\n" and $ipdata[0] =~ /^Chain OUTPUT/) {
|
||||
$config{IPTABLESWAIT} = "--wait";
|
||||
$config{WAITLOCK} = 1;
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /WAITLOCK =/) {
|
||||
print OUT "WAITLOCK = \"1\"\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
|
||||
if (-e $config{IP6TABLES} and !$vps) {
|
||||
my ($childin, $childout);
|
||||
my $cmdpid;
|
||||
if (-e $config{IP}) {$cmdpid = open3($childin, $childout, $childout, $config{IP}, "-oneline", "addr")}
|
||||
elsif (-e $config{IFCONFIG}) {$cmdpid = open3($childin, $childout, $childout, $config{IFCONFIG})}
|
||||
my @ifconfig = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ifconfig;
|
||||
if (grep {$_ =~ /\s*inet6/} @ifconfig) {
|
||||
$config{IPV6} = 1;
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (IN, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
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 > 6)) or (($maj > 1) and ($mid > 5) and ($min > 19))) {
|
||||
$config{IPV6_SPI} = 1;
|
||||
} else {
|
||||
$config{IPV6_SPI} = 0;
|
||||
}
|
||||
}
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^IPV6 =/) {
|
||||
print OUT "IPV6 = \"$config{IPV6}\"\n";
|
||||
print "\n*** IPV6 Enabled\n\n";
|
||||
}
|
||||
elsif ($line =~ /^IPV6_SPI =/) {
|
||||
print OUT "IPV6_SPI = \"$config{IPV6_SPI}\"\n";
|
||||
print "\n*** IPV6_SPI set to $config{IPV6_SPI}\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open (IN, "<", "csf.cwp.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
if ($line !~ /=/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
if (&checkversion("10.15") and !-e "/var/lib/csf/auto1015") {
|
||||
if ($name eq "MESSENGER_RATE" and $config{$name} eq "30/m") {$config{$name} = "100/s"}
|
||||
if ($name eq "MESSENGER_BURST" and $config{$name} eq "5") {$config{$name} = "150"}
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto1015");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
if ($configsetting{$name}) {
|
||||
print OUT "$name = \"$config{$name}\"\n";
|
||||
} else {
|
||||
if (&checkversion("9.29") and !-e "/var/lib/csf/auto929" and $name eq "PT_USERRSS") {
|
||||
$line = "PT_USERRSS = \"$config{PT_USERMEM}\"";
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto929");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
if ($name eq "CC_SRC") {$line = "CC_SRC = \"1\""}
|
||||
print OUT $line."\n";
|
||||
print "New setting: $name\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
|
||||
if ($config{TESTING}) {
|
||||
my @netstat = `netstat -lpn`;
|
||||
chomp @netstat;
|
||||
my @tcpports;
|
||||
my @udpports;
|
||||
my @tcp6ports;
|
||||
my @udp6ports;
|
||||
foreach my $line (@netstat) {
|
||||
if ($line =~ /^(\w+).* (\d+\.\d+\.\d+\.\d+):(\d+)/) {
|
||||
if ($2 eq '127.0.0.1') {next}
|
||||
if ($1 eq "tcp") {
|
||||
push @tcpports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udpports, $3;
|
||||
}
|
||||
}
|
||||
if ($line =~ /^(\w+).* (::):(\d+) /) {
|
||||
if ($1 eq "tcp") {
|
||||
push @tcp6ports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udp6ports, $3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@tcpports = sort { $a <=> $b } @tcpports;
|
||||
@udpports = sort { $a <=> $b } @udpports;
|
||||
@tcp6ports = sort { $a <=> $b } @tcp6ports;
|
||||
@udp6ports = sort { $a <=> $b } @udp6ports;
|
||||
|
||||
print "\nTCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n\nUDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
my $opts = "TCP_*, UDP_*";
|
||||
if (@tcp6ports or @udp6ports) {
|
||||
$opts .= ", IPV6, TCP6_*, UDP6_*";
|
||||
print "\n\nIPv6 TCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
print "\nIPv6 UDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
}
|
||||
print "\n\nNote: The port details above are for information only, csf hasn't been auto-configured.\n\n";
|
||||
print "Don't forget to:\n";
|
||||
print "1. Configure the following options in the csf configuration to suite your server: $opts\n";
|
||||
print "2. Restart csf and lfd\n";
|
||||
print "3. Set TESTING to 0 once you're happy with the firewall, lfd will not run until you do so\n";
|
||||
}
|
||||
|
||||
if ($ENV{SSH_CLIENT}) {
|
||||
my $ip = (split(/ /,$ENV{SSH_CLIENT}))[0];
|
||||
if ($ip =~ /(\d+\.\d+\.\d+\.\d+)/) {
|
||||
print "\nAdding current SSH session IP address to the csf whitelist in csf.allow:\n";
|
||||
system("/usr/sbin/csf -a $1 csf SSH installation/upgrade IP address");
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
###############################################################################
|
||||
sub loadcsfconfig {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {next}
|
||||
if ($line !~ /=/) {next}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
$config{$name} = $value;
|
||||
$configsetting{$name} = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
###############################################################################
|
||||
sub checkversion {
|
||||
my $version = shift;
|
||||
my ($maj, $min) = split(/\./,$version);
|
||||
my ($oldmaj, $oldmin) = split(/\./,$oldversion);
|
||||
|
||||
if ($oldmaj == 0 or $oldmaj eq "") {return 0}
|
||||
|
||||
if (($oldmaj < $maj) or ($oldmaj == $maj and $oldmin < $min)) {return 1} else {return 0}
|
||||
}
|
||||
###############################################################################
|
||||
589
csf/auto.cyberpanel.pl
Normal file
589
csf/auto.cyberpanel.pl
Normal file
@@ -0,0 +1,589 @@
|
||||
#!/usr/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>.
|
||||
###############################################################################
|
||||
## no critic (ProhibitBarewordFileHandles, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
use strict;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use IPC::Open3;
|
||||
|
||||
umask(0177);
|
||||
|
||||
our (%config, %configsetting, $vps, $oldversion);
|
||||
|
||||
$oldversion = $ARGV[0];
|
||||
|
||||
open (VERSION, "<","/etc/csf/version.txt");
|
||||
flock (VERSION, LOCK_SH);
|
||||
my $version = <VERSION>;
|
||||
close (VERSION);
|
||||
chomp $version;
|
||||
$version =~ s/\W/_/g;
|
||||
system("/bin/cp","-avf","/etc/csf/csf.conf","/var/lib/csf/backup/".time."_pre_v${version}_upgrade");
|
||||
|
||||
&loadcsfconfig;
|
||||
|
||||
if (-e "/proc/vz/veinfo") {
|
||||
$vps = 1;
|
||||
} else {
|
||||
open (IN, "<","/proc/self/status");
|
||||
flock (IN, LOCK_SH);
|
||||
while (my $line = <IN>) {
|
||||
chomp $line;
|
||||
if ($line =~ /^envID:\s*(\d+)\s*$/) {
|
||||
if ($1 > 0) {
|
||||
$vps = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
foreach my $alertfile ("sshalert.txt","sualert.txt","sudoalert.txt","webminalert.txt","cpanelalert.txt") {
|
||||
if (-e "/usr/local/csf/tpl/".$alertfile) {
|
||||
sysopen (my $IN, "/usr/local/csf/tpl/".$alertfile, O_RDWR | O_CREAT);
|
||||
flock ($IN, LOCK_EX);
|
||||
my @data = <$IN>;
|
||||
chomp @data;
|
||||
my $hit = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /\[text\]/) {$hit = 1}
|
||||
}
|
||||
unless ($hit) {
|
||||
print $IN "\nLog line:\n\n[text]\n";
|
||||
}
|
||||
close ($IN);
|
||||
}
|
||||
}
|
||||
|
||||
if (&checkversion("10.11") and !-e "/var/lib/csf/auto1011") {
|
||||
if (-e "/var/lib/csf/stats/lfdstats") {
|
||||
sysopen (STATS,"/var/lib/csf/stats/lfdstats", O_RDWR | O_CREAT);
|
||||
flock (STATS, LOCK_EX);
|
||||
my @stats = <STATS>;
|
||||
chomp @stats;
|
||||
my %ccs;
|
||||
my @line = split(/\,/,$stats[69]);
|
||||
for (my $x = 0; $x < @line; $x+=2) {$ccs{$line[$x]} = $line[$x+1]}
|
||||
$stats[69] = "";
|
||||
foreach my $key (keys %ccs) {$stats[69] .= "$key,$ccs{$key},"}
|
||||
seek (STATS, 0, 0);
|
||||
truncate (STATS, 0);
|
||||
foreach my $line (@stats) {
|
||||
print STATS "$line\n";
|
||||
}
|
||||
close (STATS);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1011");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("10.23") and !-e "/var/lib/csf/auto1023") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
my $SPAMDROPV6 = 0;
|
||||
my $STOPFORUMSPAMV6 = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^(\#)?SPAMDROPV6/) {$SPAMDROPV6 = 1}
|
||||
if ($line =~ /^(\#)?STOPFORUMSPAMV6/) {$STOPFORUMSPAMV6 = 1}
|
||||
print IN "$line\n";
|
||||
}
|
||||
unless ($SPAMDROPV6) {
|
||||
print IN "\n# Spamhaus IPv6 Don't Route Or Peer List (DROPv6)\n";
|
||||
print IN "# Details: http://www.spamhaus.org/drop/\n";
|
||||
print IN "#SPAMDROPV6|86400|0|https://www.spamhaus.org/drop/dropv6.txt\n";
|
||||
}
|
||||
unless ($STOPFORUMSPAMV6) {
|
||||
print IN "\n# Stop Forum Spam IPv6\n";
|
||||
print IN "# Details: http://www.stopforumspam.com/downloads/\n";
|
||||
print IN "# Many of the lists available contain a vast number of IP addresses so special\n";
|
||||
print IN "# care needs to be made when selecting from their lists\n";
|
||||
print IN "#STOPFORUMSPAMV6|86400|0|http://www.stopforumspam.com/downloads/listed_ip_1_ipv6.zip\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1023");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("12.02") and !-e "/var/lib/csf/auto1202") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /greensnow/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1202");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("14.03") and !-e "/var/lib/csf/auto1403") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /dshield/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1403");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
|
||||
if (-e "/etc/csf/csf.allow") {
|
||||
sysopen (IN,"/etc/csf/csf.allow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.allow/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.ignore") {
|
||||
sysopen (IN,"/etc/csf/csf.ignore", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.ignore/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/usr/local/csf/bin/regex.custom.pm") {
|
||||
sysopen (IN,"/usr/local/csf/bin/regex.custom.pm", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^use strict;/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /feeds\.dshield\.org/) {$line =~ s/feeds\.dshield\.org/www\.dshield\.org/g}
|
||||
if ($line =~ /openbl\.org/i) {next}
|
||||
if ($line =~ /autoshun/i) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempban") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempban", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempallow") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempallow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
if ($config{TESTING}) {
|
||||
|
||||
open (IN, "<", "/etc/ssh/sshd_config") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @sshconfig = <IN>;
|
||||
close (IN);
|
||||
chomp @sshconfig;
|
||||
|
||||
my $sshport = "22";
|
||||
foreach my $line (@sshconfig) {
|
||||
if ($line =~ /^Port (\d+)/) {$sshport = $1}
|
||||
}
|
||||
|
||||
$config{TCP_IN} =~ s/\s//g;
|
||||
if ($config{TCP_IN} ne "") {
|
||||
foreach my $port (split(/\,/,$config{TCP_IN})) {
|
||||
if ($port eq $sshport) {$sshport = "22"}
|
||||
}
|
||||
}
|
||||
|
||||
if ($sshport ne "22") {
|
||||
$config{TCP_IN} .= ",$sshport";
|
||||
$config{TCP6_IN} .= ",$sshport";
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^TCP6_IN/) {
|
||||
print OUT "TCP6_IN = \"$config{TCP6_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP6_IN port list\n\n";
|
||||
}
|
||||
elsif ($line =~ /^TCP_IN/) {
|
||||
print OUT "TCP_IN = \"$config{TCP_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP_IN port list\n\n";
|
||||
}
|
||||
else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
|
||||
}
|
||||
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (IN, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
chomp @data;
|
||||
if ($data[0] =~ /^(\d+)\.(\d+)\.(\d+)/) {
|
||||
my $maj = $1;
|
||||
my $mid = $2;
|
||||
my $min = $3;
|
||||
if ($maj == 3 and $mid > 6) {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^USE_CONNTRACK =/) {
|
||||
print OUT "USE_CONNTRACK = \"1\"\n";
|
||||
print "\n*** USE_CONNTRACK Enabled\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
|
||||
my @ipdata;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die "alarm\n"};
|
||||
alarm(3);
|
||||
my ($childin, $childout);
|
||||
my $cmdpid = open3($childin, $childout, $childout, "$config{IPTABLES} --wait -L OUTPUT -nv");
|
||||
@ipdata = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ipdata;
|
||||
if ($ipdata[0] =~ /# Warning: iptables-legacy tables present/) {shift @ipdata}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($@ ne "alarm\n" and $ipdata[0] =~ /^Chain OUTPUT/) {
|
||||
$config{IPTABLESWAIT} = "--wait";
|
||||
$config{WAITLOCK} = 1;
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /WAITLOCK =/) {
|
||||
print OUT "WAITLOCK = \"1\"\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
|
||||
if (-e $config{IP6TABLES} and !$vps) {
|
||||
my ($childin, $childout);
|
||||
my $cmdpid;
|
||||
if (-e $config{IP}) {$cmdpid = open3($childin, $childout, $childout, $config{IP}, "-oneline", "addr")}
|
||||
elsif (-e $config{IFCONFIG}) {$cmdpid = open3($childin, $childout, $childout, $config{IFCONFIG})}
|
||||
my @ifconfig = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ifconfig;
|
||||
if (grep {$_ =~ /\s*inet6/} @ifconfig) {
|
||||
$config{IPV6} = 1;
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (IN, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
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 > 6)) or (($maj > 1) and ($mid > 5) and ($min > 19))) {
|
||||
$config{IPV6_SPI} = 1;
|
||||
} else {
|
||||
$config{IPV6_SPI} = 0;
|
||||
}
|
||||
}
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^IPV6 =/) {
|
||||
print OUT "IPV6 = \"$config{IPV6}\"\n";
|
||||
print "\n*** IPV6 Enabled\n\n";
|
||||
}
|
||||
elsif ($line =~ /^IPV6_SPI =/) {
|
||||
print OUT "IPV6_SPI = \"$config{IPV6_SPI}\"\n";
|
||||
print "\n*** IPV6_SPI set to $config{IPV6_SPI}\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open (IN, "<", "csf.cyberpanel.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
if ($line !~ /=/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
if (&checkversion("10.15") and !-e "/var/lib/csf/auto1015") {
|
||||
if ($name eq "MESSENGER_RATE" and $config{$name} eq "30/m") {$config{$name} = "100/s"}
|
||||
if ($name eq "MESSENGER_BURST" and $config{$name} eq "5") {$config{$name} = "150"}
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto1015");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
if ($configsetting{$name}) {
|
||||
print OUT "$name = \"$config{$name}\"\n";
|
||||
} else {
|
||||
if (&checkversion("9.29") and !-e "/var/lib/csf/auto929" and $name eq "PT_USERRSS") {
|
||||
$line = "PT_USERRSS = \"$config{PT_USERMEM}\"";
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto929");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
if ($name eq "CC_SRC") {$line = "CC_SRC = \"1\""}
|
||||
print OUT $line."\n";
|
||||
print "New setting: $name\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
|
||||
if ($config{TESTING}) {
|
||||
my @netstat = `netstat -lpn`;
|
||||
chomp @netstat;
|
||||
my @tcpports;
|
||||
my @udpports;
|
||||
my @tcp6ports;
|
||||
my @udp6ports;
|
||||
foreach my $line (@netstat) {
|
||||
if ($line =~ /^(\w+).* (\d+\.\d+\.\d+\.\d+):(\d+)/) {
|
||||
if ($2 eq '127.0.0.1') {next}
|
||||
if ($1 eq "tcp") {
|
||||
push @tcpports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udpports, $3;
|
||||
}
|
||||
}
|
||||
if ($line =~ /^(\w+).* (::):(\d+) /) {
|
||||
if ($1 eq "tcp") {
|
||||
push @tcp6ports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udp6ports, $3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@tcpports = sort { $a <=> $b } @tcpports;
|
||||
@udpports = sort { $a <=> $b } @udpports;
|
||||
@tcp6ports = sort { $a <=> $b } @tcp6ports;
|
||||
@udp6ports = sort { $a <=> $b } @udp6ports;
|
||||
|
||||
print "\nTCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n\nUDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
my $opts = "TCP_*, UDP_*";
|
||||
if (@tcp6ports or @udp6ports) {
|
||||
$opts .= ", IPV6, TCP6_*, UDP6_*";
|
||||
print "\n\nIPv6 TCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
print "\nIPv6 UDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
}
|
||||
print "\n\nNote: The port details above are for information only, csf hasn't been auto-configured.\n\n";
|
||||
print "Don't forget to:\n";
|
||||
print "1. Configure the following options in the csf configuration to suite your server: $opts\n";
|
||||
print "2. Restart csf and lfd\n";
|
||||
print "3. Set TESTING to 0 once you're happy with the firewall, lfd will not run until you do so\n";
|
||||
}
|
||||
|
||||
if ($ENV{SSH_CLIENT}) {
|
||||
my $ip = (split(/ /,$ENV{SSH_CLIENT}))[0];
|
||||
if ($ip =~ /(\d+\.\d+\.\d+\.\d+)/) {
|
||||
print "\nAdding current SSH session IP address to the csf whitelist in csf.allow:\n";
|
||||
system("/usr/sbin/csf -a $1 csf SSH installation/upgrade IP address");
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
###############################################################################
|
||||
sub loadcsfconfig {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {next}
|
||||
if ($line !~ /=/) {next}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
$config{$name} = $value;
|
||||
$configsetting{$name} = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
###############################################################################
|
||||
sub checkversion {
|
||||
my $version = shift;
|
||||
my ($maj, $min) = split(/\./,$version);
|
||||
my ($oldmaj, $oldmin) = split(/\./,$oldversion);
|
||||
|
||||
if ($oldmaj == 0 or $oldmaj eq "") {return 0}
|
||||
|
||||
if (($oldmaj < $maj) or ($oldmaj == $maj and $oldmin < $min)) {return 1} else {return 0}
|
||||
}
|
||||
###############################################################################
|
||||
618
csf/auto.directadmin.pl
Normal file
618
csf/auto.directadmin.pl
Normal file
@@ -0,0 +1,618 @@
|
||||
#!/usr/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>.
|
||||
###############################################################################
|
||||
## no critic (ProhibitBarewordFileHandles, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
use strict;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use IPC::Open3;
|
||||
|
||||
umask(0177);
|
||||
|
||||
our (%config, %configsetting, $vps, $oldversion);
|
||||
|
||||
$oldversion = $ARGV[0];
|
||||
|
||||
open (VERSION, "<","/etc/csf/version.txt");
|
||||
flock (VERSION, LOCK_SH);
|
||||
my $version = <VERSION>;
|
||||
close (VERSION);
|
||||
chomp $version;
|
||||
$version =~ s/\W/_/g;
|
||||
system("/bin/cp","-avf","/etc/csf/csf.conf","/var/lib/csf/backup/".time."_pre_v${version}_upgrade");
|
||||
|
||||
&loadcsfconfig;
|
||||
|
||||
if (-e "/proc/vz/veinfo") {
|
||||
$vps = 1;
|
||||
} else {
|
||||
open (IN, "<","/proc/self/status");
|
||||
flock (IN, LOCK_SH);
|
||||
while (my $line = <IN>) {
|
||||
chomp $line;
|
||||
if ($line =~ /^envID:\s*(\d+)\s*$/) {
|
||||
if ($1 > 0) {
|
||||
$vps = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
foreach my $alertfile ("sshalert.txt","sualert.txt","sudoalert.txt","webminalert.txt","cpanelalert.txt") {
|
||||
if (-e "/usr/local/csf/tpl/".$alertfile) {
|
||||
sysopen (my $IN, "/usr/local/csf/tpl/".$alertfile, O_RDWR | O_CREAT);
|
||||
flock ($IN, LOCK_EX);
|
||||
my @data = <$IN>;
|
||||
chomp @data;
|
||||
my $hit = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /\[text\]/) {$hit = 1}
|
||||
}
|
||||
unless ($hit) {
|
||||
print $IN "\nLog line:\n\n[text]\n";
|
||||
}
|
||||
close ($IN);
|
||||
}
|
||||
}
|
||||
|
||||
if (&checkversion("10.11") and !-e "/var/lib/csf/auto1011") {
|
||||
if (-e "/var/lib/csf/stats/lfdstats") {
|
||||
sysopen (STATS,"/var/lib/csf/stats/lfdstats", O_RDWR | O_CREAT);
|
||||
flock (STATS, LOCK_EX);
|
||||
my @stats = <STATS>;
|
||||
chomp @stats;
|
||||
my %ccs;
|
||||
my @line = split(/\,/,$stats[69]);
|
||||
for (my $x = 0; $x < @line; $x+=2) {$ccs{$line[$x]} = $line[$x+1]}
|
||||
$stats[69] = "";
|
||||
foreach my $key (keys %ccs) {$stats[69] .= "$key,$ccs{$key},"}
|
||||
seek (STATS, 0, 0);
|
||||
truncate (STATS, 0);
|
||||
foreach my $line (@stats) {
|
||||
print STATS "$line\n";
|
||||
}
|
||||
close (STATS);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1011");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("10.23") and !-e "/var/lib/csf/auto1023") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
my $SPAMDROPV6 = 0;
|
||||
my $STOPFORUMSPAMV6 = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^(\#)?SPAMDROPV6/) {$SPAMDROPV6 = 1}
|
||||
if ($line =~ /^(\#)?STOPFORUMSPAMV6/) {$STOPFORUMSPAMV6 = 1}
|
||||
print IN "$line\n";
|
||||
}
|
||||
unless ($SPAMDROPV6) {
|
||||
print IN "\n# Spamhaus IPv6 Don't Route Or Peer List (DROPv6)\n";
|
||||
print IN "# Details: http://www.spamhaus.org/drop/\n";
|
||||
print IN "#SPAMDROPV6|86400|0|https://www.spamhaus.org/drop/dropv6.txt\n";
|
||||
}
|
||||
unless ($STOPFORUMSPAMV6) {
|
||||
print IN "\n# Stop Forum Spam IPv6\n";
|
||||
print IN "# Details: http://www.stopforumspam.com/downloads/\n";
|
||||
print IN "# Many of the lists available contain a vast number of IP addresses so special\n";
|
||||
print IN "# care needs to be made when selecting from their lists\n";
|
||||
print IN "#STOPFORUMSPAMV6|86400|0|http://www.stopforumspam.com/downloads/listed_ip_1_ipv6.zip\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1023");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("12.02") and !-e "/var/lib/csf/auto1202") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /greensnow/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1202");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("14.03") and !-e "/var/lib/csf/auto1403") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /dshield/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
}
|
||||
|
||||
if (-e "/etc/csf/csf.allow") {
|
||||
sysopen (IN,"/etc/csf/csf.allow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.allow/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.ignore") {
|
||||
sysopen (IN,"/etc/csf/csf.ignore", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.ignore/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/usr/local/csf/bin/regex.custom.pm") {
|
||||
sysopen (IN,"/usr/local/csf/bin/regex.custom.pm", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^use strict;/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /feeds\.dshield\.org/) {$line =~ s/feeds\.dshield\.org/www\.dshield\.org/g}
|
||||
if ($line =~ /openbl\.org/i) {next}
|
||||
if ($line =~ /autoshun/i) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempban") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempban", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempallow") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempallow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (IN,"<", "/usr/local/directadmin/data/admin/services.status");
|
||||
flock (IN, LOCK_SH);
|
||||
my @chkservd = <IN>;
|
||||
close (IN);
|
||||
chomp @chkservd;
|
||||
|
||||
if (not grep {$_ =~ /^lfd/} @chkservd) {
|
||||
open (OUT, ">>", "/usr/local/directadmin/data/admin/services.status");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT "lfd=ON\n";
|
||||
close OUT;
|
||||
}
|
||||
|
||||
if ($config{TESTING}) {
|
||||
|
||||
open (IN, "<", "/etc/ssh/sshd_config") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @sshconfig = <IN>;
|
||||
close (IN);
|
||||
chomp @sshconfig;
|
||||
|
||||
my $sshport = "22";
|
||||
foreach my $line (@sshconfig) {
|
||||
if ($line =~ /^Port (\d+)/) {$sshport = $1}
|
||||
}
|
||||
|
||||
$config{TCP_IN} =~ s/\s//g;
|
||||
if ($config{TCP_IN} ne "") {
|
||||
foreach my $port (split(/\,/,$config{TCP_IN})) {
|
||||
if ($port eq $sshport) {$sshport = "22"}
|
||||
}
|
||||
}
|
||||
|
||||
if ($sshport ne "22") {
|
||||
$config{TCP_IN} .= ",$sshport";
|
||||
$config{TCP6_IN} .= ",$sshport";
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^TCP6_IN/) {
|
||||
print OUT "TCP6_IN = \"$config{TCP6_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP6_IN port list\n\n";
|
||||
}
|
||||
elsif ($line =~ /^TCP_IN/) {
|
||||
print OUT "TCP_IN = \"$config{TCP_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP_IN port list\n\n";
|
||||
}
|
||||
else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (FH, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
chomp @data;
|
||||
if ($data[0] =~ /^(\d+)\.(\d+)\.(\d+)/) {
|
||||
my $maj = $1;
|
||||
my $mid = $2;
|
||||
my $min = $3;
|
||||
if ($maj == 3 and $mid > 6) {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^USE_CONNTRACK =/) {
|
||||
print OUT "USE_CONNTRACK = \"1\"\n";
|
||||
print "\n*** USE_CONNTRACK Enabled\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
|
||||
my @ipdata;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die "alarm\n"};
|
||||
alarm(3);
|
||||
my ($childin, $childout);
|
||||
my $cmdpid = open3($childin, $childout, $childout, "$config{IPTABLES} --wait -L OUTPUT -nv");
|
||||
@ipdata = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ipdata;
|
||||
if ($ipdata[0] =~ /# Warning: iptables-legacy tables present/) {shift @ipdata}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($@ ne "alarm\n" and $ipdata[0] =~ /^Chain OUTPUT/) {
|
||||
$config{IPTABLESWAIT} = "--wait";
|
||||
$config{WAITLOCK} = 1;
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /WAITLOCK =/) {
|
||||
print OUT "WAITLOCK = \"1\"\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
|
||||
if (-e $config{IP6TABLES} and !$vps) {
|
||||
my ($childin, $childout);
|
||||
my $cmdpid;
|
||||
if (-e $config{IP}) {$cmdpid = open3($childin, $childout, $childout, $config{IP}, "-oneline", "addr")}
|
||||
elsif (-e $config{IFCONFIG}) {$cmdpid = open3($childin, $childout, $childout, $config{IFCONFIG})}
|
||||
my @ifconfig = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ifconfig;
|
||||
if (grep {$_ =~ /\s*inet6/} @ifconfig) {
|
||||
$config{IPV6} = 1;
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (FH, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
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 > 6)) or (($maj > 1) and ($mid > 5) and ($min > 19))) {
|
||||
$config{IPV6_SPI} = 1;
|
||||
} else {
|
||||
$config{IPV6_SPI} = 0;
|
||||
}
|
||||
}
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^IPV6 =/) {
|
||||
print OUT "IPV6 = \"$config{IPV6}\"\n";
|
||||
print "\n*** IPV6 Enabled\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $roundcube;
|
||||
if (&checkversion("14.03") and !-e "/var/lib/csf/auto1403") {
|
||||
$roundcube = 1.4;
|
||||
open (my $RC, "<", "/var/www/html/roundcube/program/include/iniset.php");
|
||||
flock ($RC, LOCK_SH);
|
||||
foreach my $line (<$RC>) {
|
||||
chomp $line;
|
||||
if ($line =~ /define\s*\(\s*'RCMAIL_VERSION'\s*,\s*'([^']*)'/) {
|
||||
$roundcube = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close ($RC);
|
||||
if ($roundcube < 1.4) {$roundcube = 0} else {$roundcube = 1}
|
||||
}
|
||||
|
||||
open (IN, "<", "csf.directadmin.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
if ($line !~ /=/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
if (&checkversion("10.15") and !-e "/var/lib/csf/auto1015") {
|
||||
if ($name eq "MESSENGER_RATE" and $config{$name} eq "30/m") {$config{$name} = "100/s"}
|
||||
if ($name eq "MESSENGER_BURST" and $config{$name} eq "5") {$config{$name} = "150"}
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto1015");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
if (&checkversion("14.03") and !-e "/var/lib/csf/auto1403" and $name eq "DIRECTADMIN_LOG_R") {
|
||||
if ($roundcube and $config{$name} !~ /\.log$/) {$config{$name} = "/var/www/html/roundcube/logs/errors.log"}
|
||||
}
|
||||
if ($configsetting{$name}) {
|
||||
print OUT "$name = \"$config{$name}\"\n";
|
||||
} else {
|
||||
if (&checkversion("9.29") and !-e "/var/lib/csf/auto929" and $name eq "PT_USERRSS") {
|
||||
$line = "PT_USERRSS = \"$config{PT_USERMEM}\"";
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto929");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
if ($name eq "CC_SRC") {$line = "CC_SRC = \"1\""}
|
||||
print OUT $line."\n";
|
||||
print "New setting: $name\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
|
||||
if (&checkversion("14.03") and !-e "/var/lib/csf/auto1403") {
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto1403");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
|
||||
if ($config{TESTING}) {
|
||||
my @netstat = `netstat -lpn`;
|
||||
chomp @netstat;
|
||||
my @tcpports;
|
||||
my @udpports;
|
||||
my @tcp6ports;
|
||||
my @udp6ports;
|
||||
foreach my $line (@netstat) {
|
||||
if ($line =~ /^(\w+).* (\d+\.\d+\.\d+\.\d+):(\d+)/) {
|
||||
if ($2 eq '127.0.0.1') {next}
|
||||
if ($1 eq "tcp") {
|
||||
push @tcpports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udpports, $3;
|
||||
}
|
||||
}
|
||||
if ($line =~ /^(\w+).* (::):(\d+) /) {
|
||||
if ($1 eq "tcp") {
|
||||
push @tcp6ports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udp6ports, $3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@tcpports = sort { $a <=> $b } @tcpports;
|
||||
@udpports = sort { $a <=> $b } @udpports;
|
||||
@tcp6ports = sort { $a <=> $b } @tcp6ports;
|
||||
@udp6ports = sort { $a <=> $b } @udp6ports;
|
||||
|
||||
print "\nTCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n\nUDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
my $opts = "TCP_*, UDP_*";
|
||||
if (@tcp6ports or @udp6ports) {
|
||||
$opts .= ", IPV6, TCP6_*, UDP6_*";
|
||||
print "\n\nIPv6 TCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
print "\nIPv6 UDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
}
|
||||
print "\n\nNote: The port details above are for information only, csf hasn't been auto-configured.\n\n";
|
||||
print "Don't forget to:\n";
|
||||
print "1. Configure the following options in the csf configuration to suite your server: $opts\n";
|
||||
print "2. Restart csf and lfd\n";
|
||||
print "3. Set TESTING to 0 once you're happy with the firewall, lfd will not run until you do so\n";
|
||||
}
|
||||
|
||||
if ($ENV{SSH_CLIENT}) {
|
||||
my $ip = (split(/ /,$ENV{SSH_CLIENT}))[0];
|
||||
if ($ip =~ /(\d+\.\d+\.\d+\.\d+)/) {
|
||||
print "\nAdding current SSH session IP address to the csf whitelist in csf.allow:\n";
|
||||
system("/usr/sbin/csf -a $1 csf SSH installation/upgrade IP address");
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
###############################################################################
|
||||
sub loadcsfconfig {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {next}
|
||||
if ($line !~ /=/) {next}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
$config{$name} = $value;
|
||||
$configsetting{$name} = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
###############################################################################
|
||||
sub checkversion {
|
||||
my $version = shift;
|
||||
my ($maj, $min) = split(/\./,$version);
|
||||
my ($oldmaj, $oldmin) = split(/\./,$oldversion);
|
||||
|
||||
if ($oldmaj == 0 or $oldmaj eq "") {return 0}
|
||||
|
||||
if (($oldmaj < $maj) or ($oldmaj == $maj and $oldmin < $min)) {return 1} else {return 0}
|
||||
}
|
||||
###############################################################################
|
||||
589
csf/auto.generic.pl
Normal file
589
csf/auto.generic.pl
Normal file
@@ -0,0 +1,589 @@
|
||||
#!/usr/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>.
|
||||
###############################################################################
|
||||
## no critic (ProhibitBarewordFileHandles, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
use strict;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use IPC::Open3;
|
||||
|
||||
umask(0177);
|
||||
|
||||
our (%config, %configsetting, $vps, $oldversion);
|
||||
|
||||
$oldversion = $ARGV[0];
|
||||
|
||||
open (VERSION, "<","/etc/csf/version.txt");
|
||||
flock (VERSION, LOCK_SH);
|
||||
my $version = <VERSION>;
|
||||
close (VERSION);
|
||||
chomp $version;
|
||||
$version =~ s/\W/_/g;
|
||||
system("/bin/cp","-avf","/etc/csf/csf.conf","/var/lib/csf/backup/".time."_pre_v${version}_upgrade");
|
||||
|
||||
&loadcsfconfig;
|
||||
|
||||
if (-e "/proc/vz/veinfo") {
|
||||
$vps = 1;
|
||||
} else {
|
||||
open (IN, "<","/proc/self/status");
|
||||
flock (IN, LOCK_SH);
|
||||
while (my $line = <IN>) {
|
||||
chomp $line;
|
||||
if ($line =~ /^envID:\s*(\d+)\s*$/) {
|
||||
if ($1 > 0) {
|
||||
$vps = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
foreach my $alertfile ("sshalert.txt","sualert.txt","sudoalert.txt","webminalert.txt","cpanelalert.txt") {
|
||||
if (-e "/usr/local/csf/tpl/".$alertfile) {
|
||||
sysopen (my $IN, "/usr/local/csf/tpl/".$alertfile, O_RDWR | O_CREAT);
|
||||
flock ($IN, LOCK_EX);
|
||||
my @data = <$IN>;
|
||||
chomp @data;
|
||||
my $hit = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /\[text\]/) {$hit = 1}
|
||||
}
|
||||
unless ($hit) {
|
||||
print $IN "\nLog line:\n\n[text]\n";
|
||||
}
|
||||
close ($IN);
|
||||
}
|
||||
}
|
||||
|
||||
if (&checkversion("10.11") and !-e "/var/lib/csf/auto1011") {
|
||||
if (-e "/var/lib/csf/stats/lfdstats") {
|
||||
sysopen (STATS,"/var/lib/csf/stats/lfdstats", O_RDWR | O_CREAT);
|
||||
flock (STATS, LOCK_EX);
|
||||
my @stats = <STATS>;
|
||||
chomp @stats;
|
||||
my %ccs;
|
||||
my @line = split(/\,/,$stats[69]);
|
||||
for (my $x = 0; $x < @line; $x+=2) {$ccs{$line[$x]} = $line[$x+1]}
|
||||
$stats[69] = "";
|
||||
foreach my $key (keys %ccs) {$stats[69] .= "$key,$ccs{$key},"}
|
||||
seek (STATS, 0, 0);
|
||||
truncate (STATS, 0);
|
||||
foreach my $line (@stats) {
|
||||
print STATS "$line\n";
|
||||
}
|
||||
close (STATS);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1011");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("10.23") and !-e "/var/lib/csf/auto1023") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
my $SPAMDROPV6 = 0;
|
||||
my $STOPFORUMSPAMV6 = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^(\#)?SPAMDROPV6/) {$SPAMDROPV6 = 1}
|
||||
if ($line =~ /^(\#)?STOPFORUMSPAMV6/) {$STOPFORUMSPAMV6 = 1}
|
||||
print IN "$line\n";
|
||||
}
|
||||
unless ($SPAMDROPV6) {
|
||||
print IN "\n# Spamhaus IPv6 Don't Route Or Peer List (DROPv6)\n";
|
||||
print IN "# Details: http://www.spamhaus.org/drop/\n";
|
||||
print IN "#SPAMDROPV6|86400|0|https://www.spamhaus.org/drop/dropv6.txt\n";
|
||||
}
|
||||
unless ($STOPFORUMSPAMV6) {
|
||||
print IN "\n# Stop Forum Spam IPv6\n";
|
||||
print IN "# Details: http://www.stopforumspam.com/downloads/\n";
|
||||
print IN "# Many of the lists available contain a vast number of IP addresses so special\n";
|
||||
print IN "# care needs to be made when selecting from their lists\n";
|
||||
print IN "#STOPFORUMSPAMV6|86400|0|http://www.stopforumspam.com/downloads/listed_ip_1_ipv6.zip\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1023");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("12.02") and !-e "/var/lib/csf/auto1202") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /greensnow/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1202");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("14.03") and !-e "/var/lib/csf/auto1403") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /dshield/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1403");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
|
||||
if (-e "/etc/csf/csf.allow") {
|
||||
sysopen (IN,"/etc/csf/csf.allow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.allow/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.ignore") {
|
||||
sysopen (IN,"/etc/csf/csf.ignore", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.ignore/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/usr/local/csf/bin/regex.custom.pm") {
|
||||
sysopen (IN,"/usr/local/csf/bin/regex.custom.pm", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^use strict;/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /feeds\.dshield\.org/) {$line =~ s/feeds\.dshield\.org/www\.dshield\.org/g}
|
||||
if ($line =~ /openbl\.org/i) {next}
|
||||
if ($line =~ /autoshun/i) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempban") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempban", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempallow") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempallow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
if ($config{TESTING}) {
|
||||
|
||||
open (IN, "<", "/etc/ssh/sshd_config") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @sshconfig = <IN>;
|
||||
close (IN);
|
||||
chomp @sshconfig;
|
||||
|
||||
my $sshport = "22";
|
||||
foreach my $line (@sshconfig) {
|
||||
if ($line =~ /^Port (\d+)/) {$sshport = $1}
|
||||
}
|
||||
|
||||
$config{TCP_IN} =~ s/\s//g;
|
||||
if ($config{TCP_IN} ne "") {
|
||||
foreach my $port (split(/\,/,$config{TCP_IN})) {
|
||||
if ($port eq $sshport) {$sshport = "22"}
|
||||
}
|
||||
}
|
||||
|
||||
if ($sshport ne "22") {
|
||||
$config{TCP_IN} .= ",$sshport";
|
||||
$config{TCP6_IN} .= ",$sshport";
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^TCP6_IN/) {
|
||||
print OUT "TCP6_IN = \"$config{TCP6_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP6_IN port list\n\n";
|
||||
}
|
||||
elsif ($line =~ /^TCP_IN/) {
|
||||
print OUT "TCP_IN = \"$config{TCP_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP_IN port list\n\n";
|
||||
}
|
||||
else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
|
||||
}
|
||||
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (IN, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
chomp @data;
|
||||
if ($data[0] =~ /^(\d+)\.(\d+)\.(\d+)/) {
|
||||
my $maj = $1;
|
||||
my $mid = $2;
|
||||
my $min = $3;
|
||||
if ($maj == 3 and $mid > 6) {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^USE_CONNTRACK =/) {
|
||||
print OUT "USE_CONNTRACK = \"1\"\n";
|
||||
print "\n*** USE_CONNTRACK Enabled\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
|
||||
my @ipdata;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die "alarm\n"};
|
||||
alarm(3);
|
||||
my ($childin, $childout);
|
||||
my $cmdpid = open3($childin, $childout, $childout, "$config{IPTABLES} --wait -L OUTPUT -nv");
|
||||
@ipdata = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ipdata;
|
||||
if ($ipdata[0] =~ /# Warning: iptables-legacy tables present/) {shift @ipdata}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($@ ne "alarm\n" and $ipdata[0] =~ /^Chain OUTPUT/) {
|
||||
$config{IPTABLESWAIT} = "--wait";
|
||||
$config{WAITLOCK} = 1;
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /WAITLOCK =/) {
|
||||
print OUT "WAITLOCK = \"1\"\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
|
||||
if (-e $config{IP6TABLES} and !$vps) {
|
||||
my ($childin, $childout);
|
||||
my $cmdpid;
|
||||
if (-e $config{IP}) {$cmdpid = open3($childin, $childout, $childout, $config{IP}, "-oneline", "addr")}
|
||||
elsif (-e $config{IFCONFIG}) {$cmdpid = open3($childin, $childout, $childout, $config{IFCONFIG})}
|
||||
my @ifconfig = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ifconfig;
|
||||
if (grep {$_ =~ /\s*inet6/} @ifconfig) {
|
||||
$config{IPV6} = 1;
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (IN, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
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 > 6)) or (($maj > 1) and ($mid > 5) and ($min > 19))) {
|
||||
$config{IPV6_SPI} = 1;
|
||||
} else {
|
||||
$config{IPV6_SPI} = 0;
|
||||
}
|
||||
}
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^IPV6 =/) {
|
||||
print OUT "IPV6 = \"$config{IPV6}\"\n";
|
||||
print "\n*** IPV6 Enabled\n\n";
|
||||
}
|
||||
elsif ($line =~ /^IPV6_SPI =/) {
|
||||
print OUT "IPV6_SPI = \"$config{IPV6_SPI}\"\n";
|
||||
print "\n*** IPV6_SPI set to $config{IPV6_SPI}\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open (IN, "<", "csf.generic.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
if ($line !~ /=/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
if (&checkversion("10.15") and !-e "/var/lib/csf/auto1015") {
|
||||
if ($name eq "MESSENGER_RATE" and $config{$name} eq "30/m") {$config{$name} = "100/s"}
|
||||
if ($name eq "MESSENGER_BURST" and $config{$name} eq "5") {$config{$name} = "150"}
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto1015");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
if ($configsetting{$name}) {
|
||||
print OUT "$name = \"$config{$name}\"\n";
|
||||
} else {
|
||||
if (&checkversion("9.29") and !-e "/var/lib/csf/auto929" and $name eq "PT_USERRSS") {
|
||||
$line = "PT_USERRSS = \"$config{PT_USERMEM}\"";
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto929");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
if ($name eq "CC_SRC") {$line = "CC_SRC = \"1\""}
|
||||
print OUT $line."\n";
|
||||
print "New setting: $name\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
|
||||
if ($config{TESTING}) {
|
||||
my @netstat = `netstat -lpn`;
|
||||
chomp @netstat;
|
||||
my @tcpports;
|
||||
my @udpports;
|
||||
my @tcp6ports;
|
||||
my @udp6ports;
|
||||
foreach my $line (@netstat) {
|
||||
if ($line =~ /^(\w+).* (\d+\.\d+\.\d+\.\d+):(\d+)/) {
|
||||
if ($2 eq '127.0.0.1') {next}
|
||||
if ($1 eq "tcp") {
|
||||
push @tcpports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udpports, $3;
|
||||
}
|
||||
}
|
||||
if ($line =~ /^(\w+).* (::):(\d+) /) {
|
||||
if ($1 eq "tcp") {
|
||||
push @tcp6ports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udp6ports, $3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@tcpports = sort { $a <=> $b } @tcpports;
|
||||
@udpports = sort { $a <=> $b } @udpports;
|
||||
@tcp6ports = sort { $a <=> $b } @tcp6ports;
|
||||
@udp6ports = sort { $a <=> $b } @udp6ports;
|
||||
|
||||
print "\nTCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n\nUDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
my $opts = "TCP_*, UDP_*";
|
||||
if (@tcp6ports or @udp6ports) {
|
||||
$opts .= ", IPV6, TCP6_*, UDP6_*";
|
||||
print "\n\nIPv6 TCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
print "\nIPv6 UDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
}
|
||||
print "\n\nNote: The port details above are for information only, csf hasn't been auto-configured.\n\n";
|
||||
print "Don't forget to:\n";
|
||||
print "1. Configure the following options in the csf configuration to suite your server: $opts\n";
|
||||
print "2. Restart csf and lfd\n";
|
||||
print "3. Set TESTING to 0 once you're happy with the firewall, lfd will not run until you do so\n";
|
||||
}
|
||||
|
||||
if ($ENV{SSH_CLIENT}) {
|
||||
my $ip = (split(/ /,$ENV{SSH_CLIENT}))[0];
|
||||
if ($ip =~ /(\d+\.\d+\.\d+\.\d+)/) {
|
||||
print "\nAdding current SSH session IP address to the csf whitelist in csf.allow:\n";
|
||||
system("/usr/sbin/csf -a $1 csf SSH installation/upgrade IP address");
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
###############################################################################
|
||||
sub loadcsfconfig {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {next}
|
||||
if ($line !~ /=/) {next}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
$config{$name} = $value;
|
||||
$configsetting{$name} = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
###############################################################################
|
||||
sub checkversion {
|
||||
my $version = shift;
|
||||
my ($maj, $min) = split(/\./,$version);
|
||||
my ($oldmaj, $oldmin) = split(/\./,$oldversion);
|
||||
|
||||
if ($oldmaj == 0 or $oldmaj eq "") {return 0}
|
||||
|
||||
if (($oldmaj < $maj) or ($oldmaj == $maj and $oldmin < $min)) {return 1} else {return 0}
|
||||
}
|
||||
###############################################################################
|
||||
589
csf/auto.interworx.pl
Normal file
589
csf/auto.interworx.pl
Normal file
@@ -0,0 +1,589 @@
|
||||
#!/usr/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>.
|
||||
###############################################################################
|
||||
## no critic (ProhibitBarewordFileHandles, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
use strict;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use IPC::Open3;
|
||||
|
||||
umask(0177);
|
||||
|
||||
our (%config, %configsetting, $vps, $oldversion);
|
||||
|
||||
$oldversion = $ARGV[0];
|
||||
|
||||
open (VERSION, "<","/etc/csf/version.txt");
|
||||
flock (VERSION, LOCK_SH);
|
||||
my $version = <VERSION>;
|
||||
close (VERSION);
|
||||
chomp $version;
|
||||
$version =~ s/\W/_/g;
|
||||
system("/bin/cp","-avf","/etc/csf/csf.conf","/var/lib/csf/backup/".time."_pre_v${version}_upgrade");
|
||||
|
||||
&loadcsfconfig;
|
||||
|
||||
if (-e "/proc/vz/veinfo") {
|
||||
$vps = 1;
|
||||
} else {
|
||||
open (IN, "<","/proc/self/status");
|
||||
flock (IN, LOCK_SH);
|
||||
while (my $line = <IN>) {
|
||||
chomp $line;
|
||||
if ($line =~ /^envID:\s*(\d+)\s*$/) {
|
||||
if ($1 > 0) {
|
||||
$vps = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
foreach my $alertfile ("sshalert.txt","sualert.txt","sudoalert.txt","webminalert.txt","cpanelalert.txt") {
|
||||
if (-e "/usr/local/csf/tpl/".$alertfile) {
|
||||
sysopen (my $IN, "/usr/local/csf/tpl/".$alertfile, O_RDWR | O_CREAT);
|
||||
flock ($IN, LOCK_EX);
|
||||
my @data = <$IN>;
|
||||
chomp @data;
|
||||
my $hit = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /\[text\]/) {$hit = 1}
|
||||
}
|
||||
unless ($hit) {
|
||||
print $IN "\nLog line:\n\n[text]\n";
|
||||
}
|
||||
close ($IN);
|
||||
}
|
||||
}
|
||||
|
||||
if (&checkversion("10.11") and !-e "/var/lib/csf/auto1011") {
|
||||
if (-e "/var/lib/csf/stats/lfdstats") {
|
||||
sysopen (STATS,"/var/lib/csf/stats/lfdstats", O_RDWR | O_CREAT);
|
||||
flock (STATS, LOCK_EX);
|
||||
my @stats = <STATS>;
|
||||
chomp @stats;
|
||||
my %ccs;
|
||||
my @line = split(/\,/,$stats[69]);
|
||||
for (my $x = 0; $x < @line; $x+=2) {$ccs{$line[$x]} = $line[$x+1]}
|
||||
$stats[69] = "";
|
||||
foreach my $key (keys %ccs) {$stats[69] .= "$key,$ccs{$key},"}
|
||||
seek (STATS, 0, 0);
|
||||
truncate (STATS, 0);
|
||||
foreach my $line (@stats) {
|
||||
print STATS "$line\n";
|
||||
}
|
||||
close (STATS);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1011");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("10.23") and !-e "/var/lib/csf/auto1023") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
my $SPAMDROPV6 = 0;
|
||||
my $STOPFORUMSPAMV6 = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^(\#)?SPAMDROPV6/) {$SPAMDROPV6 = 1}
|
||||
if ($line =~ /^(\#)?STOPFORUMSPAMV6/) {$STOPFORUMSPAMV6 = 1}
|
||||
print IN "$line\n";
|
||||
}
|
||||
unless ($SPAMDROPV6) {
|
||||
print IN "\n# Spamhaus IPv6 Don't Route Or Peer List (DROPv6)\n";
|
||||
print IN "# Details: http://www.spamhaus.org/drop/\n";
|
||||
print IN "#SPAMDROPV6|86400|0|https://www.spamhaus.org/drop/dropv6.txt\n";
|
||||
}
|
||||
unless ($STOPFORUMSPAMV6) {
|
||||
print IN "\n# Stop Forum Spam IPv6\n";
|
||||
print IN "# Details: http://www.stopforumspam.com/downloads/\n";
|
||||
print IN "# Many of the lists available contain a vast number of IP addresses so special\n";
|
||||
print IN "# care needs to be made when selecting from their lists\n";
|
||||
print IN "#STOPFORUMSPAMV6|86400|0|http://www.stopforumspam.com/downloads/listed_ip_1_ipv6.zip\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1023");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("12.02") and !-e "/var/lib/csf/auto1202") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /greensnow/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1202");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("14.03") and !-e "/var/lib/csf/auto1403") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /dshield/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1403");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
|
||||
if (-e "/etc/csf/csf.allow") {
|
||||
sysopen (IN,"/etc/csf/csf.allow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.allow/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.ignore") {
|
||||
sysopen (IN,"/etc/csf/csf.ignore", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.ignore/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/usr/local/csf/bin/regex.custom.pm") {
|
||||
sysopen (IN,"/usr/local/csf/bin/regex.custom.pm", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^use strict;/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /feeds\.dshield\.org/) {$line =~ s/feeds\.dshield\.org/www\.dshield\.org/g}
|
||||
if ($line =~ /openbl\.org/i) {next}
|
||||
if ($line =~ /autoshun/i) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempban") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempban", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempallow") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempallow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
if ($config{TESTING}) {
|
||||
|
||||
open (IN, "<", "/etc/ssh/sshd_config") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @sshconfig = <IN>;
|
||||
close (IN);
|
||||
chomp @sshconfig;
|
||||
|
||||
my $sshport = "22";
|
||||
foreach my $line (@sshconfig) {
|
||||
if ($line =~ /^Port (\d+)/) {$sshport = $1}
|
||||
}
|
||||
|
||||
$config{TCP_IN} =~ s/\s//g;
|
||||
if ($config{TCP_IN} ne "") {
|
||||
foreach my $port (split(/\,/,$config{TCP_IN})) {
|
||||
if ($port eq $sshport) {$sshport = "22"}
|
||||
}
|
||||
}
|
||||
|
||||
if ($sshport ne "22") {
|
||||
$config{TCP_IN} .= ",$sshport";
|
||||
$config{TCP6_IN} .= ",$sshport";
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^TCP6_IN/) {
|
||||
print OUT "TCP6_IN = \"$config{TCP6_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP6_IN port list\n\n";
|
||||
}
|
||||
elsif ($line =~ /^TCP_IN/) {
|
||||
print OUT "TCP_IN = \"$config{TCP_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP_IN port list\n\n";
|
||||
}
|
||||
else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
|
||||
}
|
||||
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (IN, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
chomp @data;
|
||||
if ($data[0] =~ /^(\d+)\.(\d+)\.(\d+)/) {
|
||||
my $maj = $1;
|
||||
my $mid = $2;
|
||||
my $min = $3;
|
||||
if ($maj == 3 and $mid > 6) {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^USE_CONNTRACK =/) {
|
||||
print OUT "USE_CONNTRACK = \"1\"\n";
|
||||
print "\n*** USE_CONNTRACK Enabled\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
|
||||
my @ipdata;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die "alarm\n"};
|
||||
alarm(3);
|
||||
my ($childin, $childout);
|
||||
my $cmdpid = open3($childin, $childout, $childout, "$config{IPTABLES} --wait -L OUTPUT -nv");
|
||||
@ipdata = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ipdata;
|
||||
if ($ipdata[0] =~ /# Warning: iptables-legacy tables present/) {shift @ipdata}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($@ ne "alarm\n" and $ipdata[0] =~ /^Chain OUTPUT/) {
|
||||
$config{IPTABLESWAIT} = "--wait";
|
||||
$config{WAITLOCK} = 1;
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /WAITLOCK =/) {
|
||||
print OUT "WAITLOCK = \"1\"\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
|
||||
if (-e $config{IP6TABLES} and !$vps) {
|
||||
my ($childin, $childout);
|
||||
my $cmdpid;
|
||||
if (-e $config{IP}) {$cmdpid = open3($childin, $childout, $childout, $config{IP}, "-oneline", "addr")}
|
||||
elsif (-e $config{IFCONFIG}) {$cmdpid = open3($childin, $childout, $childout, $config{IFCONFIG})}
|
||||
my @ifconfig = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ifconfig;
|
||||
if (grep {$_ =~ /\s*inet6/} @ifconfig) {
|
||||
$config{IPV6} = 1;
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (IN, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
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 > 6)) or (($maj > 1) and ($mid > 5) and ($min > 19))) {
|
||||
$config{IPV6_SPI} = 1;
|
||||
} else {
|
||||
$config{IPV6_SPI} = 0;
|
||||
}
|
||||
}
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^IPV6 =/) {
|
||||
print OUT "IPV6 = \"$config{IPV6}\"\n";
|
||||
print "\n*** IPV6 Enabled\n\n";
|
||||
}
|
||||
elsif ($line =~ /^IPV6_SPI =/) {
|
||||
print OUT "IPV6_SPI = \"$config{IPV6_SPI}\"\n";
|
||||
print "\n*** IPV6_SPI set to $config{IPV6_SPI}\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open (IN, "<", "csf.interworx.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
if ($line !~ /=/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
if (&checkversion("10.15") and !-e "/var/lib/csf/auto1015") {
|
||||
if ($name eq "MESSENGER_RATE" and $config{$name} eq "30/m") {$config{$name} = "100/s"}
|
||||
if ($name eq "MESSENGER_BURST" and $config{$name} eq "5") {$config{$name} = "150"}
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto1015");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
if ($configsetting{$name}) {
|
||||
print OUT "$name = \"$config{$name}\"\n";
|
||||
} else {
|
||||
if (&checkversion("9.29") and !-e "/var/lib/csf/auto929" and $name eq "PT_USERRSS") {
|
||||
$line = "PT_USERRSS = \"$config{PT_USERMEM}\"";
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto929");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
if ($name eq "CC_SRC") {$line = "CC_SRC = \"1\""}
|
||||
print OUT $line."\n";
|
||||
print "New setting: $name\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
|
||||
if ($config{TESTING}) {
|
||||
my @netstat = `netstat -lpn`;
|
||||
chomp @netstat;
|
||||
my @tcpports;
|
||||
my @udpports;
|
||||
my @tcp6ports;
|
||||
my @udp6ports;
|
||||
foreach my $line (@netstat) {
|
||||
if ($line =~ /^(\w+).* (\d+\.\d+\.\d+\.\d+):(\d+)/) {
|
||||
if ($2 eq '127.0.0.1') {next}
|
||||
if ($1 eq "tcp") {
|
||||
push @tcpports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udpports, $3;
|
||||
}
|
||||
}
|
||||
if ($line =~ /^(\w+).* (::):(\d+) /) {
|
||||
if ($1 eq "tcp") {
|
||||
push @tcp6ports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udp6ports, $3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@tcpports = sort { $a <=> $b } @tcpports;
|
||||
@udpports = sort { $a <=> $b } @udpports;
|
||||
@tcp6ports = sort { $a <=> $b } @tcp6ports;
|
||||
@udp6ports = sort { $a <=> $b } @udp6ports;
|
||||
|
||||
print "\nTCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n\nUDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
my $opts = "TCP_*, UDP_*";
|
||||
if (@tcp6ports or @udp6ports) {
|
||||
$opts .= ", IPV6, TCP6_*, UDP6_*";
|
||||
print "\n\nIPv6 TCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
print "\nIPv6 UDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
}
|
||||
print "\n\nNote: The port details above are for information only, csf hasn't been auto-configured.\n\n";
|
||||
print "Don't forget to:\n";
|
||||
print "1. Configure the following options in the csf configuration to suite your server: $opts\n";
|
||||
print "2. Restart csf and lfd\n";
|
||||
print "3. Set TESTING to 0 once you're happy with the firewall, lfd will not run until you do so\n";
|
||||
}
|
||||
|
||||
if ($ENV{SSH_CLIENT}) {
|
||||
my $ip = (split(/ /,$ENV{SSH_CLIENT}))[0];
|
||||
if ($ip =~ /(\d+\.\d+\.\d+\.\d+)/) {
|
||||
print "\nAdding current SSH session IP address to the csf whitelist in csf.allow:\n";
|
||||
system("/usr/sbin/csf -a $1 csf SSH installation/upgrade IP address");
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
###############################################################################
|
||||
sub loadcsfconfig {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {next}
|
||||
if ($line !~ /=/) {next}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
$config{$name} = $value;
|
||||
$configsetting{$name} = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
###############################################################################
|
||||
sub checkversion {
|
||||
my $version = shift;
|
||||
my ($maj, $min) = split(/\./,$version);
|
||||
my ($oldmaj, $oldmin) = split(/\./,$oldversion);
|
||||
|
||||
if ($oldmaj == 0 or $oldmaj eq "") {return 0}
|
||||
|
||||
if (($oldmaj < $maj) or ($oldmaj == $maj and $oldmin < $min)) {return 1} else {return 0}
|
||||
}
|
||||
###############################################################################
|
||||
1252
csf/auto.pl
Normal file
1252
csf/auto.pl
Normal file
File diff suppressed because it is too large
Load Diff
605
csf/auto.vesta.pl
Normal file
605
csf/auto.vesta.pl
Normal file
@@ -0,0 +1,605 @@
|
||||
#!/usr/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>.
|
||||
###############################################################################
|
||||
## no critic (ProhibitBarewordFileHandles, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
use strict;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use IPC::Open3;
|
||||
|
||||
umask(0177);
|
||||
|
||||
our (%config, %configsetting, $vps, $oldversion);
|
||||
|
||||
$oldversion = $ARGV[0];
|
||||
|
||||
open (VERSION, "<","/etc/csf/version.txt");
|
||||
flock (VERSION, LOCK_SH);
|
||||
my $version = <VERSION>;
|
||||
close (VERSION);
|
||||
chomp $version;
|
||||
$version =~ s/\W/_/g;
|
||||
system("/bin/cp","-avf","/etc/csf/csf.conf","/var/lib/csf/backup/".time."_pre_v${version}_upgrade");
|
||||
|
||||
&loadcsfconfig;
|
||||
|
||||
if (-e "/proc/vz/veinfo") {
|
||||
$vps = 1;
|
||||
} else {
|
||||
open (IN, "<","/proc/self/status");
|
||||
flock (IN, LOCK_SH);
|
||||
while (my $line = <IN>) {
|
||||
chomp $line;
|
||||
if ($line =~ /^envID:\s*(\d+)\s*$/) {
|
||||
if ($1 > 0) {
|
||||
$vps = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
foreach my $alertfile ("sshalert.txt","sualert.txt","sudoalert.txt","webminalert.txt","cpanelalert.txt") {
|
||||
if (-e "/usr/local/csf/tpl/".$alertfile) {
|
||||
sysopen (my $IN, "/usr/local/csf/tpl/".$alertfile, O_RDWR | O_CREAT);
|
||||
flock ($IN, LOCK_EX);
|
||||
my @data = <$IN>;
|
||||
chomp @data;
|
||||
my $hit = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /\[text\]/) {$hit = 1}
|
||||
}
|
||||
unless ($hit) {
|
||||
print $IN "\nLog line:\n\n[text]\n";
|
||||
}
|
||||
close ($IN);
|
||||
}
|
||||
}
|
||||
|
||||
if (-e "/usr/local/vesta") {
|
||||
sysopen (my $VESTA, "/usr/local/vesta/web/templates/admin/panel.html", O_RDWR | O_CREAT);
|
||||
flock ($VESTA, LOCK_EX);
|
||||
my @data = <$VESTA>;
|
||||
chomp @data;
|
||||
seek ($VESTA, 0, 0);
|
||||
truncate ($VESTA, 0);
|
||||
foreach my $line (@data) {
|
||||
if (!(grep {$_ =~ /CSF/} @data) and $line =~ /if\(\$TAB == 'SERVER'/) {
|
||||
print $VESTA $line."\n";
|
||||
print $VESTA "<div class=\"l-menu__item <?php if(\$TAB == 'CSF' ) echo 'l-menu__item--active' ?>\"><a href=\"/list/csf/\"><?=__('CSF')?></a></div>\n";
|
||||
} else {
|
||||
print $VESTA $line."\n";
|
||||
}
|
||||
}
|
||||
close ($VESTA);
|
||||
}
|
||||
|
||||
if (&checkversion("10.11") and !-e "/var/lib/csf/auto1011") {
|
||||
if (-e "/var/lib/csf/stats/lfdstats") {
|
||||
sysopen (STATS,"/var/lib/csf/stats/lfdstats", O_RDWR | O_CREAT);
|
||||
flock (STATS, LOCK_EX);
|
||||
my @stats = <STATS>;
|
||||
chomp @stats;
|
||||
my %ccs;
|
||||
my @line = split(/\,/,$stats[69]);
|
||||
for (my $x = 0; $x < @line; $x+=2) {$ccs{$line[$x]} = $line[$x+1]}
|
||||
$stats[69] = "";
|
||||
foreach my $key (keys %ccs) {$stats[69] .= "$key,$ccs{$key},"}
|
||||
seek (STATS, 0, 0);
|
||||
truncate (STATS, 0);
|
||||
foreach my $line (@stats) {
|
||||
print STATS "$line\n";
|
||||
}
|
||||
close (STATS);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1011");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("10.23") and !-e "/var/lib/csf/auto1023") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
my $SPAMDROPV6 = 0;
|
||||
my $STOPFORUMSPAMV6 = 0;
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^(\#)?SPAMDROPV6/) {$SPAMDROPV6 = 1}
|
||||
if ($line =~ /^(\#)?STOPFORUMSPAMV6/) {$STOPFORUMSPAMV6 = 1}
|
||||
print IN "$line\n";
|
||||
}
|
||||
unless ($SPAMDROPV6) {
|
||||
print IN "\n# Spamhaus IPv6 Don't Route Or Peer List (DROPv6)\n";
|
||||
print IN "# Details: http://www.spamhaus.org/drop/\n";
|
||||
print IN "#SPAMDROPV6|86400|0|https://www.spamhaus.org/drop/dropv6.txt\n";
|
||||
}
|
||||
unless ($STOPFORUMSPAMV6) {
|
||||
print IN "\n# Stop Forum Spam IPv6\n";
|
||||
print IN "# Details: http://www.stopforumspam.com/downloads/\n";
|
||||
print IN "# Many of the lists available contain a vast number of IP addresses so special\n";
|
||||
print IN "# care needs to be made when selecting from their lists\n";
|
||||
print IN "#STOPFORUMSPAMV6|86400|0|http://www.stopforumspam.com/downloads/listed_ip_1_ipv6.zip\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1023");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("12.02") and !-e "/var/lib/csf/auto1202") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /greensnow/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1202");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
if (&checkversion("14.03") and !-e "/var/lib/csf/auto1403") {
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /dshield/) {$line =~ s/http:/https:/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
open (OUT, ">", "/var/lib/csf/auto1403");
|
||||
flock (OUT, LOCK_EX);
|
||||
print OUT time;
|
||||
close (OUT);
|
||||
}
|
||||
|
||||
if (-e "/etc/csf/csf.allow") {
|
||||
sysopen (IN,"/etc/csf/csf.allow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.allow/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.ignore") {
|
||||
sysopen (IN,"/etc/csf/csf.ignore", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^Include \/etc\/csf\/cpanel\.comodo\.ignore/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/usr/local/csf/bin/regex.custom.pm") {
|
||||
sysopen (IN,"/usr/local/csf/bin/regex.custom.pm", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^use strict;/) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/etc/csf/csf.blocklists") {
|
||||
sysopen (IN,"/etc/csf/csf.blocklists", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /feeds\.dshield\.org/) {$line =~ s/feeds\.dshield\.org/www\.dshield\.org/g}
|
||||
if ($line =~ /openbl\.org/i) {next}
|
||||
if ($line =~ /autoshun/i) {next}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempban") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempban", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
if (-e "/var/lib/csf/csf.tempallow") {
|
||||
sysopen (IN,"/var/lib/csf/csf.tempallow", O_RDWR | O_CREAT);
|
||||
flock (IN, LOCK_EX);
|
||||
my @data = <IN>;
|
||||
chomp @data;
|
||||
seek (IN, 0, 0);
|
||||
truncate (IN, 0);
|
||||
foreach my $line (@data) {
|
||||
if ($line =~ /^\d+\:/) {$line =~ s/\:/\|/g}
|
||||
print IN "$line\n";
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
if ($config{TESTING}) {
|
||||
|
||||
open (IN, "<", "/etc/ssh/sshd_config") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @sshconfig = <IN>;
|
||||
close (IN);
|
||||
chomp @sshconfig;
|
||||
|
||||
my $sshport = "22";
|
||||
foreach my $line (@sshconfig) {
|
||||
if ($line =~ /^Port (\d+)/) {$sshport = $1}
|
||||
}
|
||||
|
||||
$config{TCP_IN} =~ s/\s//g;
|
||||
if ($config{TCP_IN} ne "") {
|
||||
foreach my $port (split(/\,/,$config{TCP_IN})) {
|
||||
if ($port eq $sshport) {$sshport = "22"}
|
||||
}
|
||||
}
|
||||
|
||||
if ($sshport ne "22") {
|
||||
$config{TCP_IN} .= ",$sshport";
|
||||
$config{TCP6_IN} .= ",$sshport";
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^TCP6_IN/) {
|
||||
print OUT "TCP6_IN = \"$config{TCP6_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP6_IN port list\n\n";
|
||||
}
|
||||
elsif ($line =~ /^TCP_IN/) {
|
||||
print OUT "TCP_IN = \"$config{TCP_IN}\"\n";
|
||||
print "\n*** SSH port $sshport added to the TCP_IN port list\n\n";
|
||||
}
|
||||
else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
|
||||
}
|
||||
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (IN, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
chomp @data;
|
||||
if ($data[0] =~ /^(\d+)\.(\d+)\.(\d+)/) {
|
||||
my $maj = $1;
|
||||
my $mid = $2;
|
||||
my $min = $3;
|
||||
if ($maj == 3 and $mid > 6) {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^USE_CONNTRACK =/) {
|
||||
print OUT "USE_CONNTRACK = \"1\"\n";
|
||||
print "\n*** USE_CONNTRACK Enabled\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
|
||||
my @ipdata;
|
||||
eval {
|
||||
local $SIG{__DIE__} = undef;
|
||||
local $SIG{'ALRM'} = sub {die "alarm\n"};
|
||||
alarm(3);
|
||||
my ($childin, $childout);
|
||||
my $cmdpid = open3($childin, $childout, $childout, "$config{IPTABLES} --wait -L OUTPUT -nv");
|
||||
@ipdata = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ipdata;
|
||||
if ($ipdata[0] =~ /# Warning: iptables-legacy tables present/) {shift @ipdata}
|
||||
alarm(0);
|
||||
};
|
||||
alarm(0);
|
||||
if ($@ ne "alarm\n" and $ipdata[0] =~ /^Chain OUTPUT/) {
|
||||
$config{IPTABLESWAIT} = "--wait";
|
||||
$config{WAITLOCK} = 1;
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /WAITLOCK =/) {
|
||||
print OUT "WAITLOCK = \"1\"\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
|
||||
if (-e $config{IP6TABLES} and !$vps) {
|
||||
my ($childin, $childout);
|
||||
my $cmdpid;
|
||||
if (-e $config{IP}) {$cmdpid = open3($childin, $childout, $childout, $config{IP}, "-oneline", "addr")}
|
||||
elsif (-e $config{IFCONFIG}) {$cmdpid = open3($childin, $childout, $childout, $config{IFCONFIG})}
|
||||
my @ifconfig = <$childout>;
|
||||
waitpid ($cmdpid, 0);
|
||||
chomp @ifconfig;
|
||||
if (grep {$_ =~ /\s*inet6/} @ifconfig) {
|
||||
$config{IPV6} = 1;
|
||||
open (FH, "<", "/proc/sys/kernel/osrelease");
|
||||
flock (IN, LOCK_SH);
|
||||
my @data = <FH>;
|
||||
close (FH);
|
||||
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 > 6)) or (($maj > 1) and ($mid > 5) and ($min > 19))) {
|
||||
$config{IPV6_SPI} = 1;
|
||||
} else {
|
||||
$config{IPV6_SPI} = 0;
|
||||
}
|
||||
}
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^IPV6 =/) {
|
||||
print OUT "IPV6 = \"$config{IPV6}\"\n";
|
||||
print "\n*** IPV6 Enabled\n\n";
|
||||
}
|
||||
elsif ($line =~ /^IPV6_SPI =/) {
|
||||
print OUT "IPV6_SPI = \"$config{IPV6_SPI}\"\n";
|
||||
print "\n*** IPV6_SPI set to $config{IPV6_SPI}\n\n";
|
||||
} else {
|
||||
print OUT $line."\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
&loadcsfconfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open (IN, "<", "csf.vesta.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
open (OUT, ">", "/etc/csf/csf.conf") or die $!;
|
||||
flock (OUT, LOCK_EX) or die $!;
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
if ($line !~ /=/) {
|
||||
print OUT $line."\n";
|
||||
next;
|
||||
}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
if (&checkversion("10.15") and !-e "/var/lib/csf/auto1015") {
|
||||
if ($name eq "MESSENGER_RATE" and $config{$name} eq "30/m") {$config{$name} = "100/s"}
|
||||
if ($name eq "MESSENGER_BURST" and $config{$name} eq "5") {$config{$name} = "150"}
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto1015");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
if ($configsetting{$name}) {
|
||||
print OUT "$name = \"$config{$name}\"\n";
|
||||
} else {
|
||||
if (&checkversion("9.29") and !-e "/var/lib/csf/auto929" and $name eq "PT_USERRSS") {
|
||||
$line = "PT_USERRSS = \"$config{PT_USERMEM}\"";
|
||||
open (my $AUTO, ">", "/var/lib/csf/auto929");
|
||||
flock ($AUTO, LOCK_EX);
|
||||
print $AUTO time;
|
||||
close ($AUTO);
|
||||
}
|
||||
print OUT $line."\n";
|
||||
print "New setting: $name\n";
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
|
||||
if ($config{TESTING}) {
|
||||
my @netstat = `netstat -lpn`;
|
||||
chomp @netstat;
|
||||
my @tcpports;
|
||||
my @udpports;
|
||||
my @tcp6ports;
|
||||
my @udp6ports;
|
||||
foreach my $line (@netstat) {
|
||||
if ($line =~ /^(\w+).* (\d+\.\d+\.\d+\.\d+):(\d+)/) {
|
||||
if ($2 eq '127.0.0.1') {next}
|
||||
if ($1 eq "tcp") {
|
||||
push @tcpports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udpports, $3;
|
||||
}
|
||||
}
|
||||
if ($line =~ /^(\w+).* (::):(\d+) /) {
|
||||
if ($1 eq "tcp") {
|
||||
push @tcp6ports, $3;
|
||||
}
|
||||
elsif ($1 eq "udp") {
|
||||
push @udp6ports, $3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@tcpports = sort { $a <=> $b } @tcpports;
|
||||
@udpports = sort { $a <=> $b } @udpports;
|
||||
@tcp6ports = sort { $a <=> $b } @tcp6ports;
|
||||
@udp6ports = sort { $a <=> $b } @udp6ports;
|
||||
|
||||
print "\nTCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n\nUDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udpports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udpports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
my $opts = "TCP_*, UDP_*";
|
||||
if (@tcp6ports or @udp6ports) {
|
||||
$opts .= ", IPV6, TCP6_*, UDP6_*";
|
||||
print "\n\nIPv6 TCP ports currently listening for incoming connections:\n";
|
||||
my $last = "";
|
||||
foreach my $port (@tcp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $tcp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
print "\nIPv6 UDP ports currently listening for incoming connections:\n";
|
||||
$last = "";
|
||||
foreach my $port (@udp6ports) {
|
||||
if ($port ne $last) {
|
||||
if ($port ne $udp6ports[0]) {print ","}
|
||||
print $port;
|
||||
$last = $port;
|
||||
}
|
||||
}
|
||||
}
|
||||
print "\n\nNote: The port details above are for information only, csf hasn't been auto-configured.\n\n";
|
||||
print "Don't forget to:\n";
|
||||
print "1. Configure the following options in the csf configuration to suite your server: $opts\n";
|
||||
print "2. Restart csf and lfd\n";
|
||||
print "3. Set TESTING to 0 once you're happy with the firewall, lfd will not run until you do so\n";
|
||||
}
|
||||
|
||||
if ($ENV{SSH_CLIENT}) {
|
||||
my $ip = (split(/ /,$ENV{SSH_CLIENT}))[0];
|
||||
if ($ip =~ /(\d+\.\d+\.\d+\.\d+)/) {
|
||||
print "\nAdding current SSH session IP address to the csf whitelist in csf.allow:\n";
|
||||
system("/usr/sbin/csf -a $1 csf SSH installation/upgrade IP address");
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
###############################################################################
|
||||
sub loadcsfconfig {
|
||||
open (IN, "<", "/etc/csf/csf.conf") or die $!;
|
||||
flock (IN, LOCK_SH) or die $!;
|
||||
my @config = <IN>;
|
||||
close (IN);
|
||||
chomp @config;
|
||||
|
||||
foreach my $line (@config) {
|
||||
if ($line =~ /^\#/) {next}
|
||||
if ($line !~ /=/) {next}
|
||||
my ($name,$value) = split (/=/,$line,2);
|
||||
$name =~ s/\s//g;
|
||||
if ($value =~ /\"(.*)\"/) {
|
||||
$value = $1;
|
||||
} else {
|
||||
print "Error: Invalid configuration line [$line]";
|
||||
}
|
||||
$config{$name} = $value;
|
||||
$configsetting{$name} = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
###############################################################################
|
||||
sub checkversion {
|
||||
my $version = shift;
|
||||
my ($maj, $min) = split(/\./,$version);
|
||||
my ($oldmaj, $oldmin) = split(/\./,$oldversion);
|
||||
|
||||
if ($oldmaj == 0 or $oldmaj eq "") {return 0}
|
||||
|
||||
if (($oldmaj < $maj) or ($oldmaj == $maj and $oldmin < $min)) {return 1} else {return 0}
|
||||
}
|
||||
###############################################################################
|
||||
6142
csf/changelog.txt
Normal file
6142
csf/changelog.txt
Normal file
File diff suppressed because it is too large
Load Diff
11
csf/connectiontracking.txt
Normal file
11
csf/connectiontracking.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
From: root
|
||||
To: root
|
||||
Subject: lfd on [hostname]: [ip] blocked with too many connections
|
||||
|
||||
Time: [time]
|
||||
IP: [ip]
|
||||
Connections: [ipcount]
|
||||
Blocked: [temp]
|
||||
|
||||
Connections:
|
||||
[iptext]
|
||||
5
csf/consolealert.txt
Normal file
5
csf/consolealert.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
From: root
|
||||
To: root
|
||||
Subject: lfd on [hostname]: console login alert
|
||||
|
||||
[line]
|
||||
100
csf/cpanel.allow
Normal file
100
csf/cpanel.allow
Normal file
@@ -0,0 +1,100 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be allowed through iptables and ignored by
|
||||
# lfd to allow for unimpeded access to the cPanel license service
|
||||
#
|
||||
# Each IP address belongs to cPanel and is responsibly for authenticating
|
||||
# cPanel licenses
|
||||
#
|
||||
# Note: This file will be replaced when csf is upgraded - do NOT make any
|
||||
# changes to this file. If you do not want to whitelist these IP addresses you
|
||||
# need to remove the Include line from csf.allow as this is only added there
|
||||
# once
|
||||
|
||||
tcp|in|d=4|s=208.74.123.2 # cPanel Auth Server
|
||||
tcp|in|d=8|s=208.74.123.2 # cPanel Auth Server
|
||||
tcp|in|d=10|s=208.74.123.2 # cPanel Auth Server
|
||||
tcp|in|d=14|s=208.74.123.2 # cPanel Auth Server
|
||||
tcp|in|d=16|s=208.74.123.2 # cPanel Auth Server
|
||||
tcp|in|d=40|s=208.74.123.2 # cPanel Auth Server
|
||||
tcp|in|d=1020|s=208.74.123.2 # cPanel Auth Server
|
||||
tcp|in|d=1021|s=208.74.123.2 # cPanel Auth Server
|
||||
tcp|in|d=1022|s=208.74.123.2 # cPanel Auth Server
|
||||
|
||||
tcp|in|d=4|s=208.74.123.3 # cPanel Auth Server
|
||||
tcp|in|d=8|s=208.74.123.3 # cPanel Auth Server
|
||||
tcp|in|d=10|s=208.74.123.3 # cPanel Auth Server
|
||||
tcp|in|d=14|s=208.74.123.3 # cPanel Auth Server
|
||||
tcp|in|d=16|s=208.74.123.3 # cPanel Auth Server
|
||||
tcp|in|d=40|s=208.74.123.3 # cPanel Auth Server
|
||||
tcp|in|d=1020|s=208.74.123.3 # cPanel Auth Server
|
||||
tcp|in|d=1021|s=208.74.123.3 # cPanel Auth Server
|
||||
tcp|in|d=1022|s=208.74.123.3 # cPanel Auth Server
|
||||
|
||||
tcp|in|d=4|s=208.74.121.82 # cPanel Auth Server
|
||||
tcp|in|d=8|s=208.74.121.82 # cPanel Auth Server
|
||||
tcp|in|d=10|s=208.74.121.82 # cPanel Auth Server
|
||||
tcp|in|d=14|s=208.74.121.82 # cPanel Auth Server
|
||||
tcp|in|d=16|s=208.74.121.82 # cPanel Auth Server
|
||||
tcp|in|d=40|s=208.74.121.82 # cPanel Auth Server
|
||||
tcp|in|d=1020|s=208.74.121.82 # cPanel Auth Server
|
||||
tcp|in|d=1021|s=208.74.121.82 # cPanel Auth Server
|
||||
tcp|in|d=1022|s=208.74.121.82 # cPanel Auth Server
|
||||
|
||||
tcp|in|d=4|s=208.74.121.83 # cPanel Auth Server
|
||||
tcp|in|d=8|s=208.74.121.83 # cPanel Auth Server
|
||||
tcp|in|d=10|s=208.74.121.83 # cPanel Auth Server
|
||||
tcp|in|d=14|s=208.74.121.83 # cPanel Auth Server
|
||||
tcp|in|d=16|s=208.74.121.83 # cPanel Auth Server
|
||||
tcp|in|d=40|s=208.74.121.83 # cPanel Auth Server
|
||||
tcp|in|d=1020|s=208.74.121.83 # cPanel Auth Server
|
||||
tcp|in|d=1021|s=208.74.121.83 # cPanel Auth Server
|
||||
tcp|in|d=1022|s=208.74.121.83 # cPanel Auth Server
|
||||
|
||||
tcp|in|d=4|s=208.74.121.85 # cPanel Auth Server
|
||||
tcp|in|d=8|s=208.74.121.85 # cPanel Auth Server
|
||||
tcp|in|d=10|s=208.74.121.85 # cPanel Auth Server
|
||||
tcp|in|d=14|s=208.74.121.85 # cPanel Auth Server
|
||||
tcp|in|d=16|s=208.74.121.85 # cPanel Auth Server
|
||||
tcp|in|d=40|s=208.74.121.85 # cPanel Auth Server
|
||||
tcp|in|d=1020|s=208.74.121.85 # cPanel Auth Server
|
||||
tcp|in|d=1021|s=208.74.121.85 # cPanel Auth Server
|
||||
tcp|in|d=1022|s=208.74.121.85 # cPanel Auth Server
|
||||
|
||||
tcp|in|d=4|s=208.74.121.86 # cPanel Auth Server
|
||||
tcp|in|d=8|s=208.74.121.86 # cPanel Auth Server
|
||||
tcp|in|d=10|s=208.74.121.86 # cPanel Auth Server
|
||||
tcp|in|d=14|s=208.74.121.86 # cPanel Auth Server
|
||||
tcp|in|d=16|s=208.74.121.86 # cPanel Auth Server
|
||||
tcp|in|d=40|s=208.74.121.86 # cPanel Auth Server
|
||||
tcp|in|d=1020|s=208.74.121.86 # cPanel Auth Server
|
||||
tcp|in|d=1021|s=208.74.121.86 # cPanel Auth Server
|
||||
tcp|in|d=1022|s=208.74.121.86 # cPanel Auth Server
|
||||
|
||||
tcp|in|d=80|s=52.51.23.204 # cPanel SaaS Server
|
||||
tcp|in|d=443|s=52.51.23.204 # cPanel SaaS Server
|
||||
tcp|in|d=8443|s=52.51.23.204 # cPanel SaaS Server
|
||||
|
||||
tcp|in|d=80|s=52.213.169.7 # cPanel SaaS Server
|
||||
tcp|in|d=443|s=52.213.169.7 # cPanel SaaS Server
|
||||
tcp|in|d=8443|s=52.213.169.7 # cPanel SaaS Server
|
||||
|
||||
tcp|in|d=80|s=34.254.37.129 # cPanel SaaS Server
|
||||
tcp|in|d=443|s=34.254.37.129 # cPanel SaaS Server
|
||||
tcp|in|d=8443|s=34.254.37.129 # cPanel SaaS Server
|
||||
56
csf/cpanel.comodo.allow
Normal file
56
csf/cpanel.comodo.allow
Normal file
@@ -0,0 +1,56 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be allowed through iptables and ignored by
|
||||
# lfd to allow for unimpeded access to cPanels free SSL certificate service
|
||||
# available in cPanel v58+
|
||||
#
|
||||
# Each IP address belongs to the Sectigo SSL provider (formerly Comodo)
|
||||
#
|
||||
# Note: This file will be replaced when csf is upgraded - do NOT make any
|
||||
# changes to this file. If you do not want to whitelist these IP addresses you
|
||||
# need to remove the Include line from csf.allow as this is only added there
|
||||
# once
|
||||
|
||||
tcp|in|d=80|s=178.255.81.12 # Sectigo SSL Resolver
|
||||
tcp|in|d=443|s=178.255.81.12 # Sectigo SSL Resolver
|
||||
tcp|in|d=53|s=178.255.81.12 # Sectigo SSL Resolver
|
||||
|
||||
tcp|in|d=80|s=178.255.81.13 # Sectigo SSL Resolver
|
||||
tcp|in|d=443|s=178.255.81.13 # Sectigo SSL Resolver
|
||||
tcp|in|d=53|s=178.255.81.13 # Sectigo SSL Resolver
|
||||
|
||||
tcp|in|d=80|s=91.199.212.52 # Sectigo DCV Server
|
||||
tcp|in|d=443|s=91.199.212.52 # Sectigo DCV Server
|
||||
tcp|in|d=53|s=91.199.212.52 # Sectigo DCV Server
|
||||
|
||||
tcp|in|d=80|s=91.199.212.132 # Sectigo DCV Server
|
||||
tcp|in|d=443|s=91.199.212.132 # Sectigo DCV Server
|
||||
tcp|in|d=53|s=91.199.212.132 # Sectigo DCV Server
|
||||
|
||||
tcp|in|d=80|s=199.66.201.132 # Sectigo DCV Server
|
||||
tcp|in|d=443|s=199.66.201.132 # Sectigo DCV Server
|
||||
tcp|in|d=53|s=199.66.201.132 # Sectigo DCV Server
|
||||
|
||||
tcp|in|d=80|s=2a02:1788:402:1c80::/64 # Sectigo DCV Server
|
||||
tcp|in|d=443|s=2a02:1788:402:1c80::/64 # Sectigo DCV Server
|
||||
tcp|in|d=53|s=2a02:1788:402:1c80::/64 # Sectigo DCV Server
|
||||
|
||||
tcp|in|d=80|s=2a02:1788:400:1ce4::/64 # Sectigo DCV Server
|
||||
tcp|in|d=443|s=2a02:1788:400:1ce4::/64 # Sectigo DCV Server
|
||||
tcp|in|d=53|s=2a02:1788:400:1ce4::/64 # Sectigo DCV Server
|
||||
36
csf/cpanel.comodo.ignore
Normal file
36
csf/cpanel.comodo.ignore
Normal file
@@ -0,0 +1,36 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be allowed through iptables and ignored by
|
||||
# lfd to allow for unimpeded access to cPanels free SSL certificate service
|
||||
# available in cPanel v58+
|
||||
#
|
||||
# Each IP address belongs to the Sectigo SSL provider (formerly Comodo)
|
||||
#
|
||||
# Note: This file will be replaced when csf is upgraded - do NOT make any
|
||||
# changes to this file. If you do not want to whitelist these IP addresses you
|
||||
# need to remove the Include line from csf.ignore as this is only added there
|
||||
# once
|
||||
|
||||
178.255.81.12 # Sectigo SSL Resolver
|
||||
178.255.81.13 # Sectigo SSL Resolver
|
||||
91.199.212.52 # Sectigo DCV Server
|
||||
91.199.212.132 # Sectigo DCV Server
|
||||
199.66.201.132 # Sectigo DCV Backup Server
|
||||
2a02:1788:400:1ce4::/64 # Sectigo DCV Server
|
||||
2a02:1788:400:1ce4::/64 # Sectigo DCV Server
|
||||
35
csf/cpanel.ignore
Normal file
35
csf/cpanel.ignore
Normal file
@@ -0,0 +1,35 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be allowed through iptables and ignored by
|
||||
# lfd to allow for unimpeded access to the cPanel license service
|
||||
#
|
||||
# Each IP address belongs to cPanel and is responsibly for authenticating
|
||||
# cPanel licenses
|
||||
#
|
||||
# Note: This file will be replaced when csf is upgraded - do NOT make any
|
||||
# changes to this file. If you do not want to whitelist these IP addresses you
|
||||
# need to remove the Include line from csf.ignore as this is only added there
|
||||
# once
|
||||
|
||||
208.74.123.2 # cPanel Auth Server
|
||||
208.74.123.3 # cPanel Auth Server
|
||||
208.74.121.82 # cPanel Auth Server
|
||||
208.74.121.83 # cPanel Auth Server
|
||||
208.74.121.85 # cPanel Auth Server
|
||||
208.74.121.86 # cPanel Auth Server
|
||||
51
csf/cpanel/Driver/ConfigServercsf.pm
Normal file
51
csf/cpanel/Driver/ConfigServercsf.pm
Normal file
@@ -0,0 +1,51 @@
|
||||
package Cpanel::Config::ConfigObj::Driver::ConfigServercsf;
|
||||
|
||||
use strict;
|
||||
use Cpanel::Config::ConfigObj::Driver::ConfigServercsf::META ();
|
||||
*VERSION = \$Cpanel::Config::ConfigObj::Driver::ConfigServercsf::META::VERSION;
|
||||
|
||||
#use parent qw(Cpanel::Config::ConfigObj::Interface::Config::v1);
|
||||
our @ISA = qw(Cpanel::Config::ConfigObj::Interface::Config::v1);
|
||||
|
||||
sub init {
|
||||
my ( $class, $software_obj ) = @_;
|
||||
|
||||
my $ConfigServercsf_defaults = {
|
||||
'thirdparty_ns' => "ConfigServercsf",
|
||||
'meta' => {},
|
||||
};
|
||||
my $self = $class->SUPER::base( $ConfigServercsf_defaults, $software_obj );
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub enable {
|
||||
my ( $self, $input ) = @_;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub disable {
|
||||
my ( $self, $input ) = @_;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub info {
|
||||
my ($self) = @_;
|
||||
my $meta_obj = $self->meta();
|
||||
my $abstract = $meta_obj->abstract();
|
||||
return $abstract;
|
||||
}
|
||||
|
||||
sub acl_desc {
|
||||
return [
|
||||
{
|
||||
'acl' => 'software-ConfigServer-csf', #this should be "software-$key"
|
||||
'default_value' => 0,
|
||||
'default_ui_value' => 0, # NOTE: this is for ui; first time setting reseller privs
|
||||
'name' => 'ConfigServer Security & Firewall (Reseller UI)',
|
||||
'acl_subcat' => 'Third Party Services',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
1;
|
||||
46
csf/cpanel/Driver/ConfigServercsf/META.pm
Normal file
46
csf/cpanel/Driver/ConfigServercsf/META.pm
Normal file
@@ -0,0 +1,46 @@
|
||||
package Cpanel::Config::ConfigObj::Driver::ConfigServercsf::META;
|
||||
|
||||
use strict;
|
||||
|
||||
our $VERSION = 1.1;
|
||||
|
||||
#use parent qw(Cpanel::Config::ConfigObj::Interface::Config::Version::v1);
|
||||
sub spec_version {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub meta_version {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub get_driver_name {
|
||||
return 'ConfigServercsf_driver';
|
||||
}
|
||||
|
||||
sub content {
|
||||
my ($locale_handle) = @_;
|
||||
|
||||
my $content = {
|
||||
'vendor' => 'Jonathan Michaelson',
|
||||
'url' => 'www.configserver.com',
|
||||
'name' => {
|
||||
'short' => 'ConfigServercsf Driver',
|
||||
'long' => 'ConfigServercsf Driver',
|
||||
'driver' => get_driver_name(),
|
||||
},
|
||||
'since' => 'cPanel 11.38.1',
|
||||
'abstract' => "A ConfigServercsf driver",
|
||||
'version' => $VERSION,
|
||||
};
|
||||
|
||||
if ($locale_handle) {
|
||||
$content->{'abstract'} = $locale_handle->maketext("ConfigServer csf driver");
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
sub showcase {
|
||||
return;
|
||||
}
|
||||
1;
|
||||
340
csf/cpanel/csf.cgi
Normal file
340
csf/cpanel/csf.cgi
Normal file
@@ -0,0 +1,340 @@
|
||||
#!/usr/bin/perl
|
||||
#WHMADDON:csf:ConfigServer Security & Firewall
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen)
|
||||
use strict;
|
||||
use File::Find;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use Sys::Hostname qw(hostname);
|
||||
use IPC::Open3;
|
||||
|
||||
use lib '/usr/local/csf/lib';
|
||||
use ConfigServer::DisplayUI;
|
||||
use ConfigServer::DisplayResellerUI;
|
||||
use ConfigServer::Config;
|
||||
use ConfigServer::Slurp qw(slurp);
|
||||
|
||||
use lib '/usr/local/cpanel';
|
||||
require Cpanel::Form;
|
||||
require Cpanel::Config;
|
||||
require Whostmgr::ACLS;
|
||||
require Cpanel::Rlimit;
|
||||
require Cpanel::Template;
|
||||
require Cpanel::Version::Tiny;
|
||||
###############################################################################
|
||||
# start main
|
||||
|
||||
our ($reseller, $script, $images, %rprivs, $myv, %FORM);
|
||||
|
||||
Whostmgr::ACLS::init_acls();
|
||||
|
||||
%FORM = Cpanel::Form::parseform();
|
||||
|
||||
my $config = ConfigServer::Config->loadconfig();
|
||||
my %config = $config->config;
|
||||
my $slurpreg = ConfigServer::Slurp->slurpreg;
|
||||
my $cleanreg = ConfigServer::Slurp->cleanreg;
|
||||
|
||||
Cpanel::Rlimit::set_rlimit_to_infinity();
|
||||
|
||||
if (-e "/usr/local/cpanel/bin/register_appconfig") {
|
||||
$script = "csf.cgi";
|
||||
$images = "csf";
|
||||
} else {
|
||||
$script = "addon_csf.cgi";
|
||||
$images = "csf";
|
||||
}
|
||||
|
||||
foreach my $line (slurp("/etc/csf/csf.resellers")) {
|
||||
$line =~ s/$cleanreg//g;
|
||||
my ($user,$alert,$privs) = split(/\:/,$line);
|
||||
$privs =~ s/\s//g;
|
||||
foreach my $priv (split(/\,/,$privs)) {
|
||||
$rprivs{$user}{$priv} = 1;
|
||||
}
|
||||
$rprivs{$user}{ALERT} = $alert;
|
||||
}
|
||||
|
||||
$reseller = 0;
|
||||
if (!Whostmgr::ACLS::hasroot()) {
|
||||
if ($rprivs{$ENV{REMOTE_USER}}{USE}) {
|
||||
$reseller = 1;
|
||||
} else {
|
||||
print "Content-type: text/html\r\n\r\n";
|
||||
print "You do not have access to this feature\n";
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
open (my $IN, "<", "/etc/csf/version.txt") or die $!;
|
||||
$myv = <$IN>;
|
||||
close ($IN);
|
||||
chomp $myv;
|
||||
|
||||
my $bootstrapcss = "<link rel='stylesheet' href='$images/bootstrap/css/bootstrap.min.css'>";
|
||||
my $jqueryjs = "<script src='$images/jquery.min.js'></script>";
|
||||
my $bootstrapjs = "<script src='$images/bootstrap/js/bootstrap.min.js'></script>";
|
||||
|
||||
my @header;
|
||||
my @footer;
|
||||
my $htmltag = "data-post='$FORM{action}'";
|
||||
if (-e "/etc/csf/csf.header") {
|
||||
open (my $HEADER, "<", "/etc/csf/csf.header");
|
||||
flock ($HEADER, LOCK_SH);
|
||||
@header = <$HEADER>;
|
||||
close ($HEADER);
|
||||
}
|
||||
if (-e "/etc/csf/csf.footer") {
|
||||
open (my $FOOTER, "<", "/etc/csf/csf.footer");
|
||||
flock ($FOOTER, LOCK_SH);
|
||||
@footer = <$FOOTER>;
|
||||
close ($FOOTER);
|
||||
}
|
||||
unless ($config{STYLE_CUSTOM}) {
|
||||
undef @header;
|
||||
undef @footer;
|
||||
$htmltag = "";
|
||||
}
|
||||
|
||||
my $thisapp = "csf";
|
||||
my $reregister;
|
||||
my $modalstyle;
|
||||
if ($Cpanel::Version::Tiny::major_version >= 65) {
|
||||
if (-e "/usr/local/cpanel/whostmgr/docroot/cgi/configserver/${thisapp}/${thisapp}.conf") {
|
||||
sysopen (my $CONF, "/usr/local/cpanel/whostmgr/docroot/cgi/configserver/${thisapp}/${thisapp}.conf", O_RDWR | O_CREAT);
|
||||
flock ($CONF, LOCK_EX);
|
||||
my @confdata = <$CONF>;
|
||||
chomp @confdata;
|
||||
for (0..scalar(@confdata)) {
|
||||
if ($confdata[$_] =~ /^target=mainFrame/) {
|
||||
$confdata[$_] = "target=_self";
|
||||
$reregister = 1;
|
||||
}
|
||||
}
|
||||
if ($reregister) {
|
||||
seek ($CONF, 0, 0);
|
||||
truncate ($CONF, 0);
|
||||
foreach (@confdata) {
|
||||
print $CONF "$_\n";
|
||||
}
|
||||
&printcmd("/usr/local/cpanel/bin/register_appconfig","/usr/local/cpanel/whostmgr/docroot/cgi/configserver/${thisapp}/${thisapp}.conf");
|
||||
$reregister = "<div class='bs-callout bs-callout-info'><h4>Updated application. The next time you login to WHM this will open within the native WHM main window instead of launching a separate window</h4></div>\n";
|
||||
}
|
||||
close ($CONF);
|
||||
}
|
||||
}
|
||||
|
||||
print "Content-type: text/html\r\n\r\n";
|
||||
#if ($Cpanel::Version::Tiny::major_version < 65) {$modalstyle = "style='top:120px'"}
|
||||
|
||||
my $templatehtml;
|
||||
my $SCRIPTOUT;
|
||||
unless ($FORM{action} eq "tailcmd" or $FORM{action} =~ /^cf/ or $FORM{action} eq "logtailcmd" or $FORM{action} eq "loggrepcmd") {
|
||||
# open(STDERR, ">&STDOUT");
|
||||
open ($SCRIPTOUT, '>', \$templatehtml);
|
||||
select $SCRIPTOUT;
|
||||
|
||||
print <<EOF;
|
||||
<!-- $bootstrapcss -->
|
||||
<link href='$images/configserver.css' rel='stylesheet' type='text/css'>
|
||||
$jqueryjs
|
||||
$bootstrapjs
|
||||
<style>
|
||||
.toplink {
|
||||
top: 140px;
|
||||
}
|
||||
.mobilecontainer {
|
||||
display:none;
|
||||
}
|
||||
.normalcontainer {
|
||||
display:block;
|
||||
}
|
||||
EOF
|
||||
if ($config{STYLE_MOBILE} or $reseller) {
|
||||
print <<EOF;
|
||||
\@media (max-width: 600px) {
|
||||
.mobilecontainer {
|
||||
display:block;
|
||||
}
|
||||
.normalcontainer {
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
print "</style>\n";
|
||||
print @header;
|
||||
}
|
||||
|
||||
unless ($FORM{action} eq "tailcmd" or $FORM{action} =~ /^cf/ or $FORM{action} eq "logtailcmd" or $FORM{action} eq "loggrepcmd") {
|
||||
print <<EOF;
|
||||
<div id="loader"></div><br />
|
||||
<div class='panel panel-default'>
|
||||
<h4><img src='$images/csf_small.png' style='padding-left: 10px'> ConfigServer Security & Firewall - csf v$myv</h4></div>
|
||||
EOF
|
||||
if ($reregister ne "") {print $reregister}
|
||||
}
|
||||
|
||||
#eval {
|
||||
if ($reseller) {
|
||||
ConfigServer::DisplayResellerUI::main(\%FORM, $script, 0, $images, $myv);
|
||||
} else {
|
||||
ConfigServer::DisplayUI::main(\%FORM, $script, 0, $images, $myv);
|
||||
}
|
||||
#};
|
||||
#if ($@) {
|
||||
# print "Error during UI output generation: [$@]\n";
|
||||
# warn "Error during UI output generation: [$@]\n";
|
||||
#}
|
||||
|
||||
unless ($FORM{action} eq "tailcmd" or $FORM{action} =~ /^cf/ or $FORM{action} eq "logtailcmd" or $FORM{action} eq "loggrepcmd") {
|
||||
print <<EOF;
|
||||
<script>
|
||||
function getCookie(cname) {
|
||||
var name = cname + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i = 0; i <ca.length; i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0)==' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length,c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
\$("#loader").hide();
|
||||
\$("#docs-link").hide();
|
||||
\$.fn.scrollBottom = function() {
|
||||
return \$(document).height() - this.scrollTop() - this.height();
|
||||
};
|
||||
\$('#botlink').on("click",function(){
|
||||
\$('html,body').animate({ scrollTop: 0 }, 'slow', function () {});
|
||||
});
|
||||
\$('#toplink').on("click",function() {
|
||||
var window_height = \$(window).height();
|
||||
var document_height = \$(document).height();
|
||||
\$('html,body').animate({ scrollTop: window_height + document_height }, 'slow', function () {});
|
||||
});
|
||||
\$('#tabAll').click(function(){
|
||||
\$('#tabAll').addClass('active');
|
||||
\$('.tab-pane').each(function(i,t){
|
||||
\$('#myTabs li').removeClass('active');
|
||||
\$(this).addClass('active');
|
||||
});
|
||||
});
|
||||
\$(document).ready(function(){
|
||||
\$('[data-tooltip="tooltip"]').tooltip();
|
||||
\$(window).scroll(function () {
|
||||
if (\$(this).scrollTop() > 500) {
|
||||
\$('#botlink').fadeIn();
|
||||
} else {
|
||||
\$('#botlink').fadeOut();
|
||||
}
|
||||
if (\$(this).scrollBottom() > 500) {
|
||||
\$('#toplink').fadeIn();
|
||||
} else {
|
||||
\$('#toplink').fadeOut();
|
||||
}
|
||||
});
|
||||
EOF
|
||||
if ($config{STYLE_MOBILE} or $reseller) {
|
||||
print <<EOF;
|
||||
var csfview = getCookie('csfview');
|
||||
if (csfview == 'mobile') {
|
||||
\$(".mobilecontainer").css('display','block');
|
||||
\$(".normalcontainer").css('display','none');
|
||||
\$("#csfreturn").addClass('btn-primary btn-lg btn-block').removeClass('btn-default');
|
||||
} else if (csfview == 'desktop') {
|
||||
\$(".mobilecontainer").css('display','none');
|
||||
\$(".normalcontainer").css('display','block');
|
||||
\$("#csfreturn").removeClass('btn-primary btn-lg btn-block').addClass('btn-default');
|
||||
}
|
||||
if (top.location == location) {
|
||||
\$("#cpframetr2").show();
|
||||
} else {
|
||||
\$("#cpframetr2").hide();
|
||||
}
|
||||
if (\$(".mobilecontainer").css('display') == 'block' ) {
|
||||
document.cookie = "csfview=mobile; path=/";
|
||||
if (top.location != location) {
|
||||
top.location.href = document.location.href ;
|
||||
}
|
||||
}
|
||||
\$(window).resize(function() {
|
||||
if (\$(".mobilecontainer").css('display') == 'block' ) {
|
||||
document.cookie = "csfview=mobile; path=/";
|
||||
if (top.location != location) {
|
||||
top.location.href = document.location.href ;
|
||||
}
|
||||
}
|
||||
});
|
||||
EOF
|
||||
}
|
||||
print "});\n";
|
||||
if ($config{STYLE_MOBILE} or $reseller) {
|
||||
print <<EOF;
|
||||
\$("#NormalView").click(function(){
|
||||
document.cookie = "csfview=desktop; path=/";
|
||||
\$(".mobilecontainer").css('display','none');
|
||||
\$(".normalcontainer").css('display','block');
|
||||
});
|
||||
\$("#MobileView").click(function(){
|
||||
document.cookie = "csfview=mobile; path=/";
|
||||
if (top.location == location) {
|
||||
\$(".normalcontainer").css('display','none');
|
||||
\$(".mobilecontainer").css('display','block');
|
||||
} else {
|
||||
top.location.href = document.location.href;
|
||||
}
|
||||
});
|
||||
EOF
|
||||
}
|
||||
print "</script>\n";
|
||||
print @footer;
|
||||
}
|
||||
unless ($FORM{action} eq "tailcmd" or $FORM{action} =~ /^cf/ or $FORM{action} eq "logtailcmd" or $FORM{action} eq "loggrepcmd") {
|
||||
close ($SCRIPTOUT);
|
||||
select STDOUT;
|
||||
Cpanel::Template::process_template(
|
||||
'whostmgr',
|
||||
{
|
||||
"template_file" => "${thisapp}.tmpl",
|
||||
"${thisapp}_output" => $templatehtml,
|
||||
"print" => 1,
|
||||
}
|
||||
);
|
||||
}
|
||||
# end main
|
||||
###############################################################################
|
||||
## start printcmd
|
||||
sub printcmd {
|
||||
my @command = @_;
|
||||
my ($childin, $childout);
|
||||
my $pid = open3($childin, $childout, $childout, @command);
|
||||
while (<$childout>) {print $_}
|
||||
waitpid ($pid, 0);
|
||||
return;
|
||||
}
|
||||
## end printcmd
|
||||
###############################################################################
|
||||
|
||||
1;
|
||||
28
csf/cpanel/csf.conf
Normal file
28
csf/cpanel/csf.conf
Normal file
@@ -0,0 +1,28 @@
|
||||
# name
|
||||
name=csf
|
||||
|
||||
# Service that will serve this app
|
||||
service=whostmgr
|
||||
|
||||
# Physical path: /usr/local/cpanel/3rdparty/Foo.php
|
||||
# Literal URL path: $server:$port/$cpsession/3rdparty/Foo.php
|
||||
url=/cgi/configserver/csf.cgi
|
||||
|
||||
# System user to run process as
|
||||
user=root
|
||||
|
||||
# Required acls
|
||||
acls=software-ConfigServer-csf
|
||||
|
||||
# Display name as show in the service ui
|
||||
displayname=ConfigServer Security & Firewall
|
||||
|
||||
# Url to show in the service ui (relative to install path for whm this is cgi/)
|
||||
entryurl=configserver/csf.cgi
|
||||
|
||||
# Path to upgrade script
|
||||
upgradecall=/usr/local/cpanel/whostmgr/docroot/cgi/configserver/csf/upgrade.sh
|
||||
|
||||
icon=csf_small.png
|
||||
|
||||
target=_self
|
||||
29
csf/cpanel/csf.tmpl
Normal file
29
csf/cpanel/csf.tmpl
Normal file
@@ -0,0 +1,29 @@
|
||||
[%
|
||||
USE Whostmgr;
|
||||
USE JSON;
|
||||
|
||||
WRAPPER 'master_templates/master.tmpl'
|
||||
header = 'ConfigServer Security & Firewall'
|
||||
skipsupport = 1
|
||||
skipheader = 1
|
||||
hide_license_warnings = 1
|
||||
theme='bootstrap'
|
||||
breadcrumbdata = {
|
||||
previous = [
|
||||
{
|
||||
name = "Home",
|
||||
url = "/scripts/command?PFILE=main",
|
||||
},
|
||||
{
|
||||
name = "Plugins",
|
||||
url = "/scripts/command?PFILE=Plugins",
|
||||
}
|
||||
],
|
||||
name = 'ConfigServer Security & Firewall',
|
||||
url = '/cgi/configserver/csf.cgi',
|
||||
};
|
||||
%]
|
||||
|
||||
[% csf_output %]
|
||||
|
||||
[% END %]
|
||||
12
csf/cpanel/upgrade.sh
Normal file
12
csf/cpanel/upgrade.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -e "/usr/local/cpanel/bin/register_appconfig" ]; then
|
||||
if [ -e "/usr/local/cpanel/whostmgr/docroot/cgi/addon_csf.cgi" ]; then
|
||||
/bin/cp -af /usr/local/cpanel/whostmgr/docroot/cgi/configserver/csf/Driver/* /usr/local/cpanel/Cpanel/Config/ConfigObj/Driver/
|
||||
/bin/touch /usr/local/cpanel/Cpanel/Config/ConfigObj/Driver
|
||||
/usr/local/cpanel/bin/register_appconfig /usr/local/cpanel/whostmgr/docroot/cgi/configserver/csf/csf.conf
|
||||
|
||||
/bin/rm -f /usr/local/cpanel/whostmgr/docroot/cgi/addon_csf.cgi
|
||||
/bin/rm -Rf /usr/local/cpanel/whostmgr/docroot/cgi/csf
|
||||
fi
|
||||
fi
|
||||
11
csf/cpanelalert.txt
Normal file
11
csf/cpanelalert.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
From: root
|
||||
To: root
|
||||
Subject: lfd on [hostname]: WHM/cPanel [user] access alert from [ip]
|
||||
|
||||
Time: [time]
|
||||
IP: [ip]
|
||||
User: [user]
|
||||
|
||||
Log line:
|
||||
|
||||
[text]
|
||||
284
csf/csf.1.txt
Normal file
284
csf/csf.1.txt
Normal file
@@ -0,0 +1,284 @@
|
||||
.TH csf 1
|
||||
.SH NAME
|
||||
csf \- ConfigServer & Security Firewall
|
||||
.SH SYNOPSIS
|
||||
.B csf [OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
This manual documents the csf command line options for the ConfigServer & Security Firewall. See /etc/csf/csf.conf and /etc/csf/readme.txt for more detailed information on how to use and configure this application.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B
|
||||
-h, --help
|
||||
Show this message
|
||||
.TP
|
||||
.B
|
||||
-l, --status
|
||||
List/Show the IPv4 iptables configuration
|
||||
.TP
|
||||
.B
|
||||
-l6, --status6
|
||||
List/Show the IPv6 ip6tables configuration
|
||||
.TP
|
||||
.B
|
||||
-s, --start
|
||||
Start the firewall rules
|
||||
.TP
|
||||
.B
|
||||
-f, --stop
|
||||
Flush/Stop firewall rules (Note: lfd may restart csf)
|
||||
.TP
|
||||
.B
|
||||
-r, --restart
|
||||
Restart firewall rules (csf)
|
||||
.TP
|
||||
.B
|
||||
-q, --startq
|
||||
Quick restart (csf restarted by lfd)
|
||||
.TP
|
||||
.B
|
||||
-sf, --startf
|
||||
Force CLI restart regardless of LFDSTART setting
|
||||
.TP
|
||||
.B
|
||||
-ra, --restartall
|
||||
Restart firewall rules (csf) and then restart lfd daemon. Both csf and then lfd should be restarted after making any changes to the configuration files
|
||||
.TP
|
||||
.B
|
||||
--lfd [\fIstop\fP|\fIstart\fP|\fIrestart\fP|\fIstatus\fP]
|
||||
Actions to take with the lfd daemon
|
||||
.TP
|
||||
.B
|
||||
-a, --add \fIip\fP [\fIcomment\fP]
|
||||
Allow an IP and add to /etc/csf/csf.allow
|
||||
.TP
|
||||
.B
|
||||
-ar, --addrm \fIip\fP
|
||||
Remove an IP from /etc/csf/csf.allow and delete rule
|
||||
.TP
|
||||
.B
|
||||
-d, --deny \fIip\fP [\fIcomment\fP]
|
||||
Deny an IP and add to /etc/csf/csf.deny
|
||||
.TP
|
||||
.B
|
||||
-dr, --denyrm \fIip\fP
|
||||
Unblock an IP and remove from /etc/csf/csf.deny
|
||||
.TP
|
||||
.B
|
||||
-df, --denyf
|
||||
Remove and unblock all entries in /etc/csf/csf.deny
|
||||
.TP
|
||||
.B
|
||||
-g, --grep \fIip\fP
|
||||
Search the iptables and ip6tables rules for a match (e.g. IP, CIDR, Port Number)
|
||||
.TP
|
||||
.B
|
||||
-i, --iplookup \fIip\fP
|
||||
Lookup IP address geographical information using CC_LOOKUPS setting in /etc/csf/csf.conf
|
||||
.TP
|
||||
.B
|
||||
-t, --temp
|
||||
Displays the current list of temporary allow and deny IP entries with their TTL and comment
|
||||
.TP
|
||||
.B
|
||||
-tr, --temprm \fIip\fP
|
||||
Remove an IP from the temporary IP ban or allow list
|
||||
.TP
|
||||
.B
|
||||
-trd, --temprmd \fIip\fP
|
||||
Remove an IP from the temporary IP ban list only
|
||||
.TP
|
||||
.B
|
||||
-tra, --temprma \fIip\fP
|
||||
Remove an IP from the temporary IP allow list only
|
||||
.TP
|
||||
.B
|
||||
-td, --tempdeny \fIip\fP \fIttl\fP [-p \fIport\fP] [-d \fIdirection\fP] [\fIcomment\fP]
|
||||
Add an IP to the temp IP ban list. ttl is how long to blocks for (default:seconds, can use one suffix of h/m/d). Optional port. Optional direction of block can be one of: in, out or inout (default:in)
|
||||
.TP
|
||||
.B
|
||||
-ta, --tempallow \fIip\fP \fIttl\fP [-p \fIport\fP] [-d \fIdirection\fP] [\fIcomment\fP]
|
||||
Add an IP to the temp IP allow list (default:inout)
|
||||
.TP
|
||||
.B
|
||||
-tf, --tempf
|
||||
Flush all IPs from the temporary IP entries
|
||||
.TP
|
||||
.B
|
||||
-cp, --cping
|
||||
PING all members in an lfd Cluster
|
||||
.TP
|
||||
.B
|
||||
-cg, --cgrep \fIip\fP
|
||||
Requests the --grep output for IP from each member in an lfd Cluster
|
||||
.TP
|
||||
.B
|
||||
-cd, --cdeny \fIip\fP [\fIcomment\fP]
|
||||
Deny an IP in a Cluster and add to each remote /etc/csf/csf.deny
|
||||
.TP
|
||||
.B
|
||||
-ctd, --ctempdeny \fIip\fP \fIttl\fP [-p \fIport\fP] [-d \fIdirection\fP] [\fIcomment\fP]
|
||||
Add an IP in a Cluster to the temp IP ban list (default:in)
|
||||
.TP
|
||||
.B
|
||||
-cr, --crm \fIip\fP
|
||||
Unblock an IP in a Cluster and remove from each remote /etc/csf/csf.deny and temporary list
|
||||
.TP
|
||||
.B
|
||||
-ca, --callow \fIip\fP [\fIcomment\fP]
|
||||
Allow an IP in a Cluster and add to each remote /etc/csf/csf.allow
|
||||
.TP
|
||||
.B
|
||||
-cta, --ctempallow \fIip\fP \fIttl\fP [-p \fIport\fP] [-d \fIdirection\fP] [\fIcomment\fP]
|
||||
Add an IP in a Cluster to the temp IP allow list (default:in)
|
||||
.TP
|
||||
.B
|
||||
-car, --carm \fIip\fP
|
||||
Remove allowed IP in a Cluster and remove from each remote /etc/csf/csf.allow and temporary list
|
||||
.TP
|
||||
.B
|
||||
-ci, --cignore \fIip\fP [\fIcomment\fP]
|
||||
Ignore an IP in a Cluster and add to each remote /etc/csf/csf.ignore. Note: This will result in lfd being restarted
|
||||
.TP
|
||||
.B
|
||||
-cir, --cirm \fIip\fP
|
||||
Remove ignored IP in a Cluster and remove from each remote /etc/csf/csf.ignore. Note: This will result in lfd being restarted
|
||||
.TP
|
||||
.B
|
||||
-cc, --cconfig [\fIname\fP] [\fIvalue\fP]
|
||||
Change configuration option [name] to [value] in a Cluster
|
||||
.TP
|
||||
.B
|
||||
-cf, --cfile [\fIfile\fP]
|
||||
Send [file] in a Cluster to /etc/csf/
|
||||
.TP
|
||||
.B
|
||||
-crs, --crestart
|
||||
Cluster restart csf and lfd
|
||||
.TP
|
||||
.B
|
||||
--trace [\fIadd\fP|\fIremove\fP] \fIip\fP
|
||||
Log SYN packets for an IP across iptables chains. Note, this can create a LOT of logging information in /var/log/messages so should only be used for a short period of time. This option requires the iptables TRACE module and access to the raw PREROUTING chain to function
|
||||
.TP
|
||||
.B
|
||||
-m, --mail [\fIemail\fP]
|
||||
Display Server Check in HTML or email to [email] if present
|
||||
.TP
|
||||
.B
|
||||
--rbl [\fIemail\fP]
|
||||
Process and display RBL Check in HTML or email to [email] if present
|
||||
.TP
|
||||
.B
|
||||
-lr, --logrun
|
||||
Initiate Log Scanner report via lfd
|
||||
.TP
|
||||
.B
|
||||
-p, --ports
|
||||
View ports on the server that have a running process behind them listening for external connections
|
||||
.TP
|
||||
.B
|
||||
--graphs [\fIgraph type\fP] [\fIdirectory\fP]
|
||||
Generate System Statistics html pages and images for a given graph type into a given directory. See ST_SYSTEM for requirements
|
||||
.TP
|
||||
.B
|
||||
--profile [\fIcommand\fP] [\fIprofile\fP|\fIbackup\fP] [\fIprofile\fP|\fIbackup\fP]
|
||||
Configuration profile functions for /etc/csf/csf.conf
|
||||
.br
|
||||
You can create your own profiles using the examples provided in /usr/local/csf/profiles/
|
||||
.br
|
||||
The profile reset_to_defaults.conf is a special case and will always be the latest default csf.conf
|
||||
.IP
|
||||
.B
|
||||
list
|
||||
.br
|
||||
Lists available profiles and backups
|
||||
.IP
|
||||
.B
|
||||
apply [\fIprofile\fP]
|
||||
.br
|
||||
Modify csf.conf with Configuration Profile
|
||||
.IP
|
||||
.B
|
||||
backup "\fIname\fP"
|
||||
.br
|
||||
Create Configuration Backup with optional "\fIname\fP" stored in /var/lib/csf/backup/
|
||||
.IP
|
||||
.B
|
||||
restore [\fIbackup\fP]
|
||||
.br
|
||||
Restore a Configuration Backup
|
||||
.IP
|
||||
.B
|
||||
keep [\fInum\fP]
|
||||
.br
|
||||
Remove old Configuration Backups and keep the latest [\fInum\fP]
|
||||
.IP
|
||||
.B
|
||||
diff [\fIprofile\fP|\fIbackup\fP] [\fIprofile\fP|\fIbackup\fP]
|
||||
.br
|
||||
Report differences between Configuration Profiles or Configuration Backups, only specify one [\fIprofile\fP|\fIbackup\fP] to compare to the current Configuration
|
||||
.TP
|
||||
.B
|
||||
--mregen
|
||||
MESSENGERV2 /etc/apache2/conf.d/csf_messenger.conf regeneration. This will also gracefully restart httpd
|
||||
.TP
|
||||
.B
|
||||
--cloudflare [\fIcommand\fP]
|
||||
Commands for interacting with the CloudFlare firewall. See /etc/csf/readme.txt and CF_ENABLE for more detailed information
|
||||
|
||||
Note: target can be one of: An IP address; 2 letter Country Code; IP range CIDR. Only Enterprise customers can block a Country Code, but all can allow and challenge. IP range CIDR is limited to /16 and /24
|
||||
.IP
|
||||
.B
|
||||
list [\fIall\fP|\fIblock\fP|\fIchallenge\fP|\fIwhitelist\fP] [\fIuser1\fP,\fIuser2\fP,\fIdomain1\fP...]
|
||||
.br
|
||||
List specified type of CloudFlare Firewall rules for comma separated list of users/domains
|
||||
.IP
|
||||
.B
|
||||
add [\fIblock\fP|\fIchallenge\fP|\fIwhitelist\fP] \fItarget\fP [\fIuser1\fP,\fIuser2\fP,\fIdomain1\fP...]
|
||||
.br
|
||||
Add CloudFlare Firewall rule action for target for comma separated list of users/domains only
|
||||
.IP
|
||||
.B
|
||||
del \fItarget\fP [\fIuser1\fP,\fIuser2\fP,\fIdomain1\fP...]
|
||||
.br
|
||||
Delete CloudFlare Firewall rule for target for comma separated list of users/domains only
|
||||
.IP
|
||||
.B
|
||||
tempadd [\fIallow\fP|\fIdeny\fP] \fIip\fP [\fIuser1\fP,\fIuser2\fP,\fIdomain1\fP...]
|
||||
.br
|
||||
Add a temporary block for CF_TEMP seconds to both csf and the CloudFlare Firewall rule for ip for comma separated list of users/domains as well as any user set to "any"
|
||||
.TP
|
||||
.B
|
||||
-c, --check
|
||||
Check for updates to csf but do not upgrade
|
||||
.TP
|
||||
.B
|
||||
-u, --update
|
||||
Check for updates to csf and upgrade if available
|
||||
.TP
|
||||
.B
|
||||
-uf
|
||||
Force an update of csf whether and upgrade is required or not
|
||||
.TP
|
||||
.B
|
||||
-x, --disable
|
||||
Disable csf and lfd completely
|
||||
.TP
|
||||
.B
|
||||
-e, --enable
|
||||
Enable csf and lfd if previously disabled
|
||||
.TP
|
||||
.B
|
||||
-v, --version
|
||||
Show csf version
|
||||
.SH FILES
|
||||
.I /etc/csf/csf.conf
|
||||
.RS
|
||||
The system wide configuration file
|
||||
.RE
|
||||
.I /etc/csf/readme.txt
|
||||
.RS
|
||||
Detailed information about csf and lfd
|
||||
.SH BUGS
|
||||
Report bugs on the forums at http://forum.configserver.com
|
||||
.SH AUTHOR
|
||||
(c)2006-2023, Jonathan Michaelson (http://www.configserver.com)
|
||||
33
csf/csf.allow
Normal file
33
csf/csf.allow
Normal file
@@ -0,0 +1,33 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be allowed through iptables.
|
||||
# One IP address per line.
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24).
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
# Advanced port+ip filtering allowed with the following format
|
||||
# tcp/udp|in/out|s/d=port,port,...|s/d=ip
|
||||
# See readme.txt for more information
|
||||
#
|
||||
# Note: IP addressess listed in this file will NOT be ignored by lfd, so they
|
||||
# can still be blocked. If you do not want lfd to block an IP address you must
|
||||
# add it to csf.ignore
|
||||
|
||||
Include /etc/csf/cpanel.comodo.allow
|
||||
Include /etc/csf/cpanel.allow
|
||||
116
csf/csf.blocklists
Normal file
116
csf/csf.blocklists
Normal file
@@ -0,0 +1,116 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# This file contains definitions to IP BLOCK lists.
|
||||
#
|
||||
# Uncomment the line starting with the rule name to use it, then restart csf
|
||||
# and then lfd
|
||||
#
|
||||
# Each block list must be listed on per line: as NAME|INTERVAL|MAX|URL
|
||||
# NAME : List name with all uppercase alphabetic characters with no
|
||||
# spaces and a maximum of 25 characters - this will be used as the
|
||||
# iptables chain name
|
||||
# INTERVAL: Refresh interval to download the list, must be a minimum of 3600
|
||||
# seconds (an hour), but 86400 (a day) should be more than enough
|
||||
# MAX : This is the maximum number of IP addresses to use from the list,
|
||||
# a value of 0 means all IPs
|
||||
# URL : The URL to download the list from
|
||||
#
|
||||
# Note: Some of these lists may be very long and could cause serious network
|
||||
# and/or performance issues unless you are using LF_IPSET in csf, so setting a
|
||||
# value for the MAX field should be considered
|
||||
#
|
||||
# After making any changes to this file you must restart csf and then lfd
|
||||
#
|
||||
# If you want to redownload a blocklist you must first delete
|
||||
# /var/lib/csf/csf.block.NAME and then restart csf and then lfd
|
||||
#
|
||||
# Each URL is scanned for an IP/CIDR address per line and if found is blocked
|
||||
#
|
||||
# The downloaded list can be a zip file. The zip file MUST only contain a
|
||||
# single text file of a single IP/CIDR per line
|
||||
#
|
||||
# Note: CXS_ is a reserved prefix for the blocklist name and MUST NOT be used
|
||||
|
||||
# Spamhaus Don't Route Or Peer List (DROP)
|
||||
# Details: http://www.spamhaus.org/drop/
|
||||
#SPAMDROP|86400|0|http://www.spamhaus.org/drop/drop.txt
|
||||
|
||||
# Spamhaus IPv6 Don't Route Or Peer List (DROPv6)
|
||||
# Details: http://www.spamhaus.org/drop/
|
||||
#SPAMDROPV6|86400|0|https://www.spamhaus.org/drop/dropv6.txt
|
||||
|
||||
# Spamhaus Extended DROP List (EDROP)
|
||||
# Details: http://www.spamhaus.org/drop/
|
||||
#SPAMEDROP|86400|0|http://www.spamhaus.org/drop/edrop.txt
|
||||
|
||||
# DShield.org Recommended Block List
|
||||
# Details: https://dshield.org
|
||||
#DSHIELD|86400|0|https://www.dshield.org/block.txt
|
||||
|
||||
# TOR Exit Nodes List
|
||||
# Set URLGET in csf.conf to use LWP as this list uses an SSL connection
|
||||
# Details: https://trac.torproject.org/projects/tor/wiki/doc/TorDNSExitList
|
||||
#TOR|86400|0|https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=1.2.3.4
|
||||
|
||||
# BOGON list
|
||||
# Details: http://www.team-cymru.org/Services/Bogons/
|
||||
#BOGON|86400|0|http://www.cymru.com/Documents/bogon-bn-agg.txt
|
||||
|
||||
# Project Honey Pot Directory of Dictionary Attacker IPs
|
||||
# Details: http://www.projecthoneypot.org
|
||||
#HONEYPOT|86400|0|https://www.projecthoneypot.org/list_of_ips.php?t=d&rss=1
|
||||
|
||||
# C.I. Army Malicious IP List
|
||||
# Details: http://www.ciarmy.com
|
||||
#CIARMY|86400|0|http://www.ciarmy.com/list/ci-badguys.txt
|
||||
|
||||
# BruteForceBlocker IP List
|
||||
# Details: http://danger.rulez.sk/index.php/bruteforceblocker/
|
||||
#BFB|86400|0|http://danger.rulez.sk/projects/bruteforceblocker/blist.php
|
||||
|
||||
# MaxMind GeoIP Anonymous Proxies
|
||||
# Set URLGET in csf.conf to use LWP as this list uses an SSL connection
|
||||
# Details: https://www.maxmind.com/en/anonymous_proxies
|
||||
#MAXMIND|86400|0|https://www.maxmind.com/en/anonymous_proxies
|
||||
|
||||
# Blocklist.de
|
||||
# Set URLGET in csf.conf to use LWP as this list uses an SSL connection
|
||||
# Details: https://www.blocklist.de
|
||||
# This first list only retrieves the IP addresses added in the last hour
|
||||
#BDE|3600|0|https://api.blocklist.de/getlast.php?time=3600
|
||||
# This second list retrieves all the IP addresses added in the last 48 hours
|
||||
# and is usually a very large list (over 10000 entries), so be sure that you
|
||||
# have the resources available to use it
|
||||
#BDEALL|86400|0|http://lists.blocklist.de/lists/all.txt
|
||||
|
||||
# Stop Forum Spam
|
||||
# Details: http://www.stopforumspam.com/downloads/
|
||||
# Many of the lists available contain a vast number of IP addresses so special
|
||||
# care needs to be made when selecting from their lists
|
||||
#STOPFORUMSPAM|86400|0|http://www.stopforumspam.com/downloads/listed_ip_1.zip
|
||||
|
||||
# Stop Forum Spam IPv6
|
||||
# Details: http://www.stopforumspam.com/downloads/
|
||||
# Many of the lists available contain a vast number of IP addresses so special
|
||||
# care needs to be made when selecting from their lists
|
||||
#STOPFORUMSPAMV6|86400|0|http://www.stopforumspam.com/downloads/listed_ip_1_ipv6.zip
|
||||
|
||||
# GreenSnow Hack List
|
||||
# Details: https://greensnow.co
|
||||
#GREENSNOW|86400|0|https://blocklist.greensnow.co/greensnow.txt
|
||||
85
csf/csf.c
Normal file
85
csf/csf.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
# 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>.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
main ()
|
||||
{
|
||||
FILE *adminFile;
|
||||
FILE *resellerFile;
|
||||
uid_t ruid;
|
||||
char name[100];
|
||||
struct passwd *pw;
|
||||
int admin = 0;
|
||||
int reseller = 0;
|
||||
|
||||
setenv("CSF_RESELLER", "", 1);
|
||||
ruid = getuid();
|
||||
pw = getpwuid(ruid);
|
||||
|
||||
adminFile=fopen ("/usr/local/directadmin/data/admin/admin.list","r");
|
||||
if (adminFile!=NULL)
|
||||
{
|
||||
while(fgets(name,100,adminFile) != NULL)
|
||||
{
|
||||
int end = strlen(name) - 1;
|
||||
if (end >= 0 && name[end] == '\n') name[end] = '\0';
|
||||
//printf("Name [%s]\n", name);
|
||||
if (strcmp(pw->pw_name, name) == 0) admin = 1;
|
||||
}
|
||||
fclose(adminFile);
|
||||
}
|
||||
if (admin == 1)
|
||||
{
|
||||
setuid(0);
|
||||
setgid(0);
|
||||
|
||||
execv("/usr/local/directadmin/plugins/csf/exec/da_csf.cgi", NULL);
|
||||
} else {
|
||||
resellerFile=fopen ("/usr/local/directadmin/data/admin/reseller.list","r");
|
||||
if (resellerFile!=NULL)
|
||||
{
|
||||
while(fgets(name,100,resellerFile) != NULL)
|
||||
{
|
||||
int end = strlen(name) - 1;
|
||||
if (end >= 0 && name[end] == '\n') name[end] = '\0';
|
||||
//printf("Name [%s]\n", name);
|
||||
if (strcmp(pw->pw_name, name) == 0)
|
||||
{
|
||||
reseller = 1;
|
||||
setenv("CSF_RESELLER", pw->pw_name, 1);
|
||||
}
|
||||
}
|
||||
fclose(resellerFile);
|
||||
}
|
||||
if (reseller == 1)
|
||||
{
|
||||
setuid(0);
|
||||
setgid(0);
|
||||
|
||||
execv("/usr/local/directadmin/plugins/csf/exec/da_csf_reseller.cgi", NULL);
|
||||
} else {
|
||||
printf("Permission denied [User:%s UID:%d]\n", pw->pw_name, ruid);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
63
csf/csf.cloudflare
Normal file
63
csf/csf.cloudflare
Normal file
@@ -0,0 +1,63 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# This file contains configuration elements for the CF_ENABLE CloudFlare
|
||||
# feature
|
||||
#
|
||||
# Entries:
|
||||
#
|
||||
# DOMAIN:
|
||||
# These list the per domain CloudFlare credientials for each matching domain
|
||||
# for all relevant triggers (i.e. LF_MODSEC)
|
||||
#
|
||||
# The special case "any" can be used as the domain name for all relevant
|
||||
# triggers regardless of domain
|
||||
#
|
||||
# USER:
|
||||
# This must be a unique name for the entry, but does not have to be a local
|
||||
# linux account name
|
||||
#
|
||||
# CFACCOUNT:
|
||||
# This is the CloudFlare login user (email address)
|
||||
#
|
||||
# CFAPIKEY:
|
||||
# This is the CloudFlare Client API Key
|
||||
#
|
||||
# DISABLE:
|
||||
# Normally, comment out a line to disable it. On servers with CF_CPANEL enabled
|
||||
# a cPanel user can be disabled here
|
||||
#
|
||||
# ANY:
|
||||
# On servers with CF_CPANEL enabled a cPanel user can be configured to use the
|
||||
# special "any" case (see above)
|
||||
#
|
||||
|
||||
# CloudFlare client credientials for any domain triggered:
|
||||
#DOMAIN:any:USER:myuser:CFACCOUNT:sales@hostsdomain.com:CFAPIKEY:12345abcdef6789
|
||||
|
||||
# CloudFlare client credientials for domain.com involved in trigger:
|
||||
#DOMAIN:domain.com:USER:myuser:CFACCOUNT:sales@domain.com:CFAPIKEY:12345abcdef6789
|
||||
|
||||
# CloudFlare client credientials for domain2.com involved in trigger:
|
||||
#DOMAIN:domain2.com:USER:myuser:CFACCOUNT:myuser@hotmail.com:CFAPIKEY:12345abcdef6789
|
||||
|
||||
# Disable CloudFlare cPanel user mycpanel from this feature:
|
||||
#DISABLE:mycpanel
|
||||
|
||||
# Enable a cPanel user mycpanel to use the "any" feature:
|
||||
#ANY:mycpanel
|
||||
2825
csf/csf.conf
Normal file
2825
csf/csf.conf
Normal file
File diff suppressed because it is too large
Load Diff
30
csf/csf.cwp.allow
Normal file
30
csf/csf.cwp.allow
Normal file
@@ -0,0 +1,30 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be allowed through iptables.
|
||||
# One IP address per line.
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24).
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
# Advanced port+ip filtering allowed with the following format
|
||||
# tcp/udp|in/out|s/d=port|s/d=ip
|
||||
# See readme.txt for more information
|
||||
#
|
||||
# Note: IP addressess listed in this file will NOT be ignored by lfd, so they
|
||||
# can still be blocked. If you do not want lfd to block an IP address you must
|
||||
# add it to csf.ignore
|
||||
2685
csf/csf.cwp.conf
Normal file
2685
csf/csf.cwp.conf
Normal file
File diff suppressed because it is too large
Load Diff
25
csf/csf.cwp.ignore
Normal file
25
csf/csf.cwp.ignore
Normal file
@@ -0,0 +1,25 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be ignored by all lfd checks
|
||||
# One IP address per line
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24)
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
|
||||
127.0.0.1
|
||||
116
csf/csf.cwp.pignore
Normal file
116
csf/csf.cwp.pignore
Normal file
@@ -0,0 +1,116 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of executables (exe) command lines (cmd) and
|
||||
# usernames (user) that lfd process tracking will ignore.
|
||||
#
|
||||
# You must use the following format:
|
||||
#
|
||||
# exe:/full/path/to/file
|
||||
# user:username
|
||||
# cmd:command line
|
||||
#
|
||||
# Or, perl regular expression matching (regex):
|
||||
#
|
||||
# pexe:/full/path/to/file as a perl regex[*]
|
||||
# puser:username as a perl regex[*]
|
||||
# pcmd:command line as a perl regex[*]
|
||||
#
|
||||
# [*]You must remember to escape characters correctly when using regex's, e.g.:
|
||||
# pexe:/home/.*/public_html/cgi-bin/script\.cgi
|
||||
# puser:bob\d.*
|
||||
# pcmd:/home/.*/command\s\to\smatch\s\.pl\s.*
|
||||
#
|
||||
# It is strongly recommended that you use command line ignores very carefully
|
||||
# as any process can change what is reported to the OS.
|
||||
#
|
||||
# For more information see readme.txt
|
||||
|
||||
exe:/bin/dbus-daemon
|
||||
exe:/sbin/ntpd
|
||||
exe:/usr/bin/dbus-daemon
|
||||
exe:/usr/bin/lsmd
|
||||
exe:/usr/lib/courier-imap/bin/imapd
|
||||
exe:/usr/lib/courier-imap/bin/pop3d
|
||||
exe:/usr/lib/polkit-1/polkitd
|
||||
exe:/usr/libexec/dovecot/imap
|
||||
exe:/usr/libexec/dovecot/imap
|
||||
exe:/usr/libexec/dovecot/pop3
|
||||
exe:/usr/libexec/dovecot/pop3
|
||||
exe:/usr/libexec/dovecot/stats
|
||||
exe:/usr/libexec/dovecot/auth
|
||||
exe:/usr/libexec/mysqld
|
||||
exe:/usr/local/apache/bin/httpd
|
||||
exe:/usr/local/libexec/dovecot/imap
|
||||
exe:/usr/local/libexec/dovecot/imap-login
|
||||
exe:/usr/local/libexec/dovecot/pop3
|
||||
exe:/usr/local/libexec/dovecot/pop3-login
|
||||
exe:/usr/local/libexec/dovecot/stats
|
||||
exe:/usr/sbin/chronyd
|
||||
exe:/usr/sbin/exim
|
||||
exe:/usr/sbin/exim4
|
||||
exe:/usr/sbin/named
|
||||
exe:/usr/sbin/nscd
|
||||
exe:/usr/sbin/ntpd
|
||||
exe:/usr/sbin/ntpd
|
||||
exe:/usr/sbin/proftpd
|
||||
exe:/usr/sbin/pure-ftpd
|
||||
exe:/usr/sbin/sshd
|
||||
exe:/usr/sbin/apache2
|
||||
exe:/usr/sbin/mysqld
|
||||
exe:/lib/systemd/systemd-timesyncd
|
||||
exe:/sbin/rngd
|
||||
|
||||
exe:/usr/sbin/clamd
|
||||
exe:/usr/sbin/opendkim
|
||||
exe:/usr/libexec/mysqld
|
||||
exe:/usr/sbin/mysqld
|
||||
exe:/usr/bin/postgres
|
||||
exe:/usr/bin/mongod
|
||||
exe:/usr/libexec/dovecot/anvil
|
||||
exe:/usr/libexec/dovecot/auth
|
||||
exe:/usr/libexec/dovecot/imap-login
|
||||
exe:/usr/libexec/dovecot/dict
|
||||
exe:/usr/libexec/dovecot/pop3-login
|
||||
exe:/usr/local/cwp/php71/sbin/php-fpm
|
||||
exe:/usr/libexec/postfix/tlsmgr
|
||||
exe:/usr/libexec/postfix/qmgr
|
||||
exe:/usr/libexec/postfix/pickup
|
||||
exe:/usr/libexec/postfix/smtpd
|
||||
exe:/usr/libexec/postfix/smtp
|
||||
exe:/usr/libexec/postfix/bounce
|
||||
exe:/usr/libexec/postfix/scache
|
||||
exe:/usr/libexec/postfix/anvil
|
||||
exe:/usr/libexec/postfix/cleanup
|
||||
exe:/usr/libexec/postfix/proxymap
|
||||
exe:/usr/libexec/postfix/trivial-rewrite
|
||||
exe:/usr/libexec/postfix/local
|
||||
exe:/usr/libexec/postfix/pipe
|
||||
exe:/usr/libexec/postfix/spawn
|
||||
exe:/usr/sbin/varnishd
|
||||
exe:/usr/sbin/nginx
|
||||
exe:/usr/sbin/mariadbd
|
||||
exe:/usr/bin/dbus-broker-launch
|
||||
exe:/usr/bin/dbus-broker
|
||||
|
||||
# Some additional entries that you might want to ignore on cPanel servers.
|
||||
# However, be aware of the security implications under "Process Tracking" in
|
||||
# the csf readme.txt when using these:
|
||||
#
|
||||
#cmd:spamd child
|
||||
#cmd:/bin/sh /usr/bin/mysqld_safe --basedir=/usr
|
||||
30
csf/csf.cyberpanel.allow
Normal file
30
csf/csf.cyberpanel.allow
Normal file
@@ -0,0 +1,30 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be allowed through iptables.
|
||||
# One IP address per line.
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24).
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
# Advanced port+ip filtering allowed with the following format
|
||||
# tcp/udp|in/out|s/d=port|s/d=ip
|
||||
# See readme.txt for more information
|
||||
#
|
||||
# Note: IP addressess listed in this file will NOT be ignored by lfd, so they
|
||||
# can still be blocked. If you do not want lfd to block an IP address you must
|
||||
# add it to csf.ignore
|
||||
2679
csf/csf.cyberpanel.conf
Normal file
2679
csf/csf.cyberpanel.conf
Normal file
File diff suppressed because it is too large
Load Diff
25
csf/csf.cyberpanel.ignore
Normal file
25
csf/csf.cyberpanel.ignore
Normal file
@@ -0,0 +1,25 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be ignored by all lfd checks
|
||||
# One IP address per line
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24)
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
|
||||
127.0.0.1
|
||||
108
csf/csf.cyberpanel.pignore
Normal file
108
csf/csf.cyberpanel.pignore
Normal file
@@ -0,0 +1,108 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of executables (exe) command lines (cmd) and
|
||||
# usernames (user) that lfd process tracking will ignore.
|
||||
#
|
||||
# You must use the following format:
|
||||
#
|
||||
# exe:/full/path/to/file
|
||||
# user:username
|
||||
# cmd:command line
|
||||
#
|
||||
# Or, perl regular expression matching (regex):
|
||||
#
|
||||
# pexe:/full/path/to/file as a perl regex[*]
|
||||
# puser:username as a perl regex[*]
|
||||
# pcmd:command line as a perl regex[*]
|
||||
#
|
||||
# [*]You must remember to escape characters correctly when using regex's, e.g.:
|
||||
# pexe:/home/.*/public_html/cgi-bin/script\.cgi
|
||||
# puser:bob\d.*
|
||||
# pcmd:/home/.*/command\s\to\smatch\s\.pl\s.*
|
||||
#
|
||||
# It is strongly recommended that you use command line ignores very carefully
|
||||
# as any process can change what is reported to the OS.
|
||||
#
|
||||
# For more information see readme.txt
|
||||
|
||||
exe:/bin/dbus-daemon
|
||||
exe:/sbin/ntpd
|
||||
exe:/usr/bin/dbus-daemon
|
||||
exe:/usr/bin/lsmd
|
||||
exe:/usr/lib/courier-imap/bin/imapd
|
||||
exe:/usr/lib/courier-imap/bin/pop3d
|
||||
exe:/usr/lib/polkit-1/polkitd
|
||||
exe:/usr/libexec/dovecot/imap
|
||||
exe:/usr/libexec/mysqld
|
||||
exe:/usr/local/apache/bin/httpd
|
||||
exe:/usr/sbin/chronyd
|
||||
exe:/usr/sbin/exim
|
||||
exe:/usr/sbin/exim4
|
||||
exe:/usr/sbin/named
|
||||
exe:/usr/sbin/nscd
|
||||
exe:/usr/sbin/ntpd
|
||||
exe:/usr/sbin/ntpd
|
||||
exe:/usr/sbin/proftpd
|
||||
exe:/usr/sbin/pure-ftpd
|
||||
exe:/usr/sbin/sshd
|
||||
exe:/usr/sbin/apache2
|
||||
exe:/usr/sbin/mysqld
|
||||
exe:/lib/systemd/systemd-timesyncd
|
||||
exe:/sbin/rngd
|
||||
exe:/usr/bin/dbus-broker-launch
|
||||
exe:/usr/bin/dbus-broker
|
||||
|
||||
# CyberPanel:
|
||||
exe:/usr/sbin/pdns_server
|
||||
exe:/usr/sbin/opendkim
|
||||
exe:/usr/bin/redis-server
|
||||
exe:/usr/sbin/pure-ftpd-mysql
|
||||
exe:/usr/libexec/postfix/qmgr
|
||||
exe:/usr/libexec/postfix/pickup
|
||||
exe:/usr/libexec/postfix/tlsmgr
|
||||
exe:/usr/libexec/postfix/master
|
||||
exe:/usr/lib/postfix/sbin/tlsmgr
|
||||
exe:/usr/lib/postfix/sbin/master
|
||||
exe:/usr/lib/postfix/sbin/qmgr
|
||||
exe:/usr/lib/postfix/sbin/pickup
|
||||
exe:/usr/sbin/dovecot
|
||||
exe:/usr/lib/dovecot/imap-login
|
||||
exe:/usr/libexec/dovecot/anvil
|
||||
exe:/usr/libexec/dovecot/auth
|
||||
exe:/usr/libexec/dovecot/dict
|
||||
exe:/usr/libexec/dovecot/imap
|
||||
exe:/usr/libexec/dovecot/imap-login
|
||||
exe:/usr/libexec/dovecot/lmtp
|
||||
exe:/usr/libexec/dovecot/pop3
|
||||
exe:/usr/libexec/dovecot/pop3-login
|
||||
exe:/usr/libexec/dovecot/quota-status
|
||||
exe:/usr/libexec/dovecot/stats
|
||||
exe:/usr/lib/dovecot/anvil
|
||||
exe:/usr/lib/dovecot/auth
|
||||
exe:/usr/lib/dovecot/dict
|
||||
exe:/usr/lib/dovecot/imap
|
||||
exe:/usr/lib/dovecot/imap-login
|
||||
exe:/usr/lib/dovecot/lmtp
|
||||
exe:/usr/lib/dovecot/pop3
|
||||
exe:/usr/lib/dovecot/pop3-login
|
||||
exe:/usr/lib/dovecot/quota-status
|
||||
exe:/usr/lib/dovecot/stats
|
||||
exe:/usr/local/lsws/bin/openlitespeed
|
||||
exe:/usr/local/CyberCP/bin/lswsgi
|
||||
exe:/usr/sbin/mariadbd
|
||||
31
csf/csf.deny
Normal file
31
csf/csf.deny
Normal file
@@ -0,0 +1,31 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be blocked in iptables
|
||||
# One IP address per line
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24)
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
# Note: If you add the text "do not delete" to the comments of an entry then
|
||||
# DENY_IP_LIMIT will ignore those entries and not remove them
|
||||
#
|
||||
# Advanced port+ip filtering allowed with the following format
|
||||
# tcp/udp|in/out|s/d=port,port,...|s/d=ip
|
||||
#
|
||||
# See readme.txt for more information regarding advanced port filtering
|
||||
#
|
||||
30
csf/csf.directadmin.allow
Normal file
30
csf/csf.directadmin.allow
Normal file
@@ -0,0 +1,30 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be allowed through iptables.
|
||||
# One IP address per line.
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24).
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
# Advanced port+ip filtering allowed with the following format
|
||||
# tcp/udp|in/out|s/d=port|s/d=ip
|
||||
# See readme.txt for more information
|
||||
#
|
||||
# Note: IP addressess listed in this file will NOT be ignored by lfd, so they
|
||||
# can still be blocked. If you do not want lfd to block an IP address you must
|
||||
# add it to csf.ignore
|
||||
2739
csf/csf.directadmin.conf
Normal file
2739
csf/csf.directadmin.conf
Normal file
File diff suppressed because it is too large
Load Diff
25
csf/csf.directadmin.ignore
Normal file
25
csf/csf.directadmin.ignore
Normal file
@@ -0,0 +1,25 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be ignored by all lfd checks
|
||||
# One IP address per line
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24)
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
|
||||
127.0.0.1
|
||||
95
csf/csf.directadmin.pignore
Normal file
95
csf/csf.directadmin.pignore
Normal file
@@ -0,0 +1,95 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of executables (exe) command lines (cmd) and
|
||||
# usernames (user) that lfd process tracking will ignore.
|
||||
#
|
||||
# You must use the following format:
|
||||
#
|
||||
# exe:/full/path/to/file
|
||||
# user:username
|
||||
# cmd:command line
|
||||
#
|
||||
# Or, perl regular expression matching (regex):
|
||||
#
|
||||
# pexe:/full/path/to/file as a perl regex[*]
|
||||
# puser:username as a perl regex[*]
|
||||
# pcmd:command line as a perl regex[*]
|
||||
#
|
||||
# [*]You must remember to escape characters correctly when using regex's, e.g.:
|
||||
# pexe:/home/.*/public_html/cgi-bin/script\.cgi
|
||||
# puser:bob\d.*
|
||||
# pcmd:/home/.*/command\s\to\smatch\s\.pl\s.*
|
||||
#
|
||||
# It is strongly recommended that you use command line ignores very carefully
|
||||
# as any process can change what is reported to the OS.
|
||||
#
|
||||
# For more information see readme.txt
|
||||
|
||||
exe:/bin/dbus-daemon
|
||||
exe:/sbin/ntpd
|
||||
exe:/usr/bin/dbus-daemon
|
||||
exe:/usr/bin/dbus-daemon
|
||||
exe:/usr/bin/dbus-daemon-1
|
||||
exe:/usr/bin/lsmd
|
||||
exe:/usr/lib/polkit-1/polkitd
|
||||
exe:/usr/libexec/dovecot/anvil
|
||||
exe:/usr/libexec/dovecot/imap
|
||||
exe:/usr/libexec/dovecot/imap-login
|
||||
exe:/usr/libexec/dovecot/pop3
|
||||
exe:/usr/libexec/dovecot/pop3-login
|
||||
exe:/usr/libexec/dovecot/stats
|
||||
exe:/usr/libexec/gam_server
|
||||
exe:/usr/libexec/hald-addon-acpi
|
||||
exe:/usr/libexec/hald-addon-keyboard
|
||||
exe:/usr/local/directadmin/dataskq
|
||||
exe:/usr/local/directadmin/directadmin
|
||||
exe:/usr/local/libexec/dovecot/imap
|
||||
exe:/usr/local/libexec/dovecot/imap-login
|
||||
exe:/usr/local/libexec/dovecot/pop3
|
||||
exe:/usr/local/libexec/dovecot/pop3-login
|
||||
exe:/usr/local/mysql-5.1.54-linux-x86_64/bin/mysqld
|
||||
exe:/usr/sbin/chronyd
|
||||
exe:/usr/sbin/exim
|
||||
exe:/usr/sbin/exim
|
||||
exe:/usr/sbin/hald
|
||||
exe:/usr/sbin/httpd
|
||||
exe:/usr/sbin/mysqld
|
||||
exe:/usr/sbin/mysqld_safe
|
||||
exe:/usr/sbin/named
|
||||
exe:/usr/sbin/nscd
|
||||
exe:/usr/sbin/ntpd
|
||||
exe:/usr/sbin/proftpd
|
||||
exe:/usr/sbin/sshd
|
||||
exe:/usr/sbin/apache2
|
||||
exe:/usr/sbin/mysqld
|
||||
exe:/lib/systemd/systemd-timesyncd
|
||||
exe:/usr/local/bin/freshclam
|
||||
exe:/sbin/rngd
|
||||
exe:/usr/sbin/mariadbd
|
||||
exe:/usr/bin/dbus-broker-launch
|
||||
exe:/usr/bin/dbus-broker
|
||||
|
||||
# Some additional entries that you might want to ignore on DirectAdmin
|
||||
# servers.
|
||||
# However, be aware of the security implications under "Process Tracking" in
|
||||
# the csf readme.txt when using these:
|
||||
#
|
||||
#cmd:/bin/sh /usr/bin/mysqld_safe
|
||||
#cmd:/bin/sh /usr/bin/mysqld_safe --basedir=/usr
|
||||
#pcmd:MailScanner:.*
|
||||
27
csf/csf.dirwatch
Normal file
27
csf/csf.dirwatch
Normal file
@@ -0,0 +1,27 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following should be a list of directories and files that you want to be
|
||||
# alerted when they change. You must specify full paths for each entry.
|
||||
#
|
||||
# lfd uses a simple md5sum match from the output of:
|
||||
# ls --full-time -lARt [dir]
|
||||
# on the entry and so will traverse directories if specified.
|
||||
#
|
||||
# An example where you might want to use this is /var/spool/cron
|
||||
#
|
||||
230
csf/csf.div
Normal file
230
csf/csf.div
Normal file
@@ -0,0 +1,230 @@
|
||||
<script type="text/javascript">
|
||||
/***********************************************
|
||||
* Virtual Pagination script- © Dynamic Drive DHTML code library (www.dynamicdrive.com)
|
||||
* This notice MUST stay intact for legal use
|
||||
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
|
||||
* Additions and Modifications © Jonathan Michaelson (www.configserver.com)
|
||||
***********************************************/
|
||||
function virtualpaginate(config){ //config: {piececlass:, piececontainer:, pieces_per_page:, defaultpage:, wraparound:, persist}
|
||||
this.piececlass=config.piececlass
|
||||
var elementType=(typeof config.piececontainer=="undefined")? "div" : config.piececontainer //The type of element used to divide up content into pieces. Defaults to "div"
|
||||
this.pieces=virtualpaginate.collectElementbyClass(config.piececlass, elementType) //get total number of divs matching class name
|
||||
this.chunksize=(typeof config.pieces_per_page=="undefined")? 1 : (config.pieces_per_page>0 && config.pieces_per_page<this.pieces.length)? config.pieces_per_page : this.pieces.length
|
||||
this.pagecount=Math.ceil(this.pieces.length/this.chunksize) //calculate number of "pages" needed to show the divs
|
||||
this.wraparound=config.wraparound || false
|
||||
this.paginatediv=[], this.flatviewlinks=[], this.cpspan=[], this.selectmenu=[], this.prevlinks=[], this.nextlinks=[]
|
||||
this.persist=config.persist
|
||||
var persistedpage=virtualpaginate.getCookie("dd_"+this.piececlass) || 0
|
||||
var urlselectedpage=virtualpaginate.urlparamselect(this.piececlass) //returns null or index from: mypage.htm?piececlass=index
|
||||
this.currentpage=(typeof urlselectedpage=="number")? urlselectedpage : ((this.persist)? persistedpage : config.defaultpage)
|
||||
this.currentpage=(this.currentpage<this.pagecount)? parseInt(this.currentpage) : 0 //ensure currentpage is within range of available pages
|
||||
this.showpage(this.currentpage) //Show selected page
|
||||
}
|
||||
virtualpaginate.prototype.navigate=function(keyword){
|
||||
if ((!this.wraparound && keyword=="previous" && this.currentpage==0) || (!this.wraparound && keyword=="next" && this.currentpage==this.pagecount-1))
|
||||
return //exit immediately if wraparound is disabled and prev link is clicked when on 1st content or last link is clicked when on final content
|
||||
var prevlinkindex=this.currentpage //Get index of last clicked on page
|
||||
if (keyword=="previous")
|
||||
this.currentpage=(this.currentpage>0)? this.currentpage-1 : (this.currentpage==0)? this.pagecount-1 : 0
|
||||
else if (keyword=="next")
|
||||
this.currentpage=(this.currentpage<this.pagecount-1)? this.currentpage+1 : 0
|
||||
else if (keyword=="first")
|
||||
this.currentpage=0
|
||||
else if (keyword=="last")
|
||||
this.currentpage=this.pagecount-1 //last page number
|
||||
else
|
||||
this.currentpage=parseInt(keyword)
|
||||
this.currentpage=(this.currentpage<this.pagecount)? this.currentpage : 0 //ensure pagenumber is within range of available pages
|
||||
this.showpage(this.currentpage)
|
||||
for (var p=0; p<this.paginatediv.length; p++){ //loop through all pagination DIVs
|
||||
if (this.flatviewpresent)
|
||||
this.flatviewlinks[p][prevlinkindex].className="" //"Unhighlight" previous page (before this.currentpage increments)
|
||||
if (this.selectmenupresent)
|
||||
this.selectmenu[p].selectedIndex=this.currentpage
|
||||
if (this.flatviewpresent)
|
||||
this.flatviewlinks[p][this.currentpage].className="selected" //"Highlight" current page
|
||||
}
|
||||
if (!this.wraparound){
|
||||
for (var i=0; i<this.prevlinks.length; i++) //add or remove "disable" class from prev links depending on current page number
|
||||
virtualpaginate.setcssclass(this.prevlinks[i], "disabled", (this.currentpage==0)? "add" : "remove")
|
||||
for (var i=0; i<this.nextlinks.length; i++) //add or remove "disable" class from next links depending on current page number
|
||||
virtualpaginate.setcssclass(this.nextlinks[i], "disabled", (this.currentpage==(this.pagecount-1))? "add" : "remove")
|
||||
}
|
||||
}
|
||||
virtualpaginate.prototype.buildpagination=function(divids, optnavtext){
|
||||
var divids=(typeof divids=="string")? [divids] : divids //force divids to be an array of ids
|
||||
var primarypaginatediv=divids.shift() //get first id within divids[]
|
||||
var paginaterawHTML=document.getElementById(primarypaginatediv).innerHTML
|
||||
this.paginate_build(primarypaginatediv, 0, optnavtext)
|
||||
for (var i=0; i<divids.length; i++){
|
||||
document.getElementById(divids[i]).innerHTML=paginaterawHTML
|
||||
this.paginate_build(divids[i], i+1, optnavtext)
|
||||
}
|
||||
}
|
||||
virtualpaginate.collectElementbyClass=function(classname, element){ //Returns an array containing DIVs with specified classname. Requires setcssclass()
|
||||
if (document.querySelectorAll){
|
||||
var pieces=document.querySelectorAll(element+"."+classname) //return pieces as HTMLCollection
|
||||
}
|
||||
else{
|
||||
var pieces=[]
|
||||
var alltags=document.getElementsByTagName(element)
|
||||
for (var i=0; i<alltags.length; i++){
|
||||
if (virtualpaginate.setcssclass(alltags[i], classname, "check")) //if element carries class name in question
|
||||
pieces[pieces.length]=alltags[i] //return pieces as array
|
||||
}
|
||||
}
|
||||
return pieces
|
||||
}
|
||||
virtualpaginate.setcssclass=function(el, targetclass, action){
|
||||
var needle=new RegExp("(^|\\s+)"+targetclass+"($|\\s+)", "ig")
|
||||
if (action=="check")
|
||||
return needle.test(el.className)
|
||||
else if (action=="remove")
|
||||
el.className=el.className.replace(needle, "")
|
||||
else if (action=="add" && !needle.test(el.className))
|
||||
el.className+=" "+targetclass
|
||||
}
|
||||
virtualpaginate.urlparamselect=function(vpclass){
|
||||
var result=window.location.search.match(new RegExp(vpclass+"=(\\d+)", "i")) //check for "?piececlass=2" in URL
|
||||
return (result==null)? null : parseInt(RegExp.$1) //returns null or index, where index (int) is the selected virtual page's index
|
||||
}
|
||||
virtualpaginate.getCookie=function(Name){
|
||||
var re=new RegExp(Name+"=[^;]+", "i"); //construct RE to search for target name/value pair
|
||||
if (document.cookie.match(re)) //if cookie found
|
||||
return document.cookie.match(re)[0].split("=")[1] //return its value
|
||||
return null
|
||||
}
|
||||
virtualpaginate.setCookie=function(name, value){
|
||||
document.cookie = name+"="+value
|
||||
}
|
||||
virtualpaginate.prototype.showpage=function(pagenumber){
|
||||
var totalitems=this.pieces.length //total number of broken up divs
|
||||
var showstartindex=pagenumber*this.chunksize //array index of div to start showing per pagenumber setting
|
||||
var showendindex=showstartindex+this.chunksize-1 //array index of div to stop showing after per pagenumber setting
|
||||
for (var i=0; i<totalitems; i++){
|
||||
if (i>=showstartindex && i<=showendindex)
|
||||
this.pieces[i].style.display="block"
|
||||
else
|
||||
this.pieces[i].style.display="none"
|
||||
}
|
||||
if (this.persist){ //if persistence enabled
|
||||
virtualpaginate.setCookie("dd_"+this.piececlass, this.currentpage)
|
||||
}
|
||||
if (this.cpspan.length>0){ //if <span class="paginateinfo> element is present, update it with the most current info (ie: Page 3/4)
|
||||
for (var p=0; p<this.cpspan.length; p++)
|
||||
this.cpspan[p].innerHTML='Page '+(this.currentpage+1)+'/'+this.pagecount
|
||||
}
|
||||
}
|
||||
virtualpaginate.prototype.paginate_build=function(divid, divpos, optnavtext){
|
||||
var instanceOfBox=this
|
||||
var paginatediv=document.getElementById(divid)
|
||||
if (this.chunksize==this.pieces.length){ //if user has set to display all pieces at once, no point in creating pagination div
|
||||
paginatediv.style.display="none"
|
||||
return
|
||||
}
|
||||
var paginationcode=paginatediv.innerHTML //Get user defined, "unprocessed" HTML within paginate div
|
||||
if (paginatediv.getElementsByTagName("select").length>0) //if there's a select menu in div
|
||||
this.paginate_build_selectmenu(paginatediv.getElementsByTagName("select")[0], divpos, optnavtext)
|
||||
if (paginatediv.getElementsByTagName("a").length>0) //if there are links defined in div
|
||||
this.paginate_build_regularlinks(paginatediv.getElementsByTagName("a"))
|
||||
var allspans=paginatediv.getElementsByTagName("span") //Look for span tags within passed div
|
||||
for (var i=0; i<allspans.length; i++){
|
||||
if (allspans[i].className=="flatview")
|
||||
this.paginate_output_flatview(allspans[i], divpos, optnavtext)
|
||||
else if (allspans[i].className=="paginateinfo")
|
||||
this.paginate_build_cpinfo(allspans[i], divpos)
|
||||
}
|
||||
this.paginatediv[divpos]=paginatediv
|
||||
}
|
||||
virtualpaginate.prototype.paginate_output_flatview=function(flatviewcontainer, divpos, anchortext){
|
||||
var flatviewhtml=""
|
||||
var anchortext=anchortext || new Array()
|
||||
for (var i=0; i<this.pagecount; i++){
|
||||
if (typeof anchortext[i]!="undefined") //if custom anchor text for this link exists
|
||||
flatviewhtml+='<a href="#flatview" rel="'+i+'">'+anchortext[i]+'</a> ' //build pagination link using custom anchor text
|
||||
else
|
||||
flatviewhtml+='<a href="#flatview" rel="'+i+'">'+(i+1)+'</a> ' //build pagination link using auto incremented sequential number instead
|
||||
}
|
||||
flatviewcontainer.innerHTML=flatviewhtml
|
||||
this.paginate_build_flatview(flatviewcontainer, divpos, anchortext)
|
||||
}
|
||||
virtualpaginate.prototype.paginate_build_flatview=function(flatviewcontainer, divpos, anchortext){
|
||||
var instanceOfBox=this
|
||||
var flatviewhtml=""
|
||||
this.flatviewlinks[divpos]=flatviewcontainer.getElementsByTagName("a")
|
||||
for (var i=0; i<this.flatviewlinks[divpos].length; i++){
|
||||
this.flatviewlinks[divpos][i].onclick=function(){
|
||||
var prevlinkindex=instanceOfBox.currentpage //Get index of last clicked on flatview link
|
||||
var curlinkindex=parseInt(this.getAttribute("rel"))
|
||||
instanceOfBox.navigate(curlinkindex)
|
||||
return false
|
||||
}
|
||||
}
|
||||
this.flatviewlinks[divpos][this.currentpage].className="selected" //"Highlight" current flatview link
|
||||
this.flatviewpresent=true //indicate flat view links are present
|
||||
}
|
||||
virtualpaginate.prototype.paginate_build_selectmenu=function(paginatedropdown, divpos, anchortext){
|
||||
var instanceOfBox=this
|
||||
var anchortext=anchortext || new Array()
|
||||
this.selectmenupresent=1
|
||||
for (var i=0; i<this.pagecount; i++){
|
||||
if (typeof anchortext[i]!="undefined") //if custom anchor text for this link exists, use anchor text as each OPTION's text
|
||||
paginatedropdown.options[i]=new Option(anchortext[i], i)
|
||||
else //else, use auto incremented, sequential numbers
|
||||
paginatedropdown.options[i]=new Option("Page "+(i+1)+" of "+this.pagecount, i)
|
||||
}
|
||||
paginatedropdown.selectedIndex=this.currentpage
|
||||
setTimeout(function(){paginatedropdown.selectedIndex=instanceOfBox.currentpage}, 500) //refresh currently selected option (for IE's sake)
|
||||
paginatedropdown.onchange=function(){
|
||||
instanceOfBox.navigate(this.selectedIndex)
|
||||
}
|
||||
this.selectmenu[divpos]=paginatedropdown
|
||||
this.selectmenu[divpos].selectedIndex=this.currentpage //"Select" current page's corresponding option
|
||||
}
|
||||
virtualpaginate.prototype.paginate_build_regularlinks=function(paginatelinks){
|
||||
var instanceOfBox=this
|
||||
for (var i=0; i<paginatelinks.length; i++){
|
||||
var currentpagerel=paginatelinks[i].getAttribute("rel")
|
||||
if (/^(previous)|(next)|(first)|(last)$/.test(currentpagerel)){ //screen for these "rel" values
|
||||
paginatelinks[i].onclick=function(){
|
||||
instanceOfBox.navigate(this.getAttribute("rel"))
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (currentpagerel=="previous" || paginatelinks[i].href.indexOf("previous")!=-1){ //check if this is a "previous" link
|
||||
if (!this.wraparound && this.currentpage==0) //if current page is first page, disable "prev" link
|
||||
virtualpaginate.setcssclass(paginatelinks[i], "disabled", "add")
|
||||
this.prevlinks.push(paginatelinks[i])
|
||||
}
|
||||
else if (currentpagerel=="next" || paginatelinks[i].href.indexOf("next")!=-1){ //check if this is a "next" link
|
||||
if (!this.wraparound && this.currentpage==this.pagecount-1) //if current page is last page, disable "next" link
|
||||
virtualpaginate.setcssclass(paginatelinks[i], "disabled", "add")
|
||||
this.nextlinks.push(paginatelinks[i])
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
virtualpaginate.prototype.paginate_build_cpinfo=function(cpspan, divpos){
|
||||
this.cpspan[divpos]=cpspan
|
||||
cpspan.innerHTML='Page '+(this.currentpage+1)+'/'+this.pagecount
|
||||
}
|
||||
virtualpaginate.prototype.showall=function(){
|
||||
for (var i=0; i<this.pieces.length; i++)
|
||||
this.pieces[i].style.display="block"
|
||||
this.currentpage = -1;
|
||||
for (var p=0; p<this.paginatediv.length; p++){ //loop through all pagination DIVs
|
||||
if (this.flatviewpresent)
|
||||
this.flatviewlinks[p][prevlinkindex].className="" //"Unhighlight" previous page (before this.currentpage increments)
|
||||
if (this.selectmenupresent)
|
||||
this.selectmenu[p].selectedIndex=this.currentpage
|
||||
if (this.flatviewpresent)
|
||||
this.flatviewlinks[p][this.currentpage].className="selected" //"Highlight" current page
|
||||
}
|
||||
if (!this.wraparound){
|
||||
for (var i=0; i<this.prevlinks.length; i++) //add or remove "disable" class from prev links depending on current page number
|
||||
virtualpaginate.setcssclass(this.prevlinks[i], "disabled", (this.currentpage<1)? "add" : "remove")
|
||||
for (var i=0; i<this.nextlinks.length; i++) //add or remove "disable" class from next links depending on current page number
|
||||
virtualpaginate.setcssclass(this.nextlinks[i], "disabled", (this.currentpage==(this.pagecount-1))? "add" : "remove")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
31
csf/csf.dyndns
Normal file
31
csf/csf.dyndns
Normal file
@@ -0,0 +1,31 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following FQDN's will be allowed through the firewall. This is controlled
|
||||
# by lfd which checks the DNS resolution of the FQDN and adds the ip address
|
||||
# into the ALLOWDYNIN and ALLOWDYNOUT iptables chains. lfd will check for IP
|
||||
# updates every DYNDNS seconds if set.
|
||||
#
|
||||
# If the FQDN has multiple A records then all of the IP addresses will be
|
||||
# processed. If IPV6 is enabled and the perl module Socket6 from cpan.org is
|
||||
# installed, then all IPv6 AAAA IP address records will also be allowed.
|
||||
#
|
||||
# Only list fully qualified domain names (FQDN's) in this file, either on their
|
||||
# own to allow full access, or using Advanced Allow/Deny Filters (see
|
||||
# readme.txt)
|
||||
#
|
||||
41
csf/csf.fignore
Normal file
41
csf/csf.fignore
Normal file
@@ -0,0 +1,41 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of files that lfd directory watching will ignore. You
|
||||
# must specify the full path to the file
|
||||
#
|
||||
# You can also use perl regular expression pattern matching, for example:
|
||||
# /tmp/clamav.*
|
||||
# /tmp/.*\.wrk
|
||||
#
|
||||
# Remember that you will need to escape special characters (precede them with a
|
||||
# backslash) such as \. \?
|
||||
#
|
||||
# Pattern matching will only occur with strings containing an asterix (*),
|
||||
# otherwise full file path matching will be applied
|
||||
#
|
||||
# You can also add entries to ignore files owner by a particular user by
|
||||
# preceding it with user:, for example:
|
||||
# user:bob
|
||||
#
|
||||
# Note: files owned by root are ignored
|
||||
|
||||
#/tmp/\.horde
|
||||
#/tmp/\.horde/.*
|
||||
#/tmp/yarn--[\d\-\.]+/(node|yarn)
|
||||
#/tmp/\.spamassassin.*
|
||||
30
csf/csf.generic.allow
Normal file
30
csf/csf.generic.allow
Normal file
@@ -0,0 +1,30 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be allowed through iptables.
|
||||
# One IP address per line.
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24).
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
# Advanced port+ip filtering allowed with the following format
|
||||
# tcp/udp|in/out|s/d=port|s/d=ip
|
||||
# See readme.txt for more information
|
||||
#
|
||||
# Note: IP addressess listed in this file will NOT be ignored by lfd, so they
|
||||
# can still be blocked. If you do not want lfd to block an IP address you must
|
||||
# add it to csf.ignore
|
||||
2678
csf/csf.generic.conf
Normal file
2678
csf/csf.generic.conf
Normal file
File diff suppressed because it is too large
Load Diff
25
csf/csf.generic.ignore
Normal file
25
csf/csf.generic.ignore
Normal file
@@ -0,0 +1,25 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be ignored by all lfd checks
|
||||
# One IP address per line
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24)
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
|
||||
127.0.0.1
|
||||
81
csf/csf.generic.pignore
Normal file
81
csf/csf.generic.pignore
Normal file
@@ -0,0 +1,81 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of executables (exe) command lines (cmd) and
|
||||
# usernames (user) that lfd process tracking will ignore.
|
||||
#
|
||||
# You must use the following format:
|
||||
#
|
||||
# exe:/full/path/to/file
|
||||
# user:username
|
||||
# cmd:command line
|
||||
#
|
||||
# Or, perl regular expression matching (regex):
|
||||
#
|
||||
# pexe:/full/path/to/file as a perl regex[*]
|
||||
# puser:username as a perl regex[*]
|
||||
# pcmd:command line as a perl regex[*]
|
||||
#
|
||||
# [*]You must remember to escape characters correctly when using regex's, e.g.:
|
||||
# pexe:/home/.*/public_html/cgi-bin/script\.cgi
|
||||
# puser:bob\d.*
|
||||
# pcmd:/home/.*/command\s\to\smatch\s\.pl\s.*
|
||||
#
|
||||
# It is strongly recommended that you use command line ignores very carefully
|
||||
# as any process can change what is reported to the OS.
|
||||
#
|
||||
# For more information see readme.txt
|
||||
|
||||
exe:/bin/dbus-daemon
|
||||
exe:/sbin/ntpd
|
||||
exe:/usr/bin/dbus-daemon
|
||||
exe:/usr/bin/lsmd
|
||||
exe:/usr/lib/courier-imap/bin/imapd
|
||||
exe:/usr/lib/courier-imap/bin/pop3d
|
||||
exe:/usr/lib/polkit-1/polkitd
|
||||
exe:/usr/libexec/dovecot/imap
|
||||
exe:/usr/libexec/dovecot/imap
|
||||
exe:/usr/libexec/dovecot/pop3
|
||||
exe:/usr/libexec/dovecot/pop3
|
||||
exe:/usr/libexec/mysqld
|
||||
exe:/usr/local/apache/bin/httpd
|
||||
exe:/usr/local/libexec/dovecot/imap
|
||||
exe:/usr/local/libexec/dovecot/imap-login
|
||||
exe:/usr/local/libexec/dovecot/pop3
|
||||
exe:/usr/local/libexec/dovecot/pop3-login
|
||||
exe:/usr/sbin/chronyd
|
||||
exe:/usr/sbin/exim
|
||||
exe:/usr/sbin/exim4
|
||||
exe:/usr/sbin/named
|
||||
exe:/usr/sbin/nscd
|
||||
exe:/usr/sbin/ntpd
|
||||
exe:/usr/sbin/ntpd
|
||||
exe:/usr/sbin/proftpd
|
||||
exe:/usr/sbin/pure-ftpd
|
||||
exe:/usr/sbin/sshd
|
||||
exe:/usr/sbin/apache2
|
||||
exe:/usr/sbin/mysqld
|
||||
exe:/lib/systemd/systemd-timesyncd
|
||||
exe:/usr/lib/systemd/systemd-resolved
|
||||
exe:/usr/libexec/postfix/pickup
|
||||
exe:/usr/libexec/postfix/qmgr
|
||||
exe:/usr/libexec/postfix/tlsmgr
|
||||
exe:/sbin/rngd
|
||||
exe:/usr/sbin/mariadbd
|
||||
exe:/usr/bin/dbus-broker-launch
|
||||
exe:/usr/bin/dbus-broker
|
||||
222
csf/csf.help
Normal file
222
csf/csf.help
Normal file
@@ -0,0 +1,222 @@
|
||||
csf(1) General Commands Manual csf(1)
|
||||
|
||||
NAME
|
||||
csf - ConfigServer & Security Firewall
|
||||
|
||||
SYNOPSIS
|
||||
csf [OPTIONS]
|
||||
|
||||
DESCRIPTION
|
||||
This manual documents the csf command line options for the ConfigServer & Security Firewall. See /etc/csf/csf.conf and
|
||||
/etc/csf/readme.txt for more detailed information on how to use and configure this application.
|
||||
|
||||
OPTIONS
|
||||
-h, --help
|
||||
Show this message
|
||||
|
||||
-l, --status
|
||||
List/Show the IPv4 iptables configuration
|
||||
|
||||
-l6, --status6
|
||||
List/Show the IPv6 ip6tables configuration
|
||||
|
||||
-s, --start
|
||||
Start the firewall rules
|
||||
|
||||
-f, --stop
|
||||
Flush/Stop firewall rules (Note: lfd may restart csf)
|
||||
|
||||
-r, --restart
|
||||
Restart firewall rules (csf)
|
||||
|
||||
-q, --startq
|
||||
Quick restart (csf restarted by lfd)
|
||||
|
||||
-sf, --startf
|
||||
Force CLI restart regardless of LFDSTART setting
|
||||
|
||||
-ra, --restartall
|
||||
Restart firewall rules (csf) and then restart lfd daemon. Both csf and then lfd should be restarted after making any changes to
|
||||
the configuration files
|
||||
|
||||
--lfd [stop|start|restart|status]
|
||||
Actions to take with the lfd daemon
|
||||
|
||||
-a, --add ip [comment]
|
||||
Allow an IP and add to /etc/csf/csf.allow
|
||||
|
||||
-ar, --addrm ip
|
||||
Remove an IP from /etc/csf/csf.allow and delete rule
|
||||
|
||||
-d, --deny ip [comment]
|
||||
Deny an IP and add to /etc/csf/csf.deny
|
||||
|
||||
-dr, --denyrm ip
|
||||
Unblock an IP and remove from /etc/csf/csf.deny
|
||||
|
||||
-df, --denyf
|
||||
Remove and unblock all entries in /etc/csf/csf.deny
|
||||
|
||||
-g, --grep ip
|
||||
Search the iptables and ip6tables rules for a match (e.g. IP, CIDR, Port Number)
|
||||
|
||||
-i, --iplookup ip
|
||||
Lookup IP address geographical information using CC_LOOKUPS setting in /etc/csf/csf.conf
|
||||
|
||||
-t, --temp
|
||||
Displays the current list of temporary allow and deny IP entries with their TTL and comment
|
||||
|
||||
-tr, --temprm ip
|
||||
Remove an IP from the temporary IP ban or allow list
|
||||
|
||||
-trd, --temprmd ip
|
||||
Remove an IP from the temporary IP ban list only
|
||||
|
||||
-tra, --temprma ip
|
||||
Remove an IP from the temporary IP allow list only
|
||||
|
||||
-td, --tempdeny ip ttl [-p port] [-d direction] [comment]
|
||||
Add an IP to the temp IP ban list. ttl is how long to blocks for (default:seconds, can use one suffix of h/m/d). Optional port.
|
||||
Optional direction of block can be one of: in, out or inout (default:in)
|
||||
|
||||
-ta, --tempallow ip ttl [-p port] [-d direction] [comment]
|
||||
Add an IP to the temp IP allow list (default:inout)
|
||||
|
||||
-tf, --tempf
|
||||
Flush all IPs from the temporary IP entries
|
||||
|
||||
-cp, --cping
|
||||
PING all members in an lfd Cluster
|
||||
|
||||
-cg, --cgrep ip
|
||||
Requests the --grep output for IP from each member in an lfd Cluster
|
||||
|
||||
-cd, --cdeny ip [comment]
|
||||
Deny an IP in a Cluster and add to each remote /etc/csf/csf.deny
|
||||
|
||||
-ctd, --ctempdeny ip ttl [-p port] [-d direction] [comment]
|
||||
Add an IP in a Cluster to the temp IP ban list (default:in)
|
||||
|
||||
-cr, --crm ip
|
||||
Unblock an IP in a Cluster and remove from each remote /etc/csf/csf.deny and temporary list
|
||||
|
||||
-ca, --callow ip [comment]
|
||||
Allow an IP in a Cluster and add to each remote /etc/csf/csf.allow
|
||||
|
||||
-cta, --ctempallow ip ttl [-p port] [-d direction] [comment]
|
||||
Add an IP in a Cluster to the temp IP allow list (default:in)
|
||||
|
||||
-car, --carm ip
|
||||
Remove allowed IP in a Cluster and remove from each remote /etc/csf/csf.allow and temporary list
|
||||
|
||||
-ci, --cignore ip [comment]
|
||||
Ignore an IP in a Cluster and add to each remote /etc/csf/csf.ignore. Note: This will result in lfd being restarted
|
||||
|
||||
-cir, --cirm ip
|
||||
Remove ignored IP in a Cluster and remove from each remote /etc/csf/csf.ignore. Note: This will result in lfd being restarted
|
||||
|
||||
-cc, --cconfig [name] [value]
|
||||
Change configuration option [name] to [value] in a Cluster
|
||||
|
||||
-cf, --cfile [file]
|
||||
Send [file] in a Cluster to /etc/csf/
|
||||
|
||||
-crs, --crestart
|
||||
Cluster restart csf and lfd
|
||||
|
||||
--trace [add|remove] ip
|
||||
Log SYN packets for an IP across iptables chains. Note, this can create a LOT of logging information in /var/log/messages so
|
||||
should only be used for a short period of time. This option requires the iptables TRACE module and access to the raw PREROUTING
|
||||
chain to function
|
||||
|
||||
-m, --mail [email]
|
||||
Display Server Check in HTML or email to [email] if present
|
||||
|
||||
--rbl [email]
|
||||
Process and display RBL Check in HTML or email to [email] if present
|
||||
|
||||
-lr, --logrun
|
||||
Initiate Log Scanner report via lfd
|
||||
|
||||
-p, --ports
|
||||
View ports on the server that have a running process behind them listening for external connections
|
||||
|
||||
--graphs [graph type] [directory]
|
||||
Generate System Statistics html pages and images for a given graph type into a given directory. See ST_SYSTEM for requirements
|
||||
|
||||
--profile [command] [profile|backup] [profile|backup]
|
||||
Configuration profile functions for /etc/csf/csf.conf
|
||||
You can create your own profiles using the examples provided in /usr/local/csf/profiles/
|
||||
The profile reset_to_defaults.conf is a special case and will always be the latest default csf.conf
|
||||
|
||||
list
|
||||
Lists available profiles and backups
|
||||
|
||||
apply [profile]
|
||||
Modify csf.conf with Configuration Profile
|
||||
|
||||
backup "name"
|
||||
Create Configuration Backup with optional "name" stored in /var/lib/csf/backup/
|
||||
|
||||
restore [backup]
|
||||
Restore a Configuration Backup
|
||||
|
||||
keep [num]
|
||||
Remove old Configuration Backups and keep the latest [num]
|
||||
|
||||
diff [profile|backup] [profile|backup]
|
||||
Report differences between Configuration Profiles or Configuration Backups, only specify one [profile|backup] to compare to the
|
||||
current Configuration
|
||||
|
||||
--mregen
|
||||
MESSENGERV2 /etc/apache2/conf.d/csf_messenger.conf regeneration. This will also gracefully restart httpd
|
||||
|
||||
--cloudflare [command]
|
||||
Commands for interacting with the CloudFlare firewall. See /etc/csf/readme.txt and CF_ENABLE for more detailed information
|
||||
|
||||
Note: target can be one of: An IP address; 2 letter Country Code; IP range CIDR. Only Enterprise customers can block a Country
|
||||
Code, but all can allow and challenge. IP range CIDR is limited to /16 and /24
|
||||
|
||||
list [all|block|challenge|whitelist] [user1,user2,domain1...]
|
||||
List specified type of CloudFlare Firewall rules for comma separated list of users/domains
|
||||
|
||||
add [block|challenge|whitelist] target [user1,user2,domain1...]
|
||||
Add CloudFlare Firewall rule action for target for comma separated list of users/domains only
|
||||
|
||||
del target [user1,user2,domain1...]
|
||||
Delete CloudFlare Firewall rule for target for comma separated list of users/domains only
|
||||
|
||||
tempadd [allow|deny] ip [user1,user2,domain1...]
|
||||
Add a temporary block for CF_TEMP seconds to both csf and the CloudFlare Firewall rule for ip for comma separated list of
|
||||
users/domains as well as any user set to "any"
|
||||
|
||||
-c, --check
|
||||
Check for updates to csf but do not upgrade
|
||||
|
||||
-u, --update
|
||||
Check for updates to csf and upgrade if available
|
||||
|
||||
-uf Force an update of csf whether and upgrade is required or not
|
||||
|
||||
-x, --disable
|
||||
Disable csf and lfd completely
|
||||
|
||||
-e, --enable
|
||||
Enable csf and lfd if previously disabled
|
||||
|
||||
-v, --version
|
||||
Show csf version
|
||||
|
||||
FILES
|
||||
/etc/csf/csf.conf
|
||||
The system wide configuration file
|
||||
/etc/csf/readme.txt
|
||||
Detailed information about csf and lfd
|
||||
|
||||
BUGS
|
||||
Report bugs on the forums at http://forum.configserver.com
|
||||
|
||||
AUTHOR
|
||||
(c)2006-2023, Jonathan Michaelson (http://www.configserver.com)
|
||||
|
||||
csf(1)
|
||||
28
csf/csf.ignore
Normal file
28
csf/csf.ignore
Normal file
@@ -0,0 +1,28 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be ignored by all lfd checks
|
||||
# One IP address per line
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24)
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
|
||||
127.0.0.1
|
||||
|
||||
Include /etc/csf/cpanel.comodo.ignore
|
||||
Include /etc/csf/cpanel.ignore
|
||||
30
csf/csf.interworx.allow
Normal file
30
csf/csf.interworx.allow
Normal file
@@ -0,0 +1,30 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be allowed through iptables.
|
||||
# One IP address per line.
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24).
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
# Advanced port+ip filtering allowed with the following format
|
||||
# tcp/udp|in/out|s/d=port|s/d=ip
|
||||
# See readme.txt for more information
|
||||
#
|
||||
# Note: IP addressess listed in this file will NOT be ignored by lfd, so they
|
||||
# can still be blocked. If you do not want lfd to block an IP address you must
|
||||
# add it to csf.ignore
|
||||
2686
csf/csf.interworx.conf
Normal file
2686
csf/csf.interworx.conf
Normal file
File diff suppressed because it is too large
Load Diff
25
csf/csf.interworx.ignore
Normal file
25
csf/csf.interworx.ignore
Normal file
@@ -0,0 +1,25 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following IP addresses will be ignored by all lfd checks
|
||||
# One IP address per line
|
||||
# CIDR addressing allowed with a quaded IP (e.g. 192.168.254.0/24)
|
||||
# Only list IP addresses, not domain names (they will be ignored)
|
||||
#
|
||||
|
||||
127.0.0.1
|
||||
101
csf/csf.interworx.pignore
Normal file
101
csf/csf.interworx.pignore
Normal file
@@ -0,0 +1,101 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of executables (exe) command lines (cmd) and
|
||||
# usernames (user) that lfd process tracking will ignore.
|
||||
#
|
||||
# You must use the following format:
|
||||
#
|
||||
# exe:/full/path/to/file
|
||||
# user:username
|
||||
# cmd:command line
|
||||
#
|
||||
# Or, perl regular expression matching (regex):
|
||||
#
|
||||
# pexe:/full/path/to/file as a perl regex[*]
|
||||
# puser:username as a perl regex[*]
|
||||
# pcmd:command line as a perl regex[*]
|
||||
#
|
||||
# [*]You must remember to escape characters correctly when using regex's, e.g.:
|
||||
# pexe:/home/.*/public_html/cgi-bin/script\.cgi
|
||||
# puser:bob\d.*
|
||||
# pcmd:/home/.*/command\s\to\smatch\s\.pl\s.*
|
||||
#
|
||||
# It is strongly recommended that you use command line ignores very carefully
|
||||
# as any process can change what is reported to the OS.
|
||||
#
|
||||
# For more information see readme.txt
|
||||
|
||||
exe:/bin/dbus-daemon
|
||||
exe:/sbin/ntpd
|
||||
exe:/usr/bin/dbus-daemon
|
||||
exe:/usr/bin/lsmd
|
||||
exe:/usr/lib/courier-imap/bin/imapd
|
||||
exe:/usr/lib/courier-imap/bin/pop3d
|
||||
exe:/usr/lib/polkit-1/polkitd
|
||||
exe:/usr/libexec/dovecot/imap
|
||||
exe:/usr/libexec/dovecot/imap
|
||||
exe:/usr/libexec/dovecot/pop3
|
||||
exe:/usr/libexec/dovecot/pop3
|
||||
exe:/usr/libexec/dovecot/stats
|
||||
exe:/usr/libexec/dovecot/auth
|
||||
exe:/usr/libexec/mysqld
|
||||
exe:/usr/local/apache/bin/httpd
|
||||
exe:/usr/local/libexec/dovecot/imap
|
||||
exe:/usr/local/libexec/dovecot/imap-login
|
||||
exe:/usr/local/libexec/dovecot/pop3
|
||||
exe:/usr/local/libexec/dovecot/pop3-login
|
||||
exe:/usr/local/libexec/dovecot/stats
|
||||
exe:/usr/sbin/chronyd
|
||||
exe:/usr/sbin/exim
|
||||
exe:/usr/sbin/exim4
|
||||
exe:/usr/sbin/named
|
||||
exe:/usr/sbin/nscd
|
||||
exe:/usr/sbin/ntpd
|
||||
exe:/usr/sbin/ntpd
|
||||
exe:/usr/sbin/proftpd
|
||||
exe:/usr/sbin/pure-ftpd
|
||||
exe:/usr/sbin/sshd
|
||||
exe:/usr/sbin/apache2
|
||||
exe:/usr/sbin/mysqld
|
||||
exe:/lib/systemd/systemd-timesyncd
|
||||
exe:/sbin/rngd
|
||||
exe:/usr/bin/dbus-broker-launch
|
||||
exe:/usr/bin/dbus-broker
|
||||
|
||||
exe:/usr/local/interworx/mysql/usr/sbin/mysqld
|
||||
exe:/usr/bin/tcpserver
|
||||
exe:/usr/bin/multilog
|
||||
exe:/usr/sbin/clamd
|
||||
exe:/usr/bin/freshclam
|
||||
exe:/usr/sbin/httpd
|
||||
exe:/usr/libexec/dovecot/anvil
|
||||
exe:/var/qmail/bin/qmail-rspawn
|
||||
exe:/var/qmail/bin/qmail-send
|
||||
exe:/var/qmail/bin/qmail-clean
|
||||
exe:/usr/bin/tinydns
|
||||
exe:/usr/local/interworx/bin/httpd/httpd
|
||||
exe:/usr/bin/dnscache
|
||||
exe:/usr/sbin/mariadbd
|
||||
|
||||
# Some additional entries that you might want to ignore on cPanel servers.
|
||||
# However, be aware of the security implications under "Process Tracking" in
|
||||
# the csf readme.txt when using these:
|
||||
#
|
||||
#cmd:spamd child
|
||||
#cmd:/bin/sh /usr/bin/mysqld_safe --basedir=/usr
|
||||
49
csf/csf.logfiles
Normal file
49
csf/csf.logfiles
Normal file
@@ -0,0 +1,49 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of log files for the LOGSCANNER feature
|
||||
|
||||
# All:
|
||||
/var/log/messages
|
||||
/var/log/lfd.log
|
||||
/var/log/cxswatch.log
|
||||
|
||||
# RedHat:
|
||||
/var/log/secure
|
||||
|
||||
# Debian/Ubuntu:
|
||||
/var/log/auth.log
|
||||
/var/log/daemon.log
|
||||
/var/log/syslog
|
||||
|
||||
# cPanel:
|
||||
/usr/local/cpanel/logs/error_log
|
||||
/var/log/exim_paniclog
|
||||
|
||||
# DirectAdmin:
|
||||
/var/log/directadmin/error.log
|
||||
/var/log/directadmin/security.log
|
||||
/var/log/exim/paniclog
|
||||
|
||||
# InterWorx
|
||||
/usr/local/interworx/var/log/error.log
|
||||
|
||||
# CyberPanel
|
||||
/home/cyberpanel/error-logs.txt
|
||||
/usr/local/lscp/cyberpanel/logs/error.log
|
||||
/usr/local/lscp/cyberpanel/logs/stderr.log
|
||||
88
csf/csf.logignore
Normal file
88
csf/csf.logignore
Normal file
@@ -0,0 +1,88 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of regular expressions for the LOGSCANNER feature.
|
||||
# If a log line matches it will be ignored, otherwise it will be reported
|
||||
|
||||
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ kernel:\s(\[[^\]]+\]\s)?Firewall:
|
||||
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ suhosin\[\d+\]: ALERT - script tried to increase memory_limit
|
||||
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: client .* view internal
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: client .* view external
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: client .* view localhost_resolver
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: connection refused resolving
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: lame server resolving
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: network unreachable resolving
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: unexpected RCODE
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: zone .* loaded serial
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: zone .* sending notifies
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: FORMERR resolving
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: checkhints: view localhost_resolver:
|
||||
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: error \(unexpected RCODE REFUSED\)
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: error \(unexpected RCODE SERVFAIL\)
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: error \(host unreachable\)
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: error \(network unreachable\)
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: error \(connection refused \) resolving
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ named\[\d+\]: error \(FORMERR\) resolving
|
||||
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ pure-ftpd: \([\w\?\@\+\%\.]+\@\d+\.\d+\.\d+\.\d+\) \[(INFO|NOTICE)\]
|
||||
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ Cp-Wrap\[\d+\]:
|
||||
^\[\S+\s\S+\s\S+\] info
|
||||
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ gconfd
|
||||
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Started Session
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Starting Session
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Failed to mark scope
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd-logind(\[\d+\])?: New session
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd-logind(\[\d+\])?: Removed session
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Created slice
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Removed slice user
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Starting user
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Stopping user
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Reloading
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Starting User Slice
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Stopping User Slice
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Removed slice User
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Stopped target
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Reached target
|
||||
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ nscd(\[\d+\])?: \d+\ monitor
|
||||
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ dbus-daemon: dbus\[\d+\]: \[system\] Activating via systemd
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ dbus-daemon: dbus\[\d+\]: \[system\] Successfully activated
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ dbus\[\d+\]: \[system\] Activating via systemd
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ dbus\[\d+\]: \[system\] Successfully activated
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Starting Time
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ systemd(\[\d+\])?: Started Time
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ dovecot\[\d+\]:
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ dovecot:
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ CRON\[\d+\]:
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ MailScanner:
|
||||
^(\S+|\S+\s+\d+\s+\S+) [^\s\.]+ clamd\[\d+\]: SelfCheck: Database status OK
|
||||
|
||||
==> cpsrvd \S+ started
|
||||
==> cpsrvd: loading security policy....Done
|
||||
==> cpsrvd: Setting up SSL support ... Done
|
||||
==> cpsrvd: transferred port bindings
|
||||
==> cpsrvd: bound to ports
|
||||
|
||||
22
csf/csf.mignore
Normal file
22
csf/csf.mignore
Normal file
@@ -0,0 +1,22 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of usernames and local IP addresses that
|
||||
# RT_LOCALRELAY_ALERT will ignore
|
||||
#
|
||||
# Add only one username per line
|
||||
158
csf/csf.pignore
Normal file
158
csf/csf.pignore
Normal file
@@ -0,0 +1,158 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of executables (exe) command lines (cmd) and
|
||||
# usernames (user) that lfd process tracking will ignore.
|
||||
#
|
||||
# You must use the following format:
|
||||
#
|
||||
# exe:/full/path/to/file
|
||||
# user:username
|
||||
# cmd:command line
|
||||
#
|
||||
# Or, perl regular expression matching (regex):
|
||||
#
|
||||
# pexe:/full/path/to/file as a perl regex[*]
|
||||
# puser:username as a perl regex[*]
|
||||
# pcmd:command line as a perl regex[*]
|
||||
#
|
||||
# [*]You must remember to escape characters correctly when using regex's, e.g.:
|
||||
# pexe:/home/.*/public_html/cgi-bin/script\.cgi
|
||||
# puser:bob\d.*
|
||||
# pcmd:/home/.*/command\s\to\smatch\s\.pl\s.*
|
||||
#
|
||||
# It is strongly recommended that you use command line ignores very carefully
|
||||
# as any process can change what is reported to the OS.
|
||||
#
|
||||
# For more information see readme.txt
|
||||
|
||||
exe:/bin/dbus-daemon
|
||||
exe:/sbin/ntpd
|
||||
exe:/usr/bin/dbus-daemon
|
||||
exe:/usr/bin/dbus-daemon-1
|
||||
exe:/usr/bin/lsmd
|
||||
exe:/usr/bin/postgres
|
||||
exe:/usr/bin/spamc
|
||||
exe:/usr/lib/courier-imap/bin/imapd
|
||||
exe:/usr/lib/courier-imap/bin/pop3d
|
||||
exe:/usr/lib/polkit-1/polkitd
|
||||
exe:/usr/libexec/dovecot/anvil
|
||||
exe:/usr/libexec/dovecot/auth
|
||||
exe:/usr/libexec/dovecot/dict
|
||||
exe:/usr/libexec/dovecot/imap
|
||||
exe:/usr/libexec/dovecot/imap-login
|
||||
exe:/usr/libexec/dovecot/lmtp
|
||||
exe:/usr/libexec/dovecot/pop3
|
||||
exe:/usr/libexec/dovecot/pop3-login
|
||||
exe:/usr/libexec/dovecot/quota-status
|
||||
exe:/usr/libexec/dovecot/stats
|
||||
exe:/usr/libexec/dovecot/imap-hibernate
|
||||
exe:/usr/libexec/gam_server
|
||||
exe:/usr/libexec/hald-addon-acpi
|
||||
exe:/usr/libexec/hald-addon-keyboard
|
||||
exe:/usr/libexec/mysqld
|
||||
exe:/usr/local/apache/bin/httpd
|
||||
exe:/usr/local/cpanel/3rdparty/bin/analog
|
||||
exe:/usr/local/cpanel/3rdparty/bin/english/webalizer
|
||||
exe:/usr/local/cpanel/3rdparty/bin/imapd
|
||||
exe:/usr/local/cpanel/3rdparty/bin/php
|
||||
exe:/usr/local/cpanel/3rdparty/bin/webalizer_lang/english
|
||||
exe:/usr/local/cpanel/3rdparty/php/54/bin/php-cgi
|
||||
exe:/usr/local/cpanel/3rdparty/php/56/bin/php-cgi
|
||||
exe:/usr/local/cpanel/3rdparty/php/56/sbin/php-fpm
|
||||
exe:/usr/local/cpanel/3rdparty/php/54/sbin/php-fpm
|
||||
exe:/usr/local/cpanel/3rdparty/sbin/mydns
|
||||
exe:/usr/local/cpanel/3rdparty/sbin/p0f
|
||||
exe:/usr/local/cpanel/bin/cppop
|
||||
exe:/usr/local/cpanel/bin/cppop-ssl
|
||||
exe:/usr/local/cpanel/bin/cpuwatch
|
||||
exe:/usr/local/cpanel/bin/cpwrap
|
||||
exe:/usr/local/cpanel/bin/logrunner
|
||||
exe:/usr/local/cpanel/bin/pkgacct
|
||||
exe:/usr/local/cpanel/cpanel
|
||||
exe:/usr/local/cpanel/cpdavd
|
||||
exe:/usr/local/cpanel/cpsrvd
|
||||
exe:/usr/local/cpanel/cpsrvd-ssl
|
||||
exe:/usr/local/libexec/dovecot/imap
|
||||
exe:/usr/local/libexec/dovecot/imap-login
|
||||
exe:/usr/local/libexec/dovecot/pop3
|
||||
exe:/usr/local/libexec/dovecot/pop3-login
|
||||
exe:/usr/local/urchin/bin/urchinwebd
|
||||
exe:/usr/sbin/chronyd
|
||||
exe:/usr/sbin/exim
|
||||
exe:/usr/sbin/exim
|
||||
exe:/usr/sbin/hald
|
||||
exe:/usr/sbin/httpd
|
||||
exe:/usr/sbin/mysqld
|
||||
exe:/usr/sbin/mysqld_safe
|
||||
exe:/usr/sbin/named
|
||||
exe:/usr/sbin/nscd
|
||||
exe:/usr/sbin/nsd
|
||||
exe:/usr/sbin/ntpd
|
||||
exe:/usr/sbin/proftpd
|
||||
exe:/usr/sbin/pure-ftpd
|
||||
exe:/usr/sbin/sshd
|
||||
exe:/var/cpanel/3rdparty/bin/php
|
||||
exe:/usr/sbin/pdns_server
|
||||
exe:/usr/local/cpanel/bin/autossl_check
|
||||
exe:/usr/local/cpanel/bin/whm_xfer_download-ssl
|
||||
pexe:^/usr/lib/jvm/java-.*/jre/bin/java$
|
||||
exe:/usr/libexec/dovecot/indexer-worker
|
||||
exe:/usr/libexec/dovecot/indexer
|
||||
pexe:/usr/local/cpanel/3rdparty/bin/git.*
|
||||
pexe:/usr/local/cpanel/3rdparty/libexec/git-core/git.*
|
||||
exe:/usr/sbin/imunify-notifier
|
||||
exe:/usr/bin/sw-engine
|
||||
exe:/usr/sbin/sw-engine-fpm
|
||||
exe:/usr/sbin/sw-cp-serverd
|
||||
exe:/sbin/rngd
|
||||
exe:/usr/sbin/mariadbd
|
||||
exe:/usr/sbin/atd
|
||||
exe:/usr/lib/systemd/systemd-timesyncd
|
||||
exe:/usr/lib/systemd/systemd-networkd
|
||||
exe:/usr/sbin/rsyslogd
|
||||
exe:/usr/lib/apt/methods/http
|
||||
exe:/usr/sbin/rngd
|
||||
exe:/usr/lib/systemd/systemd-resolved
|
||||
exe:/usr/sbin/uuidd
|
||||
exe:/usr/bin/dbus-broker-launch
|
||||
exe:/usr/bin/dbus-broker
|
||||
exe:/usr/local/cpanel/3rdparty/wp-toolkit/bin/wpt-panopticon
|
||||
|
||||
# Some additional entries that you might want to ignore on cPanel servers.
|
||||
# However, be aware of the security implications under "Process Tracking" in
|
||||
# the csf readme.txt when using these:
|
||||
#
|
||||
#cmd:/bin/sh /usr/bin/mysqld_safe
|
||||
#cmd:/bin/sh /usr/bin/mysqld_safe --basedir=/usr
|
||||
#cmd:spamd child
|
||||
#pcmd:/usr/local/cpanel/3rdparty/bin/python /usr/local/cpanel/3rdparty/mailman/bin/qrunner.*
|
||||
#pcmd:/usr/local/cpanel/3rdparty/bin/python /usr/local/cpanel/3rdparty/mailman/bin/mailmanctl.*
|
||||
#pcmd:/usr/bin/python.? /usr/local/cpanel/3rdparty/mailman/bin/qrunner.*
|
||||
#pcmd:/usr/bin/python.? /usr/local/cpanel/3rdparty/mailman/bin/mailmanctl.*
|
||||
#pcmd:/usr/bin/perl /usr/local/cpanel/3rdparty/bin/awstats\.pl.*
|
||||
#pcmd:/usr/bin/perl /usr/local/cpanel/base/awstats\.pl.*
|
||||
#pcmd:cpanellogd - (http|ftp) logs for .*
|
||||
#pcmd:ubic-guardian ubic-periodic.*
|
||||
#pcmd:perl /usr/local/cpanel/3rdparty/perl/\d+/bin/ubic-periodic.*
|
||||
#pcmd:MailScanner:.*
|
||||
#pexe:/opt/cpanel/ea-php\d+/root/usr/bin/lsphp
|
||||
#pexe:/opt/cpanel/ea-php\d+/root/usr/bin/lsphp.cagefs
|
||||
#pexe:/opt/cpanel/ea-php\d+/root/usr/bin/php
|
||||
#pexe:/opt/cpanel/ea-php\d+/root/usr/bin/php.cagefs
|
||||
#pexe:/opt/cpanel/ea-php\d+/root/usr/sbin/php-fpm
|
||||
6009
csf/csf.pl
Normal file
6009
csf/csf.pl
Normal file
File diff suppressed because it is too large
Load Diff
35
csf/csf.rblconf
Normal file
35
csf/csf.rblconf
Normal file
@@ -0,0 +1,35 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# This file configures optional entries for the IP checking against RBLs within
|
||||
# csf
|
||||
#
|
||||
# There are 4 options available to enable/disable RBLs and IPs:
|
||||
#
|
||||
# To disable inbuilt RBLs or to enable other RBLs, e.g.:
|
||||
#
|
||||
# enablerbl:my.dnsrbl.net
|
||||
# disablerbl:bl.spamcop.net
|
||||
#
|
||||
# To disable local IPs or to enable other IPs, e.g.:
|
||||
#
|
||||
# enableip:11.22.33.44
|
||||
# disableip:10.10.10.10
|
||||
#
|
||||
# There should be no spaces on any of the configuration lines. Lines beginning
|
||||
# with # are comments
|
||||
41
csf/csf.rbls
Normal file
41
csf/csf.rbls
Normal file
@@ -0,0 +1,41 @@
|
||||
all.s5h.net:http://www.usenix.org.uk/content/rbl.html
|
||||
b.barracudacentral.org:http://www.barracudacentral.org/rbl
|
||||
cbl.abuseat.org:http://abuseat.org/
|
||||
csi.cloudmark.com:https://csi.cloudmark.com/en/reset/
|
||||
db.wpbl.info:http://www.wpbl.info/
|
||||
dnsbl-1.uceprotect.net:http://www.uceprotect.net/
|
||||
dnsbl-2.uceprotect.net:http://www.uceprotect.net/
|
||||
dnsbl-3.uceprotect.net:http://www.uceprotect.net/
|
||||
dnsbl.dronebl.org:https://dronebl.org/
|
||||
dnsbl.inps.de:http://dnsbl.inps.de/?lang=en
|
||||
dnsbl.sorbs.net:http://www.sorbs.net/
|
||||
drone.abuse.ch:https://www.abuse.ch/
|
||||
dul.dnsbl.sorbs.net:http://www.sorbs.net/
|
||||
dyna.spamrats.com:http://www.spamrats.com/rats-dyna.php
|
||||
http.dnsbl.sorbs.net:http://www.sorbs.net/
|
||||
httpbl.abuse.ch:https://www.abuse.ch/
|
||||
ips.backscatterer.org:http://www.backscatterer.org/
|
||||
ix.dnsbl.manitu.net:http://www.dnsbl.manitu.net/
|
||||
misc.dnsbl.sorbs.net:http://www.sorbs.net/
|
||||
multi.surbl.org:http://www.surbl.org/
|
||||
noptr.spamrats.com:http://www.spamrats.com/rats-noptr.php
|
||||
opm.tornevall.org:https://dnsbl.tornevall.org/
|
||||
pbl.spamhaus.org:https://www.spamhaus.org/pbl/
|
||||
psbl.surriel.com:http://psbl.org/
|
||||
query.senderbase.org:https://www.senderbase.org/lookup/
|
||||
rbl.efnetrbl.org:http://efnetrbl.org/
|
||||
rbl.interserver.net:http://rbldata.interserver.net/index.php
|
||||
sbl.spamhaus.org:https://www.spamhaus.org/sbl/
|
||||
smtp.dnsbl.sorbs.net:http://www.sorbs.net/
|
||||
socks.dnsbl.sorbs.net:http://www.sorbs.net/
|
||||
spam.dnsbl.sorbs.net:http://www.sorbs.net/
|
||||
spam.spamrats.com:http://www.spamrats.com/rats-spam.php
|
||||
spamrbl.imp.ch:http://antispam.imp.ch
|
||||
tor.dan.me.uk:https://www.dan.me.uk/dnsbl
|
||||
ubl.unsubscore.com:http://blacklist.lashback.com/
|
||||
virbl.bit.nl:https://virbl.bit.nl/
|
||||
web.dnsbl.sorbs.net:http://www.sorbs.net/
|
||||
wormrbl.imp.ch:http://antispam.imp.ch
|
||||
xbl.spamhaus.org:https://www.spamhaus.org/xbl/
|
||||
zen.spamhaus.org:https://www.spamhaus.org/zen/
|
||||
zombie.dnsbl.sorbs.net:http://www.sorbs.net/
|
||||
47
csf/csf.redirect
Normal file
47
csf/csf.redirect
Normal file
@@ -0,0 +1,47 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of port and/or IP address assignments to direct
|
||||
# traffic to alternative ports/IP addresses
|
||||
#
|
||||
# Requirements:
|
||||
# nat tables
|
||||
# ipt_DNAT iptables module
|
||||
# ipt_SNAT iptables module
|
||||
# ipt_REDIRECT iptables module
|
||||
#
|
||||
# The following are the allowed redirection formats
|
||||
#
|
||||
# DNAT (redirect from one IP address to a different one):
|
||||
# IPx|*|IPy|*|tcp/udp - To IPx redirects to IPy
|
||||
# IPx|portA|IPy|portB|tcp/udp - To IPx to portA redirects to IPy portB
|
||||
#
|
||||
# DNAT examples:
|
||||
# 192.168.254.62|*|10.0.0.1|*|tcp
|
||||
# 192.168.254.62|666|10.0.0.1|25|tcp
|
||||
#
|
||||
# REDIRECT (redirect from port to a different one):
|
||||
# IPx|portA|*|portB|tcp/udp - To IPx to portA redirects to portB
|
||||
# *|portA|*|portB|tcp/udp - To portA redirects to portB
|
||||
#
|
||||
# REDIRECT examples:
|
||||
# 192.168.254.60|666|*|25|tcp
|
||||
# *|666|*|25|tcp
|
||||
#
|
||||
# See readme.txt for more information
|
||||
#
|
||||
60
csf/csf.resellers
Normal file
60
csf/csf.resellers
Normal file
@@ -0,0 +1,60 @@
|
||||
###############################################################################
|
||||
# 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>.
|
||||
###############################################################################
|
||||
# The following is a list of Reseller accounts that you want to allow access to
|
||||
# limited csf functionality.
|
||||
#
|
||||
# WARNING: You should only ever provide access to this facility to people you
|
||||
# trust as it could easily render your server inaccessible or open to attack.
|
||||
# For security reasons, resellers cannot list blocked IP addresses or the whole
|
||||
# iptables configuration. They must know what IP address they want to use with
|
||||
# this facility.
|
||||
#
|
||||
# You should list each account, one per line, followed by a colon, then a 0 or
|
||||
# 1 depending on whether you want an email alert sent using the email template
|
||||
# reselleralter.txt whenever an ALLOW/DENY or UNBLOCK is performed, then a
|
||||
# colon, then a comma separated list of the feature codes that you want each
|
||||
# reseller to have access to.
|
||||
#
|
||||
# As of writing, the following is a list of the available feature codes. More
|
||||
# may be added in the feature, in which case they will be listed in the main
|
||||
# csf readme.txt:
|
||||
#
|
||||
# USE - The reseller can use this facility through WHM (required)
|
||||
# UNBLOCK - The reseller can use the Quick Unblock feature
|
||||
# GREP - The reseller can use the Search IP feature
|
||||
# ALLOW - The reseller can use the Quick Allow feature
|
||||
# DENY - The reseller can use the Quick Deny feature
|
||||
#
|
||||
# For example, to allow reseller "someuser" to unblock IP addresses and have an
|
||||
# alert email sent to root, use:
|
||||
#
|
||||
#someuser:1:USE,UNBLOCK
|
||||
#
|
||||
# For example, to allow reseller "someuser" to allow, deny and unblock IP
|
||||
# addresses, but no alert sent, use:
|
||||
#
|
||||
#someuser:0:USE,ALLOW,DENY,UNBLOCK
|
||||
#
|
||||
# RECOMMEND: For security reasons, we recommend only allowing resellers USE,
|
||||
# UNBLOCK and GREP
|
||||
#
|
||||
# NOTE: As of version cPanel v11.8.1 you must additionally grant resellers
|
||||
# access via "WHM > Edit Reseller Nameservers and Privileges > Third Party
|
||||
# Services > ConfigServer Security & Firewall (Reseller UI)".
|
||||
#
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user