asda?‰PNG  IHDR ? f ??C1 sRGB ??é gAMA ±? üa pHYs ? ??o¨d GIDATx^íüL”÷e÷Y?a?("Bh?_ò???¢§?q5k?*:t0A-o??¥]VkJ¢M??f?±8\k2íll£1]q?ù???T Slurp.pm000064400000003076151030020750006206 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;Messenger.pm000064400000122673151030020750007036 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen) # start main package ConfigServer::Messenger; use strict; use lib '/usr/local/csf/lib'; use Fcntl qw(:DEFAULT :flock); use File::Copy; use JSON::Tiny; use IO::Socket::INET; use Net::CIDR::Lite; use Net::IP; use IPC::Open3; use ConfigServer::Config; use ConfigServer::CheckIP qw(checkip); use ConfigServer::Logger qw(logfile); use ConfigServer::URLGet; use ConfigServer::Slurp qw(slurp); use ConfigServer::GetIPs qw(getips); use ConfigServer::GetEthDev; use Exporter qw(import); our $VERSION = 3.00; our @ISA = qw(Exporter); our @EXPORT_OK = qw(); my $slurpreg = ConfigServer::Slurp->slurpreg; my $cleanreg = ConfigServer::Slurp->cleanreg; my $config = ConfigServer::Config->loadconfig(); my %config = $config->config(); my $ipv4reg = ConfigServer::Config->ipv4reg; my $ipv6reg = ConfigServer::Config->ipv6reg; my $childproc; my $hostname; my %ips; my $ipscidr6; my %sslcerts; my %sslkeys; my %ssldomains; my @ssldomainkeys; my $webserver = "apache"; my $sslhost; my $sslcert; my $sslkey; my $sslca; my $osslcert; my $osslkey; my $osslca; my $sslaliases; my $litestart = 0; my $ssldir = "/var/lib/csf/ssl/"; my $phphandler; my $version = 1; my $serverroot; # end main ############################################################################### # start init sub init { my $class = shift; $version = shift; my $self = {}; bless $self,$class; 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 ($version == 1) { if ($config{MESSENGER6}) { eval('use IO::Socket::INET6;'); ##no critic if ($@) {$config{MESSENGER6} = "0"} } $ipscidr6 = Net::CIDR::Lite->new; &getethdev; foreach my $ip (split(/,/,$config{RECAPTCHA_NAT})) { $ip =~ s/\s*//g; $ips{$ip} = 1; } } elsif ($version == 2) { } elsif ($version == 3) { mkdir $ssldir; mkdir $ssldir."certs/"; mkdir $ssldir."keys/"; mkdir $ssldir."ca/"; } return $self; } # end init ############################################################################### # start start sub start { my $self = shift; my $port = shift; my $user = shift; my $type = shift; my $status; my $reason; if ($version == 1) { ($status,$reason) = &messenger($port, $user, $type); } elsif ($version == 2) { ($status,$reason) = &messengerv2(); } elsif ($version == 3) { ($status,$reason) = &messengerv3(); } return ($status,$reason); } # end start ############################################################################### # start messenger sub messenger { my $port = shift; my $user = shift; my $type = shift; my $oldtype = $type; my $server; my %sslcerts; my %sslkeys; $SIG{CHLD} = 'IGNORE'; $SIG{INT} = \&childcleanup; $SIG{TERM} = \&childcleanup; $SIG{HUP} = \&childcleanup; $SIG{__DIE__} = sub {&childcleanup(@_);}; $0 = "lfd $type messenger"; $childproc = "Messenger ($type)"; if ($type eq "HTTPS") { eval { local $SIG{__DIE__} = undef; require IO::Socket::SSL; import IO::Socket::SSL; }; my $start = 0; my $sslhost; my $sslcert; my $sslkey; my $sslaliases; my %messengerports; foreach my $serverports (split(/\,/,$config{MESSENGER_HTTPS_IN})) {$messengerports{$serverports} = 1} foreach my $file (glob($config{MESSENGER_HTTPS_CONF})) { if (-e $file) { foreach my $line (slurp($file)) { $line =~ s/\'|\"//g; if ($line =~ /^\s*]+>/) { $start = 1; } if ($webserver eq "apache" and $start) { if ($line =~ /\s*ServerName\s+(\w+:\/\/)?([a-zA-Z0-9\.\-]+)(:\d+)?/) {$sslhost = $2} if ($line =~ /\s*ServerAlias\s+(.*)/) {$sslaliases .= " ".$1} if ($line =~ /\s*SSLCertificateFile\s+(\S+)/) { my $match = $1; if (-e $match) {$sslcert = $match} } if ($line =~ /\s*SSLCertificateKeyFile\s+(\S+)/) { my $match = $1; if (-e $match) {$sslkey = $match} } } if (($webserver eq "apache" and $line =~ /^\s*<\/VirtualHost\s*>/)) { $start = 0; if ($sslhost ne "" and !checkip($sslhost) and $sslcert ne "") { $sslcerts{$sslhost} = $sslcert; if ($sslkey eq "") {$sslkey = $sslcert} $sslkeys{$sslhost} = $sslkey; foreach my $alias (split(/\s+/,$sslaliases)) { if ($alias eq "") {next} if (checkip($alias)) {next} if ($alias =~ /^[a-zA-Z0-9\.\-]+$/) { if ($config{MESSENGER_HTTPS_SKIPMAIL} and $alias =~ /^mail\./) {next} $sslcerts{$alias} = $sslcert; $sslkeys{$alias} = $sslkey; } } } $sslhost = ""; $sslcert = ""; $sslkey = ""; $sslaliases = ""; } } } } if (scalar(keys %sslcerts < 1)) { return (1, "No SSL certs found in MESSENGER_HTTPS_CONF location"); } if (-e $config{MESSENGER_HTTPS_KEY}) { $sslkeys{''} = $config{MESSENGER_HTTPS_KEY}; } if (-e $config{MESSENGER_HTTPS_CRT}) { $sslcerts{''} = $config{MESSENGER_HTTPS_CRT}; } if ($config{DEBUG} >= 1) { foreach my $key (keys %sslcerts) { logfile("SSL: [$key] [$sslcerts{$key}] [$sslkeys{$key}]"); } } eval { local $SIG{__DIE__} = undef; if ($config{MESSENGER6}) { $server = IO::Socket::SSL->new( Domain => AF_INET6, LocalPort => $port, Type => SOCK_STREAM, ReuseAddr => 1, Listen => $config{MESSENGER_CHILDREN}, SSL_server => 1, SSL_use_cert => 1, SSL_cert_file => \%sslcerts, SSL_key_file => \%sslkeys, ) or &error("MESSENGER: *Error* cannot open server on port $port: ".IO::Socket::SSL->errstr); } else { $server = IO::Socket::SSL->new( Domain => AF_INET, LocalPort => $port, Type => SOCK_STREAM, ReuseAddr => 1, Listen => $config{MESSENGER_CHILDREN}, SSL_server => 1, SSL_use_cert => 1, SSL_cert_file => \%sslcerts, SSL_key_file => \%sslkeys, ) or &error("MESSENGER: *Error* cannot open server on port $port: ".IO::Socket::SSL->errstr); } &logfile("Messenger HTTPS Service started for ".scalar(keys %sslcerts)." domains"); $type = "HTML"; }; if ($@) { return (1, $@); } } elsif ($config{MESSENGER6}) { $server = IO::Socket::INET6->new( LocalPort => $port, Type => SOCK_STREAM, ReuseAddr => 1, Listen => $config{MESSENGER_CHILDREN}) or &childcleanup(__LINE__,"*Error* cannot open server on port $port: $!"); } else { $server = IO::Socket::INET->new( LocalPort => $port, Type => SOCK_STREAM, ReuseAddr => 1, Listen => $config{MESSENGER_CHILDREN}) or &childcleanup(__LINE__,"*Error* cannot open server on port $port: $!"); } my $index; if ($type eq "HTML" and $config{RECAPTCHA_SITEKEY} ne "") {$index = "/etc/csf/messenger/index.recaptcha.html"} elsif ($type eq "HTML") {$index = "/etc/csf/messenger/index.html"} else {$index = "/etc/csf/messenger/index.text"} open (my $IN, "<", $index); flock ($IN, LOCK_SH); my @message = <$IN>; close ($IN); chomp @message; my %images; if ($type eq "HTML") { opendir (DIR, "/etc/csf/messenger"); foreach my $file (readdir(DIR)) { if ($file =~ /\.(gif|png|jpg)$/) { open (my $IN, "<", "/etc/csf/messenger/$file"); flock ($IN, LOCK_SH); my @data = <$IN>; close ($IN); chomp @data; foreach my $line (@data) { $images{$file} .= "$line\n"; } } } closedir (DIR); } my $chldallow = $config{MESSENGER_CHILDREN}; if ($oldtype eq "HTTPS") { open (my $STATUS,"<", "/proc/$$/status") or next; flock ($STATUS, LOCK_SH); my @status = <$STATUS>; close ($STATUS); chomp @status; my $vmsize = 0; my $vmrss = 0; foreach my $line (@status) { if ($line =~ /^VmSize:\s+(\d+) kB$/) {$vmsize = $1} if ($line =~ /^VmRSS:\s+(\d+) kB$/) {$vmrss = $1} } logfile("lfd $oldtype messenger using $vmrss kB of RSS memory at startup, adding up to $config{MESSENGER_CHILDREN} children = ".(($config{MESSENGER_CHILDREN} + 1) * $vmrss)." kB"); logfile("lfd $oldtype messenger using $vmsize kB of VIRT memory at startup, adding up to $config{MESSENGER_CHILDREN} children = ".(($config{MESSENGER_CHILDREN} + 1) * $vmsize)." kB"); } if ($user ne "") { my (undef,undef,$uid,$gid,undef,undef,undef,$homedir) = getpwnam($user); if (($uid > 0) and ($gid > 0)) { local $( = $gid; local $) = "$gid $gid"; local $> = local $< = $uid; if (($) != $gid) or ($> != $uid) or ($( != $gid) or ($< != $uid)) { logfile("MESSENGER_USER unable to drop privileges - stopping $oldtype Messenger"); exit; } my %children; while (1) { while (my $client = $server->accept()) { while (scalar (keys %children) >= $chldallow) { sleep 1; foreach my $pid (keys %children) { unless (kill(0,$pid)) {delete $children{$pid}} } $0 = "lfd $oldtype messenger (busy)"; } $0 = "lfd $oldtype messenger"; $SIG{CHLD} = 'IGNORE'; my $pid = fork; $children{$pid} = 1; if ($pid == 0) { eval { local $SIG{__DIE__} = undef; local $SIG{'ALRM'} = sub {die}; alarm(10); close $server; $0 = "lfd $oldtype messenger client"; binmode $client; $| = 1; my $firstline; my $hostaddress = $client->sockhost(); my $peeraddress = $client->peerhost(); $peeraddress =~ s/^::ffff://; $hostaddress =~ s/^::ffff://; if ($type eq "HTML") { while ($firstline !~ /\n$/) { my $char; $client->read($char,1); $firstline .= $char; if ($char eq "") {exit} if (length $firstline > 2048) {last} } chomp $firstline; if ($firstline =~ /\r$/) {chop $firstline} } &messengerlog($homedir,"Client connection [$peeraddress] [$firstline]"); my $error; my $success; my $failure; if (($type eq "HTML") and ($firstline =~ /^GET \/unblk\?g-recaptcha-response=(\S+)/i)) { my $recv = $1; my $status = 1; my $text; eval { local $SIG{__DIE__} = undef; eval("no lib '/usr/local/csf/lib'"); my $urlget = ConfigServer::URLGet->new(2, "", $config{URLPROXY}); my $url = "https://www.google.com/recaptcha/api/siteverify?secret=$config{RECAPTCHA_SECRET}&response=$recv"; ($status, $text) = $urlget->urlget($url); }; if ($status) { &messengerlog($homedir,"*Error*, ReCaptcha ($peeraddress): $text"); if ($config{DEBUG} >= 1) { if ($@) {$error .= "Error:".$@} if ($!) {$error .= "Error:".$!} $error .= " Error Status: $status"; } $error .= "Unable to verify with Google reCAPTCHA"; } else { my $resp = JSON::Tiny::decode_json($text); if ($resp->{success}) { my $ip = $resp->{hostname}; unless ($ip =~ /^($ipv4reg|$ipv6reg)$/) {$ip = (getips($ip))[0]} if ($ips{$ip} or $ip eq $hostaddress or $ipscidr6->find($ip)) { sysopen (my $UNBLOCK, "$homedir/unblock.txt", O_WRONLY | O_APPEND | O_CREAT) or $error .= "Unable to write to [$homedir/unblock.txt] (make sure that MESSENGER_USER has a home directory)"; flock($UNBLOCK, LOCK_EX); print $UNBLOCK "$peeraddress;$resp->{hostname};$ip\n"; close ($UNBLOCK); $success = 1; &messengerlog($homedir,"*Success*, ReCaptcha ($peeraddress): [$resp->{hostname} ($ip)] requested unblock"); } else { $error .= "Failed, [$resp->{hostname} ($ip)] does not appear to be hosted on this server."; &messengerlog($homedir,"*Failed*, ReCaptcha ($peeraddress): [$resp->{hostname} ($ip)] does not appear to be hosted on this server"); } } else { $failure = 1; my @codes = @{$resp->{'error-codes'}}; &messengerlog($homedir,"*Failure*, ReCaptcha ($peeraddress): [$codes[0]]"); } } } if (($type eq "HTML") and ($firstline =~ /^GET\s+(\S*\/)?(\S*\.(gif|png|jpg))\s+/i)) { my $type = $3; if ($type eq "jpg") {$type = "jpeg"} print $client "HTTP/1.1 200 OK\r\n"; print $client "Content-type: image/$type\r\n"; print $client "\r\n"; print $client $images{$2}; } else { if ($type eq "HTML") { print $client "HTTP/1.1 403 OK\r\n"; print $client "Content-type: text/html\r\n"; print $client "\r\n"; foreach my $line (@message) { if ($line =~ /\[IPADDRESS\]/) {$line =~ s/\[IPADDRESS\]/$peeraddress/} if ($line =~ /\[HOSTNAME\]/) {$line =~ s/\[HOSTNAME\]/$hostname/} if ($line =~ /\[RECAPTCHA_SITEKEY\]/) {$line =~ s/\[RECAPTCHA_SITEKEY\]/$config{RECAPTCHA_SITEKEY}/} if ($line =~ /\[RECAPTCHA_ERROR=\"([^\"]+)\"\]/) { my $text = $1; if ($error ne "") {$line =~ s/\[RECAPTCHA_ERROR=\"([^\"]+)\"\]/$text $error/} else {$line =~ s/\[RECAPTCHA_ERROR=\"([^\"]+)\"\]//} } if ($line =~ /\[RECAPTCHA_SUCCESS=\"([^\"]+)\"\]/) { my $text = $1; if ($success) {$line =~ s/\[RECAPTCHA_SUCCESS=\"([^\"]+)\"\]/$text/} else {$line =~ s/\[RECAPTCHA_SUCCESS=\"([^\"]+)\"\]//} } if ($line =~ /\[RECAPTCHA_FAILURE=\"([^\"]+)\"\]/) { my $text = $1; if ($failure) {$line =~ s/\[RECAPTCHA_FAILURE=\"([^\"]+)\"\]/$text/} else {$line =~ s/\[RECAPTCHA_FAILURE=\"([^\"]+)\"\]//} } print $client "$line\r\n"; } print $client "\r\n"; } else { foreach my $line (@message) { if ($line =~ /\[IPADDRESS\]/) {$line =~ s/\[IPADDRESS\]/$peeraddress/} if ($line =~ /\[HOSTNAME\]/) {$line =~ s/\[HOSTNAME\]/$hostname/} print $client "$line "; } print $client "\n"; } } alarm(0); }; shutdown ($client,2); $client->close(); alarm(0); exit; } if ($oldtype eq "HTTPS") { $client->close(SSL_no_shutdown => 1); } else { $client->close(); } } } } else { logfile("MESSENGER_USER invalid - stopping $oldtype Messenger"); } } else { logfile("MESSENGER_USER not set - stopping $oldtype Messenger"); } return; } # end messenger ############################################################################### # start messengerv2 sub messengerv2 { my (undef,undef,$uid,$gid,undef,undef,undef,$homedir) = getpwnam($config{MESSENGER_USER}); if ($homedir eq "" or $homedir eq "/" or $homedir =~ m[/etc/csf]) { return (1, "The home directory for $config{MESSENGER_USER} is not valid [$homedir]"); } if (! -e $homedir) { return (1, "The home directory for $config{MESSENGER_USER} does not exist [$homedir]"); } system("chmod","711",$homedir); my $public_html = $homedir."/public_html"; unless (-e $public_html) { system("mkdir","-p",$public_html); system("chown","$config{MESSENGER_USER}:nobody",$public_html); system("chmod","711",$public_html); } unless (-e $public_html."/.htaccess") { open (my $HTACCESS, ">", $public_html."/.htaccess"); flock ($HTACCESS, LOCK_EX); print $HTACCESS "Require all granted\n"; print $HTACCESS "DirectoryIndex index.php index.cgi index.html index.htm\n"; print $HTACCESS "Options +FollowSymLinks +ExecCGI\n"; print $HTACCESS "RewriteEngine On\n"; print $HTACCESS "RewriteCond \%{REQUEST_FILENAME} !-f\n"; print $HTACCESS "RewriteCond \%{REQUEST_FILENAME} !-d\n"; print $HTACCESS "RewriteRule ^ /index.php [L,QSA]\n"; system("chown","$config{MESSENGER_USER}:$config{MESSENGER_USER}",$public_html."/.htaccess"); system("chmod","644",$public_html."/.htaccess"); } unless (-e $public_html."/index.php") { if ($config{RECAPTCHA_SITEKEY}) { system("cp","/etc/csf/messenger/index.recaptcha.php",$public_html."/index.php"); } else { system("cp","/etc/csf/messenger/index.php",$public_html."/index.php"); } system("chown","$config{MESSENGER_USER}:$config{MESSENGER_USER}",$public_html."/index.php"); system("chmod","644",$public_html."/index.php"); } unless (-e $homedir."/en.php") { system("cp","/etc/csf/messenger/en.php",$homedir."/en.php"); system("chown","$config{MESSENGER_USER}:$config{MESSENGER_USER}",$homedir."/en.php"); system("chmod","644",$homedir."/en.php"); } open (my $CONF, ">", $homedir."/recaptcha.php"); flock ($CONF, LOCK_EX); print $CONF "\n"; system("chown","$config{MESSENGER_USER}:$config{MESSENGER_USER}",$homedir."/recaptcha.php"); system("chmod","644",$homedir."/recaptcha.php"); open (my $OUT, ">", "/var/lib/csf/csf.conf"); flock ($OUT, LOCK_EX); if ($config{MESSENGER_HTML_IN} ne "") { print $OUT "Listen 0.0.0.0:$config{MESSENGER_HTML}\n"; if ($config{IPV6}) {print $OUT "Listen [::]:$config{MESSENGER_HTML}\n"} print $OUT "\n"; print $OUT " ServerName $hostname\n"; print $OUT " DocumentRoot $public_html\n"; print $OUT " \n"; print $OUT " AllowOverride All\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " suPHP_UserGroup $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " \n"; print $OUT " SuexecUserGroup $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " \n"; print $OUT " RMode config\n"; print $OUT " RUidGid $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " AssignUserID $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " KeepAlive Off\n"; print $OUT "\n"; } if ($config{MESSENGER_HTTPS_IN} ne "") { my %sslcerts; my %sslkeys; my %ssldomains; my $start = 0; my $sslhost; my $sslcert; my $sslkey; my $sslaliases; my $ssldir = "/var/lib/csf/ssl/"; unless (-d $ssldir) { mkdir $ssldir; mkdir $ssldir."certs/"; mkdir $ssldir."keys/"; } foreach my $file (glob($config{MESSENGER_HTTPS_CONF})) { if (-e $file) { foreach my $line (slurp($file)) { $line =~ s/\'|\"//g; if ($line =~ /^\s*]+>/) { $start = 1; } if ($webserver eq "apache" and $start) { if ($line =~ /\s*ServerName\s+(\w+:\/\/)?([a-zA-Z0-9\.\-]+)(:\d+)?/) {$sslhost = $2} if ($line =~ /\s*ServerAlias\s+(.*)/) {$sslaliases .= " ".$1} if ($line =~ /\s*SSLCertificateFile\s+(\S+)/) { my $match = $1; if (-e $match) { copy($match, $ssldir."certs/".$sslhost."\.crt"); $sslcert = $ssldir."certs/".$sslhost."\.crt"; } } if ($line =~ /\s*SSLCertificateKeyFile\s+(\S+)/) { my $match = $1; if (-e $match) { copy($match, $ssldir."keys/".$sslhost."\.key"); $sslkey = $ssldir."keys/".$sslhost."\.key"; } } } if (($webserver eq "apache" and $line =~ /^\s*<\/VirtualHost\s*>/)) { $start = 0; if ($sslhost ne "" and !checkip($sslhost) and $sslcert ne "") { $ssldomains{$sslhost}{key} = $sslkey; $ssldomains{$sslhost}{aliases} = $sslaliases; $ssldomains{$sslhost}{cert} = $sslcert; } $sslhost = ""; $sslcert = ""; $sslkey = ""; $sslaliases = ""; } } } } if (scalar(keys %ssldomains < 1)) { return (1, "No SSL domains found in MESSENGER_HTTPS_CONF location"); } print $OUT "Listen 0.0.0.0:$config{MESSENGER_HTTPS}\n"; if ($config{IPV6}) {print $OUT "Listen [::]:$config{MESSENGER_HTTPS}\n"} if (-e $config{MESSENGER_HTTPS_KEY}) { print $OUT "\n"; print $OUT " ServerName $hostname\n"; print $OUT " DocumentRoot $public_html\n"; print $OUT " UseCanonicalName Off\n"; print $OUT " \n"; print $OUT " AllowOverride All\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " suPHP_UserGroup $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " \n"; print $OUT " SuexecUserGroup $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " \n"; print $OUT " RMode config\n"; print $OUT " RUidGid $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " AssignUserID $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " SSLEngine on\n"; if (-e $config{MESSENGER_HTTPS_KEY}) { copy($config{MESSENGER_HTTPS_KEY}, $ssldir."keys/".$hostname."\.key"); print $OUT " SSLCertificateKeyFile ".$ssldir."keys/".$hostname."\.key\n"; } if (-e $config{MESSENGER_HTTPS_CRT}) { copy($config{MESSENGER_HTTPS_CRT}, $ssldir."certs/".$hostname."\.crt"); print $OUT " SSLCertificateFile ".$ssldir."certs/".$hostname."\.crt\n"; } print $OUT " SSLUseStapling off\n"; print $OUT " KeepAlive Off\n"; print $OUT "\n"; } foreach my $key (keys %ssldomains) { if ($key eq "") {next} if ($key =~ /^\s+$/) {next} if (-e $ssldomains{$key}{cert}) { print $OUT "\n"; print $OUT " ServerName $key\n"; print $OUT " ServerAlias $ssldomains{$key}{aliases}\n"; print $OUT " DocumentRoot $public_html\n"; print $OUT " UseCanonicalName Off\n"; print $OUT " \n"; print $OUT " AllowOverride All\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " suPHP_UserGroup $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " \n"; print $OUT " SuexecUserGroup $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " \n"; print $OUT " RMode config\n"; print $OUT " RUidGid $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " \n"; print $OUT " AssignUserID $config{MESSENGER_USER} $config{MESSENGER_USER}\n"; print $OUT " \n"; print $OUT " SSLEngine on\n"; if (-e $ssldomains{$key}{cert}) {print $OUT " SSLCertificateFile $ssldomains{$key}{cert}\n"} if (-e $ssldomains{$key}{key}) {print $OUT " SSLCertificateKeyFile $ssldomains{$key}{key}\n"} print $OUT " SSLUseStapling off\n"; print $OUT " KeepAlive Off\n"; print $OUT "\n"; } } } close ($OUT); system("cp","-f","/var/lib/csf/csf.conf","/etc/apache2/conf.d/csf.messenger.conf"); my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, "/usr/sbin/apachectl", "configtest"); my @data = <$childout>; waitpid ($cmdpid, 0); if (-e "/var/lib/csf/apachectl.error") {unlink("/var/lib/csf/apachectl.error")} my $ok = 0; foreach (@data) { if ($_ =~ /^Syntax OK/) {$ok = 1} } if ($ok) { system("/scripts/restartsrv_httpd"); logfile("MESSENGERV2: Started Apache MESSENGERV2 service using /etc/apache2/conf.d/csf.messenger.conf"); } else { logfile("*MESSENGERV2*: Unable to generate a valid Apache configuration, see /var/lib/csf/apachectl.error"); if (-e "/etc/apache2/conf.d/csf.messenger.conf") {unlink("/etc/apache2/conf.d/csf.messenger.conf")} system("/scripts/restartsrv_httpd"); open (my $ERROR, ">", "/var/lib/csf/apachectl.error"); flock ($ERROR, LOCK_EX); foreach (@data) {print $ERROR $_} close ($ERROR); } return; } # end messengerv2 ############################################################################### # start messengerv3 sub messengerv3 { my (undef,undef,$uid,$gid,undef,undef,undef,$homedir) = getpwnam($config{MESSENGER_USER}); if ($homedir eq "" or $homedir eq "/" or $homedir =~ m[/etc/csf]) { return (1, "The home directory for $config{MESSENGER_USER} is not valid [$homedir]"); } if (! -e $homedir) { return (1, "The home directory for $config{MESSENGER_USER} does not exist [$homedir]"); } my $public_html = $homedir."/public_html"; unless (-e $public_html) { system("mkdir","-p",$public_html); system("chown","$config{MESSENGER_USER}:$config{MESSENGERV3GROUP}",$public_html); system("chmod",$config{MESSENGERV3PERMS},$public_html); } unless (-e $public_html."/.htaccess") { open (my $HTACCESS, ">", $public_html."/.htaccess"); flock ($HTACCESS, LOCK_EX); print $HTACCESS <", $homedir."/recaptcha.php"); flock ($CONF, LOCK_EX); print $CONF "\n"; system("chown","$config{MESSENGER_USER}:$config{MESSENGER_USER}",$homedir."/recaptcha.php"); system("chmod","644",$homedir."/recaptcha.php"); if ($config{MESSENGERV3WEBSERVER} eq "apache") { $webserver = "apache"; } elsif ($config{MESSENGERV3WEBSERVER} eq "litespeed") { $webserver = "litespeed"; } open (my $OUT, ">", "/var/lib/csf/csf.conf"); flock ($OUT, LOCK_EX); if ($config{MESSENGERV3PHPHANDLER} ne "") { $phphandler = $config{MESSENGERV3PHPHANDLER}; } else { my $file = "/etc/httpd/conf/extra/httpd-hostname.conf"; if (-e $file) { foreach my $line (slurp($file)) { if ($line =~ /^\s*AddHandler\s+.+\s+\.php/) { $phphandler = $line; if ($config{DEBUG} >= 1) {logfile("SSL: PHP Handler found in [$file]")} } } } } foreach my $line (slurp("/usr/local/csf/tpl/$webserver.main.txt")) { $line =~ s/\[PORT\]/$config{MESSENGER_HTML}/g; if ($line =~ /Listen \[::\]:/ and !$config{IPV6}) {next} $line =~ s/\[SERVERNAME\]/$hostname/g; $line =~ s/\[DOCUMENTROOT\]/$public_html/g; $line =~ s/\[DIRECTORY\]/$homedir/g; $line =~ s/\[USER\]/$config{MESSENGER_USER}/g; $line =~ s/\[PHPHANDLER\]/$phphandler/g; print $OUT $line."\n"; } if ($config{MESSENGER_HTML_IN} ne "") { foreach my $line (slurp("/usr/local/csf/tpl/$webserver.http.txt")) { $line =~ s/\[PORT\]/$config{MESSENGER_HTML}/g; if ($line =~ /Listen \[::\]:/ and !$config{IPV6}) {next} $line =~ s/\[SERVERNAME\]/$hostname/g; $line =~ s/\[DOCUMENTROOT\]/$public_html/g; $line =~ s/\[DIRECTORY\]/$homedir/g; $line =~ s/\[USER\]/$config{MESSENGER_USER}/g; $line =~ s/\[PHPHANDLER\]/$phphandler/g; print $OUT $line."\n"; } } if ($config{MESSENGER_HTTPS_IN} ne "") { if ($webserver eq "litespeed") { if ($config{MESSENGERV3HTTPS_CONF} =~ /(.*\/lsws\/)/) { $serverroot = $1; } } &conftree($config{MESSENGERV3HTTPS_CONF}); if ($webserver eq "litespeed") { if ($sslhost ne "" and $osslcert ne "" and $ssldomains{$sslhost}{cert} eq "") { if (-e $osslcert) { $sslcert = $ssldir."certs/".$sslhost."\.crt"; copy($osslcert, $ssldir."certs/".$sslhost."\.crt"); } if (-e $osslkey) { $sslkey = $ssldir."keys/".$sslhost."\.key"; copy($osslkey, $ssldir."keys/".$sslhost."\.key"); } if (-e $osslca) { $sslca = $ssldir."ca/".$sslhost."\.ca"; copy($osslca, $ssldir."ca/".$sslhost."\.ca"); } $sslaliases =~ s/\$VH_NAME/$sslhost/; $ssldomains{$sslhost}{key} = $sslkey; $ssldomains{$sslhost}{aliases} = $sslaliases; $ssldomains{$sslhost}{cert} = $sslcert; $ssldomains{$sslhost}{ca} = $sslca; push @ssldomainkeys, $sslhost; $sslhost = ""; $sslcert = ""; $sslkey = ""; $sslca = ""; $osslcert = ""; $osslkey = ""; $osslca = ""; $sslaliases = ""; } } if (scalar(keys %ssldomains < 1)) { return (1, "No SSL domains found in MESSENGERV3HTTPS_CONF location [$config{MESSENGERV3HTTPS_CONF}] for $webserver web server"); } my @virtualhost; my $start = 0; my $key = $ssldomainkeys[0]; foreach my $line (slurp("/usr/local/csf/tpl/$webserver.https.txt")) { if ($line =~ /^\# Virtualhost start/) {$start = 1} if ($start) { if ($line =~ /^\# Virtualhost end/) {$start = 0} push @virtualhost, $line; next; } $line =~ s/\[SSLPORT\]/$config{MESSENGER_HTTPS}/g; if ($line =~ /Listen \[::\]:/ and !$config{IPV6}) {next} $line =~ s/\[SERVERNAME\]/$hostname/g; $line =~ s/\[DOCUMENTROOT\]/$public_html/g; $line =~ s/\[DIRECTORY\]/$homedir/g; $line =~ s/\[USER\]/$config{MESSENGER_USER}/g; $line =~ s/\[PHPHANDLER\]/$phphandler/g; if ($line =~ /[MAPS]/) { my $mapping; foreach my $map (@ssldomainkeys) { if (-e $ssldomains{$map}{cert}) { $mapping .= "map csfssl.${map} ${map}\n\t"; } } $line =~ s/\[MAPS\]/$mapping/g; } if ($line =~ /\[SSLCERTIFICATEFILE\]/) { if ( -e $ssldomains{$key}{cert}) { $line =~ s/\[SSLCERTIFICATEFILE\]/$ssldomains{$key}{cert}/g; } else {next} } if ($line =~ /\[SSLCERTIFICATEKEYFILE\]/) { if (-e $ssldomains{$key}{key}) { $line =~ s/\[SSLCERTIFICATEKEYFILE\]/$ssldomains{$key}{key}/g; } else {next} } if ($line =~ /\[SSLCACERTIFICATEFILE\]/) { if (-e $ssldomains{$key}{ca}) { $line =~ s/\[SSLCACERTIFICATEFILE\]/$ssldomains{$key}{ca}/g; } else {next} } print $OUT $line."\n"; } foreach my $key (@ssldomainkeys) { if ($key eq "") {next} if ($key =~ /^\s+$/) {next} if ($config{DEBUG} >= 1) {logfile("SSL: Processing [$key]")} if (-e $ssldomains{$key}{cert}) { foreach (@virtualhost) { my $line = $_; $line =~ s/\[SSLPORT\]/$config{MESSENGER_HTTPS}/g; $line =~ s/\[SERVERNAME\]/$key/g; $line =~ s/\[SERVERALIAS\]/$ssldomains{$key}{aliases}/g; $line =~ s/\[DOCUMENTROOT\]/$public_html/g; $line =~ s/\[DIRECTORY\]/$homedir/g; $line =~ s/\[USER\]/$config{MESSENGER_USER}/g; $line =~ s/\[PHPHANDLER\]/$phphandler/g; if ($line =~ /\[SSLCERTIFICATEFILE\]/) { if ( -e $ssldomains{$key}{cert}) { $line =~ s/\[SSLCERTIFICATEFILE\]/$ssldomains{$key}{cert}/g; } else {next} } if ($line =~ /\[SSLCERTIFICATEKEYFILE\]/) { if (-e $ssldomains{$key}{key}) { $line =~ s/\[SSLCERTIFICATEKEYFILE\]/$ssldomains{$key}{key}/g; } else {next} } if ($line =~ /\[SSLCACERTIFICATEFILE\]/) { if (-e $ssldomains{$key}{ca}) { $line =~ s/\[SSLCACERTIFICATEFILE\]/$ssldomains{$key}{ca}/g; } else {next} } print $OUT $line."\n"; } } } } close ($OUT); my $location; if (-d $config{MESSENGERV3LOCATION}) { system("cp","-f","/var/lib/csf/csf.conf",$config{MESSENGERV3LOCATION}."/csf.messenger.conf"); $location = $config{MESSENGERV3LOCATION}."/csf.messenger.conf"; } elsif (-f $config{MESSENGERV3LOCATION}) { my @conf = slurp($config{MESSENGERV3LOCATION}); unless (grep {$_ =~ m[^Include /var/lib/csf/csf.conf]i} @conf) { sysopen (my $FILE, $config{MESSENGERV3LOCATION}, O_WRONLY | O_APPEND | O_CREAT); flock ($FILE, LOCK_EX); if ($webserver eq "apache") { print $FILE "Include /var/lib/csf/csf.conf\n"; } elsif ($webserver eq "litespeed") { print $FILE "include /var/lib/csf/csf.conf\n"; } close ($FILE); } $location = $config{MESSENGERV3LOCATION}; } else { logfile("MESSENGERV3: [$config{MESSENGERV3LOCATION}] is neither a directory nor a file. You must manually include /var/lib/csf/csf.conf into the $webserver configuration"); return; } if ($config{MESSENGERV3TEST} ne "") { my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, $config{MESSENGERV3TEST}); my @data = <$childout>; waitpid ($cmdpid, 0); if (-e "/var/lib/csf/messenger.error") {unlink("/var/lib/csf/messenger.error")} my $ok = 0; foreach (@data) { if ($_ =~ /^Syntax OK/) {$ok = 1} } if ($ok) { system($config{MESSENGERV3RESTART}); logfile("MESSENGERV3: Restarted $webserver MESSENGERV3 service using $location"); } else { open (my $ERROR, ">", "/var/lib/csf/messenger.error"); flock ($ERROR, LOCK_EX); foreach (@data) {print $ERROR $_} close ($ERROR); if (-d $config{MESSENGERV3LOCATION}) { unlink ($config{MESSENGERV3LOCATION}."/csf.messenger.conf"); } elsif (-f $config{MESSENGERV3LOCATION}) { my @conf = slurp($config{MESSENGERV3LOCATION}); if (grep {$_ =~ m[^Include /var/lib/csf/csf.conf]i} @conf) { sysopen (my $FILE, $config{MESSENGERV3LOCATION}, O_WRONLY | O_CREAT | O_TRUNC); flock ($FILE, LOCK_EX); foreach my $line (@conf) { $line =~ s/$cleanreg//g; if ($line =~ m[^Include /var/lib/csf/csf.conf]i) {next} print $FILE $line."\n"; } close ($FILE); } } system($config{MESSENGERV3RESTART}); logfile("*MESSENGERV3*: Unable to generate a valid $webserver configuration, see /var/lib/csf/messenger.error"); } } else { system($config{MESSENGERV3RESTART}); logfile("MESSENGERV3: Restarted $webserver MESSENGERV3 service using $location"); } return; } # end messengerv3 ############################################################################### # start messengerlog sub messengerlog { my $homedir = shift; my $message = shift; if ($config{DEBUG}) { sysopen (my $LOG, "/var/log/lfd_messenger.log", O_WRONLY | O_APPEND | O_CREAT); print $LOG "[$$]: ".$message."\n"; close ($LOG); } return; } # end messengerlog ############################################################################### # start childcleanup sub childcleanup { $SIG{INT} = 'IGNORE'; $SIG{TERM} = 'IGNORE'; $SIG{HUP} = 'IGNORE'; my $line = shift; my $message = shift; if (($message eq "") and $line) { $message = "Child $childproc: $line"; $line = ""; } $0 = "child - aborting"; if ($message) { if ($line ne "") {$message .= ", at line $line"} logfile("$message"); } exit; } # end childcleanup ############################################################################### # 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) { my $netip = Net::IP->new($key); my $type = $netip->iptype(); if ($type eq "PUBLIC") {$ips{$key} = 1} } if ($config{IPV6}) { foreach my $key (keys %g_ipv6) { if ($key !~ m[::1/128]) { eval { local $SIG{__DIE__} = undef; $ipscidr6->add($key); }; } } } return; } # end getethdev ############################################################################### # start error sub error { my $error = shift; logfile($error); exit; } # end error ############################################################################### # start conftree sub conftree { my $fileglob = shift; foreach my $file (glob($fileglob)) { if ($file =~ /csf\.messenger\.conf$/) {next} if ($file =~ /\/var\/lib\/csf\/csf.conf$/) {next} if (-e $file) { if ($config{DEBUG} >= 1) {logfile("SSL: Processing [$file]")} my $start = 0; foreach my $line (slurp($file)) { if ($webserver eq "apache") { $line =~ s/\'|\"//g; if ($line =~ /^\s*ServerRoot\s+\"?(\S+)\"?/) { $serverroot = $1; unless (-d $serverroot) {$serverroot = ""} } if ($serverroot eq "" and -d "/etc/apache2") {$serverroot = "/etc/apache2"} if ($line =~ /^\s*Include\s+(\S+)/) { my $include = $1; if ($include !~ /^\//) {$include = "$serverroot/$include"} if ($config{DEBUG} >= 1) {logfile("SSL: Including [$include]")} &conftree($include); } if ($line =~ /^\s*IncludeOptional\s+(\S+)/) { my $include = $1; if ($include !~ /^\//) {$include = "$serverroot/$include"} if ($config{DEBUG} >= 1) {logfile("SSL: IncludeOptional [$include]")} &conftree($include); } if ($line =~ /^\s*]+>/) { $start = 1; } if ($start) { if ($line =~ /\s*ServerName\s+(\w+:\/\/)?([a-zA-Z0-9\.\-]+)(:\d+)?/) {$sslhost = $2} if ($line =~ /\s*ServerAlias\s+(.*)/) {$sslaliases .= " ".$1} if ($line =~ /\s*SSLCertificateFile\s+(\S+)/) { my $match = $1; if (-e $match) { $osslcert = $match; logfile("SSL: Found [$sslhost] certificate in [$file]"); } } if ($line =~ /\s*SSLCertificateKeyFile\s+(\S+)/) { my $match = $1; if (-e $match) { $osslkey = $match; logfile("SSL: Found [$sslhost] key in [$file]"); } } if ($line =~ /\s*SSLCACertificateFile\s+(\S+)/) { my $match = $1; if (-e $match) { $osslca = $match; logfile("SSL: Found [$sslhost] ca bundle in [$file]"); } } } if ($line =~ /^\s*<\/VirtualHost\s*>/) { $start = 0; if ($sslhost ne "" and !checkip($sslhost) and $osslcert ne "") { if (-e $osslcert) { $sslcert = $ssldir."certs/".$sslhost."\.crt"; copy($osslcert, $ssldir."certs/".$sslhost."\.crt"); } if (-e $osslkey) { $sslkey = $ssldir."keys/".$sslhost."\.key"; copy($osslkey, $ssldir."keys/".$sslhost."\.key"); } if (-e $osslca) { $sslca = $ssldir."ca/".$sslhost."\.ca"; copy($osslca, $ssldir."ca/".$sslhost."\.ca"); } $ssldomains{$sslhost}{key} = $sslkey; $ssldomains{$sslhost}{aliases} = $sslaliases; $ssldomains{$sslhost}{cert} = $sslcert; $ssldomains{$sslhost}{ca} = $sslca; push @ssldomainkeys, $sslhost; if ($config{DEBUG} >= 1) {logfile("SSL: Found [$sslhost] in [$file]")} } $sslhost = ""; $sslcert = ""; $sslkey = ""; $sslca = ""; $osslcert = ""; $osslkey = ""; $osslca = ""; $sslaliases = ""; } } elsif ($webserver eq "litespeed") { $line =~ s/\'|\"//g; if ($line =~ /^\s*include\s+(\S+)/) { my $include = $1; $include =~ s/\$SERVER_ROOT/$serverroot/; $include =~ s/\$VH_NAME/$sslhost/; if ($include !~ /^\//) {$include = "$serverroot/$include"} if ($config{DEBUG} >= 1) {logfile("SSL: include [$include]")} &conftree($include); } if ($line =~ /^\s*configFile\s+(\S+)/) { my $include = $1; $include =~ s/\$SERVER_ROOT/$serverroot/; $include =~ s/\$VH_NAME/$sslhost/; if ($include !~ /^\//) {$include = "$serverroot/$include"} if ($config{DEBUG} >= 1) {logfile("SSL: configFile [$include]")} &conftree($include); } if ($line =~ /^\s*virtualHost\s+([^\{]+)\s+\{/) { my $newsslhost = $1; if ($newsslhost ne "" and $config{DEBUG} >= 1) {logfile("SSL: Found [$newsslhost] in [$file]")} if ($litestart == 1) { if ($sslhost ne "" and $osslcert ne "") { if (-e $osslcert) { $sslcert = $ssldir."certs/".$sslhost."\.crt"; copy($osslcert, $ssldir."certs/".$sslhost."\.crt"); } if (-e $osslkey) { $sslkey = $ssldir."keys/".$sslhost."\.key"; copy($osslkey, $ssldir."keys/".$sslhost."\.key"); } if (-e $osslca) { $sslca = $ssldir."ca/".$sslhost."\.ca"; copy($osslca, $ssldir."ca/".$sslhost."\.ca"); } $sslaliases =~ s/\$VH_NAME/$sslhost/; $ssldomains{$sslhost}{key} = $sslkey; $ssldomains{$sslhost}{aliases} = $sslaliases; $ssldomains{$sslhost}{cert} = $sslcert; $ssldomains{$sslhost}{ca} = $sslca; push @ssldomainkeys, $sslhost; $sslhost = ""; $sslcert = ""; $sslkey = ""; $sslca = ""; $osslcert = ""; $osslkey = ""; $osslca = ""; $sslaliases = ""; } } $litestart = 1; $sslhost = $newsslhost; } if ($litestart) { if ($line =~ /\s*vhDomain\s+(\w+:\/\/)?([a-zA-Z0-9\.\-]+)(:\d+)?/) {$sslhost = $2} if ($line =~ /\s*vhAliases\s+(.*)/) {$sslaliases .= " ".$1} if ($line =~ /\s*certFile\s+(\S+)/) { my $match = $1; if (-e $match) { $osslcert = $match; logfile("SSL: Found [$sslhost] certificate in [$file]"); } } if ($line =~ /\s*keyFile\s+(\S+)/) { my $match = $1; if (-e $match) { $osslkey = $match; logfile("SSL: Found [$sslhost] key in [$file]"); } } } } } } } return; } # end conftree ############################################################################### 1; RegexMain.pm000064400000130257151030020750006762 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen) # start main package ConfigServer::RegexMain; use strict; use lib '/usr/local/csf/lib'; use IPC::Open3; use ConfigServer::Config; use ConfigServer::CheckIP qw(checkip); use ConfigServer::Slurp qw(slurp); use ConfigServer::Logger qw(logfile); use ConfigServer::GetEthDev; use Exporter qw(import); our $VERSION = 1.03; our @ISA = qw(Exporter); our @EXPORT_OK = qw(); our (%config, %cpconfig, $slurpreg, $cleanreg, %globlogs, %brd, %ips); my $config = ConfigServer::Config->loadconfig(); %config = $config->config; $slurpreg = ConfigServer::Slurp->slurpreg; $cleanreg = ConfigServer::Slurp->cleanreg; if (-e "/etc/wwwacct.conf") { foreach my $line (slurp("/etc/wwwacct.conf")) { $line =~ s/$cleanreg//g; if ($line =~ /^(\s|\#|$)/) {next} my ($name,$value) = split (/ /,$line,2); $cpconfig{$name} = $value; } } if (-e "/usr/local/cpanel/version") { foreach my $line (slurp("/usr/local/cpanel/version")) { $line =~ s/$cleanreg//g; if ($line =~ /\d/) {$cpconfig{version} = $line} } } if ($config{LF_APACHE_ERRPORT} == 0) { my $apachebin = ""; if (-e "/usr/local/apache/bin/httpd") {$apachebin = "/usr/local/apache/bin/httpd"} elsif (-e "/usr/sbin/httpd") {$apachebin = "/usr/sbin/httpd"} elsif (-e "/usr/sbin/apache2") {$apachebin = "/usr/sbin/apache2"} elsif (-e "/usr/sbin/httpd2") {$apachebin = "/usr/sbin/httpd2"} if (-e $apachebin) { my ($childin, $childout); my $mypid = open3($childin, $childout, $childout, $apachebin,"-v"); my @version = <$childout>; waitpid ($mypid, 0); chomp @version; $version[0] =~ /Apache\/(\d+)\.(\d+)\.(\d+)/; my $mas = $1; my $maj = $2; my $min = $3; if ("$mas.$maj" < 2.4) {$config{LF_APACHE_ERRPORT} = 1} } } unless ($config{LF_APACHE_ERRPORT} == 1) {$config{LF_APACHE_ERRPORT} = 2} ConfigServer::Logger::logfile("LF_APACHE_ERRPORT: Set to [$config{LF_APACHE_ERRPORT}]"); my $ethdev = ConfigServer::GetEthDev->new(); %brd = $ethdev->brd; %ips = $ethdev->ipv4; if (-e "/usr/local/csf/bin/regex.custom.pm") {require "/usr/local/csf/bin/regex.custom.pm"} ##no critic # end main ############################################################################### # start processline sub processline { my $line = shift; my $lgfile = shift; my $globlogs_ref = shift; %globlogs = %{$globlogs_ref}; $line =~ s/\n//g; $line =~ s/\r//g; if (-e "/usr/local/csf/bin/regex.custom.pm") { my ($text,$ip,$app,$trigger,$ports,$temp,$cf) = &custom_line($line,$lgfile); if ($text) { return ($text,$ip,$app,$trigger,$ports,$temp,$cf); } } #openSSH #RH if (($config{LF_SSHD}) and (($lgfile eq "/var/log/messages") or ($lgfile eq "/var/log/secure") or ($globlogs{SSHD_LOG}{$lgfile})) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: pam_unix\(sshd:auth\): authentication failure; logname=\S* uid=\S* euid=\S* tty=\S* ruser=\S* rhost=(\S+)\s+(user=(\S+))?/)) { my $ip = $3; my $acc = $5; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SSH login from","$ip|$acc","sshd")} else {return} } if (($config{LF_SSHD}) and (($lgfile eq "/var/log/messages") or ($lgfile eq "/var/log/secure") or ($globlogs{SSHD_LOG}{$lgfile})) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: Failed none for (\S*) from (\S+) port \S+/)) { my $ip = $4; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SSH login from","$ip|$acc","sshd")} else {return} } if (($config{LF_SSHD}) and (($lgfile eq "/var/log/messages") or ($lgfile eq "/var/log/secure") or ($globlogs{SSHD_LOG}{$lgfile})) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: Failed password for (invalid user |illegal user )?(\S*) from (\S+)( port \S+ \S+\s*)?/)) { my $ip = $5; my $acc = $4; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SSH login from","$ip|$acc","sshd")} else {return} } if (($config{LF_SSHD}) and (($lgfile eq "/var/log/messages") or ($lgfile eq "/var/log/secure") or ($globlogs{SSHD_LOG}{$lgfile})) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: Failed keyboard-interactive(\/pam)? for (invalid user )?(\S*) from (\S+) port \S+/)) { my $ip = $6; my $acc = $4; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SSH login from","$ip|$acc","sshd")} else {return} } if (($config{LF_SSHD}) and (($lgfile eq "/var/log/messages") or ($lgfile eq "/var/log/secure") or ($globlogs{SSHD_LOG}{$lgfile})) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: Invalid user (\S*) from (\S+)/)) { my $ip = $4; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SSH login from","$ip|$acc","sshd")} else {return} } if (($config{LF_SSHD}) and (($lgfile eq "/var/log/messages") or ($lgfile eq "/var/log/secure") or ($globlogs{SSHD_LOG}{$lgfile})) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: User (\S*) from (\S+)\s* not allowed because not listed in AllowUsers/)) { my $ip = $4; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SSH login from","$ip|$acc","sshd")} else {return} } if (($config{LF_SSHD}) and (($lgfile eq "/var/log/messages") or ($lgfile eq "/var/log/secure") or ($globlogs{SSHD_LOG}{$lgfile})) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: Did not receive identification string from (\S+)/)) { my $ip = $3; my $acc = ""; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SSH login from","$ip|$acc","sshd")} else {return} } if (($config{LF_SSHD}) and (($lgfile eq "/var/log/messages") or ($lgfile eq "/var/log/secure") or ($globlogs{SSHD_LOG}{$lgfile})) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: refused connect from (\S+)/)) { my $ip = $3; my $acc = ""; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SSH login from","$ip|$acc","sshd")} else {return} } if (($config{LF_SSHD}) and (($lgfile eq "/var/log/messages") or ($lgfile eq "/var/log/secure") or ($globlogs{SSHD_LOG}{$lgfile})) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: error: maximum authentication attempts exceeded for (\S*) from (\S+)/)) { my $ip = $4; my $acc = ""; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SSH login from","$ip|$acc","sshd")} else {return} } #Debian/Ubuntu if (($config{LF_SSHD}) and (($lgfile eq "/var/log/messages") or ($lgfile eq "/var/log/secure") or ($globlogs{SSHD_LOG}{$lgfile})) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: Illegal user (\S*) from (\S+)/)) { my $ip = $4; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SSH login from","$ip|$acc","sshd")} else {return} } #Gentoo if (($config{LF_SSHD}) and (($lgfile eq "/var/log/messages") or ($lgfile eq "/var/log/secure") or ($globlogs{SSHD_LOG}{$lgfile})) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: error: PAM: Authentication failure for (\S*) from (\S+)/)) { my $ip = $4; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SSH login from","$ip|$acc","sshd")} else {return} } #courier-imap if (($config{LF_POP3D}) and ($globlogs{POP3D_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ pop3d(-ssl)?: LOGIN FAILED, user=(\S*), ip=\[(\S+)\]\s*$/)) { my $ip = $4; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed POP3 login from","$ip|$acc","pop3d")} else {return} } if (($config{LF_IMAPD}) and ($globlogs{IMAPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ imapd(-ssl)?: LOGIN FAILED, user=(\S*), ip=\[(\S+)\]\s*$/)) { my $ip = $4; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed IMAP login from","$ip|$acc","imapd")} else {return} } #uw-imap if (($config{LF_POP3D}) and ($globlogs{POP3D_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ ipop3d\[\d+\]: Login failed user=(\S*) auth=\S+ host=\S+ \[(\S+)\]\s*$/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed POP3 login from","$ip|$acc","pop3d")} else {return} } if (($config{LF_IMAPD}) and ($globlogs{IMAPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ imapd\[\d+\]: Login failed user=(\S*) auth=\S+ host=\S+ \[(\S+)\]\s*$/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed IMAP login from","$ip|$acc","imapd")} else {return} } #dovecot if (($config{LF_POP3D}) and ($globlogs{POP3D_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ dovecot(\[\d+\])?: pop3-login: (Disconnected: )?(Aborted login( by logging out)?|Connection closed|Disconnected|Disconnected: Inactivity)(:\s*\S+\sfailed: Connection reset by peer)?(\s*\(auth failed, \d+ attempts( in \d+ secs)?\))?: (user=(<\S*>)?, )?(method=\S+, )?rip=(\S+), lip=/)) { my $ip = $12; my $acc = $10; $ip =~ s/^::ffff://; $acc =~ s/^<|>$//g; if (checkip(\$ip)) {return ("Failed POP3 login from","$ip|$acc","pop3d")} else {return} } if (($config{LF_IMAPD}) and ($globlogs{IMAPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ dovecot(\[\d+\])?: imap-login: (Disconnected: )?(Aborted login( by logging out)?|Connection closed|Disconnected|Disconnected: Inactivity)(:\s*\S+\sfailed: Connection reset by peer)?(\s*\(auth failed, \d+ attempts( in \d+ secs)?\))?: (user=(<\S*>)?, )?(method=\S+, )?rip=(\S+), lip=/)) { my $ip = $12; my $acc = $10; $ip =~ s/^::ffff://; $acc =~ s/^<|>$//g; if (checkip(\$ip)) {return ("Failed IMAP login from","$ip|$acc","imapd")} else {return} } if (($config{LF_POP3D}) and ($globlogs{POP3D_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) pop3-login(\[\d+\])?: Info: (Aborted login( by logging out)?|Connection closed|Disconnected|Disconnected: Inactivity)(\s*\(auth failed, \d+ attempts( in \d+ secs)?\))?: (user=(<\S*>)?, )?(method=\S+, )?rip=(\S+), lip=/)) { my $ip = $10; my $acc = $8; $ip =~ s/^::ffff://; $acc =~ s/^<|>$//g; if (checkip(\$ip)) {return ("Failed POP3 login from","$ip|$acc","pop3d")} else {return} } if (($config{LF_IMAPD}) and ($globlogs{IMAPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) imap-login(\[\d+\])?: Info: (Aborted login( by logging out)?|Connection closed|Disconnected|Disconnected: Inactivity)(\s*\(auth failed, \d+ attempts( in \d+ secs)?\))?: (user=(<\S*>)?, )?(method=\S+, )?rip=(\S+), lip=/)) { my $ip = $10; my $acc = $8; $ip =~ s/^::ffff://; $acc =~ s/^<|>$//g; if (checkip(\$ip)) {return ("Failed IMAP login from","$ip|$acc","imapd")} else {return} } #Kerio Mailserver if (($config{LF_POP3D}) and ($globlogs{POP3D_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ POP3(\[\d+\])?: User (\S*) doesn\'t exist\. Attempt from IP address (\S+)\s*$/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed POP3 login from","$ip|$acc","pop3d")} else {return} } if (($config{LF_POP3D}) and ($globlogs{POP3D_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ POP3(\[\d+\])?: Invalid password for user (\S*)\. Attempt from IP address (\S+)\s*$/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed POP3 login from","$ip|$acc","pop3d")} else {return} } if (($config{LF_IMAPD}) and ($globlogs{IMAPD_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ IMAP(\[\d+\])?: User (\S*) doesn\'t exist\. Attempt from IP address (\S+)\s*$/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed IMAP login from","$ip|$acc","imapd")} else {return} } if (($config{LF_IMAPD}) and ($globlogs{IMAPD_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ IMAP(\[\d+\])?: Invalid password for user (\S*)\. Attempt from IP address (\S+)\s*$/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed IMAP login from","$ip|$acc","imapd")} else {return} } if (($config{LF_SMTPAUTH}) and ($globlogs{SMTPAUTH_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ smtp(\[\d+\])?: User (\S*) doesn\'t exist\. Attempt from IP address (\S+)\s*$/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed IMAP login from","$ip|$acc","imapd")} else {return} } #pure-ftpd #Nov 10 04:28:04 w212 pure-ftpd[3269638]: (?@152.57.198.52) [WARNING] Authentication failed for user [www] if (($config{LF_FTPD}) and ($globlogs{FTPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ pure-ftpd(\[\d+\])?: \(\?\@(\S+)\) \[WARNING\] Authentication failed for user \[(\S*)\]/)) { my $ip = $3; my $acc = $4; $ip =~ s/^::ffff://; $ip =~ s/\_/\:/g; if (checkip(\$ip)) {return ("Failed FTP login from","$ip|$acc","ftpd")} else {return} } #proftpd if (($config{LF_FTPD}) and ($globlogs{FTPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ proftpd\[\d+\]:? \S+ \([^\[]+\[(\S+)\]\)( -)?:? - no such user \'(\S*)\'/)) { my $ip = $2; my $acc = $4; $ip =~ s/^::ffff://; $acc =~ s/:$//g; if (checkip(\$ip)) {return ("Failed FTP login from","$ip|$acc","ftpd")} else {return} } if (($config{LF_FTPD}) and ($globlogs{FTPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ proftpd\[\d+\]:? \S+ \([^\[]+\[(\S+)\]\)( -)?:? USER (\S*) no such user found from/)) { my $ip = $2; my $acc = $4; $ip =~ s/^::ffff://; $acc =~ s/:$//g; if (checkip(\$ip)) {return ("Failed FTP login from","$ip|$acc","ftpd")} else {return} } if (($config{LF_FTPD}) and ($globlogs{FTPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ proftpd\[\d+\]:? \S+ \([^\[]+\[(\S+)\]\)( -)?:? - SECURITY VIOLATION/)) { my $ip = $2; my $acc = ""; $ip =~ s/^::ffff://; $acc =~ s/:$//g; if (checkip(\$ip)) {return ("Failed FTP login from","$ip|$acc","ftpd")} else {return} } if (($config{LF_FTPD}) and ($globlogs{FTPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ proftpd\[\d+\]:? \S+ \([^\[]+\[(\S+)\]\)( -)?:? - USER (\S*) \(Login failed\): Incorrect password/)) { my $ip = $2; my $acc = $4; $ip =~ s/^::ffff://; $acc =~ s/:$//g; if (checkip(\$ip)) {return ("Failed FTP login from","$ip|$acc","ftpd")} else {return} } #vsftpd if (($config{LF_FTPD}) and ($globlogs{FTPD_LOG}{$lgfile}) and ($line =~ /^\S+\s+\S+\s+\d+\s+\S+\s+\d+ \[pid \d+] \[(\S+)\] FAIL LOGIN: Client "(\S+)"/)) { my $ip = $2; my $acc = $1; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed FTP login from","$ip|$acc","ftpd")} else {return} } if (($config{LF_FTPD}) and ($globlogs{FTPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ vsftpd\[\d+\]: pam_unix\(\S+\): authentication failure; logname=\S*\s+\S+\s+\S+\s+\S+\s+ruser=\S*\s+rhost=(\S+)(\s+user=(\S*))?/)) { my $ip = $2; my $acc = $4; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed FTP login from","$ip|$acc","ftpd")} else {return} } if (($config{LF_FTPD}) and ($globlogs{FTPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ vsftpd\(pam_unix\)\[\d+\]: authentication failure; logname=\S*\s+\S+\s+\S+\s+\S+\s+ruser=\S*\s+rhost=(\S+)(\s+user=(\S*))?/)) { my $ip = $2; my $acc = $4; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed FTP login from","$ip|$acc","ftpd")} else {return} } #apache htaccess if (($config{LF_HTACCESS}) and ($globlogs{HTACCESS_LOG}{$lgfile}) and ($line =~ /^\[\S+\s+\S+\s+\S+\s+\S+\s+\S+\] \[(\S*:)?error\] (\[pid \d+(:tid \d+)?\] )?\[(client|remote) (\S+)\] (\w+: )?user (\S*)(( not found:)|(: authentication failure for))/)) { my $ip = $5; my $acc = $7; $ip =~ s/^::ffff://; if ($config{LF_APACHE_ERRPORT} == 2 and $ip =~ /(.*):\d+$/) {$ip = $1} if (checkip(\$ip)) {return ("Failed web page login from","$ip|$acc","htpasswd")} else {return} } #nginx if (($config{LF_HTACCESS}) and ($globlogs{HTACCESS_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ \[error\] \S+ \*\S+ no user\/password was provided for basic authentication, client: (\S+),/)) { my $ip = $1; my $acc = ""; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed web page login from","$ip|$acc","htpasswd")} else {return} } if (($config{LF_HTACCESS}) and ($globlogs{HTACCESS_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ \[error\] \S+ \*\S+ user \"(\S*)\": password mismatch, client: (\S+),/)) { my $ip = $2; my $acc = $1; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed web page login from","$ip|$acc","htpasswd")} else {return} } if (($config{LF_HTACCESS}) and ($globlogs{HTACCESS_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ \[error\] \S+ \*\S+ user \"(\S*)\" was not found in \".*?\", client: (\S+),/)) { my $ip = $2; my $acc = $1; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed web page login from","$ip|$acc","htpasswd")} else {return} } #cxs Apache if (($config{LF_CXS}) and ($globlogs{MODSEC_LOG}{$lgfile}) and ($line =~ /^\[\S+\s+\S+\s+\S+\s+\S+\s+\S+\] \[(\S*:)?error\] (\[pid \d+(:tid \d+)?\] )?\[(client|remote) (\S+)\]( \[client \S+\])? (\w+: )?ModSecurity:(( \[[^]]+\])*)? Access denied with code \d\d\d \(phase 2\)\. File \"[^\"]*\" rejected by the approver script \"\/etc\/cxs\/cxscgi\.sh\"/)) { my $ip = $5; my $acc = ""; my $domain = ""; if ($line =~ /\] \[hostname "([^\"]+)"\] \[/) {$domain = $1} $ip =~ s/^::ffff://; if ($config{LF_APACHE_ERRPORT} == 2 and $ip =~ /(.*):\d+$/) {$ip = $1} if (checkip(\$ip)) {return ("cxs mod_security triggered by","$ip|$acc|$domain","cxs")} else {return} } #cxs Litespeed if (($config{LF_CXS}) and ($globlogs{MODSEC_LOG}{$lgfile}) and ($line =~ /^\[\S+\s+\S+\s+\S+\s+\S+\s+\S+\] \[(\S*:)?error\] (\[pid \d+(:tid \d+)?\] )?\[(client|remote) (\S+)\]( \[client \S+\])? (\w+: )?ModSecurity:(( \[[^]]+\])*)? Access denied with code \d\d\d, \[Rule: 'FILES_TMPNAMES' '\@inspectFile \/etc\/cxs\/cxscgi\.sh'\] \[id "1010101"\]/)) { my $ip = $5; my $acc = ""; my $domain = ""; if ($line =~ /\] \[hostname "([^\"]+)"\] \[/) {$domain = $1} $ip =~ s/^::ffff://; if ($config{LF_APACHE_ERRPORT} == 2 and $ip =~ /(.*):\d+$/) {$ip = $1} if (checkip(\$ip)) {return ("cxs mod_security triggered by","$ip|$acc|$domain","cxs")} else {return} } #mod_security v1 if (($config{LF_MODSEC}) and ($globlogs{MODSEC_LOG}{$lgfile}) and ($line =~ /^\[\S+\s+\S+\s+\S+\s+\S+\s+\S+\] \[error\] \[(client|remote) (\S+)\] mod_security: Access denied/)) { my $ip = $2; my $acc = ""; my $domain = ""; if ($line =~ /\] \[hostname "([^\"]+)"\] \[/) {$domain = $1} $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("mod_security triggered by","$ip|$acc|$domain","mod_security")} else {return} } #mod_security v2 (apache) if (($config{LF_MODSEC}) and ($globlogs{MODSEC_LOG}{$lgfile}) and ($line =~ /^\[\S+\s+\S+\s+\S+\s+\S+\s+\S+\] \[(\S*:)?error\] (\[pid \d+(:tid \d+)?\] )?\[(client|remote) (\S+)\]( \[client \S+\])? (\w+: )?ModSecurity:(( \[[^]]+\])*)? Access denied/)) { my $ip = $5; my $acc = ""; my $domain = ""; if ($line =~ /\] \[hostname "([^\"]+)"\] \[/) {$domain = $1} $ip =~ s/^::ffff://; if ($config{LF_APACHE_ERRPORT} == 2 and $ip =~ /(.*):\d+$/) {$ip = $1} my $ruleid = "unknown"; if ($line =~ /\[id "(\d+)"\]/) {$ruleid = $1} if (checkip(\$ip)) {return ("mod_security (id:$ruleid) triggered by","$ip|$acc|$domain","mod_security")} else {return} } #mod_security v2 (nginx) if (($config{LF_MODSEC}) and ($globlogs{MODSEC_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ \[\S+\] \S+ \[(client|remote) (\S+)\] ModSecurity:(( \[[^]]+\])*)? Access denied/)) { my $ip = $2; my $acc = ""; my $domain = ""; if ($line =~ /\] \[hostname "([^\"]+)"\] \[/) {$domain = $1} $ip =~ s/^::ffff://; my $ruleid = "unknown"; if ($line =~ /\[id "(\d+)"\]/) {$ruleid = $1} if (checkip(\$ip)) {return ("mod_security (id:$ruleid) triggered by","$ip|$acc|$domain","mod_security")} else {return} } #BIND if (($config{LF_BIND}) and ($globlogs{BIND_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ named\[\d+\]: client( \S+)? (\S+)\#\d+(\s\(\S+\))?\:( view external\:)? (update|zone transfer|query \(cache\)) \'[^\']*\' denied$/)) { my $ip = $3; my $acc = ""; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("bind triggered by","$ip|$acc","bind")} else {return} } #suhosin if (($config{LF_SUHOSIN}) and ($globlogs{SUHOSIN_LOG}{$lgfile})and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ suhosin\[\d+\]: ALERT - .* \(attacker \'(\S+)\'/)) { my $ip = $2; my $acc = ""; $ip =~ s/^::ffff://; if ($line !~ /script tried to increase memory_limit/) { if (checkip(\$ip)) {return ("Suhosin triggered by","$ip|$acc","suhosin")} else {return} } } #cPanel/WHM if (($config{LF_CPANEL}) and ($globlogs{CPANEL_LOG}{$lgfile}) and ($line =~ /^\[\S+\s+\S+\s+\S+\] \w+ \[\w+] (\S+) - (\S+) \"[^\"]+\" FAILED LOGIN/)) { my $ip = $1; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed cPanel login from","$ip|$acc","cpanel")} else {return} } if (($config{LF_CPANEL}) and ($globlogs{CPANEL_LOG}{$lgfile}) and ($line =~ /^(\S+) - (\S+)? \[\S+ \S+\] \"[^\"]*\" FAILED LOGIN/)) { my $ip = $1; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed cPanel login from","$ip|$acc","cpanel")} else {return} } #webmin if (($config{LF_WEBMIN}) and ($globlogs{WEBMIN_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ webmin\[\d+\]: Invalid login as (\S+) from (\S+)/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed Webmin login from","$ip|$acc","webmin")} else {return} } #DirectAdmin if (($config{LF_DIRECTADMIN}) and ($globlogs{DIRECTADMIN_LOG}{$lgfile}) and ($line =~ /^\S+ \'(\S+)\' \d+ (failed login attempts\. Account|failed login attempt on account) \'(\S+)\'/)) { my $ip = $1; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed DirectAdmin login from","$ip|$acc","directadmin")} else {return} } if (($config{LF_DIRECTADMIN}) and ($globlogs{DIRECTADMIN_LOG_R}{$lgfile}) and ($line =~ /^\[\S+\s+\S+\s+\S+\]: (<\S+> )?IMAP Error: Login failed for (\S+) (against \S+ )?from (\S+)\. AUTHENTICATE PLAIN: Authentication failed\. in \/var\/www\/html\/roundcubemail/)) { my $ip = $4; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed DirectAdmin Roundcube login from","$ip|$acc","directadmin")} else {return} } if (($config{LF_DIRECTADMIN}) and ($globlogs{DIRECTADMIN_LOG_S}{$lgfile}) and ($line =~ /^\S+\s+\S+ \[LOGIN_ERROR\] (\S+)( \(\S+\))? from (\S+): Unknown user or password incorrect\.\s*$/)) { my $ip = $3; my $acc = $1; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed DirectAdmin SquirrelMail login from","$ip|$acc","directadmin")} else {return} } #Jun 12 10:58:00 phpmyadmin: user denied: bill (mysql-denied) from 192.168.254.10 if (($config{LF_DIRECTADMIN}) and ($globlogs{DIRECTADMIN_LOG_P}{$lgfile}) and ($line =~ /^\S+\s+\S+\s+\S+: pma auth user='(\S+)' status='mysql-denied' ip='(\S+)'\s*$/)) { my $ip = $2; my $acc = $1; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed DirectAdmin phpMyAdmin login from","$ip|$acc","directadmin")} else {return} } if (($config{LF_DIRECTADMIN}) and ($globlogs{DIRECTADMIN_LOG_P}{$lgfile}) and ($line =~ /^\S+\s+\S+\s+\S+ phpmyadmin: user denied: (\S+) \(mysql-denied\) from (\S+)\s*$/)) { my $ip = $2; my $acc = $1; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed DirectAdmin phpMyAdmin login from","$ip|$acc","directadmin")} else {return} } #Exim SMTP AUTH if (($config{LF_SMTPAUTH}) and ($globlogs{SMTPAUTH_LOG}{$lgfile}) and ($line =~ /^\S+\s+\S+\s+(\[\d+\] )?(\S+) authenticator failed for \S+ (\S+ )?\[(\S+)\](:\S*:?)?( I=\S+| \d+\:)? 535 Incorrect authentication data( \(set_id=(\S+)\))?/)) { my $ip = $4; my $acc = $8; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SMTP AUTH login from","$ip|$acc","smtpauth")} else {return} } #Exim Syntax Errors if (($config{LF_EXIMSYNTAX}) and ($globlogs{SMTPAUTH_LOG}{$lgfile}) and ($line =~ /^\S+\s+\S+\s+(\[\d+\] )?SMTP call from (\S+ )?\[(\S+)\](:\S*:?)?( I=\S+)? dropped: too many syntax or protocol errors/)) { my $ip = $3; my $acc = ""; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Exim syntax errors from","$ip|$acc","eximsyntax")} else {return} } if (($config{LF_EXIMSYNTAX}) and ($globlogs{SMTPAUTH_LOG}{$lgfile}) and ($line =~ /^\S+\s+\S+\s+(\[\d+\] )?SMTP protocol error in \"[^\"]+\" H=\S+ (\S+ )?\[(\S+)\](:\S*:?)?( I=\S+)? AUTH command used when not advertised/)) { my $ip = $3; my $acc = ""; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Exim syntax errors from","$ip|$acc","eximsyntax")} else {return} } #mod_qos if (($config{LF_QOS}) and ($globlogs{HTACCESS_LOG}{$lgfile}) and ($line =~ /^\[\S+\s+\S+\s+\S+\s+\S+\s+\S+\] \[(\S*:)?error\] (\[pid \d+(:tid \d+)?\] )?\[(client|remote) (\S+)\] (\w+: )?mod_qos\(\d+\): access denied,/)) { my $ip = $5; my $acc = ""; $ip =~ s/^::ffff://; if ($config{LF_APACHE_ERRPORT} == 2 and $ip =~ /(.*):\d+$/) {$ip = $1} if (checkip(\$ip)) {return ("mod_qos triggered by","$ip|$acc","mod_qos")} else {return} } #Apache symlink race condition if (($config{LF_SYMLINK}) and ($globlogs{MODSEC_LOG}{$lgfile}) and ($line =~ /^\[\S+\s+\S+\s+\S+\s+\S+\s+\S+\] \[(\S*:)?error\] (\[pid \d+(:tid \d+)?\] )?\[(client|remote) (\S+)\] (\w+: )?Caught race condition abuser/)) { my $ip = $5; my $acc = ""; $ip =~ s/^::ffff://; if ($config{LF_APACHE_ERRPORT} == 2 and $ip =~ /(.*):\d+$/) {$ip = $1} if ($line !~ /\/cgi-sys\/suspendedpage\.cgi$/) { if (checkip(\$ip)) {return ("symlink race condition triggered by","$ip|$acc","symlink")} else {return} } } #courier-imap (Plesk) if (($config{LF_POP3D}) and ($globlogs{POP3D_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ (courier-)?pop3(?:d|s)(-ssl)?(\[\d+\])?: LOGIN FAILED, user=(\S*), ip=\[(\S+)\]\s*$/)) { my $ip = $6; my $acc = $5; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed POP3 login from","$ip|$acc","pop3d")} else {return} } if (($config{LF_IMAPD}) and ($globlogs{IMAPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ (courier-)?imap(?:d|s)(-ssl)?(\[\d+\])?: LOGIN FAILED, user=(\S*), ip=\[(\S+)\]\s*$/)) { my $ip = $6; my $acc = $5; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed IMAP login from","$ip|$acc","imapd")} else {return} } #Qmail SMTP AUTH (Plesk) if (($config{LF_SMTPAUTH}) and ($globlogs{SMTPAUTH_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ smtp_auth(?:\[\d+\])?: FAILED: (\S*) - password incorrect from \S+ \[(\S+)\]\s*$/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SMTP AUTH login from","$ip|$acc","smtpauth")} else {return} } #Postfix SMTP AUTH (Plesk) if (($config{LF_SMTPAUTH}) and ($globlogs{SMTPAUTH_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ postfix\/(submission\/)?smtpd(?:\[\d+\])?: warning: \S+\[(\S+)\]: SASL (?:(?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed/)) { my $ip = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SMTP AUTH login from","$ip","smtpauth")} else {return} } #InterWorx (dovecot, proftpd, qmail) if (($config{LF_POP3D}) and ($globlogs{POP3D_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) pop3-login(\[\d+\])?: Info: (Aborted login|Disconnected|Disconnected: Inactivity)( \(auth failed, \d+ attempts( in \d+ secs)?\))?: (user=(<\S*>)?, )?(method=\S+, )?rip=(\S+), lip=/)) { my $ip = $9; my $acc = $7; $ip =~ s/^::ffff://; $acc =~ s/^<|>$//g; if (checkip(\$ip)) {return ("Failed POP3 login from","$ip|$acc","pop3d")} else {return} } if (($config{LF_IMAPD}) and ($globlogs{IMAPD_LOG}{$lgfile}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) imap-login(\[\d+\])?: Info: (Aborted login|Disconnected|Disconnected: Inactivity)( \(auth failed, \d+ attempts( in \d+ secs)?\))?: (user=(<\S*>)?, )?(method=\S+, )?rip=(\S+), lip=/)) { my $ip = $9; my $acc = $7; $ip =~ s/^::ffff://; $acc =~ s/^<|>$//g; if (checkip(\$ip)) {return ("Failed IMAP login from","$ip|$acc","imapd")} else {return} } if (($config{LF_FTPD}) and ($globlogs{FTPD_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ \S+ proftpd\[\d+\]:? \S+ \(\S+?[^\[]+\[(\S+)\]\)( -)?:? USER (\S*): no such user found from/)) { my $ip = $1; my $acc = $3; $ip =~ s/^::ffff://; $acc =~ s/:$//g; if (checkip(\$ip)) {return ("Failed FTP login from","$ip|$acc","ftpd")} else {return} } if (($config{LF_FTPD}) and ($globlogs{FTPD_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ \S+ proftpd\[\d+\]:? \S+ \(\S+?[^\[]+\[(\S+)\]\)( -)?:? USER (\S*) \(Login failed\): Incorrect password/)) { my $ip = $1; my $acc = $3; $ip =~ s/^::ffff://; $acc =~ s/:$//g; if (checkip(\$ip)) {return ("Failed FTP login from","$ip|$acc","ftpd")} else {return} } if (($config{LF_SMTPAUTH}) and ($globlogs{SMTPAUTH_LOG}{$lgfile}) and ($line =~ /^\S+ qmail-smtpd\[\d+\]: AUTH failed \[(\S+)\] (\S+)/)) { my $ip = $1; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed SMTP AUTH login from","$ip|$acc","smtpauth")} else {return} } if (($config{LF_INTERWORX}) and ($globlogs{INTERWORX_LOG}{$lgfile}) and ($line =~ /^\S+ \S+ (\S+) (\S+) (\S+)/)) { my $iw = "SiteWorx"; if ($1 eq "NW") {$iw = "NodeWorx"} my $ip = $2; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed $iw login from","$ip|$acc","interworx")} else {return} } # CWP if (($config{LF_CWP}) and ($globlogs{CWP_LOG}{$lgfile}) and ($line =~ /^\S+\s+\S+\s+(\S+)\s+Failed Login from:\s+(\S+) on:/)) { my $ip = $2; my $acc = $1; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed CWP login from","$ip|$acc","cwp")} else {return} } # VestaCP if (($config{LF_VESTA}) and ($globlogs{VESTA_LOG}{$lgfile}) and ($line =~ /^\S+\s+\S+\s+(\S+)\s+(\S+) failed to login/)) { my $ip = $2; my $acc = $1; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("Failed VestaCP login from","$ip|$acc","vesta")} else {return} } } # end processline ############################################################################### # start processloginline sub processloginline { my $line = shift; #courier-imap if (($config{LT_POP3D}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ pop3d(-ssl)?: LOGIN, user=(\S*), ip=\[(\S+)\], port=\S+/)) { my $ip = $4; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("pop3d",$acc,$ip)} else {return} } if (($config{LT_IMAPD}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ imapd(-ssl)?: LOGIN, user=(\S*), ip=\[(\S+)\], port=\S+/)) { my $ip = $4; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("imapd",$acc,$ip)} else {return} } #dovecot if (($config{LT_POP3D}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ dovecot(\[\d+\])?: pop3-login: Login: user=<(\S*)>, method=\S+, rip=(\S+), lip=/)) { my $ip = $4; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("pop3d",$acc,$ip)} else {return} } if (($config{LT_IMAPD}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ dovecot(\[\d+\])?: imap-login: Login: user=<(\S*)>, method=\S+, rip=(\S+), lip=/)) { my $ip = $4; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("imapd",$acc,$ip)} else {return} } #InterWorx (dovecot) if (($config{LT_POP3D}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) pop3-login: Info: Login: user=<(\S*)>, method=\S+, rip=(\S+), lip=/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("pop3d",$acc,$ip)} else {return} } if (($config{LT_IMAPD}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) imap-login: Info: Login: user=<(\S*)>, method=\S+, rip=(\S+), lip=/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ("imapd",$acc,$ip)} else {return} } } # end processloginline ############################################################################### # start processsshline sub processsshline { my $line = shift; if (($config{LF_SSH_EMAIL_ALERT}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sshd\[\d+\]: Accepted (\S+) for (\S+) from (\S+) port \S+/)) { my $ip = $5; my $acc = $4; my $how = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ($acc,$ip,$how)} else {return} } } # end processsshline ############################################################################### # start processsuline sub processsuline { my $line = shift; #RH + Debian/Ubuntu if (($config{LF_SU_EMAIL_ALERT}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?su(\[\d+\])?: pam_unix\(su(-l)?:session\): session opened for user\s+(\S+)\s+by\s+(\S+)\s*$/)) { return ($5,$6,"Successful login"); } if (($config{LF_SU_EMAIL_ALERT}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?su(\[\d+\])?: pam_unix\(su(-l)?:auth\): authentication failure; logname=\S*\s+\S+\s+\S+\s+\S+\s+ruser=(\S+)+\s+\S+\s+user=(\S+)\s*$/)) { return ($6,$5,"Failed login"); } if (($config{LF_SU_EMAIL_ALERT}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?su(\[\d+\])?: pam_unix\(su(-l)?:session\): session opened for user\s+(\S+)\s+by\s+(\S+)\s*$/)) { return ($5,$6,"Successful login"); } if (($config{LF_SU_EMAIL_ALERT}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?su(\[\d+\])?: pam_unix\(su(-l)?:auth\): authentication failure; logname=\S*\s+\S+\s+\S+\s+\S+\s+ruser=(\S+)+\s+\S+\s+user=(\S+)\s*$/)) { return ($6,$5,"Failed login"); } if (($config{LF_SU_EMAIL_ALERT}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?su\(pam_unix\)\[\d+\]: session opened for user\s+(\S+)\s+by\s+(\S+)\s*$/)) { return ($3,$4,"Successful login"); } if (($config{LF_SU_EMAIL_ALERT}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?su\(pam_unix\)\[\d+\]: authentication failure; logname=\S*\s+\S+\s+\S+\s+\S+\s+ruser=(\S+)+\s+\S+\s+user=(\S+)\s*$/)) { return ($4,$3,"Failed login"); } return; } # end processsuline ############################################################################### # start processsudoline sub processsudoline { my $line = shift; if (($config{LF_SUDO_EMAIL_ALERT}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sudo(\[\d+\])?: pam_unix\(sudo(-l)?:auth\): authentication failure; logname=\S*\s+\S+\s+\S+\s+\S+\s+ruser=(\S+)+\s+\S+\s+user=(\S+)\s*$/)) { return ($6,$5,"Failed login"); } if (($config{LF_SUDO_EMAIL_ALERT}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sudo\(pam_unix\)\[\d+\]: authentication failure; logname=\S*\s+\S+\s+\S+\s+\S+\s+ruser=(\S+)+\s+\S+\s+user=(\S+)\s*$/)) { return ($4,$3,"Failed login"); } if (($config{LF_SUDO_EMAIL_ALERT}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) (\S+ )?sudo(\[\d+\])?:\s+(\S+)\s+:\s+(.*)$/)) { my $from = $4; my @items = split(/\s+;\s+/, $5); if ($items[0] =~ /^TTY/) { if ($items[2] =~ /^USER=(\S+)$/) { return ($1,$from,"Successful login"); } } elsif ($items[0] =~ /^user NOT in sudoers/) { if ($items[3] =~ /^USER=(\w+)$/) { return ($1,$from,"Failed login"); } } } return; } # end processsudoline ############################################################################### # start processconsoleline sub processconsoleline { my $line = shift; if (($config{LF_CONSOLE_EMAIL_ALERT}) and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ login(\[\d+\])?: ROOT LOGIN/)) { return 1; } } # end processconsoleline ############################################################################### # start processcpanelline sub processcpanelline { my $line = shift; if ($config{LF_CPANEL_ALERT} and ($line =~ /^(\S+)\s+\-\s+(\w+)\s+\[[^\]]+\]\s\"[^\"]+\"\s200\s/)) { my $ip = $1; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ($ip,$acc)} else {return} } } # end processcpanelline ############################################################################### # start processwebminline sub processwebminline { my $line = shift; if ($config{LF_WEBMIN_EMAIL_ALERT} and ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ webmin\[\d+\]: Successful login as (\S+) from (\S+)/)) { my $ip = $3; my $acc = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ($acc,$ip)} else {return} } } # end processwebminline ############################################################################### # start scriptlinecheck sub scriptlinecheck { my $line = shift; if ($config{LF_SCRIPT_ALERT}) { my $fulldir; if ($line =~ /^\S+\s+\S+\s+(\[\d+\]\s)?cwd=(.*) \d+ args:/) {$fulldir = $2} elsif ($line =~ /^\S+\s+\S+\s+(\[\d+\]\s)?\S+ H=localhost (.*)PWD=(.*) REMOTE_ADDR=\S+$/) {$fulldir = $3} if ($fulldir ne "") { my (undef,$dir,undef) = split(/\//,$fulldir); if ($dir eq "home") {return $fulldir} if ($cpconfig{HOMEDIR} and ($fulldir =~ /^$cpconfig{HOMEDIR}/)) {return $fulldir} if ($cpconfig{HOMEMATCH} and ($dir =~ /$cpconfig{HOMEMATCH}/)) {return $fulldir} } } } # end scriptlinecheck ############################################################################### # start relaycheck sub relaycheck { my $line = shift; my $tline = $line; $tline =~ s/".*"/""/g; my @bits =split(/\s+/,$tline); my $ip; if ($tline !~ /^\S+\s+\S+\s+(\[\d+\]\s)?\S+ <=/) {return} #exim if ($tline =~ / U=(\S+) P=local /) { return ($1, "LOCALRELAY"); } if ($tline =~ / H=[^=]*\[(\S+)\]/) { $ip = $1; unless (checkip(\$ip) or $ip eq "127.0.0.1" or $ip eq "::1") {return} } else { return; } if (($tline =~ / A=(courier_plain|courier_login|dovecot_plain|dovecot_login|fixed_login|fixed_plain|login|plain):/) and ($tline =~ / P=(esmtpa|esmtpsa) /)) { return ($ip, "AUTHRELAY"); } if ($tline =~ / P=(smtp|esmtp|esmtps) /) { return ($ip, "RELAY"); } } # end relaycheck ############################################################################### # start pslinecheck sub pslinecheck { my $line = shift; if ($line !~ /^(\S+|\S+\s+\d+\s+\S+) \S+ kernel:\s(\[[^\]]+\]\s)?Firewall:/) {return} if ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ kernel:\s(\[[^\]]+\]\s)?Firewall: \*INVALID\*/ and $config{PS_PORTS} !~ /INVALID/) {return} if ($line =~ /IN=\S+.*SRC=(\S+).*DST=(\S+).*PROTO=(\w+).*DPT=(\d+)/) { my $ip = $1; my $dst = $2; my $proto = $3; my $port = $4; $ip =~ s/^::ffff://; if ($config{PS_PORTS} !~ /BRD/ and $proto eq "UDP" and $brd{$dst} and !$ips{$dst}) {return} if ($config{PS_PORTS} !~ /OPEN/) { my $hit = 0; if ($proto eq "TCP" and $line =~ /kernel:\s(\[[^\]]+\]\s)?Firewall: \*TCP_IN Blocked\*/) { foreach my $ports (split(/\,/,$config{TCP_IN})) { if ($ports =~ /\:/) { my ($start,$end) = split(/\:/,$ports); if ($port >= $start and $port <= $end) {$hit = 1} } elsif ($port == $ports) {$hit = 1} if ($hit) {last} } if ($hit) { if ($config{DEBUG} >= 1) {ConfigServer::Logger::logfile("debug: *Port Scan* ignored TCP_IN port: $ip:$port")} return; } } elsif ($proto eq "UDP" and $line =~ /kernel:\s(\[[^\]]+\]\s)?Firewall: \*UDP_IN Blocked\*/) { foreach my $ports (split(/\,/,$config{UDP_IN})) { if ($ports =~ /\:/) { my ($start,$end) = split(/\:/,$ports); if ($port >= $start and $port <= $end) {$hit = 1} } elsif ($port == $ports) {$hit = 1} if ($hit) {last} } if ($hit) { if ($config{DEBUG} >= 1) {ConfigServer::Logger::logfile("debug: *Port Scan* ignored UDP_IN port: $ip:$port")} return; } } } if (checkip(\$ip)) {return ($ip,$port)} else {return} } if ($line =~ /IN=\S+.*SRC=(\S+).*PROTO=(ICMP)/) { my $ip = $1; my $port = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ($ip,$port)} else {return} } if ($line =~ /IN=\S+.*SRC=(\S+).*PROTO=(ICMPv6)/) { my $ip = $1; my $port = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ($ip,$port)} else {return} } } # end pslinecheck ############################################################################### # start uidlinecheck sub uidlinecheck { my $line = shift; if ($line !~ /^(\S+|\S+\s+\d+\s+\S+) \S+ kernel(\[\d+\])?:\s(\[[^\]]+\]\s)?Firewall:/) {return} if ($line =~ /OUT=\S+.*DPT=(\S+).*UID=(\d+)/) {return ($1,$2)} } # end uidlinecheck ############################################################################### # start portknockingcheck sub portknockingcheck { my $line = shift; if ($line !~ /^(\S+|\S+\s+\d+\s+\S+) \S+ kernel(\[\d+\])?:\s(\[[^\]]+\]\s)?Knock: \*\d+_IN\*/) {return} if ($line =~ /SRC=(\S+).*DPT=(\d+)/) { my $ip = $1; my $port = $2; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ($ip,$port)} else {return} } } # end portknockingcheck ############################################################################### # start processdistftpline sub processdistftpline { my $line = shift; #pure-ftpd if ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ pure-ftpd(\[\d+\])?: \(\?\@(\S+)\) \[INFO\] (\S*) is now logged in$/) { my $ip = $3; my $acc = $4; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ($ip,$acc)} else {return} } #proftpd if ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ proftpd\[\d+\]: \S+ \([^\[]+\[(\S+)\]\) - USER (\S*): Login successful\.\s*$/) { my $ip = $2; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ($ip,$acc)} else {return} } #InterWorx proftpd if ($line =~ /^\S+ \S+ \S+ proftpd\[\d+\]:? \S+ \(\S+?[^\[]+\[(\S+)\]\)( -)?:? USER (\S*): Login successful/) { my $ip = $1; my $acc = $3; $ip =~ s/^::ffff://; if (checkip(\$ip)) {return ($ip,$acc)} else {return} } } # end processdistftpline ############################################################################### # start processdistsmtpline sub processdistsmtpline { my $line = shift; my $tline = $line; $tline =~ s/".*"/""/g; my @bits =split(/\s+/,$tline); my $ip; #postfix if ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ postfix\/(submission\/)?smtpd(?:\[\d+\])?: \w+: client=\S+\[(\S+)\], sasl_method=(?:(?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5), sasl_username=(\S+)$/) { $ip = $3; my $account = $4; $ip =~ s/^::ffff://; if (checkip(\$ip) and $ip ne "127.0.0.1" and $ip ne "::1") {return ($ip,$account)} else {return} } #InterWorx qmail if ($line =~ /^\S+ qmail-smtpd\[\d+\]: AUTH successful \[(\S+)\] (\S+)/) { $ip = $1; my $account = $2; $ip =~ s/^::ffff://; if (checkip(\$ip) and $ip ne "127.0.0.1" and $ip ne "::1") {return ($ip,$account)} else {return} } #exim if ($tline !~ /^\S+\s+\S+\s+(\[\d+\]\s)?\S+ <=/) {return} if ($tline =~ / U=(\S+) P=local /) {return} if ($tline =~ / H=[^=]*\[(\S+)\]/) { $ip = $1; unless (checkip(\$ip) or $ip eq "127.0.0.1" or $ip eq "::1") {return} } else { return; } if (($tline =~ / A=(courier_plain|courier_login|dovecot_plain|dovecot_login|fixed_login|fixed_plain|login|plain):(\S+)/)){ my $account = $2; if (($tline =~ / P=(esmtpa|esmtpsa) /)) {return ($ip, $account)} } } # end processdistsmtpline ############################################################################### # start loginline404 sub loginline404 { my $line = shift; if ($line =~ /^\[\S+\s+\S+\s+\S+\s+\S+\s+\S+\] \[(\S*:)?(error|info)\] (\[pid \d+(:tid \d+)?\] )?\[(client|remote) (\S+)\] (\w+: )?File does not exist\:/) { my $ip = $6; $ip =~ s/^::ffff://; if ($config{LF_APACHE_ERRPORT} == 2 and $ip =~ /(.*):\d+$/) {$ip = $1} if (checkip(\$ip)) {return ($ip)} else {return} } } # end loginline404 ############################################################################### # start loginline403 sub loginline403 { my $line = shift; if ($line =~ /^\[\S+\s+\S+\s+\S+\s+\S+\s+\S+\] \[(\S*:)?error\] (\[pid \d+(:tid \d+)?\] )?\[(client|remote) (\S+)\] (\w+: )?client denied by server configuration\:/) { my $ip = $5; $ip =~ s/^::ffff://; if ($config{LF_APACHE_ERRPORT} == 2 and $ip =~ /(.*):\d+$/) {$ip = $1} if (checkip(\$ip)) {return ($ip)} else {return} } } # end loginline403 ############################################################################### # start loginline401 sub loginline401 { my $line = shift; if ($line =~ /^\[\S+\s+\S+\s+\S+\s+\S+\s+\S+\] \[(\S*:)?error\] (\[pid \d+(:tid \d+)?\] )?\[(client|remote) (\S+)\] (\w+: )?(user not found|user \w+ not found|user \w+: authentication failure for "\/\w+\/")\:/) { my $ip = $5; $ip =~ s/^::ffff://; if ($config{LF_APACHE_ERRPORT} == 2 and $ip =~ /(.*):\d+$/) {$ip = $1} if (checkip(\$ip)) {return ($ip)} else {return} } } # end loginline401 ############################################################################### # start statscheck sub statscheck { my $line = shift; if ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ kernel:\s(\[[^\]]+\]\s)?(Firewall|Knock):/) {return 1} } # end statscheck ############################################################################### # start syslogcheckline sub syslogcheckline { my $line = shift; my $syslogcheckcode = shift; if ($line =~ /^(\S+|\S+\s+\d+\s+\S+) \S+ lfd\[\d+\]: SYSLOG check \[(\S+)\]\s*$/) { if ($2 eq $syslogcheckcode) {return 1} else {return} } } # end syslogcheckline ############################################################################### 1; DisplayResellerUI.pm000064400000024245151030020750010443 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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 "\n"; print "
"; print "[$FORM{ip}] is not a valid IP address\n"; print "
\n"; print "

\n"; } else { if ($FORM{action} eq "qallow" and $rprivs{$ENV{REMOTE_USER}}{ALLOW}) { if ($FORM{comment} eq "") { print "\n"; print "
You must provide a Comment for this option
\n"; } else { $FORM{comment} =~ s/"//g; print "\n"; print "
"; print "

Allowing $FORM{ip}...

\n

\n";
				my $text = &printcmd("/usr/sbin/csf","-a",$FORM{ip},"ALLOW by Reseller $ENV{REMOTE_USER} ($FORM{comment})");
				print "

\n

...Done.

\n"; print "
\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 "

\n"; } elsif ($FORM{action} eq "qdeny" and $rprivs{$ENV{REMOTE_USER}}{DENY}) { if ($FORM{comment} eq "") { print "\n"; print "
You must provide a Comment for this option
\n"; } else { $FORM{comment} =~ s/"//g; print "\n"; print "
"; print "

Blocking $FORM{ip}...

\n

\n";
				my $text = &printcmd("/usr/sbin/csf","-d",$FORM{ip},"DENY by Reseller $ENV{REMOTE_USER} ($FORM{comment})");
				print "

\n

...Done.

\n"; print "
\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 "

\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 "\n"; print "
"; print "

Unblock $FORM{ip}, trying permanent blocks...

\n

\n";
			my $text1 = &printcmd("/usr/sbin/csf","-dr",$FORM{ip});
			print "

\n

...Done.

\n"; print "

Unblock $FORM{ip}, trying temporary blocks...

\n

\n";
			my $text2 = &printcmd("/usr/sbin/csf","-tr",$FORM{ip});
			print "

\n

...Done.

\n"; print "
\n"; print "

\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 "\n"; print "
"; print "

Searching for $FORM{ip}...

\n

\n";
			&printcmd("/usr/sbin/csf","-g",$FORM{ip});
			print "

\n

...Done.

\n"; print "
\n"; print "

\n"; } else { print "\n"; print ""; if ($rprivs{$ENV{REMOTE_USER}}{ALLOW}) {print "\n"} if ($rprivs{$ENV{REMOTE_USER}}{DENY}) {print "\n"} if ($rprivs{$ENV{REMOTE_USER}}{UNBLOCK}) {print "\n"} if ($rprivs{$ENV{REMOTE_USER}}{GREP}) {print "\n"} print "
csf - ConfigServer Firewall options for $ENV{REMOTE_USER}
Allow IP address through the firewall and add to the allow file (csf.allow).
Comment for Allow: (required)
Block IP address in the firewall and add to the deny file (csf.deny).
Comment for Block: (required)
Remove IP address from the firewall (temp and perm blocks)
Search iptables for IP address

\n"; } } print "
\n"; print "
csf: v$myv
"; print "

©2006-2023, ConfigServer Services (Way to the Web Limited)

\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; CloudFlare.pm000064400000036235151030020750007124 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### # 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; GetIPs.pm000064400000004277151030020750006240 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;DisplayUI.pm000064400000424115151030020750006745 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen) package ConfigServer::DisplayUI; use strict; use lib '/usr/local/csf/lib'; use Fcntl qw(:DEFAULT :flock); use File::Basename; use File::Copy; use Net::CIDR::Lite; use IPC::Open3; use ConfigServer::Config; use ConfigServer::CheckIP qw(checkip); use ConfigServer::Ports; use ConfigServer::URLGet; use ConfigServer::Sanity qw(sanity);; use ConfigServer::ServerCheck; use ConfigServer::ServerStats; use ConfigServer::Service; use ConfigServer::RBLCheck; use ConfigServer::GetEthDev; use ConfigServer::Slurp qw(slurp); 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, $urlget, %FORM, $script, $script_da, $images, $myv); my $slurpreg = ConfigServer::Slurp->slurpreg; my $cleanreg = ConfigServer::Slurp->cleanreg; # ############################################################################### # start main sub main { my $form_ref = shift; %FORM = %{$form_ref}; $script = shift; $script_da = shift; $images = shift; $myv = shift; $config{THIS_UI} = shift; $| = 1; $ipscidr6 = Net::CIDR::Lite->new; my $thisui = $config{THIS_UI}; my $config = ConfigServer::Config->loadconfig(); %config = $config->config; $config{THIS_UI} = $thisui; $ipv4reg = $config->ipv4reg; $ipv6reg = $config->ipv6reg; if ($config{CF_ENABLE}) { require ConfigServer::CloudFlare; import ConfigServer::CloudFlare; } $mobile = 0; if ($FORM{mobi}) {$mobile = 1} $chart = 1; if ($config{ST_ENABLE}) { if (!defined ConfigServer::ServerStats::init()) {$chart = 0} } $urlget = ConfigServer::URLGet->new($config{URLGET}, "csf/$myv", $config{URLPROXY}); unless (defined $urlget) { $config{URLGET} = 1; $urlget = ConfigServer::URLGet->new($config{URLGET}, "csf/$myv", $config{URLPROXY}); print "

*WARNING* URLGET set to use LWP but perl module is not installed, reverting to HTTP::Tiny

\n"; } if ($config{RESTRICT_UI} == 2) { print "\n"; print "\n"; print "
csf UI Disabled via the RESTRICT_UI option in /etc/csf/csf.conf
\n"; exit; } if ($FORM{ip} ne "") {$FORM{ip} =~ s/(^\s+)|(\s+$)//g} if (($FORM{ip} ne "") and ($FORM{ip} ne "all") and (!checkip(\$FORM{ip}))) { print "[$FORM{ip}] is not a valid IP/CIDR"; } elsif (($FORM{ignorefile} ne "") and ($FORM{ignorefile} =~ /[^\w\.]/)) { print "[$FORM{ignorefile}] is not a valid file"; } elsif (($FORM{template} ne "") and ($FORM{template} =~ /[^\w\.]/)) { print "[$FORM{template}] is not a valid file"; } elsif ($FORM{action} eq "manualcheck") { print "

Checking version...

\n\n"; my ($upgrade, $actv) = &manualversion($myv); if ($upgrade) { print "
A new version of csf (v$actv) is available. Upgrading will retain your settings. View ChangeLog
\n"; } else { if ($actv ne "") { print "
$actv
\n"; } else { print "
You are running the latest version of csf (v$myv). An Upgrade button will appear here if a new version becomes available
\n"; } } print "
\n"; &printreturn; } elsif ($FORM{action} eq "lfdstatus") { print "

Show lfd status...

\n
\n";
		ConfigServer::Service::statuslfd();
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "ms_list") { &modsec; } elsif ($FORM{action} eq "chart") { &chart; } elsif ($FORM{action} eq "systemstats") { &systemstats($FORM{graph}); } elsif ($FORM{action} eq "lfdstart") { print "

Starting lfd...

\n
\n";
		ConfigServer::Service::startlfd();
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "lfdrestart") { if ($config{THIS_UI}) { print "

Signal lfd to restart...

\n
\n";
			sysopen (my $OUT, "/var/lib/csf/lfd.restart",, O_WRONLY | O_CREAT) or die "Unable to open file: $!";
			close ($OUT);
		} else {
			print "

Restarting lfd...

\n
\n";
			ConfigServer::Service::restartlfd();
		}
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "lfdstop") { print "

Stopping lfd...

\n
\n";
		ConfigServer::Service::stoplfd();
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "status") { &resize("top"); print "
\n";
		&printcmd("/usr/sbin/csf","-l");
		if ($config{IPV6}) {
			print "\n\nip6tables:\n\n";
			&printcmd("/usr/sbin/csf","-l6");
		}
		print "
\n"; &resize("bot",1); &printreturn; } elsif ($FORM{action} eq "start") { print "

Starting csf...

\n"; &resize("top"); print "
\n";
		&printcmd("/usr/sbin/csf","-sf");
		print "
\n

...Done.

\n"; &resize("bot",1); &printreturn; } elsif ($FORM{action} eq "restart") { print "

Restarting csf...

\n"; &resize("top"); print "
\n";
		&printcmd("/usr/sbin/csf","-sf");
		print "
\n

...Done.

\n"; &resize("bot",1); &printreturn; } elsif ($FORM{action} eq "restartq") { print "

Restarting csf via lfd...

\n
\n";
		&printcmd("/usr/sbin/csf","-q");
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "temp") { print "\n"; print "\n"; my @deny; if (! -z "/var/lib/csf/csf.tempban") { open (my $IN, "<", "/var/lib/csf/csf.tempban") or die $!; flock ($IN, LOCK_SH); @deny = <$IN>; chomp @deny; close ($IN); } foreach my $line (reverse @deny) { if ($line eq "") {next} my ($time,$ip,$port,$inout,$timeout,$message) = split(/\|/,$line); $time = $timeout - (time - $time); if ($port eq "") {$port = "*"} if ($inout eq "") {$inout = " *"} if ($time < 1) { $time = "<1"; } else { my $days = int($time/(24*60*60)); my $hours = ($time/(60*60))%24; my $mins = ($time/60)%60; my $secs = $time%60; $days = $days < 1 ? '' : $days .'d '; $hours = $hours < 1 ? '' : $hours .'h '; $mins = $mins < 1 ? '' : $mins . 'm '; $time = $days . $hours . $mins . $secs . 's'; } print "\n"; print "\n"; } my @allow; if (! -z "/var/lib/csf/csf.tempallow") { open (my $IN, "<", "/var/lib/csf/csf.tempallow") or die $!; flock ($IN, LOCK_SH); @allow = <$IN>; chomp @allow; close ($IN); } foreach my $line (@allow) { if ($line eq "") {next} my ($time,$ip,$port,$inout,$timeout,$message) = split(/\|/,$line); $time = $timeout - (time - $time); if ($port eq "") {$port = "*"} if ($inout eq "") {$inout = " *"} if ($time < 1) { $time = "<1"; } else { my $days = int($time/(24*60*60)); my $hours = ($time/(60*60))%24; my $mins = ($time/60)%60; my $secs = $time%60; $days = $days < 1 ? '' : $days .'d '; $hours = $hours < 1 ? '' : $hours .'h '; $mins = $mins < 1 ? '' : $mins . 'm '; $time = $days . $hours . $mins . $secs . 's'; } print "\n"; } print "
 A/DIP addressPortDirTime To LiveComment
\n"; print "DENY$ip$port$inout$time$message
\n"; print "ALLOW$ip$port$inout$time$message
\n"; if (@deny or @allow) { print "\n"; } else { print "
There are no temporary IP entries
\n"; } &printreturn; } elsif ($FORM{action} eq "temprm") { print "

Removing all temporary entries:

\n
\n";
		if ($FORM{ip} eq "all") {
			&printcmd("/usr/sbin/csf","-tf");
		}
		print "
\n

...Done.

\n"; print "
\n"; } elsif ($FORM{action} eq "temprmd") { print "

Removing temporary deny entry for $FORM{ip}:

\n
\n";
		&printcmd("/usr/sbin/csf","-trd",$FORM{ip});
		print "
\n

...Done.

\n"; print "
\n"; } elsif ($FORM{action} eq "temprma") { print "

Removing temporary allow entry for $FORM{ip}:

\n
\n";
		&printcmd("/usr/sbin/csf","-tra",$FORM{ip});
		print "
\n

...Done.

\n"; print "
\n"; } elsif ($FORM{action} eq "temptoperm") { print "

Permanent ban for $FORM{ip}:

\n
\n";
		&printcmd("/usr/sbin/csf","-tr",$FORM{ip});
		&printcmd("/usr/sbin/csf","-d",$FORM{ip});
		print "
\n

...Done.

\n"; print "
\n"; } elsif ($FORM{action} eq "tempdeny") { $FORM{timeout} =~ s/\D//g; if ($FORM{dur} eq "minutes") {$FORM{timeout} = $FORM{timeout} * 60} if ($FORM{dur} eq "hours") {$FORM{timeout} = $FORM{timeout} * 60 * 60} if ($FORM{dur} eq "days") {$FORM{timeout} = $FORM{timeout} * 60 * 60 * 24} if ($FORM{ports} eq "") {$FORM{ports} = "*"} print "

Temporarily $FORM{do}ing $FORM{ip} for $FORM{timeout} seconds:

\n
\n";
		if ($FORM{do} eq "block") {
			&printcmd("/usr/sbin/csf","-td",$FORM{ip},$FORM{timeout},"-p",$FORM{ports},$FORM{comment});
		} else {
			&printcmd("/usr/sbin/csf","-ta",$FORM{ip},$FORM{timeout},"-p",$FORM{ports},$FORM{comment});
		}
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "stop") { print "

Stopping csf...

\n"; &resize("top"); print "
\n";
		&printcmd("/usr/sbin/csf","-f");
		print "
\n

...Done.

\n"; &resize("bot",1); &printreturn; } elsif ($FORM{action} eq "disable") { print "

Disabling csf...

\n"; &resize("top"); print "
\n";
		&printcmd("/usr/sbin/csf","-x");
		print "
\n

...Done.

\n"; &resize("bot",1); &printreturn; } elsif ($FORM{action} eq "enable") { if ($config{THIS_UI}) { print "

You must login to the root shell to enable csf using:\n

csf -e

\n"; } else { print "

Enabling csf...

\n"; &resize("top"); print "
\n";
			&printcmd("/usr/sbin/csf","-e");
			print "
"; &resize("bot",1); } print "

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "logtail") { $FORM{lines} =~ s/\D//g; if ($FORM{lines} eq "" or $FORM{lines} == 0) {$FORM{lines} = 30} my $script_safe = $script; my $CSFfrombot = 120; my $CSFfromright = 10; if ($config{DIRECTADMIN}) { $script = $script_da; $CSFfrombot = 400; $CSFfromright = 150; } my @data = slurp("/etc/csf/csf.syslogs"); foreach my $line (@data) { if ($line =~ /^Include\s*(.*)$/) { my @incfile = slurp($1); push @data,@incfile; } } @data = sort @data; my $options = "  
Refresh in 0
   
EOF if ($config{DIRECTADMIN}) {$script = $script_safe} &printreturn; } elsif ($FORM{action} eq "logtailcmd") { $FORM{lines} =~ s/\D//g; if ($FORM{lines} eq "" or $FORM{lines} == 0) {$FORM{lines} = 30} my @data = slurp("/etc/csf/csf.syslogs"); foreach my $line (@data) { if ($line =~ /^Include\s*(.*)$/) { my @incfile = slurp($1); push @data,@incfile; } } @data = sort @data; my $cnt = 0; my $logfile = "/var/log/lfd.log"; my $hit = 0; foreach my $file (@data) { $file =~ s/$cleanreg//g; if ($file eq "") {next} if ($file =~ /^\s*\#|Include/) {next} my @globfiles; if ($file =~ /\*|\?|\[/) { foreach my $log (glob $file) {push @globfiles, $log} } else {push @globfiles, $file} foreach my $globfile (@globfiles) { if (-f $globfile) { if ($FORM{lognum} == $cnt) { $logfile = $globfile; $hit = 1; last; } $cnt++; } } if ($hit) {last} } if (-z $logfile) { print "<---- $logfile is currently empty ---->"; } else { if (-x $config{TAIL}) { my $timeout = 30; eval { local $SIG{__DIE__} = undef; local $SIG{'ALRM'} = sub {die}; alarm($timeout); my ($childin, $childout); my $pid = open3($childin, $childout, $childout,$config{TAIL},"-$FORM{lines}",$logfile); while (<$childout>) { my $line = $_; $line =~ s/&/&/g; $line =~ s//>/g; print $line; } waitpid ($pid, 0); alarm(0); }; alarm(0); if ($@) {print "TIMEOUT: tail command took too long. Timed out after $timeout seconds\n"} } else { print "Executable [$config{TAIL}] invalid"; } } } elsif ($FORM{action} eq "loggrep") { $FORM{lines} =~ s/\D//g; if ($FORM{lines} eq "" or $FORM{lines} == 0) {$FORM{lines} = 30} my $script_safe = $script; my $CSFfrombot = 120; my $CSFfromright = 10; if ($config{DIRECTADMIN}) { $script = $script_da; $CSFfrombot = 400; $CSFfromright = 150; } my @data = slurp("/etc/csf/csf.syslogs"); foreach my $line (@data) { if ($line =~ /^Include\s*(.*)$/) { my @incfile = slurp($1); push @data,@incfile; } } @data = sort @data; my $options = "  -i  -E  wildcard   
Please Note:

 1. Searches use $config{GREP}/$config{ZGREP} if wildcard is used), so the search text/regex must be syntactically correct
 2. Use the "-i" option to ignore case
 3. Use the "-E" option to perform an extended regular expression search
 4. Searching large log files can take a long time. This feature has a 30 second timeout
 5. The searched for text will usually be highlighted but may not always be successful
 6. Only log files listed in /etc/csf/csf.syslogs can be searched. You can add to this file
 7. The wildcard option will use $config{ZGREP} and search logs with a wildcard suffix, e.g. /var/log/lfd.log*
EOF if ($config{DIRECTADMIN}) {$script = $script_safe} &printreturn; } elsif ($FORM{action} eq "loggrepcmd") { my @data = slurp("/etc/csf/csf.syslogs"); foreach my $line (@data) { if ($line =~ /^Include\s*(.*)$/) { my @incfile = slurp($1); push @data,@incfile; } } @data = sort @data; my $cnt = 0; my $logfile = "/var/log/lfd.log"; my $hit = 0; foreach my $file (@data) { $file =~ s/$cleanreg//g; if ($file eq "") {next} if ($file =~ /^\s*\#|Include/) {next} my @globfiles; if ($file =~ /\*|\?|\[/) { foreach my $log (glob $file) {push @globfiles, $log} } else {push @globfiles, $file} foreach my $globfile (@globfiles) { if (-f $globfile) { if ($FORM{lognum} == $cnt) { $logfile = $globfile; $hit = 1; last; } $cnt++; } } if ($hit) {last} } my @cmd; my $grepbin = $config{GREP}; if ($FORM{grepZ}) {$grepbin = $config{ZGREP}} if ($FORM{grepi}) {push @cmd, "-i"} if ($FORM{grepE}) {push @cmd, "-E"} push @cmd, $FORM{grep}; if (-z $logfile) { print "<---- $logfile is currently empty ---->"; } else { if (-x $grepbin) { my $timeout = 30; eval { local $SIG{__DIE__} = undef; local $SIG{'ALRM'} = sub {die}; my $total; if ($FORM{grepZ}) { foreach my $file (glob $logfile."\*") { print "\nSearching $file:\n"; alarm($timeout); my ($childin, $childout); my $pid = open3($childin, $childout, $childout,$grepbin,@cmd,$file); while (<$childout>) { my $line = $_; $line =~ s/&/&/g; $line =~ s//>/g; if ($FORM{grep} ne "") { eval { local $SIG{__DIE__} = undef; if ($FORM{grepi}) { $line =~ s/$FORM{grep}/$&<\/mark>/ig; } else { $line =~ s/$FORM{grep}/$&<\/mark>/g; } }; } print $line; $total += length $line; } waitpid ($pid, 0); unless ($total) {print "<---- No matches found for \"$FORM{grep}\" in $file ---->\n"} alarm(0); } } else { alarm($timeout); my ($childin, $childout); my $pid = open3($childin, $childout, $childout,$grepbin,@cmd,$logfile); while (<$childout>) { my $line = $_; $line =~ s/&/&/g; $line =~ s//>/g; if ($FORM{grep} ne "") { eval { local $SIG{__DIE__} = undef; if ($FORM{grepi}) { $line =~ s/$FORM{grep}/$&<\/mark>/ig; } else { $line =~ s/$FORM{grep}/$&<\/mark>/g; } }; } print $line; $total += length $line; } waitpid ($pid, 0); unless ($total) {print "<---- No matches found for \"$FORM{grep}\" in $logfile ---->\n"} alarm(0); } }; alarm(0); if ($@) {print "TIMEOUT: grep command took too long. Timed out after $timeout seconds\n"} } else { print "Executable [$grepbin] invalid"; } } } elsif ($FORM{action} eq "readme") { &resize("top"); print "
\n";
		open (my $IN, "<", "/etc/csf/readme.txt") or die $!;
		flock ($IN, LOCK_SH);
		my @readme = <$IN>;
		close ($IN);
		chomp @readme;

		foreach my $line (@readme) {
			$line =~ s/\/\>\;/g;
			print $line."\n";
		}
		print "
\n"; &resize("bot",0); &printreturn; } elsif ($FORM{action} eq "servercheck") { print ConfigServer::ServerCheck::report($FORM{verbose}); open (my $IN, "<", "/etc/cron.d/csf-cron"); flock ($IN, LOCK_SH); my @data = <$IN>; close ($IN); chomp @data; my $optionselected = "never"; my $email; if (my @ls = grep {$_ =~ /csf \-m/} @data) { if ($ls[0] =~ /\@(\w+)\s+root\s+\/usr\/sbin\/csf \-m (.*)/) {$optionselected = $1; $email = $2} } print "
\n"; print "Generate and email this report to the email address
\n"; print "
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "serverchecksave") { my $extra = ""; my $freq = "daily"; my $email; if ($FORM{email} ne "") {$email = "root"} if ($FORM{email} =~ /^[a-zA-Z0-9\-\_\.\@\+]+$/) {$email = $FORM{email}} foreach my $option ("never","hourly","daily","weekly","monthly") {if ($FORM{freq} eq $option) {$freq = $option}} unless ($email) {$freq = "never"; $extra = "(no valid email address supplied)";} sysopen (my $CRON, "/etc/cron.d/csf-cron", O_RDWR | O_CREAT) or die "Unable to open file: $!"; flock ($CRON, LOCK_EX); my @data = <$CRON>; chomp @data; seek ($CRON, 0, 0); truncate ($CRON, 0); my $done = 0; foreach my $line (@data) { if ($line =~ /csf \-m/) { if ($freq and ($freq ne "never") and !$done) { print $CRON "\@$freq root /usr/sbin/csf -m $email\n"; $done = 1; } } else { print $CRON "$line\n"; } } if (!$done and ($freq ne "never")) { print $CRON "\@$freq root /usr/sbin/csf -m $email\n"; } close ($CRON); if ($freq and $freq ne "never") { print "
Report scheduled to be emailed to $email $freq
\n"; } else { print "
Report schedule cancelled $extra
\n"; } print "
\n"; } elsif ($FORM{action} eq "rblcheck") { my ($status, undef) = ConfigServer::RBLCheck::report($FORM{verbose},$images,1); print "
These options can take a long time to run (several minutes) depending on the number of IP addresses to check and the response speed of the DNS requests:
\n"; print "
Generates the normal report showing exceptions only
\n"; print "
Generates the normal report but shows successes and failures
\n"; print "
Edit csf.rblconf to enable and disable IPs and RBLs
\n"; open (my $IN, "<", "/etc/cron.d/csf-cron"); flock ($IN, LOCK_SH); my @data = <$IN>; close ($IN); chomp @data; my $optionselected = "never"; my $email; if (my @ls = grep {$_ =~ /csf \-\-rbl/} @data) { if ($ls[0] =~ /\@(\w+)\s+root\s+\/usr\/sbin\/csf \-\-rbl (.*)/) {$optionselected = $1; $email = $2} } print "
\n"; print "Generate and email this report to the email address
\n"; &printreturn; } elsif ($FORM{action} eq "rblchecksave") { my $extra = ""; my $freq = "daily"; my $email; if ($FORM{email} ne "") {$email = "root"} if ($FORM{email} =~ /^[a-zA-Z0-9\-\_\.\@\+]+$/) {$email = $FORM{email}} foreach my $option ("never","hourly","daily","weekly","monthly") {if ($FORM{freq} eq $option) {$freq = $option}} unless ($email) {$freq = "never"; $extra = "(no valid email address supplied)";} sysopen (my $CRON, "/etc/cron.d/csf-cron", O_RDWR | O_CREAT) or die "Unable to open file: $!"; flock ($CRON, LOCK_EX); my @data = <$CRON>; chomp @data; seek ($CRON, 0, 0); truncate ($CRON, 0); my $done = 0; foreach my $line (@data) { if ($line =~ /csf \-\-rbl/) { if ($freq and ($freq ne "never") and !$done) { print $CRON "\@$freq root /usr/sbin/csf --rbl $email\n"; $done = 1; } } else { print $CRON "$line\n"; } } if (!$done and ($freq ne "never")) { print $CRON "\@$freq root /usr/sbin/csf --rbl $email\n"; } close ($CRON); if ($freq and $freq ne "never") { print "
Report scheduled to be emailed to $email $freq
\n"; } else { print "
Report schedule cancelled $extra
\n"; } print "
\n"; } elsif ($FORM{action} eq "rblcheckedit") { &editfile("/etc/csf/csf.rblconf","saverblcheckedit"); print "
\n"; } elsif ($FORM{action} eq "saverblcheckedit") { &savefile("/etc/csf/csf.rblconf",""); print "
\n"; } elsif ($FORM{action} eq "cloudflareedit") { &editfile("/etc/csf/csf.cloudflare","savecloudflareedit"); &printreturn; } elsif ($FORM{action} eq "savecloudflareedit") { &savefile("/etc/csf/csf.cloudflare",""); &printreturn; } elsif ($FORM{action} eq "restartboth") { print "

Restarting csf...

\n"; &resize("top"); print "
\n";
		&printcmd("/usr/sbin/csf","-sf");
		print "
\n

...Done.

\n"; if ($config{THIS_UI}) { print "

Signal lfd to restart...

\n
\n";
			sysopen (my $OUT, "/var/lib/csf/lfd.restart",, O_WRONLY | O_CREAT) or die "Unable to open file: $!";
			close ($OUT);
		} else {
			print "

Restarting lfd...

\n
\n";
			ConfigServer::Service::restartlfd();
		}
		print "
\n

...Done.

\n"; &resize("bot",1); &printreturn; } elsif ($FORM{action} eq "remapf") { print "

Removing APF/BFD...

\n
\n";
		&printcmd("sh","/usr/local/csf/bin/remove_apf_bfd.sh");
		print "
\n

...Done.

\n"; print "

Note: You should check the root cron and /etc/crontab to ensure that there are no apf or bfd related cron jobs remaining

\n"; &printreturn; } elsif ($FORM{action} eq "qallow") { print "

Allowing $FORM{ip}...

\n
\n";
		&printcmd("/usr/sbin/csf","-a",$FORM{ip},$FORM{comment});
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "qdeny") { print "

Blocking $FORM{ip}...

\n
\n";
		&printcmd("/usr/sbin/csf","-d",$FORM{ip},$FORM{comment});
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "qignore") { print "

Ignoring $FORM{ip}...\n"; open (my $OUT, ">>", "/etc/csf/csf.ignore"); flock ($OUT, LOCK_EX); print $OUT "$FORM{ip}\n"; close ($OUT); print "Done.

\n"; if ($config{THIS_UI}) { print "

Signal lfd to restart...

\n
\n";
			sysopen (my $OUT, "/var/lib/csf/lfd.restart",, O_WRONLY | O_CREAT) or die "Unable to open file: $!";
			close ($OUT);
		} else {
			print "

Restarting lfd...

\n
\n";
			ConfigServer::Service::restartlfd();
		}
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "kill") { print "

Unblock $FORM{ip}, trying permanent blocks...

\n
\n";
		&printcmd("/usr/sbin/csf","-dr",$FORM{ip});
		print "
\n

...Done.

\n"; print "

Unblock $FORM{ip}, trying temporary blocks...

\n
\n";
		&printcmd("/usr/sbin/csf","-trd",$FORM{ip});
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "killallow") { print "

Unblock $FORM{ip}, trying permanent blocks...

\n
\n";
		&printcmd("/usr/sbin/csf","-ar",$FORM{ip});
		print "
\n

...Done.

\n"; print "

Unblock $FORM{ip}, trying temporary blocks...

\n
\n";
		&printcmd("/usr/sbin/csf","-tra",$FORM{ip});
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "grep") { print "

Searching for $FORM{ip}...

\n"; &resize("top"); print "
\n";
		my ($childin, $childout);
		my $pid = open3($childin, $childout, $childout, "/usr/sbin/csf","-g",$FORM{ip});
		my $unblock;
		my $unallow;
		while (<$childout>) {
			my $line = $_;
			if ($line =~ /^csf.deny:\s(\S+)\s*/) {$unblock = 1}
			if ($line =~ /^Temporary Blocks: IP:(\S+)\s*/) {$unblock = 1}
			if ($line =~ /^csf.allow:\s(\S+)\s*/) {$unallow = 1}
			if ($line =~ /^Temporary Allows: IP:(\S+)\s*/) {$unallow = 1}
			print $_;
		}
		waitpid ($pid, 0);
		print "
\n

...Done.

\n"; &resize("bot",1); if ($unblock) {print "\n"} if ($unallow) {print "\n"} &printreturn; } elsif ($FORM{action} eq "callow") { print "

Cluster Allow $FORM{ip}...

\n
\n";
		&printcmd("/usr/sbin/csf","-ca",$FORM{ip},$FORM{comment});
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "cignore") { print "

Cluster Ignore $FORM{ip}...

\n
\n";
		&printcmd("/usr/sbin/csf","-ci",$FORM{ip},$FORM{comment});
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "cirm") { print "

Cluster Remove ignore $FORM{ip}...

\n
\n";
		&printcmd("/usr/sbin/csf","-cir",$FORM{ip});
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "cloudflare") { &cloudflare; } elsif ($FORM{action} eq "cflist") { print "
CloudFlare list $FORM{type} rules for user(s) $FORM{domains}:
\n"; print "
";
		&printcmd("/usr/sbin/csf","--cloudflare","list",$FORM{type},$FORM{domains});
		print "
\n
\n"; } elsif ($FORM{action} eq "cftempdeny") { print "
CloudFlare $FORM{do} $FORM{target} for user(s) $FORM{domains}:
\n"; print "
\n";
		&printcmd("/usr/sbin/csf","--cloudflare","tempadd",$FORM{do},$FORM{target},$FORM{domains});
		print "
\n
\n"; } elsif ($FORM{action} eq "cfadd") { print "
CloudFlare Add $FORM{type} $FORM{target} for user(s) $FORM{domains}:
\n"; print "
";
		&printcmd("/usr/sbin/csf","--cloudflare","add",$FORM{type},$FORM{target},$FORM{domains});
		print "
\n
\n"; } elsif ($FORM{action} eq "cfremove") { print "
CloudFlare Delete $FORM{type} $FORM{target} for user(s) $FORM{domains}:
\n"; print "
";
		&printcmd("/usr/sbin/csf","--cloudflare","del", $FORM{target},$FORM{domains});
		print "
\n
\n"; } elsif ($FORM{action} eq "cdeny") { print "

Cluster Deny $FORM{ip}...

\n
\n";
		&printcmd("/usr/sbin/csf","-cd",$FORM{ip},$FORM{comment});
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "ctempdeny") { $FORM{timeout} =~ s/\D//g; if ($FORM{dur} eq "minutes") {$FORM{timeout} = $FORM{timeout} * 60} if ($FORM{dur} eq "hours") {$FORM{timeout} = $FORM{timeout} * 60 * 60} if ($FORM{dur} eq "days") {$FORM{timeout} = $FORM{timeout} * 60 * 60 * 24} if ($FORM{ports} eq "") {$FORM{ports} = "*"} print "

cluster Temporarily $FORM{do}ing $FORM{ip} for $FORM{timeout} seconds:

\n
\n";
		if ($FORM{do} eq "block") {
			&printcmd("/usr/sbin/csf","-ctd",$FORM{ip},$FORM{timeout},"-p",$FORM{ports},$FORM{comment});
		} else {
			&printcmd("/usr/sbin/csf","-cta",$FORM{ip},$FORM{timeout},"-p",$FORM{ports},$FORM{comment});
		}
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "crm") { print "

Cluster Remove Deny $FORM{ip}...

\n
\n";
		&printcmd("/usr/sbin/csf","-cr",$FORM{ip});
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "carm") { print "

Cluster Remove Allow $FORM{ip}...

\n
\n";
		&printcmd("/usr/sbin/csf","-car",$FORM{ip});
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "cping") { print "

Cluster PING...

\n
\n";
		&printcmd("/usr/sbin/csf","-cp");
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "cgrep") { print "

Cluster GREP for $FORM{ip}...

\n"; print "
\n";
		my ($childin, $childout);
		my $pid = open3($childin, $childout, $childout, "/usr/sbin/csf","-cg",$FORM{ip});
		my $unblock;
		my $start = 0;
		while (<$childout>) {
			my $line = $_;
			if ($line =~ /^====/) {
				if ($start) {
					print "$line
";
					$start = 0;
				} else {
					print "
$line";
					$start = 1;
				}
			} else {
				print $line;
			}
		}
		waitpid ($pid, 0);
		print "...Done\n
\n"; &printreturn; } elsif ($FORM{action} eq "cconfig") { $FORM{option} =~ s/\s*//g; my %restricted; if ($config{RESTRICT_UI}) { sysopen (my $IN, "/usr/local/csf/lib/restricted.txt", O_RDWR | O_CREAT) or die "Unable to open file: $!"; flock ($IN, LOCK_SH); while (my $entry = <$IN>) { chomp $entry; $restricted{$entry} = 1; } close ($IN); } if ($restricted{$FORM{option}}) { print "
Option $FORM{option} cannot be set with RESTRICT_UI enabled
\n"; exit; } print "

Cluster configuration option...

\n
\n";
		&printcmd("/usr/sbin/csf","-cc",$FORM{option},$FORM{value});
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "crestart") { print "

Cluster restart csf and lfd...

\n
\n";
		&printcmd("/usr/sbin/csf --crestart");
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "allow") { &editfile("/etc/csf/csf.allow","saveallow"); &printreturn; } elsif ($FORM{action} eq "saveallow") { &savefile("/etc/csf/csf.allow","both"); &printreturn; } elsif ($FORM{action} eq "redirect") { &editfile("/etc/csf/csf.redirect","saveredirect"); &printreturn; } elsif ($FORM{action} eq "saveredirect") { &savefile("/etc/csf/csf.redirect","both"); &printreturn; } elsif ($FORM{action} eq "smtpauth") { &editfile("/etc/csf/csf.smtpauth","savesmtpauth"); &printreturn; } elsif ($FORM{action} eq "savesmtpauth") { &savefile("/etc/csf/csf.smtpauth","both"); &printreturn; } elsif ($FORM{action} eq "reseller") { &editfile("/etc/csf/csf.resellers","savereseller"); &printreturn; } elsif ($FORM{action} eq "savereseller") { &savefile("/etc/csf/csf.resellers",""); &printreturn; } elsif ($FORM{action} eq "dirwatch") { &editfile("/etc/csf/csf.dirwatch","savedirwatch"); &printreturn; } elsif ($FORM{action} eq "savedirwatch") { &savefile("/etc/csf/csf.dirwatch","lfd"); &printreturn; } elsif ($FORM{action} eq "dyndns") { &editfile("/etc/csf/csf.dyndns","savedyndns"); &printreturn; } elsif ($FORM{action} eq "savedyndns") { &savefile("/etc/csf/csf.dyndns","lfd"); &printreturn; } elsif ($FORM{action} eq "blocklists") { &editfile("/etc/csf/csf.blocklists","saveblocklists"); &printreturn; } elsif ($FORM{action} eq "saveblocklists") { &savefile("/etc/csf/csf.blocklists","both"); &printreturn; } elsif ($FORM{action} eq "syslogusers") { &editfile("/etc/csf/csf.syslogusers","savesyslogusers"); &printreturn; } elsif ($FORM{action} eq "savesyslogusers") { &savefile("/etc/csf/csf.syslogusers","lfd"); &printreturn; } elsif ($FORM{action} eq "logfiles") { &editfile("/etc/csf/csf.logfiles","savelogfiles"); &printreturn; } elsif ($FORM{action} eq "savelogfiles") { &savefile("/etc/csf/csf.logfiles","lfd"); &printreturn; } elsif ($FORM{action} eq "deny") { &editfile("/etc/csf/csf.deny","savedeny"); &printreturn; } elsif ($FORM{action} eq "savedeny") { &savefile("/etc/csf/csf.deny","both"); &printreturn; } elsif ($FORM{action} eq "templates") { &editfile("/usr/local/csf/tpl/$FORM{template}","savetemplates","template"); &printreturn; } elsif ($FORM{action} eq "savetemplates") { &savefile("/usr/local/csf/tpl/$FORM{template}","",1); &printreturn; } elsif ($FORM{action} eq "ignorefiles") { &editfile("/etc/csf/$FORM{ignorefile}","saveignorefiles","ignorefile"); &printreturn; } elsif ($FORM{action} eq "saveignorefiles") { &savefile("/etc/csf/$FORM{ignorefile}","lfd"); &printreturn; } elsif ($FORM{action} eq "conf") { sysopen (my $IN, "/etc/csf/csf.conf", O_RDWR | O_CREAT) or die "Unable to open file: $!"; flock ($IN, LOCK_SH); my @confdata = <$IN>; close ($IN); chomp @confdata; my %restricted; if ($config{RESTRICT_UI}) { sysopen (my $IN, "/usr/local/csf/lib/restricted.txt", O_RDWR | O_CREAT) or die "Unable to open file: $!"; flock ($IN, LOCK_SH); while (my $entry = <$IN>) { chomp $entry; $restricted{$entry} = 1; } close ($IN); } print < function CSFexpand(obj){ if (!obj.savesize) {obj.savesize=obj.size;} var newsize = Math.max(obj.savesize,obj.value.length); if (newsize > 120) {newsize = 120;} obj.size = newsize; } EOF print "\n"; open (my $DIV, "<", "/usr/local/csf/lib/csf.div"); flock ($DIV, LOCK_SH); my @divdata = <$DIV>; close ($DIV); print @divdata; print "
\n"; print "
\n"; print "\n"; my $first = 1; my @divnames; my $comment = 0; foreach my $line (@confdata) { if (($line !~ /^\#/) and ($line =~ /=/)) { if ($comment) {print "
\n"} $comment = 0; my ($start,$end) = split (/=/,$line,2); my $name = $start; my $cleanname = $start; $cleanname =~ s/\s//g; $name =~ s/\s/\_/g; if ($end =~ /\"(.*)\"/) {$end = $1} my $size = length($end) + 4; my $class = "value-default"; my ($status,$range,$default) = sanity($start,$end); my $showrange = ""; my $showfrom; my $showto; if ($range =~ /^(\d+)-(\d+)$/) { $showfrom = $1; $showto = $2; } if ($default ne "") { $showrange = " Default: $default [$range]"; if ($end ne $default) {$class = "value-other"} } if ($status) {$class = "value-warning"; $showrange = " Recommended range: $range (Default: $default)"} if ($config{RESTRICT_UI} and ($cleanname eq "CLUSTER_KEY" or $cleanname eq "UI_PASS" or $cleanname eq "UI_USER")) { print "
$start = (hidden restricted UI item)
\n"; } elsif ($restricted{$cleanname}) { print "
$start = (restricted UI item)
\n"; } else { if ($range eq "0-1") { my $switch_checked_0 = ""; my $switch_checked_1 = ""; my $switch_active_0 = ""; my $switch_active_1 = ""; if ($end == 0) {$switch_checked_0 = "checked"; $switch_active_0 = "active"} if ($end == 1) {$switch_checked_1 = "checked"; $switch_active_1 = "active"} print "
$start = "; print "
\n"; print "\n"; print "\n"; print "
\n"; } elsif ($range =~ /^(\d+)-(\d+)$/ and !(-e "/etc/csuibuttondisable") and ($showto - $showfrom <= 20) and $end >= $showfrom and $end <= $showto) { my $selected = ""; print "
$start =
\n"; } else { print "
$start = $showrange
\n"; } } } else { if ($line =~ /^\# SECTION:(.*)/) { push @divnames, $1; unless ($first) {print "
\n"} print "
\n
"; print "$1
\n"; $first = 0; next; } if ($line =~ /^\# / and $comment == 0) { $comment = 1; print "
\n"; } $line =~ s/\#//g; $line =~ s/&/&/g; $line =~ s//>/g; $line =~ s/\n/
\n/g; print "$line
\n"; } } print "

\n"; print "\n"; print < var pagecontent=new virtualpaginate({ piececlass: "virtualpage", //class of container for each piece of content piececontainer: "div", //container element type (ie: "div", "p" etc) pieces_per_page: 1, //Pieces of content to show per page (1=1 piece, 2=2 pieces etc) defaultpage: 0, //Default page selected (0=1st page, 1=2nd page etc). Persistence if enabled overrides this setting. wraparound: false, persist: false //Remember last viewed page and recall it when user returns within a browser session? }); EOD print "pagecontent.buildpagination(['paginatediv','paginatediv2'],["; foreach my $line (@divnames) {print "'$line',"} print "''])\npagecontent.showall();\n\n"; print "
\n"; print "\n"; &printreturn; } elsif ($FORM{action} eq "saveconf") { sysopen (my $IN, "/etc/csf/csf.conf", O_RDWR | O_CREAT) or die "Unable to open file: $!"; flock ($IN, LOCK_SH); my @confdata = <$IN>; close ($IN); chomp @confdata; my %restricted; if ($config{RESTRICT_UI}) { sysopen (my $IN, "/usr/local/csf/lib/restricted.txt", O_RDWR | O_CREAT) or die "Unable to open file: $!"; flock ($IN, LOCK_SH); while (my $entry = <$IN>) { chomp $entry; $restricted{$entry} = 1; } close ($IN); } sysopen (my $OUT, "/etc/csf/csf.conf", O_WRONLY | O_CREAT) or die "Unable to open file: $!"; flock ($OUT, LOCK_EX); seek ($OUT, 0, 0); truncate ($OUT, 0); for (my $x = 0; $x < @confdata;$x++) { if (($confdata[$x] !~ /^\#/) and ($confdata[$x] =~ /=/)) { my ($start,$end) = split (/=/,$confdata[$x],2); if ($end =~ /\"(.*)\"/) {$end = $1} my $name = $start; my $sanity_name = $start; $name =~ s/\s/\_/g; $sanity_name =~ s/\s//g; if ($restricted{$sanity_name}) { print $OUT "$confdata[$x]\n"; } else { print $OUT "$start= \"$FORM{$name}\"\n"; $end = $FORM{$name}; } } else { print $OUT "$confdata[$x]\n"; } } close ($OUT); ConfigServer::Config::resetconfig(); my $newconfig = ConfigServer::Config->loadconfig(); my %newconfig = $config->config; foreach my $key (keys %newconfig) { my ($insane,$range,$default) = sanity($key,$newconfig{$key}); if ($insane) {print "
WARNING: $key sanity check. $key = \"$newconfig{$key}\". Recommended range: $range (Default: $default)\n"} } print "
Changes saved. You should restart both csf and lfd.
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "viewlogs") { if (-e "/var/lib/csf/stats/iptables_log") { open (my $IN, "<", "/var/lib/csf/stats/iptables_log") or die "Unable to open file: $!"; flock ($IN, LOCK_SH); my @iptables = <$IN>; close ($IN); chomp @iptables; @iptables = reverse @iptables; my $from; my $to; my $divcnt = 0; my $expcnt = @iptables; if ($iptables[0] =~ /\|(\S+\s+\d+\s+\S+)/) {$from = $1} if ($iptables[-1] =~ /\|(\S+\s+\d+\s+\S+)/) {$to = $1} print "
\n"; print "
\n"; print "

Last $config{ST_IPTABLES} iptables logs*, latest:$from oldest:$to


\n"; print "\n"; print "\n"; my $size = scalar @iptables; if ($size > $config{ST_IPTABLES}) {$size = $config{ST_IPTABLES}} for (my $x = 0 ;$x < $size ;$x++) { my $line = $iptables[$x]; $divcnt++; my ($text,$log) = split(/\|/,$line); my ($time,$desc,$in,$out,$src,$dst,$spt,$dpt,$proto,$inout); if ($log =~ /IN=(\S+)/) {$in = $1} if ($log =~ /OUT=(\S+)/) {$out = $1} if ($log =~ /SRC=(\S+)/) {$src = $1} if ($log =~ /DST=(\S+)/) {$dst = $1} if ($log =~ /SPT=(\d+)/) {$spt = $1} if ($log =~ /DPT=(\d+)/) {$dpt = $1} if ($log =~ /PROTO=(\S+)/) {$proto = $1} if ($text ne "") { $text =~ s/\(/\\(/g; if ($in and $src) {$src = $text ; $dst .= "
(server)"} elsif ($out and $dst) {$dst = $text ; $src .= "
(server)"} } if ($log =~ /^(\S+\s+\d+\s+\S+)/) {$time = $1} $inout = "n/a"; if ($in) {$inout = "in"} elsif ($out) {$inout = "out"} print "
\n"; $log =~ s/\&/\&\;/g; $log =~ s/>/\>\;/g; $log =~ s/\n"; } print "
TimeFromPortI/OToPortProto
$time$src$spt$inout$dst$dpt$proto
$log
\n"; print "
* These iptables logs taken from $config{IPTABLES_LOG} will not necessarily show all packets blocked by iptables. For example, ports listed in DROP_NOLOG or the settings for DROP_LOGGING/DROP_IP_LOGGING/DROP_ONLYRES/DROP_PF_LOGGING will affect what is logged. Additionally, there is rate limiting on all iptables log rules to prevent log file flooding
\n"; } else { print "
No logs entries found
\n"; } &printreturn; } elsif ($FORM{action} eq "sips") { sysopen (my $IN, "/etc/csf/csf.sips", O_RDWR | O_CREAT) or die "Unable to open file: $!"; flock ($IN, LOCK_SH); my @confdata = <$IN>; close ($IN); chomp @confdata; print "

\n"; print "\n"; print "\n"; my %sips; open (my $SIPS, "<","/etc/csf/csf.sips"); flock ($SIPS, LOCK_SH); my @data = <$SIPS>; close ($SIPS); chomp @data; foreach my $line (@data) { if ($line =~ /^(\s|\#|$)/) {next} $sips{$line} = 1; } my $ethdev = ConfigServer::GetEthDev->new(); my %g_ipv4 = $ethdev->ipv4; my %g_ipv6 = $ethdev->ipv6; foreach my $key (sort keys %g_ipv4) { my $ip = $key; if ($ip =~ /^127\.0\.0/) {next} my $chk = "ip_$ip"; $chk =~ s/\./\_/g; my $checked = ""; if ($sips{$ip}) {$checked = "checked"} print "\n"; } foreach my $key (sort keys %g_ipv6) { my $ip = $key; my $chk = "ip_$ip"; $chk =~ s/\./\_/g; my $checked = ""; if ($sips{$ip}) {$checked = "checked"} print "\n"; } print "\n"; print "
IP AddressDeny All Access to IP
$ip
$ip
\n"; &printreturn; } elsif ($FORM{action} eq "sipsave") { open (my $IN,"<","/etc/csf/csf.sips"); flock ($IN, LOCK_SH); my @data = <$IN>; close ($IN); chomp @data; open (my $OUT,">","/etc/csf/csf.sips"); flock ($OUT, LOCK_EX); foreach my $line (@data) { if ($line =~ /^\#/) {print $OUT "$line\n"} else {last} } foreach my $key (keys %FORM) { if ($key =~ /^ip_(.*)/) { my $ip = $1; $ip =~ s/\_/\./g; print $OUT "$ip\n"; } } close($OUT); print "
Changes saved. You should restart csf.
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "upgrade") { if ($config{THIS_UI}) { print "
You cannot upgrade through the UI as restarting lfd will interrupt this session. You must login to the root shell to upgrade csf using:\n

csf -u

\n"; } else { print "

Upgrading csf...

\n"; &resize("top"); print "
\n";
			&printcmd("/usr/sbin/csf","-u");
			print "
\n

...Done.

\n"; &resize("bot",1); open (my $IN, "<", "/etc/csf/version.txt") or die $!; flock ($IN, LOCK_SH); $myv = <$IN>; close ($IN); chomp $myv; } &printreturn; } elsif ($FORM{action} eq "denyf") { print "

Removing all entries from csf.deny...

\n"; &resize("top"); print "
\n";
		&printcmd("/usr/sbin/csf","-df");
		&printcmd("/usr/sbin/csf","-tf");
		print "
\n

...Done.

\n"; &resize("bot",1); &printreturn; } elsif ($FORM{action} eq "csftest") { print "

Testing iptables...

\n
\n";
		&printcmd("/usr/local/csf/bin/csftest.pl");
		print "
\n

...Done.

\n"; print "
You should restart csf after having run this test.
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "profiles") { my @profiles = sort glob("/usr/local/csf/profiles/*"); my @backups = reverse glob("/var/lib/csf/backup/*"); print "
\n"; print "\n"; print "\n"; foreach my $profile (@profiles) { my ($file, undef) = fileparse($profile); $file =~ s/\.conf$//; my $text; open (my $IN, "<", $profile); flock ($IN, LOCK_SH); my @profiledata = <$IN>; close ($IN); chomp @profiledata; if ($file eq "reset_to_defaults") { $text = "This is the installation default profile and will reset all csf.conf settings, including enabling TESTING mode"; } elsif ($profiledata[0] =~ /^\# Profile:/) { foreach my $line (@profiledata) { if ($line =~ /^\# (.*)$/) {$text .= "$1 "} } } print "\n"; } print "\n"; print "
Preconfigured Profiles 
$file
\n$text
You can apply one or more of these profiles to csf.conf. Apart from reset_to_defaults, most of these profiles contain only a subset of settings. You can find out what will be changed by comparing the profile to the current configuration below. A backup of csf.conf will be created before any profile is applied.
\n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
Backup csf.conf
Create a backup of csf.conf. You can use an optional name for the backup that should only contain alphanumerics. Other characters (including spaces) will be replaced with an underscore ( _ )
\n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
Restore Backup Of csf.conf
\n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
Compare Configurations
Select first configuration:
\n
Select second configuration:
\n
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "profileapply") { my $profile = $FORM{profile}; $profile =~ s/\W/_/g; print "

Applying profile ($profile)...

\n
\n";
		&printcmd("/usr/sbin/csf","--profile","apply",$profile);
		print "
\n

...Done.

\n"; print "
You should restart both csf and lfd.
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "profilebackup") { my $profile = $FORM{backup}; $profile =~ s/\W/_/g; print "

Creating backup...

\n
\n";
		&printcmd("/usr/sbin/csf","--profile","backup",$profile);
		print "
\n

...Done.

\n"; &printreturn; } elsif ($FORM{action} eq "profilerestore") { my $profile = $FORM{backup}; $profile =~ s/\W/_/g; print "

Restoring backup ($profile)...

\n
\n";
		&printcmd("/usr/sbin/csf","--profile","restore",$profile);
		print "
\n

...Done.

\n"; print "
You should restart both csf and lfd.
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "profilediff") { my $profile1 = $FORM{profile1}; my $profile2 = $FORM{profile2}; $profile2 =~ s/\W/_/g; $profile2 =~ s/\W/_/g; print "\n"; my ($childin, $childout); my $pid = open3($childin, $childout, $childout, "/usr/sbin/csf","--profile","diff",$profile1,$profile2); while (<$childout>) { $_ =~ s/\[|\]//g; my ($var,$p1,$p2) = split(/\s+/,$_); if ($var eq "") { next; } elsif ($var eq "SETTING") { print "\n"; } else { print "\n"; } } waitpid ($pid, 0); print "
$var$p1$p2
$var$p1$p2
\n"; &printreturn; } elsif ($FORM{action} eq "viewports") { print "

Ports listening for external connections and the executables running behind them:

\n"; print "\n"; print "\n"; my %listen = ConfigServer::Ports->listening; my %ports = ConfigServer::Ports->openports; foreach my $protocol (sort keys %listen) { foreach my $port (sort {$a <=> $b} keys %{$listen{$protocol}}) { foreach my $pid (sort {$a <=> $b} keys %{$listen{$protocol}{$port}}) { my $fopen; if ($ports{$protocol}{$port}) {$fopen = "4"} else {$fopen = "-"} if ($config{IPV6} and $ports{$protocol."6"}{$port}) {$fopen .= "/6"} else {$fopen .= "/-"} my $fcmd = ($listen{$protocol}{$port}{$pid}{cmd}); $fcmd =~ s/\\n"; } } } print "
PortProtoOpenConnsPIDUserCommand LineExecutable
$port$protocol$fopen$fconn$pid$listen{$protocol}{$port}{$pid}{user}$fcmd$fexe
\n"; &printreturn; } elsif ($mobile) { print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
\n"; } elsif ($FORM{action} eq "fix") { print "
These options should only be used as a last resort as most of them will reduce the effectiveness of csf and lfd to protect the server
\n"; print "\n"; print ""; if ($config{LF_SPI} == 0) { print "\n"; if ($config{TCP_IN} =~ /30000:35000/) { print "\n"; if ($config{PT_USERKILL} == 0) { print "\n"; if ($config{SMTP_BLOCK} == 0) { print "\n"; print "\n"; print "\n"; print "
Fix Common Problems
\n"; } else { print "
\n"; } print "If you find that ports listed in TCP_IN/UDP_IN are being blocked by iptables (e.g. port 80) as seen in /var/log/messages and users can only connect to the server if entered in csf.allow, then it could be that the kernel (usually on virtual servers) is broken and cannot perform connection tracking. In this case, disabling the Stateful Packet Inspection functionality of csf (LF_SPI) may help\n"; if ($config{LF_SPI} == 0) { print "
Note: LF_SPI is already disabled"; } print "
\n"; } else { print "
\n"; } print "If the kernel (usually on virtual servers) is broken and cannot perform ftp connection tracking, or if you are trying to use FTP over SSL, this option will open a hole in the firewall to allow PASV connections through\n"; if ($config{TCP_IN} =~ /30000:35000/) { print "
Note: The port range 30000 to 35000 is already open in csf\n"; } print "
\n"; } else { print "
\n"; } print "If lfd is killing running processes and you have PT_USERKILL enabled, then we recommend that you disable this feature\n"; if ($config{PT_USERKILL} == 0) { print "
Note: PT_USERKILL is already disabled"; } print "
\n"; } else { print "
\n"; } print "If scripts on the server are unable to send out email via external SMTP connections and you have SMTP_BLOCK enabled then those scripts should be configured to send email either through /usr/sbin/sendmail or localhost on the server. If this is not possible then disabling SMTP_BLOCK can fix this\n"; if ($config{SMTP_BLOCK} == 0) { print "
Note: SMTP_BLOCK is already disabled"; } print "
\n"; print "If you really want to disable all alerts in lfd you can do so here. This is not recommended in any situation - you should go through the csf configuration and only disable those you do not want. As new features are added to csf you may find that you have to go into the csf configuration and disable them manually as this procedure only disables the ones that it is aware of when applied\n"; print "
\n"; print "If all else fails this option will completely uninstall csf and install it again with completely default options (including TESTING mode). The previous configuration will be lost including all modifications\n"; print "
\n"; &printreturn; &confirmmodal; } elsif ($FORM{action} eq "fixpasvftp") { print "
\n"; print "
Enabling pure-ftpd PASV hole:
\n"; print "
"; &resize("top"); print "
\n";

		my $ftpdone = 0;
		if (-e "/usr/local/cpanel/version") {
			require Cpanel::Config;
			import Cpanel::Config;
			my $cpconf = Cpanel::Config::loadcpconf();
			if ($cpconf->{ftpserver} eq "pure-ftpd") {
				copy("/etc/pure-ftpd.conf","/etc/pure-ftpd.conf-".time."_prefixpasvftp");
				sysopen (my $PUREFTP,"/etc/pure-ftpd.conf", O_RDWR | O_CREAT);
				flock ($PUREFTP, LOCK_EX);
				my @ftp = <$PUREFTP>;
				chomp @ftp;
				seek ($PUREFTP, 0, 0);
				truncate ($PUREFTP, 0);
				my $hit = 0;
				foreach my $line (@ftp) {
					if ($line =~ /^#?\s*PassivePortRange/i) {
						if ($hit) {next}
						$line = "PassivePortRange 30000 35000";
						$hit = 1;
					}
					print $PUREFTP "$line\n";
				}
				unless ($hit) {print $PUREFTP "PassivePortRange 30000 35000"}
				close ($PUREFTP);
				&printcmd("/scripts/restartsrv_pureftpd");
				$ftpdone = 1;
			}
		}

		if ($config{TCP_IN} =~ /30000:35000/) {
			print "PASV port range 30000:35000 already exists in TCP_IN/TCP6_IN\n";
		} else {
			$config{TCP_IN} .= ",30000:35000";
			$config{TCP6_IN} .= ",30000:35000";

			copy("/etc/csf/csf.conf","/var/lib/csf/backup/".time."_prefixpasvftp");
			sysopen (my $CSFCONF,"/etc/csf/csf.conf", O_RDWR | O_CREAT);
			flock ($CSFCONF, LOCK_EX);
			my @csf = <$CSFCONF>;
			chomp @csf;
			seek ($CSFCONF, 0, 0);
			truncate ($CSFCONF, 0);
			foreach my $line (@csf) {
				if ($line =~ /^TCP6_IN/) {
					print $CSFCONF "TCP6_IN = \"$config{TCP6_IN}\"\n";
					print "*** PASV port range 30000:35000 added to the TCP6_IN port list\n";
				}
				elsif ($line =~ /^TCP_IN/) {
					print $CSFCONF "TCP_IN = \"$config{TCP_IN}\"\n";
					print "*** PASV port range 30000:35000 added to the TCP_IN port list\n";
				}
				else {
					print $CSFCONF $line."\n";
				}
			}
			close ($CSFCONF);
		}

		print "
\n"; &resize("bot",1); print "\n"; print "
\n"; print "
You MUST now restart both csf and lfd:
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "fixspi") { print "
\n"; print "
Disabling LF_SPI:
\n"; print "
"; copy("/etc/csf/csf.conf","/var/lib/csf/backup/".time."_prefixspi"); sysopen (my $CSFCONF,"/etc/csf/csf.conf", O_RDWR | O_CREAT); flock ($CSFCONF, LOCK_EX); my @csf = <$CSFCONF>; chomp @csf; seek ($CSFCONF, 0, 0); truncate ($CSFCONF, 0); foreach my $line (@csf) { if ($line =~ /^LF_SPI /) { print $CSFCONF "LF_SPI = \"0\"\n"; print "*** LF_SPI disabled ***\n"; } else { print $CSFCONF $line."\n"; } } close ($CSFCONF); print "
\n"; print "\n"; print "
\n"; print "
You MUST now restart both csf and lfd:
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "fixkill") { print "
\n"; print "
Disabling PT_USERKILL:
\n"; print "
"; copy("/etc/csf/csf.conf","/var/lib/csf/backup/".time."_prefixkill"); sysopen (my $CSFCONF,"/etc/csf/csf.conf", O_RDWR | O_CREAT); flock ($CSFCONF, LOCK_EX); my @csf = <$CSFCONF>; chomp @csf; seek ($CSFCONF, 0, 0); truncate ($CSFCONF, 0); foreach my $line (@csf) { if ($line =~ /^PT_USERKILL /) { print $CSFCONF "PT_USERKILL = \"0\"\n"; print "*** PT_USERKILL disabled ***\n"; } else { print $CSFCONF $line."\n"; } } close ($CSFCONF); print "
\n"; print "\n"; print "
\n"; print "
You MUST now restart both csf and lfd:
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "fixsmtp") { print "
\n"; print "
Disabling SMTP_BLOCK:
\n"; print "
"; copy("/etc/csf/csf.conf","/var/lib/csf/backup/".time."_prefixsmtp"); sysopen (my $CSFCONF,"/etc/csf/csf.conf", O_RDWR | O_CREAT); flock ($CSFCONF, LOCK_EX); my @csf = <$CSFCONF>; chomp @csf; seek ($CSFCONF, 0, 0); truncate ($CSFCONF, 0); foreach my $line (@csf) { if ($line =~ /^SMTP_BLOCK /) { print $CSFCONF "SMTP_BLOCK = \"0\"\n"; print "*** SMTP_BLOCK disabled ***\n"; } else { print $CSFCONF $line."\n"; } } close ($CSFCONF); print "
\n"; print "\n"; print "
\n"; print "
You MUST now restart both csf and lfd:
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "fixalerts") { print "
\n"; print "
Disabling All Alerts:
\n"; print "
"; &resize("top"); print "
\n";
		copy("/etc/csf/csf.conf","/var/lib/csf/backup/".time."_prefixalerts");
		&printcmd("/usr/sbin/csf","--profile","apply","disable_alerts");
		print "
\n"; &resize("bot",1); print "
\n"; print "\n"; print "
\n"; print "
You MUST now restart both csf and lfd:
\n"; print "
\n"; &printreturn; } elsif ($FORM{action} eq "fixnuclear") { print "
\n"; print "
Nuclear Option:
\n"; print "
"; my $time = time; sysopen (my $REINSTALL, "/usr/src/reinstall_$time.sh", O_WRONLY | O_CREAT | O_TRUNC); flock ($REINSTALL, LOCK_EX); print $REINSTALL <\n"; &printcmd("bash","/usr/src/reinstall_$time.sh"); unlink "/usr/src/reinstall_$time.sh"; print "\n"; &resize("bot",1); print "
\n"; print "\n"; print "
\n"; &printreturn; } else { if (defined $ENV{WEBMIN_VAR} and defined $ENV{WEBMIN_CONFIG} and -e "module.info") { my @data = slurp("module.info"); foreach my $line (@data) { if ($line =~ /^name=csf$/) { unless (-l "index.cgi") { unlink "index.cgi"; my $status = symlink ("/usr/local/csf/lib/webmin/csf/index.cgi","index.cgi"); if ($status and -l "index.cgi") { symlink ("/usr/local/csf/lib/webmin/csf/images","csfimages"); print "

csf updated to symlink webmin module to /usr/local/csf/lib/webmin/csf/. Click here to continue

\n"; exit; } else { print "

Failed to symlink to /usr/local/csf/lib/webmin/csf/

\n"; } } last; } } } &getethdev; my ($childin, $childout); my $pid = open3($childin, $childout, $childout, "$config{IPTABLES} $config{IPTABLESWAIT} -L LOCALINPUT -n"); my @iptstatus = <$childout>; waitpid ($pid, 0); chomp @iptstatus; if ($iptstatus[0] =~ /# Warning: iptables-legacy tables present/) {shift @iptstatus} my $status = "

Firewall Status: Enabled and Running

"; if (-e "/etc/csf/csf.disable") { $status = "

Firewall Status: Disabled and Stopped

\n" } elsif ($config{TESTING}) { $status = "

Firewall Status: Enabled but in Test Mode - Don't forget to disable TESTING in the Firewall Configuration

"; } elsif ($iptstatus[0] !~ /^Chain LOCALINPUT/) { $status = "

Firewall Status: Enabled but Stopped

" } if (-e "/var/lib/csf/lfd.restart") {$status .= "

lfd restart request pending

"} unless ($config{RESTRICT_SYSLOG}) {$status .= "

WARNING: RESTRICT_SYSLOG is disabled. See SECURITY WARNING in Firewall Configuration

\n"} my $tempcnt = 0; if (! -z "/var/lib/csf/csf.tempban") { sysopen (my $IN, "/var/lib/csf/csf.tempban", O_RDWR); flock ($IN, LOCK_EX); my @data = <$IN>; close ($IN); chomp @data; $tempcnt = scalar @data; } my $tempbans = "(Currently: $tempcnt temp IP bans, "; $tempcnt = 0; if (! -z "/var/lib/csf/csf.tempallow") { sysopen (my $IN, "/var/lib/csf/csf.tempallow", O_RDWR); flock ($IN, LOCK_EX); my @data = <$IN>; close ($IN); chomp @data; $tempcnt = scalar @data; } $tempbans .= "$tempcnt temp IP allows)"; my $permcnt = 0; if (! -z "/etc/csf/csf.deny") { sysopen (my $IN, "/etc/csf/csf.deny", O_RDWR); flock ($IN, LOCK_SH); while (my $line = <$IN>) { chomp $line; if ($line =~ /^(\#|\n|\r)/) {next} if ($line =~ /$ipv4reg|$ipv6reg/) {$permcnt++} } close ($IN); } my $permbans = "(Currently: $permcnt permanent IP bans)"; $permcnt = 0; if (! -z "/etc/csf/csf.allow") { sysopen (my $IN, "/etc/csf/csf.allow", O_RDWR); flock ($IN, LOCK_SH); while (my $line = <$IN>) { chomp $line; if ($line =~ /^(\#|\n|\r)/) {next} if ($line =~ /$ipv4reg|$ipv6reg/) {$permcnt++} } close ($IN); } my $permallows = "(Currently: $permcnt permanent IP allows)"; print $status; print "
\n"; print "

A new version of csf is available

"; print "
\n"; print "
\n"; print "
\n"; print "
\n"; print "\n"; print ""; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; if ($config{ST_ENABLE}) { print "\n"; if ($chart) { print "\n"; if ($config{ST_SYSTEM}) { print "\n"; } } } print "
Server Information
Perform a basic security, stability and settings check on the server
View the csf+lfd readme.txt file
Watch (tail) various system log files (listed in csf.syslogs)
Search (grep) various system log files (listed in csf.syslogs)
View ports on the server that have a running process behind them listening for external connections
Check whether any of the servers IP addresses are listed in RBLs
View the last $config{ST_IPTABLES} iptables log lines
View lfd blocking statistics
View basic system statistics
\n"; print "
\n"; print "
\n"; print "\n"; print ""; my ($upgrade, $actv) = &csgetversion("csf",$myv); if ($upgrade) { print "\n"; } else { print "\n"; } else { print "You are running the latest version of csf. An Upgrade button will appear here if a new version becomes available. New version checking is performed automatically by a daily cron job (csget)\n"; } } if (!$config{INTERWORX} and (-e "/etc/apf" or -e "/usr/local/bfd")) { print "\n"; } unless (-e "/etc/cxs/cxs.pl") { if (-e "/usr/local/cpanel/version" or $config{DIRECTADMIN} or $config{INTERWORX} or $config{VESTA} or $config{CWP} or $config{CYBERPANEL}) { print "\n"; } } unless (-e "/etc/osm/osmd.pl") { if (-e "/usr/local/cpanel/version" or $config{DIRECTADMIN}) { print "\n"; } } unless (-e "/usr/msfe/mschange.pl") { if (-e "/usr/local/cpanel/version" or $config{DIRECTADMIN}) { print "\n"; } } print "
Upgrade
A new version of csf (v$actv) is available. Upgrading will retain your settings
View ChangeLog
"; if ($actv ne "") { print "(csget cron check) $actv
Remove APF/BFD from the server. You must not run both APF or BFD with csf on the same server
\n"; print "
Add server and user data protection against exploits using ConfigServer eXploit Scanner (cxs)
\n"; print "
\n"; print "
Add outgoing spam monitoring and prevention using ConfigServer Outgoing Spam Monitor(osm)
\n"; print "
\n"; print "
Add effective incoming virus and spam detection and user level processing using ConfigServer MailScanner Front-End (msfe)
\n"; print "
\n"; print "
\n"; if ($upgrade) {print "\n"} print "
\n"; print "
\n"; print "\n"; print ""; print "\n"; print "\n"; print "\n"; print "\n"; print "
csf - Quick Actions
Allow IP address through the firewall and add to the allow file (csf.allow).
Comment for Allow:
Block IP address in the firewall and add to the deny file (csf.deny).
Comment for Block:
Ignore IP address in lfd, add to the ignore file (csf.ignore) and restart lfd
Remove IP address from the firewall (temp and perm blocks)
\n"; print "\n"; print ""; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
csf - ConfigServer Firewall
Edit the configuration file for the csf firewall and lfd
Apply pre-configured csf.conf profiles and backup/restore csf.conf
Display the active iptables rules
Search iptables for IP address
Edit csf.allow, the IP address allow file $permallows
Edit csf.deny, the IP address deny file $permbans
Enables csf and lfd if previously Disabled
Completely disables csf and lfd
Restart the csf iptables firewall
Have lfd restart the csf iptables firewall
Temporarily IP address to port(s) for .
Comment:
\n(ports can be either * for all ports, a single port, or a comma separated list of ports)
View/Remove the temporary IP entries $tempbans
Deny access to and from specific IP addresses configured on the server (csf.sips)
Removes and unblocks all entries in csf.deny (excluding those marked \"do not delete\") and all temporary IP entries (blocks and allows)
Redirect connections to this server to other ports/IP addresses
Offers solutions to some common problems when using an SPI firewall
\n"; print "\n"; print "
\n"; print "
\n"; print "\n"; print ""; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
lfd - Login Failure Daemon
Display lfd status
Restart lfd
Edit lfd ignore file
Edit the Directory File Watching file (csf.dirwatch) - all listed files and directories will be watched for changes by lfd
Edit the Dynamic DNS file (csf.dyndns) - all listed domains will be resolved and allowed through the firewall
Edit email alert templates. See Firewall Information for details of each file
Edit the Log Scanner file (csf.logfiles) - Scan listed log files for log lines and periodically send a report
Edit the Blocklists configuration file (csf.blocklists)
Edit the syslog/rsyslog allowed users file (csf.syslogusers)
\n"; print "
\n"; if ($config{CLUSTER_SENDTO}) { print "
\n"; print "\n"; print ""; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; if ($config{CLUSTER_CONFIG}) { if ($ips{$config{CLUSTER_MASTER}} or $ipscidr6->find($config{CLUSTER_MASTER}) or ($config{CLUSTER_MASTER} eq $config{CLUSTER_NAT})) { my $options; my %restricted; if ($config{RESTRICT_UI}) { sysopen (my $IN, "/usr/local/csf/lib/restricted.txt", O_RDWR | O_CREAT) or die "Unable to open file: $!"; flock ($IN, LOCK_SH); while (my $entry = <$IN>) { chomp $entry; $restricted{$entry} = 1; } close ($IN); } foreach my $key (sort keys %config) { unless ($restricted{$key}) {$options .= ""} } print "\n"; print "\n"; } } print "
csf - ConfigServer lfd Cluster
Ping each member of the cluster (logged in lfd.log)
Allow IP address through the Cluster and add to the allow file (csf.allow)
Comment:
Block IP address in the Cluster and add to the deny file (csf.deny)
Comment:
Ignore IP address in the Cluster and add to the ignore file (csf.ignore)
Comment: Note: This will result in lfd being restarted
Search iptables for IP address
Temporarily IP address to port(s) for .
Comment:
\n(ports can be either * for all ports, a single port, or a comma separated list of ports)
Remove Deny IP address in the Cluster (temporary or permanent)
Remove Allow IP address in the Cluster (temporary or permanent)
Remove Ignore IP address in the Cluster
Note: This will result in lfd being restarted
Change configuration option to in the Cluster"; if ($config{RESTRICT_UI}) {print "
\nSome items have been removed with RESTRICT_UI enabled"} print "
Restart csf and lfd on Cluster members
\n"; print "
\n"; } print "
\n"; if ($config{CF_ENABLE}) { print "\n"; print ""; print "\n"; print "\n"; print "
CloudFlare Firewall
Access CloudFlare firewall functionality
Edit the CloudFlare Configuration file (csf.cloudflare)
\n"; } if ($config{SMTPAUTH_RESTRICT}) { print "\n"; print ""; print "\n"; print "
cPanel SMTP AUTH Restrictions
Edit the file that allows SMTP AUTH to be advertised to listed IP addresses (csf.smtpauth)
\n"; } if (-e "/usr/local/cpanel/version" or $config{DIRECTADMIN} or $config{INTERWORX}) { my $resellers = "cPanel Resellers"; if ($config{DIRECTADMIN}) {$resellers = "DirectAdmin Resellers"} elsif ($config{INTERWORX}) {$resellers = "InterWorx Resellers"} print "\n"; print ""; print "\n"; print "
$resellers
Privileges can be assigned to $resellers accounts by editing this file (csf.resellers)
\n"; } print "\n"; print ""; print "\n"; print "
Extra
Check that iptables has the required modules to run csf
\n"; # if ($config{DIRECTADMIN} and !$config{THIS_UI}) { # print " DirectAdmin Main Page\n"; # } print "
\n
\n"; if ($config{STYLE_MOBILE}) { if (-e "/usr/local/cpanel/version" and !$config{THIS_UI}) { require Cpanel::Version::Tiny; if ($Cpanel::Version::Tiny::major_version < 65) { print " cPanel Main Page\n"; } } if (defined $ENV{WEBMIN_VAR} and defined $ENV{WEBMIN_CONFIG} and !$config{THIS_UI}) { print " Webmin Main Page\n"; } print "
Shows a subset of functions suitable for viewing on mobile devices
\n"; print "
\n"; print "
\n
\n"; print "
\n"; print "
\n"; print "

\n"; print "

\n"; print "

\n"; print "

\n"; print "

\n"; print "

\n"; print "
\n"; print "
\n"; print "

\n"; print "

\n"; print "


\n"; print "

\n"; print "

\n"; print "
\n"; print "
\n"; if (-e "/usr/local/cpanel/version" and !$config{THIS_UI}) { if ($Cpanel::Version::Tiny::major_version < 65) { print "

cPanel Main Page

\n"; } } # if ($config{DIRECTADMIN} and !$config{THIS_UI}) { # print "

DirectAdmin Main Page

\n"; # } if (defined $ENV{WEBMIN_VAR} and defined $ENV{WEBMIN_CONFIG} and !$config{THIS_UI}) { print "

Webmin Main Page

\n"; } print "

\n"; print "
\n

\n"; } print "
\n"; print "
Development Contribution
"; print "
We are very happy to be able to provide this and other products for free. However, it does take time for us to develop and maintain them. If you would like to help with their development by providing a PayPal contribution, please contact us for details
\n"; print "
\n"; } unless ($FORM{action} eq "tailcmd" or $FORM{action} =~ /^cf/ or $FORM{action} eq "logtailcmd" or $FORM{action} eq "loggrepcmd") { print "
\n"; print "
csf: v$myv
"; print "

©2006-2023, ConfigServer Services (Way to the Web Limited)

\n"; print "
\n"; } return; } # 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 ############################################################################### # 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 ############################################################################### # start chart sub chart { my $img; my $imgdir = ""; my $imghddir = ""; if (-e "/usr/local/cpanel/version") { $imgdir = "/"; $imghddir = ""; } elsif (-e "/usr/local/directadmin/conf/directadmin.conf") { $imgdir = "/CMD_PLUGINS_ADMIN/csf/images/"; $imghddir = "plugins/csf/images/"; umask(0133); } elsif (-e "/usr/local/interworx") { $imgdir = "/configserver/csf/"; $imghddir = "/usr/local/interworx/html/configserver/csf/"; umask(0133); } elsif (-e "/usr/local/CyberCP/") { $imgdir = "/static/configservercsf/"; $imghddir = "/usr/local/CyberCP/public/static/configservercsf/"; umask(0133); } if ($config{THIS_UI}) { $imgdir = "$images/"; $imghddir = "/etc/csf/ui/images/"; } my $STATS; if (-e "/var/lib/csf/stats/lfdstats") { sysopen ($STATS,"/var/lib/csf/stats/lfdstats", O_RDWR | O_CREAT); } elsif (-e "/var/lib/csf/stats/lfdmain") { sysopen (my $OLDSTATS,"/var/lib/csf/stats/lfdmain", O_RDWR | O_CREAT); flock ($OLDSTATS, LOCK_EX); my @stats = <$OLDSTATS>; chomp @stats; my @newstats; my $cnt = 0; foreach my $line (@stats) { if ($cnt == 55) {push @newstats,""} push @newstats,$line; $cnt++; } sysopen ($STATS,"/var/lib/csf/stats/lfdstats", O_RDWR | O_CREAT); flock ($STATS, LOCK_EX); seek ($STATS, 0, 0); truncate ($STATS, 0); foreach my $line (@newstats) { print $STATS "$line\n"; } close ($STATS); rename "/var/lib/csf/stats/lfdmain", "/var/lib/csf/stats/lfdmain.".time; close ($OLDSTATS); sysopen ($STATS,"/var/lib/csf/stats/lfdstats", O_RDWR | O_CREAT); } else { sysopen ($STATS,"/var/lib/csf/stats/lfdstats", O_RDWR | O_CREAT); } flock ($STATS, LOCK_SH); my @stats = <$STATS>; chomp @stats; close ($STATS); if (@stats) { ConfigServer::ServerStats::charts($config{CC_LOOKUPS},$imghddir); print ConfigServer::ServerStats::charts_html($config{CC_LOOKUPS},$imgdir); } else { print "\n"; print "
No statistical data has been collected yet
\n"; } &printreturn; return; } # end chart ############################################################################### # start systemstats sub systemstats { my $type = shift; if ($type eq "") {$type = "load"} my $img; my $imgdir = ""; my $imghddir = ""; if (-e "/usr/local/cpanel/version") { if (-e "/usr/local/cpanel/bin/register_appconfig") { $imgdir = "csf/"; $imghddir = "cgi/configserver/csf/"; } else { $imgdir = "/"; $imghddir = ""; } } elsif (-e "/usr/local/directadmin/conf/directadmin.conf") { $imgdir = "/CMD_PLUGINS_ADMIN/csf/images/"; $imghddir = "plugins/csf/images/"; umask(0133); } elsif (-e "/usr/local/interworx") { $imgdir = "/configserver/csf/"; $imghddir = "/usr/local/interworx/html/configserver/csf/"; umask(0133); } elsif (-e "/usr/local/CyberCP/") { $imgdir = "/static/configservercsf/"; $imghddir = "/usr/local/CyberCP/public/static/configservercsf/"; umask(0133); } if ($config{THIS_UI}) { $imgdir = "$images/"; $imghddir = "/etc/csf/ui/images/"; } if (defined $ENV{WEBMIN_VAR} and defined $ENV{WEBMIN_CONFIG}) { $imgdir = "/csf/"; $imghddir = ""; } sysopen (my $STATS,"/var/lib/csf/stats/system", O_RDWR | O_CREAT); flock ($STATS, LOCK_SH); my @stats = <$STATS>; chomp @stats; close ($STATS); if (@stats > 1) { ConfigServer::ServerStats::graphs($type,$config{ST_SYSTEM_MAXDAYS},$imghddir); print "

\n"; print ConfigServer::ServerStats::graphs_html($imgdir); unless ($config{ST_MYSQL} and $config{ST_APACHE}) { print "
\n\n"; print "
You may be able to collect more statistics by enabling ST_MYSQL or ST_APACHE in the csf configuration
\n"; } } else { print "\n"; print "
No statistical data has been collected yet
\n"; } &printreturn; return; } # end systemstats ############################################################################### # start editfile sub editfile { my $file = shift; my $save = shift; my $extra = shift; my $ace = 0; sysopen (my $IN, $file, O_RDWR | O_CREAT) or die "Unable to open file: $!"; flock ($IN, LOCK_SH); my @confdata = <$IN>; close ($IN); chomp @confdata; if (-e "/usr/local/cpanel/3rdparty/share/ace-editor/optimized/src-min-noconflict/ace.js") {$ace = 1} if (-e "/usr/local/cpanel/version" and $ace and !$config{THIS_UI}) { print "\n"; print "

Edit $file

\n"; print "\n"; print "
\n"; print "
\n"; print "
\n"; print "\n"; print "\n"; if ($extra) {print "\n";} print "\n"; print "

\n"; print "
\n"; print "
\n"; print < var myFont = 14; var textarea = \$('#formdata'); var editordiv = \$('#editor'); var editor = ace.edit("editor"); editor.setTheme("ace/theme/tomorrow"); editor.setShowPrintMargin(false); editor.setOptions({ fontFamily: "Courier New, Courier", fontSize: "14px" }); editor.getSession().setMode("ace/mode/space"); editor.getSession().on('change', function () { textarea.val(editor.getSession().getValue()); }); textarea.on('change', function () { editor.getSession().setValue(textarea.val()); }); editor.getSession().setValue(textarea.val()); \$('#textarea').hide(); editordiv.show(); \$("#toggletextarea-btn").on('click', function () { \$('#textarea').toggle(); editordiv.toggle(); }); \$("#fontplus-btn").on('click', function () { myFont++; if (myFont > 20) {myFont = 20} editor.setFontSize(myFont) textarea.css("font-size",myFont+"px"); }); \$("#fontminus-btn").on('click', function () { myFont--; if (myFont < 12) {myFont = 12} editor.setFontSize(myFont) textarea.css("font-size",myFont+"px"); }); EOF } else { if ($config{DIRECTADMIN}) { print "
\n
\n"; } else { print "\n
\n"; } print "
Edit $file
\n"; print "
\n"; print "\n"; if ($extra) {print "\n";} print "
\n"; print "\n"; print "
\n"; } return; } # end editfile ############################################################################### # start savefile sub savefile { my $file = shift; my $restart = shift; $FORM{formdata} =~ s/\r//g; if ($FORM{ace} == "1") { if ($FORM{formdata} !~ /^# Do not remove or change this line as it is a safeguard for the UI editor\n/) { print "
UI editor safeguard missing, changes have not been saved.
\n"; return; } $FORM{formdata} =~ s/^# Do not remove or change this line as it is a safeguard for the UI editor\n//g; } sysopen (my $OUT, $file, O_WRONLY | O_CREAT) or die "Unable to open file: $!"; flock ($OUT, LOCK_EX); seek ($OUT, 0, 0); truncate ($OUT, 0); if ($FORM{formdata} !~ /\n$/) {$FORM{formdata} .= "\n"} print $OUT $FORM{formdata}; close ($OUT); if ($restart eq "csf") { print "
Changes saved. You should restart csf.
\n"; print "
\n"; } elsif ($restart eq "lfd") { print "
Changes saved. You should restart lfd.
\n"; print "
\n"; } elsif ($restart eq "both") { print "
Changes saved. You should restart csf and lfd.

\n"; print "
\n"; } else { print "
Changes saved.
\n"; } return; } # end cloudflare ############################################################################### # start cloudflare sub cloudflare { my $scope = &ConfigServer::CloudFlare::getscope(); print "\n"; print "\n"; print "\n"; print "\n"; print ""; print "\n"; # } else { # print "\n"; # } print ""; print "\n"; print "\n"; print ""; print "
csf - CloudFlare
Select the user(s), then select the action below
Select the domain(s), then select the action below
List rules in CloudFlare ONLY for the chosen accounts
Add rule for target in CloudFlare ONLY for the chosen accounts
Delete rule for target in CloudFlare ONLY
Temporarily IP address for $config{CF_TEMP} secs in CloudFlare AND csf for the chosen accounts and those with to \"any\"
\n"; print "
Output will appear here
\n"; print "
Note:\n
    \n"; print "
  • target can be one of:
    • An IP address
    • \n
    • 2 letter Country Code
    • \n
    • IP range CIDR
    \n
  • \n"; print "
  • Only Enterprise customers can block a Country Code, but all can allow and challenge\n"; print "
  • \nIP range CIDR is limited to /16 and /24
\n"; print "\n"; &printreturn; return; } # end cloudflare ############################################################################### # start resize sub resize { my $part = shift; my $scroll = shift; if ($part eq "top") { print "
\n"; print "
\n"; } else { print " EOF } return; } # end resize ############################################################################### # start printreturn sub printreturn { print "
\n"; return; } # end printreturn ############################################################################### # start confirmmodal # print "\n"; # &confirmmodal; sub confirmmodal { print "\n"; print "\n"; return; } # end confirmmodal ############################################################################### # start csgetversion sub csgetversion { my $product = shift; my $current = shift; my $upgrade = 0; my $newversion; if (-e "/var/lib/configserver/".$product.".txt.error") { open (my $VERSION, "<", "/var/lib/configserver/".$product.".txt.error"); flock ($VERSION, LOCK_SH); $newversion = <$VERSION>; close ($VERSION); chomp $newversion; if ($newversion eq "") { $newversion = "Failed to retrieve latest version from ConfigServer"; } else { $newversion = "Failed to retrieve latest version from ConfigServer: $newversion"; } } elsif (-e "/var/lib/configserver/".$product.".txt") { open (my $VERSION, "<", "/var/lib/configserver/".$product.".txt"); flock ($VERSION, LOCK_SH); $newversion = <$VERSION>; close ($VERSION); chomp $newversion; if ($newversion eq "") { $newversion = "Failed to retrieve latest version from ConfigServer"; } else { if ($newversion =~ /^[\d\.]*$/) { if ($newversion > $current) {$upgrade = 1} else {$newversion = ""} } else {$newversion = ""} } } elsif (-e "/var/lib/configserver/error") { open (my $VERSION, "<", "/var/lib/configserver/error"); flock ($VERSION, LOCK_SH); $newversion = <$VERSION>; close ($VERSION); chomp $newversion; if ($newversion eq "") { $newversion = "Failed to retrieve latest version from ConfigServer"; } else { $newversion = "Failed to retrieve latest version from ConfigServer: $newversion"; } } else { $newversion = "Failed to retrieve latest version from ConfigServer"; } return ($upgrade, $newversion); } # end csgetversion ############################################################################### # start manualversion sub manualversion { my $current = shift; my $upgrade = 0; my $url = "https://$config{DOWNLOADSERVER}/csf/version.txt"; if ($config{URLGET} == 1) {$url = "http://$config{DOWNLOADSERVER}/csf/version.txt";} my ($status, $newversion) = $urlget->urlget($url); if (!$status and $newversion ne "" and $newversion =~ /^[\d\.]*$/ and $newversion > $current) {$upgrade = 1} else {$newversion = ""} return ($upgrade, $newversion); } # end manualversion ############################################################################### 1; Service.pm000064400000005602151030020750006476 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;Sendmail.pm000064400000010361151030020750006630 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;ServerStats.pm000064400000414671151030020750007375 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen) # start main package ConfigServer::ServerStats; use strict; use lib '/usr/local/csf/lib'; use Fcntl qw(:DEFAULT :flock); use Exporter qw(import); our $VERSION = 1.02; our @ISA = qw(Exporter); our @EXPORT_OK = qw(); my %minmaxavg; # end main ############################################################################### # start init sub init { eval ('use GD::Graph::bars;'); ##no critic if ($@) {return undef} eval ('use GD::Graph::pie;'); ##no critic if ($@) {return undef} eval ('use GD::Graph::lines;'); ##no critic if ($@) {return undef} } # end init ############################################################################### # start graphs sub graphs { my $type = shift; my $system_maxdays = shift; my $imghddir = shift; my $img; $| = 1; require GD::Graph::bars; import GD::Graph::bars; require GD::Graph::pie; import GD::Graph::pie; require GD::Graph::lines; import GD::Graph::lines; sysopen (my $STATS,"/var/lib/csf/stats/system", O_RDWR | O_CREAT); flock ($STATS, LOCK_SH); my @stats = <$STATS>; chomp @stats; close ($STATS); if (@stats > 1) { local $SIG{__DIE__} = undef; my $time = time; my %stata; foreach my $line (@stats) { my ($thistime,undef) = split(/\,/,$line); if (time - $thistime > (86400 * $system_maxdays)) {next} my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($thistime); $stata{$year}{$mon}{$mday}{$hour}{$min} = $line; } if ($type eq "cpu") { my (@h,@p,@t); my $cputotal_prev; my $cpuidle_prev; my $cpuiowait_prev; for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $cputotal eq "") { $cputotal_prev = 0; $cpuidle_prev = 0; $cpuiowait_prev = 0; push @p,undef; push @t,undef; } else { my $idle_diff = $cpuidle - $cpuidle_prev; my $iowait_diff = $cpuiowait - $cpuiowait_prev; my $total_diff = $cputotal - $cputotal_prev; if ($total_diff == 0) { $cputotal_prev = 0; $cpuidle_prev = 0; $cpuiowait_prev = 0; push @p,undef; push @t,undef; next; } my $idle_use = 100 - 100 * ($total_diff - $idle_diff) / $total_diff; my $iowait_use = 100 - 100 * ($total_diff - $iowait_diff) / $total_diff; $cpuidle_prev = $cpuidle; $cpuiowait_prev = $cpuiowait; $cputotal_prev = $cputotal; push @p,$idle_use; push @t,$iowait_use; &minmaxavg("HOUR","1Idle",$idle_use); &minmaxavg("HOUR","2IOWAIT",$iowait_use); } } if ($minmaxavg{HOUR}{"1Idle"}{CNT} > 0) {$minmaxavg{HOUR}{"1Idle"}{AVG} /= $minmaxavg{HOUR}{"1Idle"}{CNT}} if ($minmaxavg{HOUR}{"2IOWAIT"}{CNT} > 0) {$minmaxavg{HOUR}{"2IOWAIT"}{AVG} /= $minmaxavg{HOUR}{"2IOWAIT"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => '% CPU', x_label_skip => 3, line_width => 2, title => 'CPU Usage in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Idle IOWAIT)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "cpu") { my (@h,@p,@t); my $cputotal_prev; my $cpuidle_prev; my $cpuiowait_prev; for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $cputotal eq "") { $cputotal_prev = 0; $cpuidle_prev = 0; $cpuiowait_prev = 0; push @p,undef; push @t,undef; } else { my $idle_diff = $cpuidle - $cpuidle_prev; my $iowait_diff = $cpuiowait - $cpuiowait_prev; my $total_diff = $cputotal - $cputotal_prev; if ($total_diff == 0) { $cputotal_prev = 0; $cpuidle_prev = 0; $cpuiowait_prev = 0; push @p,undef; push @t,undef; next; } my $idle_use = 100 - 100 * ($total_diff - $idle_diff) / $total_diff; my $iowait_use = 100 - 100 * ($total_diff - $iowait_diff) / $total_diff; $cpuidle_prev = $cpuidle; $cpuiowait_prev = $cpuiowait; $cputotal_prev = $cputotal; push @p,$idle_use; push @t,$iowait_use; &minmaxavg("DAY","1Idle",$idle_use); &minmaxavg("DAY","2IOWAIT",$iowait_use); } } if ($minmaxavg{DAY}{"1Idle"}{CNT} > 0) {$minmaxavg{DAY}{"1Idle"}{AVG} /= $minmaxavg{DAY}{"1Idle"}{CNT}} if ($minmaxavg{DAY}{"2IOWAIT"}{CNT} > 0) {$minmaxavg{DAY}{"2IOWAIT"}{AVG} /= $minmaxavg{DAY}{"2IOWAIT"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Hour', y_label => '% CPU', x_label_skip => 60, title => 'CPU Usage in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Idle IOWAIT)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "cpu") { my (@h,@p,@t); my $cputotal_prev; my $cpuidle_prev; my $cpuiowait_prev; $minmaxavg{WEEK}{"1Idle"}{MIN} = 100; $minmaxavg{WEEK}{"1Idle"}{MAX} = 0; $minmaxavg{WEEK}{"2IOWAIT"}{MIN} = 100; $minmaxavg{WEEK}{"2IOWAIT"}{MAX} = 0; for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $idle_avg; my $iowait_avg; my $cnt_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $cputotal ne "") { my $idle_diff = $cpuidle - $cpuidle_prev; my $iowait_diff = $cpuiowait - $cpuiowait_prev; my $total_diff = $cputotal - $cputotal_prev; if ($total_diff == 0) { $cputotal_prev = 0; $cpuidle_prev = 0; $cpuiowait_prev = 0; next; } my $idle_use = 100 - 100 * ($total_diff - $idle_diff) / $total_diff; my $iowait_use = 100 - 100 * ($total_diff - $iowait_diff) / $total_diff; $cpuidle_prev = $cpuidle; $cpuiowait_prev = $cpuiowait; $cputotal_prev = $cputotal; $idle_avg += $idle_use; $iowait_avg += $iowait_use; $cnt_avg++; } else { $cputotal_prev = 0; $cpuidle_prev = 0; $cpuiowait_prev = 0; } } unless (defined $cnt_avg) { push @p,undef; push @t,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$idle_avg/$cnt_avg; push @t,$iowait_avg/$cnt_avg; &minmaxavg("WEEK","1Idle",($idle_avg/$cnt_avg)); &minmaxavg("WEEK","2IOWAIT",($iowait_avg/$cnt_avg)); } } if ($minmaxavg{WEEK}{"1Idle"}{CNT} > 0) {$minmaxavg{WEEK}{"1Idle"}{AVG} /= $minmaxavg{WEEK}{"1Idle"}{CNT}} if ($minmaxavg{WEEK}{"2IOWAIT"}{CNT} > 0) {$minmaxavg{WEEK}{"2IOWAIT"}{AVG} /= $minmaxavg{WEEK}{"2IOWAIT"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => '% CPU', x_label_skip => 24, title => 'CPU Usage in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Idle IOWAIT)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "cpu") { my (@h,@p,@t); my $cputotal_prev; my $cpuidle_prev; my $cpuiowait_prev; $minmaxavg{MONTH}{"1Idle"}{MIN} = 100; $minmaxavg{MONTH}{"1Idle"}{MAX} = 0; $minmaxavg{MONTH}{"2IOWAIT"}{MIN} = 100; $minmaxavg{MONTH}{"2IOWAIT"}{MAX} = 0; for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $idle_avg; my $iowait_avg; my $cnt_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $cputotal ne "") { my $idle_diff = $cpuidle - $cpuidle_prev; my $iowait_diff = $cpuiowait - $cpuiowait_prev; my $total_diff = $cputotal - $cputotal_prev; if ($total_diff == 0) { $cputotal_prev = 0; $cpuidle_prev = 0; $cpuiowait_prev = 0; next; } my $idle_use = 100 - 100 * ($total_diff - $idle_diff) / $total_diff; my $iowait_use = 100 - 100 * ($total_diff - $iowait_diff) / $total_diff; $cpuidle_prev = $cpuidle; $cpuiowait_prev = $cpuiowait; $cputotal_prev = $cputotal; $idle_avg += $idle_use; $iowait_avg += $iowait_use; $cnt_avg++; } else { $cputotal_prev = 0; $cpuidle_prev = 0; $cpuiowait_prev = 0; } } unless (defined $cnt_avg) { push @p,undef; push @t,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$idle_avg/$cnt_avg; push @t,$iowait_avg/$cnt_avg; &minmaxavg("MONTH","1Idle",($idle_avg/$cnt_avg)); &minmaxavg("MONTH","2IOWAIT",($iowait_avg/$cnt_avg)); } } if ($minmaxavg{MONTH}{"1Idle"}{CNT} > 0) {$minmaxavg{MONTH}{"1Idle"}{AVG} /= $minmaxavg{MONTH}{"1Idle"}{CNT}} if ($minmaxavg{MONTH}{"2IOWAIT"}{CNT} > 0) {$minmaxavg{MONTH}{"2IOWAIT"}{AVG} /= $minmaxavg{MONTH}{"2IOWAIT"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => '% CPU', x_label_skip => 24, title => "CPU Usage in last $system_maxdays days", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Idle IOWAIT)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mem") { my (@h,@p,@t,@c,@a,@b); for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $memtotal eq "") { push @p,undef; push @t,undef; push @c,undef; push @a,undef; push @b,undef; } else { $memfree = $memtotal - $memfree; $memswapfree = $memswaptotal - $memswapfree; push @p,$memtotal; push @t,$memfree; push @c,$memcached; push @a,$memswaptotal; push @b,$memswapfree; &minmaxavg("HOUR","1Used",$memfree); &minmaxavg("HOUR","2Cached",$memcached); &minmaxavg("HOUR","3SwapUsed",$memswapfree); } } if ($minmaxavg{HOUR}{"1Used"}{CNT} > 0) {$minmaxavg{HOUR}{"1Used"}{AVG} /= $minmaxavg{HOUR}{"1Used"}{CNT}} if ($minmaxavg{HOUR}{"2Cached"}{CNT} > 0) {$minmaxavg{HOUR}{"2Cached"}{AVG} /= $minmaxavg{HOUR}{"2Cached"}{CNT}} if ($minmaxavg{HOUR}{"3SwapUsed"}{CNT} > 0) {$minmaxavg{HOUR}{"3SwapUsed"}{AVG} /= $minmaxavg{HOUR}{"3SwapUsed"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t],[reverse @c],[reverse @a],[reverse @b]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple blue green) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'Memory (KB)', x_label_skip => 3, title => 'Memory Usage in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Total Used Cached SwapTotal SwapUsed)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mem") { my (@h,@p,@c,@t,@a,@b); for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $memtotal eq "") { push @p,undef; push @t,undef; push @c,undef; push @a,undef; push @b,undef; } else { $memfree = $memtotal - $memfree; $memswapfree = $memswaptotal - $memswapfree; push @p,$memtotal; push @t,$memfree; push @c,$memcached; push @a,$memswaptotal; push @b,$memswapfree; &minmaxavg("DAY","1Used",$memfree); &minmaxavg("DAY","2Cached",$memcached); &minmaxavg("DAY","3SwapUsed",$memswapfree); } } if ($minmaxavg{DAY}{"1Used"}{CNT} > 0) {$minmaxavg{DAY}{"1Used"}{AVG} /= $minmaxavg{DAY}{"1Used"}{CNT}} if ($minmaxavg{DAY}{"2Cached"}{CNT} > 0) {$minmaxavg{DAY}{"2Cached"}{AVG} /= $minmaxavg{DAY}{"2Cached"}{CNT}} if ($minmaxavg{DAY}{"3SwapUsed"}{CNT} > 0) {$minmaxavg{DAY}{"3SwapUsed"}{AVG} /= $minmaxavg{DAY}{"3SwapUsed"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t],[reverse @c],[reverse @a],[reverse @b]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple blue green) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'Memory (KB)', x_label_skip => 60, title => 'Memory Usage in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Total Used Cached SwapTotal SwapUsed)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mem") { my (@h,@p,@t,@c,@a,@b); for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $memtotal_avg; my $memfree_avg; my $memcached_avg; my $memswaptotal_avg; my $memswapfree_avg; my $cnt_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $memtotal ne "") { $memfree = $memtotal - $memfree; $memswapfree = $memswaptotal - $memswapfree; $memtotal_avg += $memtotal; $memfree_avg += $memfree; $memcached_avg += $memcached; $memswaptotal_avg += $memswaptotal; $memswapfree_avg += $memswapfree; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; push @t,undef; push @c,undef; push @a,undef; push @b,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$memtotal_avg/$cnt_avg; push @t,$memfree_avg/$cnt_avg; push @c,$memcached_avg/$cnt_avg; push @a,$memswaptotal_avg/$cnt_avg; push @b,$memswapfree_avg/$cnt_avg; &minmaxavg("WEEK","1Used",($memfree_avg/$cnt_avg)); &minmaxavg("WEEK","2Cached",($memcached_avg/$cnt_avg)); &minmaxavg("WEEK","3SwapUsed",($memswapfree_avg/$cnt_avg)); } } if ($minmaxavg{WEEK}{"1Used"}{CNT} > 0) {$minmaxavg{WEEK}{"1Used"}{AVG} /= $minmaxavg{WEEK}{"1Used"}{CNT}} if ($minmaxavg{WEEK}{"2Cached"}{CNT} > 0) {$minmaxavg{WEEK}{"2Cached"}{AVG} /= $minmaxavg{WEEK}{"2Cached"}{CNT}} if ($minmaxavg{WEEK}{"3SwapUsed"}{CNT} > 0) {$minmaxavg{WEEK}{"3SwapUsed"}{AVG} /= $minmaxavg{WEEK}{"3SwapUsed"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t],[reverse @c],[reverse @a],[reverse @b]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple blue green) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Memory (KB)', x_label_skip => 24, title => 'Memory Usage in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Total Used Cached SwapTotal SwapUsed)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mem") { my (@h,@p,@t,@c,@a,@b); for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $memtotal_avg; my $memfree_avg; my $memcached_avg; my $memswaptotal_avg; my $memswapfree_avg; my $cnt_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $memtotal ne "") { $memfree = $memtotal - $memfree; $memswapfree = $memswaptotal - $memswapfree; $memtotal_avg += $memtotal; $memfree_avg += $memfree; $memcached_avg += $memcached; $memswaptotal_avg += $memswaptotal; $memswapfree_avg += $memswapfree; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; push @t,undef; push @c,undef; push @a,undef; push @b,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$memtotal_avg/$cnt_avg; push @t,$memfree_avg/$cnt_avg; push @c,$memcached_avg/$cnt_avg; push @a,$memswaptotal_avg/$cnt_avg; push @b,$memswapfree_avg/$cnt_avg; &minmaxavg("MONTH","1Used",($memfree_avg/$cnt_avg)); &minmaxavg("MONTH","2Cached",($memcached_avg/$cnt_avg)); &minmaxavg("MONTH","3SwapUsed",($memswapfree_avg/$cnt_avg)); } } if ($minmaxavg{MONTH}{"1Used"}{CNT} > 0) {$minmaxavg{MONTH}{"1Used"}{AVG} /= $minmaxavg{MONTH}{"1Used"}{CNT}} if ($minmaxavg{MONTH}{"2Cached"}{CNT} > 0) {$minmaxavg{MONTH}{"2Cached"}{AVG} /= $minmaxavg{MONTH}{"2Cached"}{CNT}} if ($minmaxavg{MONTH}{"3SwapUsed"}{CNT} > 0) {$minmaxavg{MONTH}{"3SwapUsed"}{AVG} /= $minmaxavg{MONTH}{"3SwapUsed"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t],[reverse @c],[reverse @a],[reverse @b]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple blue green) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Memory (Bytes)', x_label_skip => 24, title => "Memory Usage in last $system_maxdays days", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Total Used Cached SwapTotal SwapUsed)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "load") { my (@h,@p,@t,@a); for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $load1 eq "") { push @p,undef; push @t,undef; push @a,undef; } else { push @p,$load1; push @t,$load5; push @a,$load15; &minmaxavg("HOUR","1Load_1",$load1); &minmaxavg("HOUR","2Load_5",$load5); &minmaxavg("HOUR","3Load_15",$load15); } } if ($minmaxavg{HOUR}{"1Load_1"}{CNT} > 0) {$minmaxavg{HOUR}{"1Load_1"}{AVG} /= $minmaxavg{HOUR}{"1Load_1"}{CNT}} if ($minmaxavg{HOUR}{"2Load_5"}{CNT} > 0) {$minmaxavg{HOUR}{"2Load_5"}{AVG} /= $minmaxavg{HOUR}{"2Load_5"}{CNT}} if ($minmaxavg{HOUR}{"3Load_15"}{CNT} > 0) {$minmaxavg{HOUR}{"3Load_15"}{AVG} /= $minmaxavg{HOUR}{"3Load_15"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t],[reverse @a]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'Load Average', x_label_skip => 3, title => 'Load Averages in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Load_1 Load_5 Load_15)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "load") { my (@h,@p,@t,@a); for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $load1 eq "") { push @p,undef; push @t,undef; push @a,undef; } else { push @p,$load1; push @t,$load5; push @a,$load15; &minmaxavg("DAY","1Load_1",$load1); &minmaxavg("DAY","2Load_5",$load5); &minmaxavg("DAY","3Load_15",$load15); } } if ($minmaxavg{DAY}{"1Load_1"}{CNT} > 0) {$minmaxavg{DAY}{"1Load_1"}{AVG} /= $minmaxavg{DAY}{"1Load_1"}{CNT}} if ($minmaxavg{DAY}{"2Load_5"}{CNT} > 0) {$minmaxavg{DAY}{"2Load_5"}{AVG} /= $minmaxavg{DAY}{"2Load_5"}{CNT}} if ($minmaxavg{DAY}{"3Load_15"}{CNT} > 0) {$minmaxavg{DAY}{"3Load_15"}{AVG} /= $minmaxavg{DAY}{"3Load_15"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t],[reverse @a]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'Load Average', x_label_skip => 60, title => 'Load Averages in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Load_1 Load_5 Load_15)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "load") { my (@h,@p,@t,@a); for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $load1_avg; my $load5_avg; my $load15_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $load1 ne "") { $load1_avg += $load1; $load5_avg += $load5; $load15_avg += $load15; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; push @t,undef; push @a,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$load1_avg/$cnt_avg; push @t,$load5_avg/$cnt_avg; push @a,$load15_avg/$cnt_avg; &minmaxavg("WEEK","1Load_1",($load1_avg/$cnt_avg)); &minmaxavg("WEEK","2Load_5",($load5_avg/$cnt_avg)); &minmaxavg("WEEK","3Load_15",($load15_avg/$cnt_avg)); } } if ($minmaxavg{WEEK}{"1Load_1"}{CNT} > 0) {$minmaxavg{WEEK}{"1Load_1"}{AVG} /= $minmaxavg{WEEK}{"1Load_1"}{CNT}} if ($minmaxavg{WEEK}{"2Load_5"}{CNT} > 0) {$minmaxavg{WEEK}{"2Load_5"}{AVG} /= $minmaxavg{WEEK}{"2Load_5"}{CNT}} if ($minmaxavg{WEEK}{"3Load_15"}{CNT} > 0) {$minmaxavg{WEEK}{"3Load_15"}{AVG} /= $minmaxavg{WEEK}{"3Load_15"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t],[reverse @a]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Load Average', x_label_skip => 24, title => 'Load Averages in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Load_1 Load_5 Load_15)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "load") { my (@h,@p,@t,@a); for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $load1_avg; my $load5_avg; my $load15_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $load1 ne "") { $load1_avg += $load1; $load5_avg += $load5; $load15_avg += $load15; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; push @t,undef; push @a,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$load1_avg/$cnt_avg; push @t,$load5_avg/$cnt_avg; push @a,$load15_avg/$cnt_avg; &minmaxavg("MONTH","1Load_1",($load1_avg/$cnt_avg)); &minmaxavg("MONTH","2Load_5",($load5_avg/$cnt_avg)); &minmaxavg("MONTH","3Load_15",($load15_avg/$cnt_avg)); } } if ($minmaxavg{MONTH}{"1Load_1"}{CNT} > 0) {$minmaxavg{MONTH}{"1Load_1"}{AVG} /= $minmaxavg{MONTH}{"1Load_1"}{CNT}} if ($minmaxavg{MONTH}{"2Load_5"}{CNT} > 0) {$minmaxavg{MONTH}{"2Load_5"}{AVG} /= $minmaxavg{MONTH}{"2Load_5"}{CNT}} if ($minmaxavg{MONTH}{"3Load_15"}{CNT} > 0) {$minmaxavg{MONTH}{"3Load_15"}{AVG} /= $minmaxavg{MONTH}{"3Load_15"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t],[reverse @a]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple blue) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Load Average', x_label_skip => 24, title => "Load Averages in last $system_maxdays days", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Load_1 Load_5 Load_15)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "net") { my (@h,@p,@t); my $netin_prev; my $netout_prev; for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $netin eq "") { $netin_prev = 0; $netout_prev = 0; push @p,undef; push @t,undef; } else { if ($netin_prev < $netin or $netin eq "") { push @p,undef; $netin_prev = $netin; } else { my $netin_val = ($netin_prev - $netin) / 60; push @p,$netin_val; $netin_prev = $netin; &minmaxavg("HOUR","1Inbound",$netin_val); } if ($netout_prev < $netout or $netout eq "") { push @t,undef; $netout_prev = $netout; } else { my $netout_val = ($netout_prev - $netout) / 60; push @t,$netout_val; $netout_prev = $netout; &minmaxavg("HOUR","2Outbound",$netout_val); } } } if ($minmaxavg{HOUR}{"1Inbound"}{CNT} > 0) {$minmaxavg{HOUR}{"1Inbound"}{AVG} /= $minmaxavg{HOUR}{"1Inbound"}{CNT}} if ($minmaxavg{HOUR}{"2Outbound"}{CNT} > 0) {$minmaxavg{HOUR}{"2Outbound"}{AVG} /= $minmaxavg{HOUR}{"2Outbound"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'Bytes/Second', x_label_skip => 3, title => 'Network Usage in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Inbound Outbound)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "net") { my (@h,@p,@t); my $netin_prev; my $netout_prev; for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $netin eq "") { $netin_prev = 0; $netout_prev = 0; push @p,undef; push @t,undef; } else { if ($netin_prev < $netin or $netin eq "") { push @p,undef; $netin_prev = $netin; } else { my $netin_val = ($netin_prev - $netin) / 60; push @p,$netin_val; $netin_prev = $netin; &minmaxavg("DAY","1Inbound",$netin_val); } if ($netout_prev < $netout or $netout eq "") { push @t,undef; $netout_prev = $netout; } else { my $netout_val = ($netout_prev - $netout) / 60; push @t,$netout_val; $netout_prev = $netout; &minmaxavg("DAY","2Outbound",$netout_val); } } } if ($minmaxavg{DAY}{"1Inbound"}{CNT} > 0) {$minmaxavg{DAY}{"1Inbound"}{AVG} /= $minmaxavg{DAY}{"1Inbound"}{CNT}} if ($minmaxavg{DAY}{"2Outbound"}{CNT} > 0) {$minmaxavg{DAY}{"2Outbound"}{AVG} /= $minmaxavg{DAY}{"2Outbound"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'Bytes/Second', x_label_skip => 60, title => 'Network Usage in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Inbound Outbound)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "net") { my (@h,@p,@t); my $netin_prev; my $netout_prev; for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $netin_avg; my $netout_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $netin eq "") { $netin_prev = 0; $netout_prev = 0; } else { if ($netin_prev < $netin or $netin eq "") { $netin_prev = $netin; } else { my $netin_val = ($netin_prev - $netin) / 60; $netin_avg = $netin_avg + $netin_val; $netin_prev = $netin; } if ($netout_prev < $netout or $netout eq "") { $netout_prev = $netout; } else { my $netout_val = ($netout_prev - $netout) / 60; $netout_avg = $netout_avg + $netout_val; $netout_prev = $netout; } } } unless (defined $netin_avg) { push @p,undef; } else { push @p,($netin_avg/60); &minmaxavg("WEEK","1Inbound",($netin_avg/60)); } unless (defined $netout_avg) { push @t,undef; } else { push @t,($netout_avg/60); &minmaxavg("WEEK","2Outbound",($netout_avg/60)); } } if ($minmaxavg{WEEK}{"1Inbound"}{CNT} > 0) {$minmaxavg{WEEK}{"1Inbound"}{AVG} /= $minmaxavg{WEEK}{"1Inbound"}{CNT}} if ($minmaxavg{WEEK}{"2Outbound"}{CNT} > 0) {$minmaxavg{WEEK}{"2Outbound"}{AVG} /= $minmaxavg{WEEK}{"2Outbound"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Bytes/Second', x_label_skip => 24, title => 'Network Usage in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Inbound Outbound)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "net") { my (@h,@p,@t); my $netin_prev; my $netout_prev; for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $netin_avg; my $netout_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $netin eq "") { $netin_prev = 0; $netout_prev = 0; } else { if ($netin_prev < $netin or $netin eq "") { $netin_prev = $netin; } else { my $netin_val = ($netin_prev - $netin) / 60; $netin_avg = $netin_avg + $netin_val; $netin_prev = $netin; } if ($netout_prev < $netout or $netout eq "") { $netout_prev = $netout; } else { my $netout_val = ($netout_prev - $netout) / 60; $netout_avg = $netout_avg + $netout_val; $netout_prev = $netout; } } } unless (defined $netin_avg) { push @p,undef; } else { push @p,($netin_avg/60); &minmaxavg("MONTH","1Inbound",($netin_avg/60)); } unless (defined $netout_avg) { push @t,undef; } else { push @t,($netout_avg/60); &minmaxavg("MONTH","2Outbound",($netout_avg/60)); } } if ($minmaxavg{MONTH}{"1Inbound"}{CNT} > 0) {$minmaxavg{MONTH}{"1Inbound"}{AVG} /= $minmaxavg{MONTH}{"1Inbound"}{CNT}} if ($minmaxavg{MONTH}{"2Outbound"}{CNT} > 0) {$minmaxavg{MONTH}{"2Outbound"}{AVG} /= $minmaxavg{MONTH}{"2Outbound"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Bytes/Second', x_label_skip => 24, title => "Network Usage in last $system_maxdays days", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Inbound Outbound)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "disk") { my (@h,@p,@t); my $diskread_prev; my $diskwrite_prev; for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $diskread eq "") { $diskread_prev = 0; $diskwrite_prev = 0; push @p,undef; push @t,undef; } else { if ($diskread_prev < $diskread or $diskread eq "") { push @p,undef; $diskread_prev = $diskread; } else { my $diskread_val = ($diskread_prev - $diskread) / 60; push @p,$diskread_val; $diskread_prev = $diskread; &minmaxavg("HOUR","1Reads",$diskread_val); } if ($diskwrite_prev < $diskwrite or $diskwrite eq "") { push @t,undef; $diskwrite_prev = $diskwrite; } else { my $diskwrite_val = ($diskwrite_prev - $diskwrite) / 60; push @t,$diskwrite_val; $diskwrite_prev = $diskwrite; &minmaxavg("HOUR","2Writes",$diskwrite_val); } } } if ($minmaxavg{HOUR}{"1Reads"}{CNT} > 0) {$minmaxavg{HOUR}{"1Reads"}{AVG} /= $minmaxavg{HOUR}{"1Reads"}{CNT}} if ($minmaxavg{HOUR}{"2Writes"}{CNT} > 0) {$minmaxavg{HOUR}{"2Writes"}{AVG} /= $minmaxavg{HOUR}{"2Writes"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'IO/Second', x_label_skip => 3, title => 'Disk Usage in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Reads Writes)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "disk") { my (@h,@p,@t); my $diskread_prev; my $diskwrite_prev; for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $diskread eq "") { $diskread_prev = 0; $diskwrite_prev = 0; push @p,undef; push @t,undef; } else { if ($diskread_prev < $diskread or $diskread eq "") { push @p,undef; $diskread_prev = $diskread; } else { my $diskread_val = ($diskread_prev - $diskread) / 60; push @p,$diskread_val; $diskread_prev = $diskread; &minmaxavg("DAY","1Reads",$diskread_val); } if ($diskwrite_prev < $diskwrite or $diskwrite eq "") { push @t,undef; $diskwrite_prev = $diskwrite; } else { my $diskwrite_val = ($diskwrite_prev - $diskwrite) / 60; push @t,$diskwrite_val; $diskwrite_prev = $diskwrite; &minmaxavg("DAY","2Writes",$diskwrite_val); } } } if ($minmaxavg{DAY}{"1Reads"}{CNT} > 0) {$minmaxavg{DAY}{"1Reads"}{AVG} /= $minmaxavg{DAY}{"1Reads"}{CNT}} if ($minmaxavg{DAY}{"2Writes"}{CNT} > 0) {$minmaxavg{DAY}{"2Writes"}{AVG} /= $minmaxavg{DAY}{"2Writes"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'IO/Second', x_label_skip => 60, title => 'Disk Usage in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Reads Writes)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "disk") { my (@h,@p,@t); my $diskread_prev; my $diskwrite_prev; for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $diskread_avg; my $diskwrite_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $diskread eq "") { $diskread_prev = 0; $diskwrite_prev = 0; } else { if ($diskread_prev < $diskread or $diskread eq "") { $diskread_prev = $diskread; } else { $diskread_avg = $diskread_avg + ($diskread_prev - $diskread)/60; $diskread_prev = $diskread; } if ($diskwrite_prev < $diskwrite or $diskwrite eq "") { $diskwrite_prev = $diskwrite; } else { $diskwrite_avg = $diskwrite_avg + ($diskwrite_prev - $diskwrite)/60; $diskwrite_prev = $diskwrite; } } } unless (defined $diskread_avg) { push @p,undef; } else { push @p,($diskread_avg/60); &minmaxavg("WEEK","1Reads",($diskread_avg/60)); } unless (defined $diskwrite_avg) { push @t,undef; } else { push @t,($diskwrite_avg/60); &minmaxavg("WEEK","2Writes",($diskwrite_avg/60)); } } if ($minmaxavg{WEEK}{"1Reads"}{CNT} > 0) {$minmaxavg{WEEK}{"1Reads"}{AVG} /= $minmaxavg{WEEK}{"1Reads"}{CNT}} if ($minmaxavg{WEEK}{"2Writes"}{CNT} > 0) {$minmaxavg{WEEK}{"2Writes"}{AVG} /= $minmaxavg{WEEK}{"2Writes"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'IO/Second', x_label_skip => 24, title => 'Disk Usage in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Reads Writes)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "disk") { my (@h,@p,@t); my $diskread_prev; my $diskwrite_prev; for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $diskread_avg; my $diskwrite_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $diskread eq "") { $diskread_prev = 0; $diskwrite_prev = 0; } else { if ($diskread_prev < $diskread or $diskread eq "") { $diskread_prev = $diskread; } else { $diskread_avg = $diskread_avg + ($diskread_prev - $diskread)/60; $diskread_prev = $diskread; } if ($diskwrite_prev < $diskwrite or $diskwrite eq "") { $diskwrite_prev = $diskwrite; } else { $diskwrite_avg = $diskwrite_avg + ($diskwrite_prev - $diskwrite)/60; $diskwrite_prev = $diskwrite; } } } unless (defined $diskread_avg) { push @p,undef; } else { push @p,($diskread_avg/60); &minmaxavg("MONTH","1Reads",($diskread_avg/60)); } unless (defined $diskwrite_avg) { push @t,undef; } else { push @t,($diskwrite_avg/60); &minmaxavg("MONTH","2Writes",($diskwrite_avg/60)); } } if ($minmaxavg{MONTH}{"1Reads"}{CNT} > 0) {$minmaxavg{MONTH}{"1Reads"}{AVG} /= $minmaxavg{MONTH}{"1Reads"}{CNT}} if ($minmaxavg{MONTH}{"2Writes"}{CNT} > 0) {$minmaxavg{MONTH}{"2Writes"}{AVG} /= $minmaxavg{MONTH}{"2Writes"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'IO/Second', x_label_skip => 24, title => "Disk Usage in last $system_maxdays days", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Reads Writes)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "email") { my (@h,@p,@t); for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $mailin eq "") { push @p,undef; push @t,undef; } else { push @p,$mailin; push @t,$mailout; &minmaxavg("HOUR","1Received",$mailin); &minmaxavg("HOUR","2Sent",$mailout); } } if ($minmaxavg{HOUR}{"1Received"}{CNT} > 0) {$minmaxavg{HOUR}{"1Received"}{AVG} /= $minmaxavg{HOUR}{"1Received"}{CNT}} if ($minmaxavg{HOUR}{"2Sent"}{CNT} > 0) {$minmaxavg{HOUR}{"2Sent"}{AVG} /= $minmaxavg{HOUR}{"2Sent"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'Emails', x_label_skip => 3, title => 'Email Usage in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Received Sent)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "email") { my (@h,@p,@t); for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $mailin eq "") { push @p,undef; push @t,undef; } else { push @p,$mailin; push @t,$mailout; &minmaxavg("DAY","1Received",$mailin); &minmaxavg("DAY","2Sent",$mailout); } } if ($minmaxavg{DAY}{"1Received"}{CNT} > 0) {$minmaxavg{DAY}{"1Received"}{AVG} /= $minmaxavg{DAY}{"1Received"}{CNT}} if ($minmaxavg{DAY}{"2Sent"}{CNT} > 0) {$minmaxavg{DAY}{"2Sent"}{AVG} /= $minmaxavg{DAY}{"2Sent"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'Emails', x_label_skip => 60, title => 'Email Usage in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Received Sent)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "email") { my (@h,@p,@t); for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $mailin_avg; my $mailout_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $mailin ne "") { $mailin_avg += $mailin; $mailout_avg += $mailout; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; push @t,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$mailin_avg/$cnt_avg; push @t,$mailout_avg/$cnt_avg; &minmaxavg("WEEK","1Received",($mailin_avg/$cnt_avg)); &minmaxavg("WEEK","2Sent",($mailout_avg/$cnt_avg)); } } if ($minmaxavg{WEEK}{"1Received"}{CNT} > 0) {$minmaxavg{WEEK}{"1Received"}{AVG} /= $minmaxavg{WEEK}{"1Received"}{CNT}} if ($minmaxavg{WEEK}{"2Sent"}{CNT} > 0) {$minmaxavg{WEEK}{"2Sent"}{AVG} /= $minmaxavg{WEEK}{"2Sent"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Emails', x_label_skip => 24, title => 'Email Usage in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Received Sent)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "email") { my (@h,@p,@t); for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $mailin_avg; my $mailout_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $mailin ne "") { $mailin_avg += $mailin; $mailout_avg += $mailout; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; push @t,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$mailin_avg/$cnt_avg; push @t,$mailout_avg/$cnt_avg; &minmaxavg("MONTH","1Received",($mailin_avg/$cnt_avg)); &minmaxavg("MONTH","2Sent",($mailout_avg/$cnt_avg)); } } if ($minmaxavg{MONTH}{"1Received"}{CNT} > 0) {$minmaxavg{MONTH}{"1Received"}{AVG} /= $minmaxavg{MONTH}{"1Received"}{CNT}} if ($minmaxavg{MONTH}{"2Sent"}{CNT} > 0) {$minmaxavg{MONTH}{"2Sent"}{AVG} /= $minmaxavg{MONTH}{"2Sent"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Emails', x_label_skip => 24, title => "Email Usage in last $system_maxdays", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Received Sent)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "temp") { my (@h,@p); for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $cputemp eq "") { push @p,undef; } else { push @p,$cputemp; &minmaxavg("HOUR","1CPU",$cputemp); } } if ($minmaxavg{HOUR}{"1CPU"}{CNT} > 0) {$minmaxavg{HOUR}{"1CPU"}{AVG} /= $minmaxavg{HOUR}{"1CPU"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'Centigrade', x_label_skip => 3, title => 'CPU Temp in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Highest Core Temperature"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "temp") { my (@h,@p); for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $cputemp eq "") { push @p,undef; } else { push @p,$cputemp; &minmaxavg("DAY","1CPU",$cputemp); } } if ($minmaxavg{DAY}{"1CPU"}{CNT} > 0) {$minmaxavg{DAY}{"1CPU"}{AVG} /= $minmaxavg{DAY}{"1CPU"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'Centigrade', x_label_skip => 60, title => 'CPU Temp in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Highest Core Temperature"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "temp") { my (@h,@p); for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $cputemp_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $cputemp ne "") { $cputemp_avg += $cputemp; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$cputemp_avg/$cnt_avg; &minmaxavg("WEEK","1CPU",($cputemp_avg/$cnt_avg)); } } if ($minmaxavg{WEEK}{"1CPU"}{CNT} > 0) {$minmaxavg{WEEK}{"1CPU"}{AVG} /= $minmaxavg{WEEK}{"1CPU"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Centigrade', x_label_skip => 24, title => 'CPU Temp in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Highest Core Temperature"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "temp") { my (@h,@p); for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $cputemp_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $cputemp ne "") { $cputemp_avg += $cputemp; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$cputemp_avg/$cnt_avg; &minmaxavg("MONTH","1CPU",($cputemp_avg/$cnt_avg)); } } if ($minmaxavg{MONTH}{"1CPU"}{CNT} > 0) {$minmaxavg{MONTH}{"1CPU"}{AVG} /= $minmaxavg{MONTH}{"1CPU"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Centigrade', x_label_skip => 24, title => "CPU Temp in last $system_maxdays days", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Highest Core Temperature"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqldata") { my (@h,@p,@t); my $mysqlin_prev; my $mysqlout_prev; for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $mysqlin eq "") { $mysqlin_prev = 0; $mysqlout_prev = 0; push @p,undef; push @t,undef; } else { if ($mysqlin_prev < $mysqlin or $mysqlin eq "") { push @p,undef; $mysqlin_prev = $mysqlin; } else { my $mysqlin_val = ($mysqlin_prev - $mysqlin) / 60; push @p,$mysqlin_val; $mysqlin_prev = $mysqlin; &minmaxavg("HOUR","1Inbound",$mysqlin_val); } if ($mysqlout_prev < $mysqlout or $mysqlout eq "") { push @t,undef; $mysqlout_prev = $mysqlout; } else { my $mysqlout_val = ($mysqlout_prev - $mysqlout) / 60; push @t,$mysqlout_val; $mysqlout_prev = $mysqlout; &minmaxavg("HOUR","2Outbound",$mysqlout_val); } } } if ($minmaxavg{HOUR}{"1Inbound"}{CNT} > 0) {$minmaxavg{HOUR}{"1Inbound"}{AVG} /= $minmaxavg{HOUR}{"1Inbound"}{CNT}} if ($minmaxavg{HOUR}{"2Outbound"}{CNT} > 0) {$minmaxavg{HOUR}{"2Outbound"}{AVG} /= $minmaxavg{HOUR}{"2Outbound"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'Bytes/Second', x_label_skip => 3, title => 'MySQL Data in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Inbound Outbound)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqldata") { my (@h,@p,@t); my $mysqlin_prev; my $mysqlout_prev; for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $mysqlin eq "") { $mysqlin_prev = 0; $mysqlout_prev = 0; push @p,undef; push @t,undef; } else { if ($mysqlin_prev < $mysqlin or $mysqlin eq "") { push @p,undef; $mysqlin_prev = $mysqlin; } else { my $mysqlin_val = ($mysqlin_prev - $mysqlin) / 60; push @p,$mysqlin_val; $mysqlin_prev = $mysqlin; &minmaxavg("DAY","1Inbound",$mysqlin_val); } if ($mysqlout_prev < $mysqlout or $mysqlout eq "") { push @t,undef; $mysqlout_prev = $mysqlout; } else { my $mysqlout_val = ($mysqlout_prev - $mysqlout) / 60; push @t,$mysqlout_val; $mysqlout_prev = $mysqlout; &minmaxavg("DAY","2Outbound",$mysqlout_val); } } } if ($minmaxavg{DAY}{"1Inbound"}{CNT} > 0) {$minmaxavg{DAY}{"1Inbound"}{AVG} /= $minmaxavg{DAY}{"1Inbound"}{CNT}} if ($minmaxavg{DAY}{"2Outbound"}{CNT} > 0) {$minmaxavg{DAY}{"2Outbound"}{AVG} /= $minmaxavg{DAY}{"2Outbound"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'Bytes/Second', x_label_skip => 60, title => 'MySQL Data in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Inbound Outbound)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqldata") { my (@h,@p,@t); my $mysqlin_prev; my $mysqlout_prev; for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $mysqlin_avg; my $mysqlout_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $mysqlin eq "") { $mysqlin_prev = 0; $mysqlout_prev = 0; } else { if ($mysqlin_prev < $mysqlin or $mysqlin eq "") { $mysqlin_prev = $mysqlin; } else { my $mysqlin_val = ($mysqlin_prev - $mysqlin) / 60; $mysqlin_avg = $mysqlin_avg + $mysqlin_val; $mysqlin_prev = $mysqlin; } if ($mysqlout_prev < $mysqlout or $mysqlout eq "") { $mysqlout_prev = $mysqlout; } else { my $mysqlout_val = ($mysqlout_prev - $mysqlout) / 60; $mysqlout_avg = $mysqlout_avg + $mysqlout_val; $mysqlout_prev = $mysqlout; } } } unless (defined $mysqlin_avg) { push @p,undef; } else { push @p,($mysqlin_avg/60); &minmaxavg("WEEK","1Inbound",($mysqlin_avg/60)); } unless (defined $mysqlout_avg) { push @t,undef; } else { push @t,($mysqlout_avg/60); &minmaxavg("WEEK","2Outbound",($mysqlout_avg/60)); } } if ($minmaxavg{WEEK}{"1Inbound"}{CNT} > 0) {$minmaxavg{WEEK}{"1Inbound"}{AVG} /= $minmaxavg{WEEK}{"1Inbound"}{CNT}} if ($minmaxavg{WEEK}{"2Outbound"}{CNT} > 0) {$minmaxavg{WEEK}{"2Outbound"}{AVG} /= $minmaxavg{WEEK}{"2Outbound"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Bytes/Second', x_label_skip => 24, title => 'MySQL Data in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Inbound Outbound)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqldata") { my (@h,@p,@t); my $mysqlin_prev; my $mysqlout_prev; for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $mysqlin_avg; my $mysqlout_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $mysqlin eq "") { $mysqlin_prev = 0; $mysqlout_prev = 0; } else { if ($mysqlin_prev < $mysqlin or $mysqlin eq "") { $mysqlin_prev = $mysqlin; } else { my $mysqlin_val = ($mysqlin_prev - $mysqlin) / 60; $mysqlin_avg = $mysqlin_avg + $mysqlin_val; $mysqlin_prev = $mysqlin; } if ($mysqlout_prev < $mysqlout or $mysqlout eq "") { $mysqlout_prev = $mysqlout; } else { my $mysqlout_val = ($mysqlout_prev - $mysqlout) / 60; $mysqlout_avg = $mysqlout_avg + $mysqlout_val; $mysqlout_prev = $mysqlout; } } } unless (defined $mysqlin_avg) { push @p,undef; } else { push @p,($mysqlin_avg/60); &minmaxavg("MONTH","1Inbound",($mysqlin_avg/60)); } unless (defined $mysqlout_avg) { push @t,undef; } else { push @t,($mysqlout_avg/60); &minmaxavg("MONTH","2Outbound",($mysqlout_avg/60)); } } if ($minmaxavg{MONTH}{"1Inbound"}{CNT} > 0) {$minmaxavg{MONTH}{"1Inbound"}{AVG} /= $minmaxavg{MONTH}{"1Inbound"}{CNT}} if ($minmaxavg{MONTH}{"2Outbound"}{CNT}) {$minmaxavg{MONTH}{"2Outbound"}{AVG} /= $minmaxavg{MONTH}{"2Outbound"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Bytes/Second', x_label_skip => 24, title => "MySQL Data in last $system_maxdays days", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Inbound Outbound)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlqueries") { my (@h,@p,@t); my $mysqlq_prev; my $mysqlsq_prev; for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $mysqlq eq "") { $mysqlq_prev = 0; push @p,undef; } else { if ($mysqlq_prev < $mysqlq or $mysqlq eq "") { push @p,undef; $mysqlq_prev = $mysqlq; } else { my $mysqlq_val = ($mysqlq_prev - $mysqlq); push @p,$mysqlq_val; $mysqlq_prev = $mysqlq; &minmaxavg("HOUR","1Queries",$mysqlq_val); } } } if ($minmaxavg{HOUR}{"1Queries"}{CNT} > 0) {$minmaxavg{HOUR}{"1Queries"}{AVG} /= $minmaxavg{HOUR}{"1Queries"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'Queries', x_label_skip => 3, title => 'MySQL Queries in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Queries)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlqueries") { my (@h,@p,@t); my $mysqlq_prev; my $mysqlsq_prev; for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $mysqlq eq "") { $mysqlq_prev = 0; push @p,undef; } else { if ($mysqlq_prev < $mysqlq or $mysqlq eq "") { push @p,undef; $mysqlq_prev = $mysqlq; } else { my $mysqlq_val = ($mysqlq_prev - $mysqlq); push @p,$mysqlq_val; $mysqlq_prev = $mysqlq; &minmaxavg("DAY","1Queries",$mysqlq_val); } } } if ($minmaxavg{DAY}{"1Queries"}{CNT} > 0) {$minmaxavg{DAY}{"1Queries"}{AVG} /= $minmaxavg{DAY}{"1Queries"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'Queries', x_label_skip => 60, title => 'MySQL Queries in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Queries)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlqueries") { my (@h,@p,@t); my $mysqlq_prev; for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $mysqlq_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $mysqlq eq "") { $mysqlq_prev = 0; } else { if ($mysqlq_prev < $mysqlq or $mysqlq eq "") { $mysqlq_prev = $mysqlq; } else { my $mysqlq_val = ($mysqlq_prev - $mysqlq); $mysqlq_avg = $mysqlq_avg + $mysqlq_val; $mysqlq_prev = $mysqlq; } } } unless (defined $mysqlq_avg) { push @p,undef; } else { push @p,($mysqlq_avg/60); &minmaxavg("WEEK","1Queries",($mysqlq_avg/60)); } } if ($minmaxavg{WEEK}{"1Queries"}{CNT} > 0) {$minmaxavg{WEEK}{"1Queries"}{AVG} /= $minmaxavg{WEEK}{"1Queries"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Queries', x_label_skip => 24, title => 'MySQL Queries in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Queries)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlqueries") { my (@h,@p,@t); my $mysqlq_prev; for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $mysqlq_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $mysqlq eq "") { $mysqlq_prev = 0; } else { if ($mysqlq_prev < $mysqlq or $mysqlq eq "") { $mysqlq_prev = $mysqlq; } else { my $mysqlq_val = ($mysqlq_prev - $mysqlq); $mysqlq_avg = $mysqlq_avg + $mysqlq_val; $mysqlq_prev = $mysqlq; } } } unless (defined $mysqlq_avg) { push @p,undef; } else { push @p,($mysqlq_avg/60); &minmaxavg("MONTH","1Queries",($mysqlq_avg/60)); } } if ($minmaxavg{MONTH}{"1Queries"}{CNT} > 0) {$minmaxavg{MONTH}{"1Queries"}{AVG} /= $minmaxavg{MONTH}{"1Queries"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Queries', x_label_skip => 24, title => "MySQL Queries in last $system_maxdays", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Queries)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlslowqueries") { my (@h,@p,@t); my $mysqlsq_prev; for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $mysqlq eq "") { $mysqlsq_prev = 0; push @t,undef; } else { if ($mysqlsq_prev < $mysqlsq or $mysqlsq eq "") { push @t,undef; $mysqlsq_prev = $mysqlsq; } else { my $mysqlsq_val = ($mysqlsq_prev - $mysqlsq); push @t,$mysqlsq_val; $mysqlsq_prev = $mysqlsq; &minmaxavg("HOUR","1Slow_Queries",$mysqlsq_val); } } } if ($minmaxavg{HOUR}{"1Slow_Queries"}{CNT} > 0) {$minmaxavg{HOUR}{"1Slow_Queries"}{AVG} /= $minmaxavg{HOUR}{"1Slow_Queries"}{CNT}} my @data = ([reverse @h],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'Slow Queries', x_label_skip => 3, title => 'MySQL Slow Queries in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Slow_Queries)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlslowqueries") { my (@h,@p,@t); my $mysqlsq_prev; for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $mysqlq eq "") { $mysqlsq_prev = 0; push @t,undef; } else { if ($mysqlsq_prev < $mysqlsq or $mysqlsq eq "") { push @t,undef; $mysqlsq_prev = $mysqlsq; } else { my $mysqlsq_val = ($mysqlsq_prev - $mysqlsq); push @t,$mysqlsq_val; $mysqlsq_prev = $mysqlsq; &minmaxavg("DAY","1Slow_Queries",$mysqlsq_val); } } } if ($minmaxavg{DAY}{"1Slow_Queries"}{CNT} > 0) {$minmaxavg{DAY}{"1Slow_Queries"}{AVG} /= $minmaxavg{DAY}{"1Slow_Queries"}{CNT}} my @data = ([reverse @h],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'Slow Queries', x_label_skip => 60, title => 'MySQL Slow Queries in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Slow_Queries)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlslowqueries") { my (@h,@p,@t); my $mysqlsq_prev; for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $mysqlsq_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $mysqlsq eq "") { $mysqlsq_prev = 0; } else { if ($mysqlsq_prev < $mysqlsq or $mysqlsq eq "") { $mysqlsq_prev = $mysqlsq; } else { my $mysqlsq_val = ($mysqlsq_prev - $mysqlsq); $mysqlsq_avg = $mysqlsq_avg + $mysqlsq_val; $mysqlsq_prev = $mysqlsq; } } } unless (defined $mysqlsq_avg) { push @t,undef; } else { push @t,($mysqlsq_avg/60); &minmaxavg("WEEK","1Slow_Queries",($mysqlsq_avg/60)); } } if ($minmaxavg{WEEK}{"1Slow_Queries"}{CNT} > 0) {$minmaxavg{WEEK}{"1Slow_Queries"}{AVG} /= $minmaxavg{WEEK}{"1Slow_Queries"}{CNT}} my @data = ([reverse @h],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Slow Queries', x_label_skip => 24, title => 'MySQL Slow Queries in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Slow_Queries)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlslowqueries") { my (@h,@p,@t); my $mysqlsq_prev; for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $mysqlsq_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $mysqlsq eq "") { $mysqlsq_prev = 0; } else { if ($mysqlsq_prev < $mysqlsq or $mysqlsq eq "") { $mysqlsq_prev = $mysqlsq; } else { my $mysqlsq_val = ($mysqlsq_prev - $mysqlsq); $mysqlsq_avg = $mysqlsq_avg + $mysqlsq_val; $mysqlsq_prev = $mysqlsq; } } } unless (defined $mysqlsq_avg) { push @t,undef; } else { push @t,($mysqlsq_avg/60); &minmaxavg("MONTH","1Slow_Queries",($mysqlsq_avg/60)); } } if ($minmaxavg{MONTH}{"1Slow_Queries"}{CNT} > 0) {$minmaxavg{MONTH}{"1Slow_Queries"}{AVG} /= $minmaxavg{MONTH}{"1Slow_Queries"}{CNT}} my @data = ([reverse @h],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Slow Queries', x_label_skip => 24, title => "MySQL Slow Queries in last $system_maxdays", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Slow_Queries)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlconns") { my (@h,@p,@t); my $mysqlcn_prev; for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $mysqlq eq "") { $mysqlcn_prev = 0; push @p,undef; push @t,undef; } else { if ($mysqlcn_prev < $mysqlcn or $mysqlcn eq "") { push @p,undef; $mysqlcn_prev = $mysqlcn; } else { my $mysqlcn_val = ($mysqlcn_prev - $mysqlcn); push @p,$mysqlcn_val; $mysqlcn_prev = $mysqlcn; &minmaxavg("HOUR","1Connections",$mysqlcn_val); } if ($mysqlth eq "") { push @t,undef; } else { push @t,$mysqlth; &minmaxavg("HOUR","2Threads",$mysqlth); } } } if ($minmaxavg{HOUR}{"1Connections"}{CNT} > 0) {$minmaxavg{HOUR}{"1Connections"}{AVG} /= $minmaxavg{HOUR}{"1Connections"}{CNT}} if ($minmaxavg{HOUR}{"2Threads"}{CNT} > 0) {$minmaxavg{HOUR}{"2Threads"}{AVG} /= $minmaxavg{HOUR}{"2Threads"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => '', x_label_skip => 3, title => 'MySQL Connections & Threads in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Connections Threads)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlconns") { my (@h,@p,@t); my $mysqlcn_prev; for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $mysqlq eq "") { $mysqlcn_prev = 0; push @p,undef; push @t,undef; } else { if ($mysqlcn_prev < $mysqlcn or $mysqlcn eq "") { push @p,undef; $mysqlcn_prev = $mysqlcn; } else { my $mysqlcn_val = ($mysqlcn_prev - $mysqlcn); push @p,$mysqlcn_val; $mysqlcn_prev = $mysqlcn; &minmaxavg("DAY","1Connections",$mysqlcn_val); } if ($mysqlth eq "") { push @t,undef; } else { push @t,$mysqlth; &minmaxavg("DAY","2Threads",$mysqlth); } } } if ($minmaxavg{DAY}{"1Connections"}{CNT} > 0) {$minmaxavg{DAY}{"1Connections"}{AVG} /= $minmaxavg{DAY}{"1Connections"}{CNT}} if ($minmaxavg{DAY}{"2Threads"}{CNT} > 0) {$minmaxavg{DAY}{"2Threads"}{AVG} /= $minmaxavg{DAY}{"2Threads"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Hour', y_label => '', x_label_skip => 60, title => 'MySQL Connections & Threads in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Connections Threads)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlconns") { my (@h,@p,@t); my $mysqlcn_prev; for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $mysqlcn_avg; my $mysqlth_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $mysqlq eq "") { $mysqlcn_prev = 0; } else { if ($mysqlcn_prev < $mysqlcn or $mysqlcn eq "") { $mysqlcn_prev = $mysqlcn; } else { my $mysqlcn_val = ($mysqlcn_prev - $mysqlcn); $mysqlcn_avg = $mysqlcn_avg + $mysqlcn_val; $mysqlcn_prev = $mysqlcn; } $mysqlth_avg = $mysqlth_avg + $mysqlth; } } unless (defined $mysqlcn_avg) { push @p,undef; } else { push @p,($mysqlcn_avg/60); &minmaxavg("WEEK","1Connections",($mysqlcn_avg/60)); } unless (defined $mysqlth_avg) { push @t,undef; } else { push @t,($mysqlth_avg/60); &minmaxavg("WEEK","2Threads",($mysqlth_avg/60)); } } if ($minmaxavg{WEEK}{"1Connections"}{CNT} > 0) {$minmaxavg{WEEK}{"1Connections"}{AVG} /= $minmaxavg{WEEK}{"1Connections"}{CNT}} if ($minmaxavg{WEEK}{"2Threads"}{CNT} > 0) {$minmaxavg{WEEK}{"2Threads"}{AVG} /= $minmaxavg{WEEK}{"2Threads"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => '', x_label_skip => 24, title => 'MySQL Connections & Threads in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Connections Threads)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "mysqlconns") { my (@h,@p,@t); my $mysqlcn_prev; for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $mysqlcn_avg; my $mysqlth_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $mysqlq eq "") { $mysqlcn_prev = 0; } else { if ($mysqlcn_prev < $mysqlcn or $mysqlcn eq "") { $mysqlcn_prev = $mysqlcn; } else { my $mysqlcn_val = ($mysqlcn_prev - $mysqlcn); $mysqlcn_avg = $mysqlcn_avg + $mysqlcn_val; $mysqlcn_prev = $mysqlcn; } $mysqlth_avg = $mysqlth_avg + $mysqlth; } } unless (defined $mysqlcn_avg) { push @p,undef; } else { push @p,($mysqlcn_avg/60); &minmaxavg("MONTH","1Connections",($mysqlcn_avg/60)); } unless (defined $mysqlth_avg) { push @t,undef; } else { push @t,($mysqlth_avg/60); &minmaxavg("MONTH","2Threads",($mysqlth_avg/60)); } } if ($minmaxavg{MONTH}{"1Connections"}{CNT} > 0) {$minmaxavg{MONTH}{"1Connections"}{AVG} /= $minmaxavg{MONTH}{"1Connections"}{CNT}} if ($minmaxavg{MONTH}{"2Threads"}{CNT} > 0) {$minmaxavg{MONTH}{"2Threads"}{AVG} /= $minmaxavg{MONTH}{"2Threads"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => '', x_label_skip => 24, title => "MySQL Connections & Threads in last $system_maxdays days", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Connections Threads)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apachecpu") { my (@h,@p); for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $apachecpu eq "") { push @p,undef; } else { push @p,$apachecpu; &minmaxavg("HOUR","1Apache_CPU",$apachecpu); } } if ($minmaxavg{HOUR}{"1Apache_CPU"}{CNT} > 0) {$minmaxavg{HOUR}{"1Apache_CPU"}{AVG} /= $minmaxavg{HOUR}{"1Apache_CPU"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'Percentage', x_label_skip => 3, title => 'Apache CPU Usage in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Apache CPU"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apachecpu") { my (@h,@p); for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $apachecpu eq "") { push @p,undef; } else { push @p,$apachecpu; &minmaxavg("DAY","1Apache_CPU",$apachecpu); } } if ($minmaxavg{DAY}{"1Apache_CPU"}{CNT} > 0) {$minmaxavg{DAY}{"1Apache_CPU"}{AVG} /= $minmaxavg{DAY}{"1Apache_CPU"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'Percentage', x_label_skip => 60, title => 'Apache CPU Usage in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Apache CPU"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apachecpu") { my (@h,@p); for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $apachecpu_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $apachecpu ne "") { $apachecpu_avg += $apachecpu; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$apachecpu_avg/$cnt_avg; &minmaxavg("WEEK","1Apache_CPU",($apachecpu_avg/$cnt_avg)); } } if ($minmaxavg{WEEK}{"1Apache_CPU"}{CNT} > 0) {$minmaxavg{WEEK}{"1Apache_CPU"}{AVG} /= $minmaxavg{WEEK}{"1Apache_CPU"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Percentage', x_label_skip => 24, title => 'Apache CPU Usage in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Apache CPU"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apachecpu") { my (@h,@p); for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $apachecpu_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $apachecpu ne "") { $apachecpu_avg += $apachecpu; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$apachecpu_avg/$cnt_avg; &minmaxavg("MONTH","1Apache_CPU",($apachecpu_avg/$cnt_avg)); } } if ($minmaxavg{MONTH}{"1Apache_CPU"}{CNT} > 0) {$minmaxavg{MONTH}{"1Apache_CPU"}{AVG} /= $minmaxavg{MONTH}{"1Apache_CPU"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Percentage', x_label_skip => 24, title => "Apache CPU Usage in last $system_maxdays", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Apache CPU"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apacheconn") { my (@h,@p); my $apacheacc_prev; for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $apacheacc eq "") { $apacheacc_prev = 0; push @p,undef; } else { if ($apacheacc_prev < $apacheacc or $apacheacc eq "") { push @p,undef; $apacheacc_prev = $apacheacc; } else { my $apacheacc_val = ($apacheacc_prev - $apacheacc); push @p,$apacheacc_val; $apacheacc_prev = $apacheacc; &minmaxavg("HOUR","1Connections",$apacheacc_val); } } } if ($minmaxavg{HOUR}{"1Connections"}{CNT} > 0) {$minmaxavg{HOUR}{"1Connections"}{AVG} /= $minmaxavg{HOUR}{"1Connections"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => '', x_label_skip => 3, title => 'Apache Connections in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Connections)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apacheconn") { my (@h,@p,@t); my $apacheacc_prev; for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $apacheacc eq "") { $apacheacc_prev = 0; push @p,undef; } else { if ($apacheacc_prev < $apacheacc or $apacheacc eq "") { push @p,undef; $apacheacc_prev = $apacheacc; } else { my $apacheacc_val = ($apacheacc_prev - $apacheacc); push @p,$apacheacc_val; $apacheacc_prev = $apacheacc; &minmaxavg("DAY","1Connections",$apacheacc_val); } } } if ($minmaxavg{DAY}{"1Connections"}{CNT} > 0) {$minmaxavg{DAY}{"1Connections"}{AVG} /= $minmaxavg{DAY}{"1Connections"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Hour', y_label => '', x_label_skip => 60, title => 'Apache Connections in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Connections)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apacheconn") { my (@h,@p,@t); my $apacheacc_prev; for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $apacheacc_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $apacheacc eq "") { $apacheacc_prev = 0; } else { if ($apacheacc_prev < $apacheacc or $apacheacc eq "") { $apacheacc_prev = $apacheacc; } else { my $apacheacc_val = ($apacheacc_prev - $apacheacc); $apacheacc_avg = $apacheacc_avg + $apacheacc_val; $apacheacc_prev = $apacheacc; } } } unless (defined $apacheacc_avg) { push @p,undef; } else { push @p,($apacheacc_avg/60); &minmaxavg("WEEK","1Connections",($apacheacc_avg/60)); } } if ($minmaxavg{WEEK}{"1Connections"}{CNT} > 0) {$minmaxavg{WEEK}{"1Connections"}{AVG} /= $minmaxavg{WEEK}{"1Connections"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => '', x_label_skip => 24, title => 'Apache Connections in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Connections Threads)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apacheconn") { my (@h,@p,@t); my $apacheacc_prev; for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $apacheacc_avg; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time eq "" or $apacheacc eq "") { $apacheacc_prev = 0; } else { if ($apacheacc_prev < $apacheacc or $apacheacc eq "") { $apacheacc_prev = $apacheacc; } else { my $apacheacc_val = ($apacheacc_prev - $apacheacc); $apacheacc_avg = $apacheacc_avg + $apacheacc_val; $apacheacc_prev = $apacheacc; } } } unless (defined $apacheacc_avg) { push @p,undef; } else { push @p,($apacheacc_avg/60); &minmaxavg("MONTH","1Connections",($apacheacc_avg/60)); } } if ($minmaxavg{MONTH}{"1Connections"}{CNT} > 0) {$minmaxavg{MONTH}{"1Connections"}{AVG} /= $minmaxavg{MONTH}{"1Connections"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => '', x_label_skip => 24, title => "Apache Connections in last $system_maxdays", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Connections Threads)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apachework") { my (@h,@p,@t); for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $apachebwork eq "") { push @p,undef; push @t,undef; } else { push @p,$apachebwork; push @t,$apacheiwork; &minmaxavg("HOUR","1Busy",$apachebwork); &minmaxavg("HOUR","2Idle",$apacheiwork); } } if ($minmaxavg{HOUR}{"1Busy"}{CNT} > 0) {$minmaxavg{HOUR}{"1Busy"}{AVG} /= $minmaxavg{HOUR}{"1Busy"}{CNT}} if ($minmaxavg{HOUR}{"2Idle"}{CNT} > 0) {$minmaxavg{HOUR}{"2Idle"}{AVG} /= $minmaxavg{HOUR}{"2Idle"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'Workers', x_label_skip => 3, title => 'Apache Workers in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Busy Idle)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apachework") { my (@h,@p,@t); for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $apachebwork eq "") { push @p,undef; push @t,undef; } else { push @p,$apachebwork; push @t,$apacheiwork; &minmaxavg("DAY","1Busy",$apachebwork); &minmaxavg("DAY","2Idle",$apacheiwork); } } if ($minmaxavg{DAY}{"1Busy"}{CNT} > 0) {$minmaxavg{DAY}{"1Busy"}{AVG} /= $minmaxavg{DAY}{"1Busy"}{CNT}} if ($minmaxavg{DAY}{"2Idle"}{CNT} > 0) {$minmaxavg{DAY}{"2Idle"}{AVG} /= $minmaxavg{DAY}{"2Idle"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'Workers', x_label_skip => 60, title => 'Apache Workers in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Busy Idle)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apachework") { my (@h,@p,@t); for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $apachebwork_avg; my $apacheiwork_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $apachebwork ne "") { $apachebwork_avg += $apachebwork; $apacheiwork_avg += $apacheiwork; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; push @t,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$apachebwork_avg/$cnt_avg; push @t,$apacheiwork_avg/$cnt_avg; &minmaxavg("WEEK","1Busy",($apachebwork_avg/$cnt_avg)); &minmaxavg("WEEK","2Idle",($apacheiwork_avg/$cnt_avg)); } } if ($minmaxavg{WEEK}{"1Busy"}{CNT} > 0) {$minmaxavg{WEEK}{"1Busy"}{AVG} /= $minmaxavg{WEEK}{"1Busy"}{CNT}} if ($minmaxavg{WEEK}{"2Idle"}{CNT} > 0) {$minmaxavg{WEEK}{"2Idle"}{AVG} /= $minmaxavg{WEEK}{"2Idle"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Workers', x_label_skip => 24, title => 'Apache Workers in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Busy Idle)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "apachework") { my (@h,@p,@t); for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $apachebwork_avg; my $apacheiwork_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $apachebwork ne "") { $apachebwork_avg += $apachebwork; $apacheiwork_avg += $apacheiwork; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; push @t,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$apachebwork_avg/$cnt_avg; push @t,$apacheiwork_avg/$cnt_avg; &minmaxavg("MONTH","1Busy",($apachebwork_avg/$cnt_avg)); &minmaxavg("MONTH","2Idle",($apacheiwork_avg/$cnt_avg)); } } if ($minmaxavg{MONTH}{"1Busy"}{CNT} > 0) {$minmaxavg{MONTH}{"1Busy"}{AVG} /= $minmaxavg{MONTH}{"1Busy"}{CNT}} if ($minmaxavg{MONTH}{"2Idle"}{CNT} > 0) {$minmaxavg{MONTH}{"2Idle"}{AVG} /= $minmaxavg{MONTH}{"2Idle"}{CNT}} my @data = ([reverse @h],[reverse @p],[reverse @t]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'Workers', x_label_skip => 24, title => "Apache Workers in last $system_maxdays", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend( qw(Busy Idle)); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "diskw") { my (@h,@p); for (my $mins = 0; $mins < 60;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$min; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $diskw eq "") { push @p,undef; } else { push @p,$diskw; &minmaxavg("HOUR","1Disk_Write",$diskw); } } if ($minmaxavg{HOUR}{"1Disk_Write"}{CNT} > 0) {$minmaxavg{HOUR}{"1Disk_Write"}{AVG} /= $minmaxavg{HOUR}{"1Disk_Write"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Minute', y_label => 'MB/s', x_label_skip => 3, title => 'Disk Write Performance in last hour', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Disk_Write"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemhour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "diskw") { my (@h,@p); for (my $mins = 0; $mins < 1440;$mins++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($mins * 60)); push @h,$hour; my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$min}); if ($time eq "" or $diskw eq "") { push @p,undef; } else { push @p,$diskw; &minmaxavg("DAY","1Disk_Write",$diskw); } } if ($minmaxavg{DAY}{"1Disk_Write"}{CNT} > 0) {$minmaxavg{DAY}{"1Disk_Write"}{AVG} /= $minmaxavg{DAY}{"1Disk_Write"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred purple) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'MB/s', x_label_skip => 60, title => 'Disk Write Performance in last 24 hours', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Disk_Write"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemday.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "diskw") { my (@h,@p); for (my $hours = 0; $hours < 168;$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $diskw_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $diskw ne "") { $diskw_avg += $diskw; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$diskw_avg/$cnt_avg; &minmaxavg("WEEK","1Disk_Write",($diskw_avg/$cnt_avg)); } } if ($minmaxavg{WEEK}{"1Disk_Write"}{CNT} > 0) {$minmaxavg{WEEK}{"1Disk_Write"}{AVG} /= $minmaxavg{WEEK}{"1Disk_Write"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'MB/s', x_label_skip => 24, title => 'Disk Write Performance in last 7 days', borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Disk_Write"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemweek.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } if ($type eq "diskw") { my (@h,@p); for (my $hours = 0; $hours < (24 * $system_maxdays);$hours++) { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time - ($hours * 60 * 60)); push @h,$mday; my $diskw_avg; my $cnt_avg = 0; for (my $mins = 59; $mins >= 0;$mins--) { my ($time,$cputotal,$cpuidle,$cpuiowait,$memtotal,$memfree,$memswaptotal,$memswapfree,$load1,$load5,$load15,$netin,$netout,$diskread,$diskwrite,$mailin,$mailout,$cputemp,$mysqlin,$mysqlout,$mysqlq,$mysqlsq,$mysqlcn,$mysqlth,$apachecpu,$apacheacc,$apachebwork,$apacheiwork,$diskw,$memcached) = split(/\,/,$stata{$year}{$mon}{$mday}{$hour}{$mins}); if ($time and $diskw ne "") { $diskw_avg += $diskw; $cnt_avg++; } } unless (defined $cnt_avg) { push @p,undef; } else { if ($cnt_avg == 0) {$cnt_avg = 1} push @p,$diskw_avg/$cnt_avg; &minmaxavg("MONTH","1Disk_Write",($diskw_avg/$cnt_avg)); } } if ($minmaxavg{MONTH}{"1Disk_Write"}{CNT} > 0) {$minmaxavg{MONTH}{"1Disk_Write"}{AVG} /= $minmaxavg{MONTH}{"1Disk_Write"}{CNT}} my @data = ([reverse @h],[reverse @p]); my $hour_graph = GD::Graph::lines->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Day (Hourly Average)', y_label => 'MB/s', x_label_skip => 24, title => "Disk Write Performance in last $system_maxdays", borderclrs => $hour_graph->{dclrs}, transparent => 0, ); $hour_graph->set_legend("Disk_Write"); $hour_graph->plot(\@data); $img = $imghddir."lfd_systemmonth.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); } } return; } # end graphs ############################################################################### # start charts sub charts { my $cc_lookups = shift; my $imghddir = shift; my $img; $| = 1; require GD::Graph::bars; import GD::Graph::bars; require GD::Graph::pie; import GD::Graph::pie; require GD::Graph::lines; import GD::Graph::lines; sysopen (my $STATS,"/var/lib/csf/stats/lfdstats", O_RDWR | O_CREAT); flock ($STATS, LOCK_SH); my @stats = <$STATS>; chomp @stats; close ($STATS); if (@stats) { my $time = time; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time); # Blocks by lfd in the last 24 hours my $cnt = $hour + 1; if ($cnt > 23) {$cnt = 0} my (@h,@p,@t,@hp,@cp); my %triggers; for (my $hours = 0; $hours < 24;$hours++) { push @h,$cnt; my ($permdate,$permcount,$tempdate,$tempcount) = split(/\,/,$stats[$cnt]); if ($time - $permdate > (24 * 60 * 60)) {$permdate = 0; $permcount = 0} if ($time - $tempdate > (24 * 60 * 60)) {$tempdate = 0; $tempcount = 0} push @p,$permcount; push @t,$tempcount; my @line = split(/\,/,$stats[$cnt]); for (my $loop = 4; $loop < @line; $loop+=2) { if ($time - $line[$loop] > (24 * 60 * 60)) {next} my ($triggerstat,$triggercount) = split(/\:/,$line[$loop+1]); $triggers{$triggerstat} += $triggercount; } $cnt++; if ($cnt > 23) {$cnt = 0} } my @data = ([@h],[@p],[@t]); my $hour_graph = GD::Graph::bars->new(750,350); $hour_graph->set( dclrs => [ qw(yellow dred) ] ); $hour_graph->set( x_label => 'Hour', y_label => 'Total Blocks', long_ticks => 1, tick_length => 0, x_ticks => 0, title => 'Blocks by lfd in the last 24 hours', cumulate => 1, borderclrs => $hour_graph->{dclrs}, bar_spacing => 4, shadow_depth => 1, transparent => 0, x_label_position => 1/2, ); $hour_graph->set_legend( qw(Permanent Temporary)); $hour_graph->plot(\@data); $img = $imghddir."lfd_hour.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $hour_graph->gd->gif(); close ($OUT); foreach my $key (keys %triggers) { push @hp, "$key ($triggers{$key})"; push @cp, $triggers{$key}; } my @piedata = ([@hp],[@cp]); my $hour_pie_graph = GD::Graph::pie->new( 400, 300 ); $hour_pie_graph->set( title => 'Block triggers in the last 24 hours', label => 'Trigger in csf.conf', axislabelclr => 'black', pie_height => 36, l_margin => 15, r_margin => 15, start_angle => 235, transparent => 0, ); $hour_pie_graph->plot(\@piedata); $img = $imghddir."lfd_pie_hour.gif"; open (my $OUT2, ">", "$img"); flock ($OUT2, LOCK_EX); binmode ($OUT2); print $OUT2 $hour_pie_graph->gd->gif(); close ($OUT2); # Blocks by lfd in the last 30 Days my $maxdays = 30; my ($hsec,$hmin,$hhour,$hmday,$hmon,$hyear,$hwday,$hyday,$hisdst) = localtime($time - (29 * 24 * 60 * 60)); my $hdim = (31,28,31,30,31,30,31,31,30,31,30,31)[$hmon]; if ($hmon == 1 && (($hyear % 4 == 0) && ($hyear % 100 != 0) && ($hyear % 400 == 0))) {$hdim++} if ($hmon == 1) { $maxdays = $hdim; ($hsec,$hmin,$hhour,$hmday,$hmon,$hyear,$hwday,$hyday,$hisdst) = localtime($time - (($maxdays - 1) * 24 * 60 * 60)); } $cnt = $hmday; my (@hh,@ph,@th,@hhp,@hcp); my %htriggers; for (my $days = 1; $days <= $maxdays;$days++) { push @hh,$cnt; my ($permdate,$permcount,$tempdate,$tempcount) = split(/\,/,$stats[$cnt+24]); if ($time - $permdate > (($maxdays - 1) * 24 * 60 * 60)) {$permdate = 0; $permcount = 0} if ($time - $tempdate > (($maxdays - 1) * 24 * 60 * 60)) {$tempdate = 0; $tempcount = 0} push @ph,$permcount; push @th,$tempcount; my @line = split(/\,/,$stats[$cnt+24]); for (my $loop = 4; $loop < @line; $loop+=2) { if ($time - $line[$loop] > (($maxdays - 1) * 24 * 60 * 60)) {next} my ($triggerstat,$triggercount) = split(/\:/,$line[$loop+1]); $htriggers{$triggerstat} += $triggercount; } $cnt++; if ($cnt > $hdim) {$cnt = 1} } my @datah = ([@hh],[@ph],[@th]); my $day_graph = GD::Graph::bars->new(750,350); $day_graph->set( dclrs => [ qw(yellow dred) ] ); $day_graph->set( x_label => 'Day', y_label => 'Total Blocks', long_ticks => 1, tick_length => 0, x_ticks => 0, title => "Blocks by lfd in the last $maxdays Days", cumulate => 1, borderclrs => $day_graph->{dclrs}, bar_spacing => 4, shadow_depth => 1, transparent => 0, x_label_position => 1/2, ); $day_graph->set_legend( qw(Permanent Temporary)); $day_graph->plot(\@datah); $img = $imghddir."lfd_month.gif"; open (my $OUT3, ">", "$img"); flock ($OUT3, LOCK_EX); binmode ($OUT3); print $OUT3 $day_graph->gd->gif(); close ($OUT3); foreach my $key (keys %htriggers) { push @hhp, "$key ($htriggers{$key})"; push @hcp, $htriggers{$key}; } my @hpiedata = ([@hhp],[@hcp]); my $day_pie_graph = GD::Graph::pie->new( 400, 300 ); $day_pie_graph->set( title => "Block triggers in the last $maxdays days", label => 'Trigger in csf.conf', axislabelclr => 'black', pie_height => 36, l_margin => 15, r_margin => 15, start_angle => 235, transparent => 0, ); $day_pie_graph->plot(\@hpiedata); $img = $imghddir."lfd_pie_day.gif"; open (my $OUT4, ">", "$img"); flock ($OUT4, LOCK_EX); binmode ($OUT4); print $OUT4 $day_pie_graph->gd->gif(); close ($OUT4); # Blocks by lfd in the last 12 months $cnt = $mon + 2; if ($cnt > 12) {$cnt = 1} my (@hy,@py,@ty,@yhp,@ycp); my %ytriggers; for (my $months = 1; $months < 13;$months++) { push @hy,$cnt; my ($permdate,$permcount,$tempdate,$tempcount) = split(/\,/,$stats[$cnt+55]); if ($time - $permdate > (364 * 24 * 60 * 60)) {$permdate = 0; $permcount = 0} if ($time - $tempdate > (364 * 24 * 60 * 60)) {$tempdate = 0; $tempcount = 0} push @py,$permcount; push @ty,$tempcount; my @line = split(/\,/,$stats[$cnt+55]); for (my $loop = 4; $loop < @line; $loop+=2) { if ($time - $line[$loop] > (364 * 24 * 60 * 60)) {next} my ($triggerstat,$triggercount) = split(/\:/,$line[$loop+1]); $ytriggers{$triggerstat} += $triggercount; } $cnt++; if ($cnt > 12) {$cnt = 1} } my @datay = ([@hy],[@py],[@ty]); my $year_graph = GD::Graph::bars->new(750,350); $year_graph->set( dclrs => [ qw(yellow dred) ] ); $year_graph->set( x_label => 'Month', y_label => 'Total Blocks', long_ticks => 1, tick_length => 0, x_ticks => 0, title => 'Blocks by lfd in the last 12 months', cumulate => 1, borderclrs => $year_graph->{dclrs}, bar_spacing => 4, shadow_depth => 1, transparent => 0, x_label_position => 1/2, ); $year_graph->set_legend( qw(Permanent Temporary)); $year_graph->plot(\@datay); $img = $imghddir."lfd_year.gif"; open (my $OUT5, ">", "$img"); flock ($OUT5, LOCK_EX); binmode ($OUT5); print $OUT5 $year_graph->gd->gif(); close ($OUT5); foreach my $key (keys %ytriggers) { push @yhp, "$key ($ytriggers{$key})"; push @ycp, $ytriggers{$key}; } my @ypiedata = ([@yhp],[@ycp]); my $year_pie_graph = GD::Graph::pie->new( 400, 300 ); $year_pie_graph->set( title => 'Block triggers in the last 12 months', label => 'Trigger in csf.conf', axislabelclr => 'black', pie_height => 36, l_margin => 15, r_margin => 15, start_angle => 235, transparent => 0, ); $year_pie_graph->plot(\@ypiedata); $img = $imghddir."lfd_pie_year.gif"; open (my $OUT6, ">", "$img"); flock ($OUT6, LOCK_EX); binmode ($OUT6); print $OUT6 $year_pie_graph->gd->gif(); close ($OUT6); if ($cc_lookups) { # Total Top 30 Country Code blocks by lfd my (@ccy,@ccx); my %ccs; my $cntcc; my @line = split(/\,/,$stats[69]); for (my $x = 0; $x < @line; $x+=2) {$ccs{$line[$x]} = $line[$x+1]} foreach my $key (sort {$ccs{$b} <=> $ccs{$a}} keys %ccs) { push @ccy,$key; push @ccx,$ccs{$key}; $cntcc++; if ($cntcc > 29) {last} } my @datacc = ([@ccy],[@ccx]); my $cc_graph = GD::Graph::bars->new(750,350); $cc_graph->set( dclrs => [ qw(yellow) ] ); $cc_graph->set( x_label => 'Country Code', y_label => 'Total Blocks', long_ticks => 1, tick_length => 0, x_ticks => 0, title => 'Total Top 30 Country Code blocks by lfd', cumulate => 1, borderclrs => $cc_graph->{dclrs}, bar_spacing => 4, shadow_depth => 1, transparent => 0, x_label_position => 1/2, ); $cc_graph->plot(\@datacc); $img = $imghddir."lfd_cc.gif"; open (my $OUT, ">", "$img"); flock ($OUT, LOCK_EX); binmode ($OUT); print $OUT $cc_graph->gd->gif(); close ($OUT); } } return; } # end charts ############################################################################### # start minmaxavg sub minmaxavg { my $graph = shift; my $name = shift; my $value = shift; unless (defined $minmaxavg{$graph}{$name}{MIN}) {$minmaxavg{$graph}{$name}{MIN} = $value} unless (defined $minmaxavg{$graph}{$name}{MAX}) {$minmaxavg{$graph}{$name}{MAX} = $value} if ($minmaxavg{$graph}{$name}{MIN} > $value) {$minmaxavg{$graph}{$name}{MIN} = $value} if ($minmaxavg{$graph}{$name}{MAX} < $value) {$minmaxavg{$graph}{$name}{MAX} = $value} $minmaxavg{$graph}{$name}{AVG} += $value; $minmaxavg{$graph}{$name}{CNT}++; return; } # end minmaxavg ############################################################################### # start graphs_html sub graphs_html { my $imgdir = shift; my $html; $html .= "\n"; $html .= "\n
\n"; $html .= "


\n"; foreach my $key (sort keys %{$minmaxavg{HOUR}}) { my $item = $key; if ($key =~ /^\d(.*)$/) {$item = $1} $html .= ""; $html .= ""; $html .= ""; $html .= "\n"; } $html .= "
$itemMin:".sprintf("%.2f",$minmaxavg{HOUR}{$key}{MIN})."Max:".sprintf("%.2f",$minmaxavg{HOUR}{$key}{MAX})."Avg:".sprintf("%.2f",$minmaxavg{HOUR}{$key}{AVG})."

Note: This graph displays per minute statistics unless otherwise stated
\n"; $html .= "


\n"; foreach my $key (sort keys %{$minmaxavg{DAY}}) { my $item = $key; if ($key =~ /^\d(.*)$/) {$item = $1} $html .= ""; $html .= ""; $html .= ""; $html .= "\n"; } $html .= "
$itemMin:".sprintf("%.2f",$minmaxavg{DAY}{$key}{MIN})."Max:".sprintf("%.2f",$minmaxavg{DAY}{$key}{MAX})."Avg:".sprintf("%.2f",$minmaxavg{DAY}{$key}{AVG})."

Note: This graph displays per minute statistics unless otherwise stated
\n"; $html .= "


\n"; foreach my $key (sort keys %{$minmaxavg{WEEK}}) { my $item = $key; if ($key =~ /^\d(.*)$/) {$item = $1} $html .= ""; $html .= ""; $html .= ""; $html .= "\n"; } $html .= "
$itemMin:".sprintf("%.2f",$minmaxavg{WEEK}{$key}{MIN})."Max:".sprintf("%.2f",$minmaxavg{WEEK}{$key}{MAX})."Avg:".sprintf("%.2f",$minmaxavg{WEEK}{$key}{AVG})."

Note: This graph displays an hourly average of the per minute statistics, so you will not see the peak minute values
\n"; $html .= "


\n"; foreach my $key (sort keys %{$minmaxavg{MONTH}}) { my $item = $key; if ($key =~ /^\d(.*)$/) {$item = $1} $html .= ""; $html .= ""; $html .= ""; $html .= "\n"; } $html .= "
$itemMin:".sprintf("%.2f",$minmaxavg{MONTH}{$key}{MIN})."Max:".sprintf("%.2f",$minmaxavg{MONTH}{$key}{MAX})."Avg:".sprintf("%.2f",$minmaxavg{MONTH}{$key}{AVG})."

Note: This graph displays an hourly average of the per minute statistics, so you will not see the peak minute values
\n"; return $html; } # end graphs_html ############################################################################### # start charts_html sub charts_html { my $cc_lookups = shift; my $imgdir = shift; my $html; $html .= "\n"; $html .= "\n\n\n
\n"; $html .= "

 

\n"; $html .= "

\n"; $html .= "
\n"; $html .= "

 

\n"; $html .= "

\n"; if ($cc_lookups) { $html .= "
\n"; $html .= "

 

\n"; $html .= "

\n"; $html .= "
\n"; $html .= "

\n"; } else { $html .= "
\n"; $html .= "

 

\n"; $html .= "

\n"; } $html .= "
\n"; return $html; } # end charts_html ############################################################################### 1;CheckIP.pm000064400000006006151030020750006343 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;KillSSH.pm000064400000004671151030020750006354 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;RBLLookup.pm000064400000005653151030020750006715 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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; Ports.pm000064400000013277151030020750006214 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;Sanity.pm000064400000003603151030020750006344 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;GetEthDev.pm000064400000007171151030020750006720 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;ServerCheck.pm000064400000233172151030020750007307 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen) # start main package ConfigServer::ServerCheck; use strict; use lib '/usr/local/csf/lib'; use Fcntl qw(:DEFAULT :flock); use File::Basename; use IPC::Open3; use ConfigServer::Slurp qw(slurp); use ConfigServer::Sanity qw(sanity);; use ConfigServer::Config; use ConfigServer::GetIPs qw(getips); use ConfigServer::CheckIP qw(checkip); use ConfigServer::Service; use ConfigServer::GetEthDev; use Exporter qw(import); our $VERSION = 1.05; our @ISA = qw(Exporter); our @EXPORT_OK = qw(); my (%config, $cpconf, %daconfig, $cleanreg, $mypid, $childin, $childout, $verbose, $cpurl, @processes, $total, $failures, $current, $DEBIAN, $output, $sysinit, %g_ifaces, %g_ipv4, %g_ipv6); my $ipv4reg = ConfigServer::Config->ipv4reg; my $ipv6reg = ConfigServer::Config->ipv6reg; use Exporter qw(import); # end main ############################################################################### # start report sub report { $verbose = shift; my $config = ConfigServer::Config->loadconfig(); %config = $config->config(); $cleanreg = ConfigServer::Slurp->cleanreg; $| = 1; if (defined $ENV{WEBMIN_VAR} and defined $ENV{WEBMIN_CONFIG}) { $config{GENERIC} = 1; $config{DIRECTADMIN} = 0; } elsif (-e "/usr/local/cpanel/version") { use lib "/usr/local/cpanel"; require Cpanel::Form; import Cpanel::Form; require Cpanel::Config; import Cpanel::Config; $cpconf = Cpanel::Config::loadcpconf(); } elsif (-e "/usr/local/directadmin/conf/directadmin.conf") { my ($childin, $childout); my $mypid = open3($childin, $childout, $childout, "/usr/local/directadmin/directadmin", "c"); my @data = <$childout>; waitpid ($mypid, 0); chomp @data; foreach my $line (@data) { my ($name,$value) = split(/\=/,$line); $daconfig{lc($name)} = $value; } $config{DIRECTADMIN} = 1; } elsif (-e "/etc/psa/psa.conf") { $config{PLESK} = 1; } $failures = 0; $total = 0; if ($ENV{cp_security_token}) {$cpurl = $ENV{cp_security_token}} $DEBIAN = 0; if (-e "/etc/lsb-release" or -e "/etc/debian_version") {$DEBIAN = 1} $sysinit = ConfigServer::Service::type(); if ($sysinit ne "systemd") {$sysinit = "init"} opendir (PROCDIR, "/proc"); while (my $pid = readdir(PROCDIR)) { if ($pid !~ /^\d+$/) {next} push @processes, readlink("/proc/$pid/exe"); } my $ethdev = ConfigServer::GetEthDev->new(); %g_ifaces = $ethdev->ifaces; %g_ipv4 = $ethdev->ipv4; %g_ipv6 = $ethdev->ipv6; &startoutput; &firewallcheck; &servercheck; &sshtelnetcheck; unless ($config{DNSONLY} or $config{GENERIC}) {&mailcheck} unless ($config{DNSONLY} or $config{GENERIC}) {&apachecheck} unless ($config{DNSONLY} or $config{GENERIC}) {&phpcheck} unless ($config{DNSONLY} or $config{GENERIC}) {&whmcheck} if ($config{DIRECTADMIN}) { &mailcheck; &apachecheck; &phpcheck; &dacheck; } &servicescheck; &endoutput; return $output; } # end report ############################################################################### # start startoutput sub startoutput { if ($config{THIS_UI} and !$config{GENERIC}) { $output .= "

Note: Internal WHM links will not work within the csf Integrated UI

\n"; } return; } # end startoutput ############################################################################### # start addline sub addline { my $status = shift; my $check = shift; my $comment = shift; $total++; if ($status) { $output .= "
\n"; $output .= "
$check
\n"; $output .= "
$comment
\n"; $output .= "
\n"; $failures ++; $current++; } elsif ($verbose) { $output .= "
\n"; $output .= "
$check
\n"; $output .= "
$comment
\n"; $output .= "
\n"; $current++; } return; } # end addline ############################################################################### # start addtitle sub addtitle { my $title = shift; if (defined $current and $current == 0) { $output .= "
OK
\n"; } $current = 0; $output .= "
$title
\n"; return; } # end addtitle ############################################################################### # start endoutput sub endoutput { if (defined $current and $current == 0) { $output .= "
OK
\n"; } $output .= "
\n"; my $gap = int(($total-3)/4); my $score = ($total - $failures); my $width = int ((400 / $total) * $score) - 4; $output .= "
\n\n
\n"; $output .= "

Server Score: $score/$total*

\n"; $output .= "
\n"; $output .= "\n"; $output .= "\n"; $output .= "\n"; $output .= "\n"; $output .= "\n"; $output .= "\n"; $output .= "\n"; $output .= "
    $total (max) 
\n"; $output .= "
\n"; $output .= "
\n"; $output .= "\n"; $output .= "\n"; $output .= "\n"; $output .= "\n"; $output .= "\n"; $output .= "\n"; $output .= "
   $score (score)
\n"; $output .= "
\n"; $output .= "
* This scoring does not necessarily reflect the security of the server or the relative merits of each check
"; $output .= "
"; return; } # end endoutput ############################################################################### # start firewallcheck sub firewallcheck { &addtitle("Firewall Check"); my $status = 0; open (my $IN, "<", "/etc/csf/csf.conf"); flock ($IN, LOCK_SH); my @config = <$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 { &error(__LINE__,"Invalid configuration line"); } $config{$name} = $value; } $status = 0; if (-e "/etc/csf/csf.disable") {$status = 1} &addline($status,"csf enabled check","csf is currently disabled and should be enabled otherwise it is not functioning"); if (-x $config{IPTABLES}) { my ($childin, $childout); my $mypid = open3($childin, $childout, $childout, "$config{IPTABLES} $config{IPTABLESWAIT} -L INPUT -n"); my @iptstatus = <$childout>; waitpid ($mypid, 0); chomp @iptstatus; if ($iptstatus[0] =~ /# Warning: iptables-legacy tables present/) {shift @iptstatus} $status = 0; if ($iptstatus[0] =~ /policy ACCEPT/) {$status = 1} &addline($status,"csf running check","iptables is not configured. You need to start csf"); } $status = 0; if ($config{TESTING}) {$status = 1} &addline($status,"TESTING mode check","csf is in TESTING mode. If the firewall is working set TESTING to \"0\" in the Firewall Configuration otherwise it will continue to be stopped"); $status = 0; unless ($config{RESTRICT_SYSLOG}) {$status = 1} &addline($status,"RESTRICT_SYSLOG option check","Due to issues with syslog/rsyslog you should consider enabling this option. See the Firewall Configuration (/etc/csf/csf.conf) for more information"); $status = 0; unless ($config{AUTO_UPDATES}) {$status = 1} &addline($status,"AUTO_UPDATES option check","To keep csf up to date and secure you should enable AUTO_UPDATES. You should also monitor our blog"); $status = 0; unless ($config{LF_DAEMON}) {$status = 1} &addline($status,"lfd enabled check","lfd is disabled in the csf configuration which limits the affectiveness of this application"); $status = 0; if ($config{TCP_IN} =~ /\b3306\b/) {$status = 1} &addline($status,"Incoming MySQL port check","The TCP incoming MySQL port (3306) is open. This can pose both a security and server abuse threat since not only can hackers attempt to break into MySQL, any user can host their SQL database on your server and access it from another host and so (ab)use your server resources"); unless ($config{DNSONLY} or $config{GENERIC}) { unless ($config{VPS}) { $status = 0; unless ($config{SMTP_BLOCK}) {$status = 1} &addline($status,"SMTP_BLOCK option check","This option will help prevent the most common form of spam abuse on a server that bypasses exim and sends spam directly out through port 25. Enabling this option will prevent any web script from sending out using socket connection, such scripts should use the exim or sendmail binary instead"); } $status = 0; unless ($config{LF_SCRIPT_ALERT}) {$status = 1} &addline($status,"LF_SCRIPT_ALERT option check","This option will notify you when a large amount of email is sent from a particular script on the server, helping track down spam scripts"); } $status = 0; my @options = ("LF_SSHD","LF_FTPD","LF_SMTPAUTH","LF_POP3D","LF_IMAPD","LF_HTACCESS","LF_MODSEC","LF_CPANEL","LF_CPANEL_ALERT","SYSLOG_CHECK","RESTRICT_UI"); if ($config{GENERIC}) {@options = ("LF_SSHD","LF_FTPD","LF_SMTPAUTH","LF_POP3D","LF_IMAPD","LF_HTACCESS","LF_MODSEC","SYSLOG_CHECK","FASTSTART","RESTRICT_UI");} if ($config{DNSONLY}) {@options = ("LF_SSHD","LF_CPANEL","SYSLOG_CHECK","FASTSTART","RESTRICT_UI")} foreach my $option (@options) { $status = 0; unless ($config{$option}) {$status = 1} &addline($status,"$option option check","This option helps prevent brute force attacks on your server services or overall server stability"); } $status = 0; unless ($config{LF_DIRWATCH}) {$status = 1} &addline($status,"LF_DIRWATCH option check","This option will notify when a suspicious file is found in one of the common temp directories on the server"); $status = 0; unless ($config{LF_INTEGRITY}) {$status = 1} &addline($status,"LF_INTEGRITY option check","This option will notify when an executable in one of the common directories on the server changes in some way. This helps alert you to potential rootkit installation or server compromise"); $status = 0; unless ($config{FASTSTART}) {$status = 1} &addline($status,"FASTSTART option check","This option can dramatically improve the startup time of csf and the rule loading speed of lfd"); $status = 0; if ($config{URLGET} == 1) {$status = 1} &addline($status,"URLGET option check","This option determines which perl module is used to upgrade csf. It is recommended to set this to use LWP rather than HTTP::Tiny so that upgrades are performed over an SSL connection"); $status = 0; if ($config{PT_USERKILL} == 1) {$status = 1} &addline($status,"PT_USERKILL option check","This option should not normally be enabled as it can easily lead to legitimate processes being terminated, use csf.pignore instead"); unless ($config{DNSONLY} or $config{GENERIC}) { $status = 0; if ($config{PT_SKIP_HTTP}) {$status = 1} &addline($status,"PT_SKIP_HTTP option check","This option disables checking of processes running under apache and can limit false-positives but may then miss running exploits"); } $status = 0; if (!$config{LF_IPSET} and !$config{VPS} and ($config{CC_DENY} or $config{CC_ALLOW} or $config{CC_ALLOW_FILTER} or $config{CC_ALLOW_PORTS} or $config{CC_DENY_PORTS})) {$status = 1} &addline($status,"LF_IPSET option check","If support by your OS, you should install ipset and enable LF_IPSET when using Country Code (CC_*) filters"); unless ($config{DNSONLY} or $config{GENERIC}) { $status = 0; unless ($config{PT_ALL_USERS}) {$status = 1} &addline($status,"PT_ALL_USERS option check","This option ensures that almost all Linux accounts are checked with Process Tracking, not just the cPanel ones"); } sysopen (my $CONF, "/etc/csf/csf.conf", O_RDWR | O_CREAT); flock ($CONF, LOCK_SH); my @confdata = <$CONF>; close ($CONF); chomp @confdata; foreach my $line (@confdata) { if (($line !~ /^\#/) and ($line =~ /=/)) { my ($start,$end) = split (/=/,$line,2); my $name = $start; $name =~ s/\s/\_/g; if ($end =~ /\"(.*)\"/) {$end = $1} my ($insane,$range,$default) = sanity($start,$end); if ($insane) { &addline(1,"$start sanity check","$start = $end. Recommended range: $range (Default: $default)"); } } } return; } # end firewallcheck ############################################################################### # start servercheck sub servercheck { &addtitle("Server Check"); my $status = 0; my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("/tmp"); my $pmode = sprintf "%03o", $mode & oct("07777"); $status = 0; if ($pmode != 1777) {$status = 1} &addline($status,"Check /tmp permissions","/tmp should be chmod 1777"); $status = 0; if (($uid != 0) or ($gid != 0)) {$status = 1} &addline($status,"Check /tmp ownership","/tmp should be owned by root:root"); if (-d "/var/tmp") { ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("/var/tmp"); $pmode = sprintf "%04o", $mode & oct("07777"); $status = 0; if ($pmode != 1777) {$status = 1} &addline($status,"Check /var/tmp permissions","/var/tmp should be chmod 1777"); $status = 0; if (($uid != 0) or ($gid != 0)) {$status = 1} &addline($status,"Check /var/tmp ownership","/var/tmp should be owned by root:root"); } if (-d "/usr/tmp") { ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("/usr/tmp"); $pmode = sprintf "%04o", $mode & oct("07777"); $status = 0; if ($pmode != 1777) {$status = 1} &addline($status,"Check /usr/tmp permissions","/usr/tmp should be chmod 1777"); $status = 0; if (($uid != 0) or ($gid != 0)) {$status = 1} &addline($status,"Check /usr/tmp ownership","/usr/tmp should be owned by root:root"); } $status = 0; if (&getportinfo(53)) { my @files = ("/var/named/chroot/etc/named.conf","/etc/named.conf","/etc/bind/named.conf","/var/named/chroot/etc/bind/named.conf"); my @namedconf; my @morefiles; my $hit; foreach my $file (@files) { if (-e $file) { $hit = 1; open (my $IN, "<", "$file"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; if (my @ls = grep {$_ =~ /^\s*include\s+(.*)\;\s*$/i} @conf) { foreach my $more (@ls) { if ($more =~ /^\s*include\s+\"(.*)\"\s*\;\s*$/i) {push @morefiles, $1} } } @namedconf = (@namedconf, @conf); } } foreach my $file (@morefiles) { if (-e $file) { open (my $IN, "<", "$file"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; @namedconf = (@namedconf, @conf); } } if ($hit) { # if (my @ls = grep {$_ =~ /^\s*(recursion\s+no|allow-recursion)/} @namedconf) {$status = 0} else {$status = 1} # &addline($status,"Check for DNS recursion restrictions","You have a local DNS server running but do not appear to have any recursion restrictions set. This is a security and performance risk and you should look at restricting recursive lookups to the local IP addresses only"); if (my @ls = grep {$_ =~ /^\s*(query-source\s[^\;]*53)/} @namedconf) {$status = 1} else {$status = 0} &addline($status,"Check for DNS random query source port","ISC recommend that you do not configure BIND to use a static query port. You should remove/disable the query-source line that specifies port 53 from the named configuration files"); } } if (!$DEBIAN and $sysinit eq "init" and -x "/sbin/runlevel") { $status = 0; $mypid = open3($childin, $childout, $childout, "/sbin/runlevel"); my @conf = <$childout>; waitpid ($mypid, 0); chomp @conf; my (undef,$runlevel) = split(/\s/,$conf[0]); if ($runlevel != 3) {$status = 1} &addline($status,"Check server runlevel","The servers runlevel is currently set to $runlevel. For a secure server environment you should only run the server at runlevel 3. You can fix this by editing /etc/inittab and changing the initdefault line to:
id:3:initdefault:
and then rebooting the server"); } $status = 0; if ((-e "/var/spool/cron/nobody") and !(-z "/var/spool/cron/nobody")) {$status = 1} &addline($status,"Check nobody cron","You have a nobody cron log file - you should check that this has not been created by an exploit"); $status = 0; my ($isfedora, $isrh, $version, $conf) = 0; if (-e "/etc/fedora-release") { open (my $IN, "<", "/etc/fedora-release"); flock ($IN, LOCK_SH); $conf = <$IN>; close ($IN); $isfedora = 1; if ($conf =~ /release (\d+)/i) {$version = $1} } elsif (-e "/etc/redhat-release") { open (my $IN, "<", "/etc/redhat-release"); flock ($IN, LOCK_SH); $conf = <$IN>; close ($IN); $isrh = 1; if ($conf =~ /release (\d+)/i) {$version = $1} } chomp $conf; if ($isrh or $isfedora) { if (($isfedora and $version < 30) or ($isrh and $version < 6)) {$status = 1} &addline($status,"Check Operating System support","You are running an OS - $conf - that is no longer supported by the OS vendor, or is about to become obsolete. This means that you will be receiving no OS updates (i.e. application or security bug fixes) or kernel updates and should consider moving to an OS that is supported as soon as possible"); } $status = 0; if ($] < 5.008008) { $status = 1; } else {$status = 0} &addline($status,"Check perl version","The version of perl (v$]) is out of date and you should upgrade it"); $status = 0; while (my ($name,undef,$uid) = getpwent()) { if (($uid == 0) and ($name ne "root")) {$status = 1} } &addline($status,"Check SUPERUSER accounts","You have accounts other than root set up with UID 0. This is a considerable security risk. You should use su, or best of all sudo for such access"); if (-e "/usr/local/cpanel/version" or $config{DIRECTADMIN}) { $status = 0; unless (-e "/etc/cxs/cxs.pl") { $status = 1; } &addline($status,"Check for cxs","You should consider using cxs to scan web script uploads and user accounts for exploits uploaded to the server"); $status = 0; unless (-e "/etc/osm/osmd.pl") { $status = 1; } &addline($status,"Check for osm","You should consider using osm to provide protection from spammers exploiting the server"); } unless ($config{IPV6}) { $status = 0; my $ipv6 = ""; foreach my $key (keys %g_ipv6) { if ($ipv6) {$ipv6 .= ", "} $ipv6 .= $key; $status = 1; } if ($ipv6 eq "::1") {$ipv6 = ""; $status = 0} &addline($status,"Check for IPv6","IPv6 appears to be enabled [$ipv6]. If ip6tables is installed, you should enable the csf IPv6 firewall (IPV6 in csf.conf)"); } if ($sysinit eq "init") { $status = 1; my $syslog = 0; if (grep {$_ =~ /\/syslogd\s*/} @processes) { $syslog = 1; if (grep {$_ =~ /\/klogd$/} @processes) {$status = 0} &addline($status,"Check for kernel logger","syslogd appears to be running, but not klogd which logs kernel firewall messages to syslog. You should ensure that klogd is running"); } if (grep {$_ =~ /\/rsyslogd\s*/} @processes) { $syslog = 1; if (grep {$_ =~ /\/rklogd\s*/} @processes) { $status = 0; } else { open (my $IN, "<", "/etc/rsyslog.conf"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; if (grep {$_ =~ /^\$ModLoad imklog/} @conf) {$status = 0} } &addline($status,"Check for kernel logger","rsyslogd appears to be running, but klog may not be loaded which logs kernel firewall messages to rsyslog. You should modify /etc/rsyslogd to load the klog module with:
\$ModLoad imklog
Then restart rsyslog"); } unless ($syslog) { $status = 1; &addline($status,"Check for syslog or rsyslog","Neither syslog nor rsyslog appear to be running"); } } $status = 0; if (grep {$_ =~ /\/dhclient\s*/} @processes) {$status = 1} &addline($status,"Check for dhclient","dhclient appears to be running which suggests that the server is obtaining an IP address via DHCP. This can pose a security risk. You should configure static IP addresses for all ethernet controllers"); unless ($config{VPS}) { $status = 1; open (my $IN, "<", "/proc/swaps"); flock ($IN, LOCK_SH); my @swaps = <$IN>; close ($IN); if (scalar(@swaps) > 1) {$status = 0} &addline($status,"Check for swap file","The server appears to have no swap file. This is usually considered a stability and performance risk. You should either add a swap partition, or create one via a normal file on an existing partition"); if (-e "/etc/redhat-release") { open (my $IN, "<", "/etc/redhat-release"); flock ($IN, LOCK_SH); $conf = <$IN>; close ($IN); chomp $conf; if ($conf =~ /^CloudLinux/i) { $status = 0; if (-e "/usr/sbin/cagefsctl") { } else {$status = 1} &addline($status,"CloudLinux CageFS","CloudLinux CageFS is not installed. This CloudLinux option greatly improves server security on we servers by separating user accounts into their own environment"); unless ($status) { $status = 0; $mypid = open3($childin, $childout, $childout, "/usr/sbin/cagefsctl","--cagefs-status"); my @conf = <$childout>; waitpid ($mypid, 0); chomp @conf; if ($conf[0] !~ /^Enabled/) {$status = 1} &addline($status,"CloudLinux CageFS Enabled","CloudLinux CageFS is not enabled. This CloudLinux option greatly improves server security on we servers by separating user accounts into their own environment"); } $status = 0; open (my $ENFORCE_SYMLINKSIFOWNER, "<", "/proc/sys/fs/enforce_symlinksifowner"); flock ($ENFORCE_SYMLINKSIFOWNER, LOCK_SH); $conf = <$ENFORCE_SYMLINKSIFOWNER>; close ($ENFORCE_SYMLINKSIFOWNER); chomp $conf; if ($conf < 1) {$status = 1} &addline($status,"CloudLinux Symlink Protection","CloudLinux Symlink Protection is not configured. You should configure it in /etc/sysctl.conf to prevent symlink attacks on web servers"); $status = 0; open (my $PROC_CAN_SEE_OTHER_UID, "<", "/proc/sys/fs/proc_can_see_other_uid"); flock ($PROC_CAN_SEE_OTHER_UID, LOCK_SH); $conf = <$PROC_CAN_SEE_OTHER_UID>; close ($PROC_CAN_SEE_OTHER_UID); chomp $conf; if ($conf > 0) {$status = 1} &addline($status,"CloudLinux Virtualised /proc","CloudLinux Virtualised /proc is not configured. You should configure it in /etc/sysctl.conf to prevent users accessing server resources that they do not need on web servers"); $status = 0; open (my $USER_PTRACE, "<", "/proc/sys/kernel/user_ptrace"); flock ($USER_PTRACE, LOCK_SH); $conf = <$USER_PTRACE>; close ($USER_PTRACE); chomp $conf; if ($conf > 0) {$status = 1} &addline($status,"CloudLinux Disable ptrace","CloudLinux Disable ptrace is not configured. You should configure it in /etc/sysctl.conf to prevent users accessing server resources that they do not need on web servers"); } } } return; } # end servercheck ############################################################################### # start whmcheck sub whmcheck { my $status = 0; &addtitle("WHM Settings Check"); $status = 0; unless ($cpconf->{alwaysredirecttossl}) {$status = 1} &addline($status,"Check cPanel login is SSL only","You should check WHM > Tweak Settings > Choose the closest matched domain for which that the system has a valid certificate when redirecting from non-SSL to SSL URLs"); $status = 0; unless ($cpconf->{skipboxtrapper}) {$status = 1} &addline($status,"Check boxtrapper is disabled","Having boxtrapper enabled can very easily lead to your server being listed in common RBLs and usually has the effect of increasing the overall spam load, not reducing it. You should disable it in WHM > Tweak Settings > BoxTrapper Spam Trap"); $status = 0; if (-e "/var/cpanel/greylist/enabled") {$status = 1} &addline($status,"Check GreyListing is disabled","Using GreyListing can and will lead to lost legitimate emails. It can also cause significant problems with \"password verification\" systems. See here for more information"); if (defined $cpconf->{popbeforesmtp}) { $status = 0; if ($cpconf->{popbeforesmtp}) {$status = 1} &addline($status,"Check popbeforesmtp is disabled","Using pop before smtp is considered a security risk, SMTP AUTH should be used instead. You should disable it in WHM > Tweak Settings > Allow users to relay mail if they use an IP address through which someone has validated an IMAP or POP3 login"); } $status = 0; unless ($cpconf->{maxemailsperhour}) {$status = 1} &addline($status,"Check max emails per hour is set","To limit the damage that can be caused by potential spammers on the server you should set a value for WHM > Tweak Settings > Max hourly emails per domain"); $status = 0; if ($cpconf->{resetpass}) {$status = 1} &addline($status,"Check Reset Password for cPanel accounts","This poses a potential security risk and should be disabled unless necessary in WHM > Tweak Settings > Reset Password for cPanel accounts"); $status = 0; if ($cpconf->{resetpass_sub}) {$status = 1} &addline($status,"Check Reset Password for Subaccounts","This poses a potential security risk and should be disabled unless necessary in WHM > Tweak Settings > Reset Password for Subaccounts "); foreach my $openid (glob "/var/cpanel/authn/openid_connect/*") { open (my $IN, "<", $openid); flock ($IN, LOCK_SH); my $line = <$IN>; close ($IN); chomp $line; my ($file, $filedir) = fileparse($openid); $status = 0; if ($line =~ /\{"cpanelid"/) {$status = 1} &addline($status,"Check cPanelID for $file","You should only enable this option if you are going to use it otherwise it is a potential security risk in WHM > Manage External Authentications > $file"); } unless ($cpconf->{nativessl} eq undef) { $status = 0; unless ($cpconf->{nativessl}) {$status = 1} &addline($status,"Check whether native cPanel SSL is enabled","You should enable this option so that lfd tracks SSL cpanel login attempts WHM > Tweak Settings > Use native SSL support if possible, negating need for Stunnel"); } $status = 0; my $cc = '/usr/bin/cc'; while ( readlink($cc) ) { $cc = readlink($cc); } if ( $cc !~ /^\// ) { $cc = '/usr/bin/' . $cc; } my $mode = substr( sprintf( "%o", ( ( stat($cc) )[2] ) ), 2, 4 ); if ( $mode > 750 ) {$status = 1} &addline($status,"Check compilers","You should disable compilers WHM > Security Center > Compilers Access"); if (-e "/etc/pure-ftpd.conf" and ($cpconf->{ftpserver} eq "pure-ftpd") and !(-e "/etc/ftpddisable")) { $status = 0; open (my $IN, "<", "/etc/pure-ftpd.conf"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; if (my @ls = grep {$_ =~ /^\s*NoAnonymous\s*(no|off)/i} @conf) {$status = 1} &addline($status,"Check Anonymous FTP Logins","Used as an attack vector by hackers and should be disabled unless actively used WHM > FTP Server Configuration > Allow Anonymous Logins > No"); $status = 0; if (my @ls = grep {$_ =~ /^\s*AnonymousCantUpload\s*(no|off)/i} @conf) {$status = 1} &addline($status,"Check Anonymous FTP Uploads","Used as an attack vector by hackers and should be disabled unless actively used WHM > FTP Server Configuration > Allow Anonymous Uploads > No"); $status = 0; my $ciphers; my $error; if (my @ls = grep {$_ =~ /^\s*TLSCipherSuite/} @conf) { if ($ls[0] =~ /TLSCipherSuite\s+(.*)$/) {$ciphers = $1} $ciphers =~ s/\s*|\"|\'//g; if ($ciphers eq "") { $status = 1; } elsif ($ciphers !~ /SSL/) { $status = 0 } else { if (-x "/usr/bin/openssl") { my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, "/usr/bin/openssl","ciphers","-v",$ciphers); my @openssl = <$childout>; waitpid ($cmdpid, 0); chomp @openssl; if (my @ls = grep {$_ =~ /error/i} @openssl) {$error = $openssl[0]; $status=2} if (my @ls = grep {$_ =~ /SSLv2/} @openssl) {$status = 1} } } } else {$status = 1} if ($status == 2) { &addline($status,"Check pure-ftpd weak SSL/TLS Ciphers (TLSCipherSuite)","Unable to determine cipher list for [$ciphers] from openssl:
[$error]"); } &addline($status,"Check pure-ftpd weak SSL/TLS Ciphers (TLSCipherSuite)","Cipher list [$ciphers]. Due to weaknesses in the SSLv2 cipher you should disable SSLv2 in WHM > FTP Server Configuration > TLS Cipher Suite > Remove +SSLv2 or Add -SSLv2"); $status = 0; unless (-e "/var/cpanel/conf/pureftpd/root_password_disabled") {$status = 1} &addline($status,"Check FTP Logins with Root Password","Allowing root login via FTP is a considerable security risk and should be disabled WHM > FTP Server Configuration > Allow Logins with Root Password > No"); } if (-e "/var/cpanel/conf/proftpd/main" and ($cpconf->{ftpserver} eq "proftpd") and !(-e "/etc/ftpddisable")) { $status = 0; open (my $IN, "<", "/var/cpanel/conf/proftpd/main"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; if (my @ls = grep {$_ =~ /^cPanelAnonymousAccessAllowed: 'yes'/i} @conf) {$status = 1} &addline($status,"Check Anonymous FTP Logins","Used as an attack vector by hackers and should be disabled unless actively used WHM > FTP Server Configuration > Allow Anonymous Logins > No"); $status = 0; my $ciphers; my $error; if (my @ls = grep {$_ =~ /^\s*TLSCipherSuite/} @conf) { if ($ls[0] =~ /TLSCipherSuite\:\s+(.*)$/) {$ciphers = $1} $ciphers =~ s/\s*|\"|\'//g; if ($ciphers eq "") { $status = 1; } else { if (-e "/usr/bin/openssl") { my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, "/usr/bin/openssl","ciphers","-v",$ciphers); my @openssl = <$childout>; waitpid ($cmdpid, 0); chomp @openssl; if (my @ls = grep {$_ =~ /error/i} @openssl) {$error = $openssl[0]; $status=2} if (my @ls = grep {$_ =~ /SSLv2/} @openssl) {$status = 1} } } } else {$status = 1} if ($status == 2) { &addline($status,"Check proftpd weak SSL/TLS Ciphers (TLSCipherSuite)","Unable to determine cipher list for [$ciphers] from openssl:
[$error]"); } &addline($status,"Check proftpd weak SSL/TLS Ciphers (TLSCipherSuite)","Cipher list [$ciphers]. Due to weaknesses in the SSLv2 cipher you should disable SSLv2 in WHM > FTP Server Configuration > TLS Cipher Suite > Remove +SSLv2 or Add -SSLv2"); if ($config{VPS}) { $status = 0; open (my $IN, "<", "/etc/proftpd.conf"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; if (my @ls = grep {$_ =~ /^\s*PassivePorts\s+(\d+)\s+(\d+)/} @conf) { if ($config{TCP_IN} !~ /\b$1:$2\b/) {$status = 1} } else {$status = 1} &addline($status,"Check VPS FTP PASV hole","Since the Virtuozzo VPS iptables ip_conntrack_ftp kernel module is currently broken you have to open a PASV port hole in iptables for incoming FTP connections to work correctly. See the csf readme.txt under 'A note about FTP Connection Issues' on how to do this"); } } $status = 0; if ($cpconf->{allowremotedomains}) {$status = 1} &addline($status,"Check allow remote domains","User can park domains that resolve to other servers on this server. You should disable WHM > Tweak Settings > Allow Remote Domains"); $status = 0; unless ($cpconf->{blockcommondomains}) {$status = 1} &addline($status,"Check block common domains","User can park common domain names on this server. You should disable WHM > Tweak Settings > Prevent cPanel users from creating specific domains"); $status = 0; if ($cpconf->{allowparkonothers}) {$status = 1} &addline($status,"Check allow park domains","User can park/addon domains that belong to other users on this server. You should disable WHM > Tweak Settings > Allow cPanel users to create subdomains across accounts"); $status = 0; if ($cpconf->{proxysubdomains}) {$status = 1} &addline($status,"Check proxy subdomains","This option can mask a users real IP address and hinder security. You should disable WHM > Tweak Settings > Service subdomains"); $status = 1; if ($cpconf->{cpaddons_notify_owner}) {$status = 0} &addline($status,"Check cPAddons update email to resellers","You should have cPAddons email users if cPAddon installations require updating WHM > Tweak Settings > Notify reseller of cPAddons Site Software installations"); $status = 1; if ($cpconf->{cpaddons_notify_root}) {$status = 0} &addline($status,"Check cPAddons update email to root","You should have cPAddons email root if cPAddon installations require updating WHM > Tweak Settings > Notify root of cPAddons Site Software installations"); if (-e "/etc/cpupdate.conf") { open (my $IN, "<", "/etc/cpupdate.conf"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; $status = 0; if (my @ls = grep {$_ =~ /^CPANEL=(edge|beta|nightly)/i} @conf) {$status = 1} &addline($status,"Check cPanel tree","Running EDGE/BETA on a production server could lead to server instability"); $status = 1; if (my @ls = grep {$_ =~ /^UPDATES=daily/i} @conf) {$status = 0} &addline($status,"Check cPanel updates","You have cPanel updating disabled, this can pose a security and stability risk. WHM > Update Preferences > Enabled Automatic Updates"); # $status = 0; # if (grep {$_ =~ /^SYSUP=/i} @conf) {$status = 1} # if (grep {$_ =~ /^SYSUP=daily/i} @conf) {$status = 0} # &addline($status,"Check package updates","You have package updating disabled, this can pose a security and stability risk. WHM > Update Config >cPanel Package Updates > Automatic"); # $status = 1; # if (my @ls = grep {$_ =~ /^RPMUP=daily/i} @conf) {$status = 0} # &addline($status,"Check security updates","You have security updating disabled, this can pose a security and stability risk. WHM > Update Config >Operating System Package Updates > Automatic"); } else {&addline(1,"Check cPanel updates","Unable to find /etc/cpupdate.conf");} $status = 1; if ($cpconf->{account_login_access} eq "user") {$status = 0} &addline($status,"Check accounts that can access a cPanel user","You should consider setting this option to \"user\" after use. WHM > Tweak Settings > Accounts that can access a cPanel user account"); unless ($status) { $status = 0; open (my $IN, "<", "/usr/local/cpanel/3rdparty/etc/php.ini"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; if (my @ls = grep {$_ =~ /^\s*register_globals\s*=\s*on/i} @conf) {$status = 1} &addline($status,"Check cPanel php.ini file for register_globals","PHP register_globals is considered a high security risk. It is currently enabled in /usr/local/cpanel/3rdparty/etc/php.ini and should be disabled (disabling may break 3rd party PHP cPanel apps)"); } $status = 0; if ($cpconf->{emailpasswords}) {$status = 1} &addline($status,"Check cPanel passwords in email","You should not send passwords out in plain text emails. You should disable WHM > Tweak Settings > Send passwords when creating a new account"); $status = 0; if ($cpconf->{coredump}) {$status = 1} &addline($status,"Check core dumps","You should disable WHM > Tweak Settings > Allow WHM/Webmail/cPanel services to create core dumps for debugging purposes"); $status = 1; if ($cpconf->{cookieipvalidation} eq "strict") {$status = 0} &addline($status,"Check Cookie IP Validation","You should enable strict Cookie IP validation in WHM > Tweak Settings > Cookie IP validation"); $status = 1; if ($cpconf->{use_apache_md5_for_htaccess}) {$status = 0} &addline($status,"Check MD5 passwords with Apache","You should enable WHM > Tweak Settings > Use MD5 passwords with Apache"); $status = 1; if ($cpconf->{referrerblanksafety}) {$status = 0} &addline($status,"Check Referrer Blank Security","You should enable WHM > Tweak Settings > Blank referrer safety check"); $status = 1; if ($cpconf->{referrersafety}) {$status = 0} &addline($status,"Check Referrer Security","You should enable WHM > Tweak Settings > Referrer safety check"); $status = 1; if ($cpconf->{skiphttpauth}) {$status = 0} &addline($status,"Check HTTP Authentication","You should disable skiphttpauth in /var/cpanel/cpanel.config"); $status = 0; if ($cpconf->{skipparentcheck}) {$status = 1} &addline($status,"Check Parent Security","You should disable WHM > Tweak Settings > Allow other applications to run the cPanel and admin binaries"); $status = 0; if ($cpconf->{"cpsrvd-domainlookup"}) {$status = 1} &addline($status,"Check Domain Lookup Security","You should disable WHM > Tweak Settings > cpsrvd username domain lookup"); $status = 1; if ($cpconf->{"cgihidepass"}) {$status = 0} &addline($status,"Check Password ENV variable","You should enable WHM > Tweak Settings > Hide login password from cgi scripts "); $status = 0; if (-e "/var/cpanel/smtpgidonlytweak") {$status = 1} &addline($status,"Check SMTP Restrictions","This option in WHM will not function when running csf. You should disable WHM > Security Center > SMTP Restrictions and use the csf configuration option SMTP_BLOCK instead"); if (-e "/etc/wwwacct.conf") { $status = 1; open (my $IN, "<", "/etc/wwwacct.conf"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; my %ips; foreach my $key (keys %g_ipv4) { $ips{$key} = 1; } my $nameservers; my $local = 0; my $allns = 0; foreach my $line (@conf) { if ($line =~ /^NS(\d)?\s+(.*)\s*$/) { my $ns = $2; $ns =~ s/\s//g; if ($ns) { $allns++; $nameservers .= "$ns
\n"; my $ip; if (checkip(\$ns)) { $ip = $ns; if ($ips{$ip}) {$local++} } else { my @ips = getips($ns); unless (scalar @ips) {&addline(1,"Check nameservers","Unable to resolve nameserver [$ns]")} my $hit = 0; foreach my $oip (@ips) { if ($ips{$oip}) {$hit = 1} } if ($hit) {$local++} } } } } if ($local < $allns) {$status = 0} &addline($status,"Check nameservers","At least one of the configured nameservers:
\n$nameservers should be located in a topologically and geographically dispersed location on the Internet - See RFC 2182 (Section 3.1)"); } if (-e "/usr/local/cpanel/bin/register_appconfig") { $status = 0; if ($cpconf->{permit_unregistered_apps_as_reseller}) {$status = 1} &addline($status,"Check AppConfig Required","You should disable WHM > Tweak Settings > Allow apps that have not registered with AppConfig to be run when logged in as a reseller in WHM"); $status = 0; if ($cpconf->{permit_unregistered_apps_as_root}) {$status = 1} &addline($status,"Check AppConfig as root","You should disable WHM > Tweak Settings > Allow apps that have not registered with AppConfig to be run when logged in as root or a reseller with the \"all\" ACL in WHM"); $status = 0; if ($cpconf->{permit_appconfig_entries_without_acls}) {$status = 1} &addline($status,"Check AppConfig ACLs","You should disable WHM > Tweak Settings > Allow WHM apps registered with AppConfig to be executed even if a Required ACLs list has not been defined"); $status = 0; if ($cpconf->{permit_appconfig_entries_without_features}) {$status = 1} &addline($status,"Check AppConfig Feature List","You should disable WHM > Tweak Settings > Allow cPanel and Webmail apps registered with AppConfig to be executed even if a Required Features list has not been defined"); } $status = 0; if ($cpconf->{"disable-security-tokens"}) {$status = 1} &addline($status,"Check Security Tokens","Security Tokens should not be disabled as without them security of WHM/cPanel is compromised. The setting disable-security-tokens=0 should be set in /var/cpanel/cpanel.config"); return; } # end whmcheck ############################################################################### # start dacheck sub dacheck { my $status = 0; &addtitle("DirectAdmin Settings Check"); $status = 0; unless ($daconfig{ssl}) {$status = 1} &addline($status,"Check DirectAdmin login is SSL only","You should enable SSL only login to DirectAdmin"); if (($daconfig{ftpconfig} =~ /proftpd.conf/) and ($daconfig{pureftp} != 1)) { $status = 0; open (my $IN, "<", $daconfig{ftpconfig}); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; my $ciphers; my $error; if (my @ls = grep {$_ =~ /^\s*TLSCipherSuite/} @conf) { if ($ls[0] =~ /TLSCipherSuite\s+(.*)$/) {$ciphers = $1} $ciphers =~ s/\s*|\"|\'//g; if ($ciphers eq "") { $status = 1; } else { if (-e "/usr/bin/openssl") { my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, "/usr/bin/openssl","ciphers","-v",$ciphers); my @openssl = <$childout>; waitpid ($cmdpid, 0); chomp @openssl; if (my @ls = grep {$_ =~ /error/i} @openssl) {$error = $openssl[0]; $status=2} if (my @ls = grep {$_ =~ /SSLv2/} @openssl) {$status = 1} } } } else {$status = 1} if ($status == 2) { &addline($status,"Check proftpd weak SSL/TLS Ciphers (TLSCipherSuite)","Unable to determine cipher list for [$ciphers] from openssl:
[$error]"); } &addline($status,"Check proftpd weak SSL/TLS Ciphers (TLSCipherSuite)","Cipher list [$ciphers]. Due to weaknesses in the SSLv2 cipher you should add a TLSCipherSuite with SSLv2 disabled in $daconfig{ftpconfig}. For example,
<IfModule mod_tls.c>
TLSCipherSuite HIGH
</IfModule> container
"); if ($config{VPS}) { $status = 0; if (my @ls = grep {$_ =~ /^\s*PassivePorts\s+(\d+)\s+(\d+)/} @conf) { if ($config{TCP_IN} !~ /\b$1:$2\b/) {$status = 1} } else {$status = 1} &addline($status,"Check VPS FTP PASV hole","Since the Virtuozzo VPS iptables ip_conntrack_ftp kernel module is currently broken you have to open a PASV port hole in iptables for incoming FTP connections to work correctly. See the csf readme.txt under 'A note about FTP Connection Issues' on how to do this"); } } $status = 1; my %ips; foreach my $key (keys %g_ipv4) { $ips{$key} = 1; } my $nameservers; for (my $x = 1; $x < 3; $x++) { my $ns = $daconfig{"ns$x"}; $ns =~ s/\s//g; if ($ns) { $nameservers .= "$ns
\n"; my $ip; if ($ns =~ /\d+\.\d+\.\d+\.d+/) { $ip = $ns; } else { eval { local $SIG{__DIE__} = undef; local $SIG{'ALRM'} = sub {die}; alarm(5); $ip = gethostbyname($ns); $ip = inet_ntoa($ip); alarm(0); }; alarm(0); unless ($ip) {&addline(1,"Check nameservers","Unable to resolve nameserver [$ns] within 5 seconds")} } if ($ip) { unless ($ips{$ip}) {$status = 0} } } } &addline($status,"Check nameservers","At least one of the configured nameservers:
\n$nameservers should be located in a topologically and geographically dispersed location on the Internet - See RFC 2182 (Section 3.1)"); return; } # end dacheck ############################################################################### # start mailcheck sub mailcheck { &addtitle("Mail Check"); my $status = 0; unless ($config{DIRECTADMIN}) { if (-e "/root/.forward") { if (-z "/root/.forward") {$status = 1} } else {$status = 1} &addline($status,"Check root forwarder","The root account should have a forwarder set so that you receive essential email from your server"); } if (-e "/etc/exim.conf" and -x "/usr/sbin/exim") { $status = 0; my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, "/usr/sbin/exim","-bP"); my @eximconf = <$childout>; waitpid ($cmdpid, 0); chomp @eximconf; if (my @ls = grep {$_ =~ /^\s*log_selector/} @eximconf) { if (($ls[0] !~ /\+all/) and ($ls[0] !~ /\+arguments/) and ($ls[0] !~ /\+arguments/)) {$status = 1} } else {$status = 1} if ($config{DIRECTADMIN}) { &addline($status,"Check exim for extended logging (log_selector)","You should enable extended exim logging to enable easier tracking potential outgoing spam issues. Add:
log_selector = +arguments +subject +received_recipients
to /etc/exim.conf"); } else { &addline($status,"Check exim for extended logging (log_selector)","You should enable extended exim logging to enable easier tracking potential outgoing spam issues. Add:
log_selector = +arguments +subject +received_recipients
in WHM > Exim Configuration Manager > Advanced Editor > log_selector"); } $status = 0; my $ciphers; my $error; if (my @ls = grep {$_ =~ /^\s*tls_require_ciphers/} @eximconf) { (undef,$ciphers) = split(/\=/,$ls[0]); $ciphers =~ s/\s*|\"|\'//g; if ($ciphers eq "") { $status = 1; } else { if (-x "/usr/bin/openssl") { my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, "/usr/bin/openssl","ciphers","-v",$ciphers); my @openssl = <$childout>; waitpid ($cmdpid, 0); chomp @openssl; if (my @ls = grep {$_ =~ /error/i} @openssl) {$error = $openssl[0]; $status=2} if (my @ls = grep {$_ =~ /SSLv2/} @openssl) {$status = 1} } } } else {$status = 1} if ($status == 2) { &addline($status,"Check exim weak SSL/TLS Ciphers (tls_require_ciphers)","Unable to determine cipher list for [$ciphers] from openssl:
[$error]"); } if ($config{DIRECTADMIN}) { &addline($status,"Check exim weak SSL/TLS Ciphers (tls_require_ciphers)","Cipher list [$ciphers]. Due to weaknesses in the SSLv2 cipher you should edit /etc/exim.conf and set tls_require_ciphers to explicitly exclude it. For example:
tls_require_ciphers=ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP"); } else { &addline($status,"Check exim weak SSL/TLS Ciphers (tls_require_ciphers)","Cipher list [$ciphers]. Due to weaknesses in the SSLv2 cipher you should disable WHM > Exim Configuration Manager > Allow weak ssl/tls ciphers to be used, and also ensure tls_require_ciphers in /etc/exim.conf does not allow SSLv2 as openssl currently shows that it does"); } } else {&addline(1,"Check exim configuration","Unable to find /etc/exim.conf and/or /usr/sbin/exim");} if (-e "/etc/exim.conf.localopts") { $status = 0; open (my $IN, "<", "/etc/exim.conf.localopts"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; if (my @ls = grep {$_ =~ /require_secure_auth=0/i} @conf) {$status = 1} &addline($status,"Check exim for secure authentication","You should require clients to connect with SSL or issue the STARTTLS command before they are allowed to authenticate with the server, otherwise passwords may be sent in plain text
in WHM > Exim Configuration Manager"); } if ($config{DIRECTADMIN}) { if (-e "/etc/dovecot.conf" and ($daconfig{dovecot})) { $status = 0; open (my $IN, "<", "/etc/dovecot.conf"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; my @morefiles; if (my @ls = grep {$_ =~ /^\s*\!\s*include(_try)?\s+(.*)\s*$/i} @conf) { foreach my $more (@ls) { if ($more =~ /^\s*\!\s*include(_try)?\s+(.*)\s*$/i) { my $conf = $2; if ($conf !~ /^\//) {$conf = "/etc/dovecot/".$conf} push @morefiles, $conf; } } } foreach my $file (@morefiles) { if (-e $file) { open (my $IN, "<", "$file"); flock ($IN, LOCK_SH); my @moreconf = <$IN>; close ($IN); chomp @conf; @conf = (@conf, @moreconf); } } my $ciphers; my $error; if (my @ls = grep {$_ =~ /^ssl_cipher_list/} @conf) { (undef,$ciphers) = split(/\=/,$ls[0]); $ciphers =~ s/\s*|\"|\'//g; if ($ciphers eq "") { $status = 1; } else { if (-x "/usr/bin/openssl") { my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, "/usr/bin/openssl","ciphers","-v",$ciphers); my @openssl = <$childout>; waitpid ($cmdpid, 0); chomp @openssl; if (my @ls = grep {$_ =~ /error/i} @openssl) {$error = $openssl[0]; $status=2} if (my @ls = grep {$_ =~ /SSLv2/} @openssl) {$status = 1} } } } else {$status = 1} if ($status == 2) { &addline($status,"Check dovecot weak SSL/TLS Ciphers (ssl_cipher_list)","Unable to determine cipher list for [$ciphers] from openssl:
[$error]"); } &addline($status,"Check dovecot weak SSL/TLS Ciphers (ssl_cipher_list)","Cipher list [$ciphers]. Due to weaknesses in the SSLv2 cipher you should /etc/dovecot.conf and set ssl_cipher_list to explicitly exclude it. For example:
ssl_cipher_list = ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP"); } } else { if (-e "/etc/dovecot/dovecot.conf" and ($cpconf->{mailserver} eq "dovecot")) { $status = 0; open (my $IN, "<", "/etc/dovecot/dovecot.conf"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; my @morefiles; if (my @ls = grep {$_ =~ /^\s*\!?include(_try)?\s+(.*)\s*$/i} @conf) { foreach my $more (@ls) { if ($more =~ /^\s*\!?include(_try)?\s+(.*)\s*$/i) {push @morefiles, $2} } } foreach my $file (@morefiles) { if (-e $file) { open (my $IN, "<", "$file"); flock ($IN, LOCK_SH); my @moreconf = <$IN>; close ($IN); chomp @conf; @conf = (@conf, @moreconf); } } $status = 0; my $ciphers; my $error; if (my @ls = grep {$_ =~ /^ssl_cipher_list/} @conf) { (undef,$ciphers) = split(/\=/,$ls[0]); $ciphers =~ s/\s*|\"|\'//g; if ($ciphers eq "") { $status = 1; } else { if (-x "/usr/bin/openssl") { my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, "/usr/bin/openssl","ciphers","-v",$ciphers); my @openssl = <$childout>; waitpid ($cmdpid, 0); chomp @openssl; if (my @ls = grep {$_ =~ /error/i} @openssl) {$error = $openssl[0]; $status=2} if (my @ls = grep {$_ =~ /SSLv2/} @openssl) {$status = 1} } } } else {$status = 1} if ($status == 2) { &addline($status,"Check dovecot weak SSL/TLS Ciphers (ssl_cipher_list)","Unable to determine cipher list for [$ciphers] from openssl:
[$error]"); } &addline($status,"Check dovecot weak SSL/TLS Ciphers (ssl_cipher_list)","Cipher list [$ciphers]. Due to weaknesses in the SSLv2 cipher you should disable SSLv2 in WHM > Mailserver Configuration > SSL Cipher List > Remove +SSLv2 or Add -SSLv2"); } if (-e "/usr/lib/courier-imap/etc/imapd-ssl" and ($cpconf->{mailserver} eq "courier")) { $status = 0; open (my $IN, "<", "/usr/lib/courier-imap/etc/imapd-ssl"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; $status = 0; my $ciphers; my $error; if (my @ls = grep {$_ =~ /^TLS_CIPHER_LIST/} @conf) { (undef,$ciphers) = split(/\=/,$ls[0]); $ciphers =~ s/\s*|\"|\'//g; if ($ciphers eq "") { $status = 1; } else { if (-x "/usr/bin/openssl") { my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, "/usr/bin/openssl","ciphers","-v",$ciphers); my @openssl = <$childout>; waitpid ($cmdpid, 0); chomp @openssl; if (my @ls = grep {$_ =~ /error/i} @openssl) {$error = $openssl[0]; $status=2} if (my @ls = grep {$_ =~ /SSLv2/} @openssl) {$status = 1} } } } else {$status = 1} if ($status == 2) { &addline($status,"Check Courier IMAP weak SSL/TLS Ciphers (TLS_CIPHER_LIST)","Unable to determine cipher list for [$ciphers] from openssl:
[$error]"); } &addline($status,"Check Courier IMAP weak SSL/TLS Ciphers (TLS_CIPHER_LIST)","Cipher list [$ciphers]. Due to weaknesses in the SSLv2 cipher you should disable SSLv2 in WHM > Mailserver Configuration > IMAP TLS/SSL Cipher List > Remove +SSLv2 or Add -SSLv2"); } if (-e "/usr/lib/courier-imap/etc/pop3d-ssl" and ($cpconf->{mailserver} eq "courier")) { $status = 0; open (my $IN, "<", "/usr/lib/courier-imap/etc/pop3d-ssl"); flock ($IN, LOCK_SH); my @conf = <$IN>; close ($IN); chomp @conf; $status = 0; my $ciphers; my $error; if (my @ls = grep {$_ =~ /^TLS_CIPHER_LIST/} @conf) { (undef,$ciphers) = split(/\=/,$ls[0]); $ciphers =~ s/\s*|\"|\'//g; if ($ciphers eq "") { $status = 1; } else { if (-x "/usr/bin/openssl") { my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, "/usr/bin/openssl","ciphers","-v",$ciphers); my @openssl = <$childout>; waitpid ($cmdpid, 0); chomp @openssl; if (my @ls = grep {$_ =~ /error/i} @openssl) {$error = $openssl[0]; $status=2} if (my @ls = grep {$_ =~ /SSLv2/} @openssl) {$status = 1} } } } else {$status = 1} if ($status == 2) { &addline($status,"Check Courier POP3D weak SSL/TLS Ciphers (TLS_CIPHER_LIST)","Unable to determine cipher list for [$ciphers] from openssl:
[$error]"); } &addline($status,"Check Courier POP3D weak SSL/TLS Ciphers (TLS_CIPHER_LIST)","Cipher list [$ciphers]. Due to weaknesses in the SSLv2 cipher you should disable SSLv2 in WHM > Mailserver Configuration > POP3 TLS/SSL Cipher List > Remove +SSLv2 or Add -SSLv2"); } } return; } # end mailcheck ############################################################################### # start phpcheck sub phpcheck { &addtitle("PHP Check"); my %phpbinaries; my %phpinis; if (-e "/usr/local/cpanel/version" and -e "/etc/cpanel/ea4/is_ea4") { foreach my $phpdir (glob("/opt/cpanel/ea-*")) { if (-e "${phpdir}/root/usr/bin/php") {$phpbinaries{"${phpdir}/root/usr/bin/php"} = 1} } } elsif ($config{DIRECTADMIN}) { foreach my $phpdir (glob("/usr/local/php*")) { if (-e "${phpdir}/bin/php") {$phpbinaries{"${phpdir}/bin/php"} = 1} } } elsif (-e "/usr/local/bin/php") {$phpbinaries{"/usr/local/bin/php"} = 1} elsif (-e "/usr/bin/php") {$phpbinaries{"/usr/bin/php"} = 1} if (-e "/opt/alt/alt-php-config") { foreach my $phpdir (glob("/opt/alt/php*")) { if (-e "${phpdir}/usr/bin/php") {$phpbinaries{"${phpdir}/usr/bin/php"} = 1} } } if (scalar(keys %phpbinaries) == 0) { &addline(1,"PHP Binary","PHP binary not found or not executable"); return; } foreach my $phpbin (keys %phpbinaries) { if ($phpbin =~ /php44/) {$phpinis{"/opt/alt/php44/etc/php.ini"} = $phpbin} elsif ($phpbin =~ /php51/) {$phpinis{"/opt/alt/php51/etc/php.ini"} = $phpbin} else { my ($childin, $childout); my $mypid = open3($childin, $childout, $childout, $phpbin,"-d","zlib.output_compression=Off","--ini"); my @conf = <$childout>; waitpid ($mypid, 0); chomp @conf; foreach my $line (@conf) { if ($line =~ /^Loaded Configuration File:\s*(\S+)$/) {$phpinis{$1} = $phpbin} } } } my %phpconf; foreach my $phpini (sort keys %phpinis) { my $phpbin = $phpinis{$phpini}; my $status = 0; my ($childin, $childout); my $mypid; if ($phpbin =~ /php44|php51/) { $mypid = open3($childin, $childout, $childout, $phpbin,"-i"); } else { $mypid = open3($childin, $childout, $childout, $phpbin,"-d","zlib.output_compression=Off","-i"); } my @conf = <$childout>; waitpid ($mypid, 0); chomp @conf; if (my @ls = grep {$_ =~ /^PHP License/} @conf) { my $version = 0; my ($mas,$maj,$min); if (my @ls = grep {$_ =~ /^PHP Version\s*=>\s*/i} @conf) { my $line = $ls[0]; $line =~ /^PHP Version\s*=>\s*(.*)/i; ($mas,$maj,$min) = split(/\./,$1); $version = "$mas.$maj.$min"; if ($mas < 8) {$status = 1} if ($mas == 8 and $maj < 1) {$status = 1} } open (my $IN, "<", "/usr/local/apache/conf/php.conf.yaml"); flock ($IN, LOCK_SH); my @phpyamlconf = <$IN>; close ($IN); chomp @phpyamlconf; if (my @ls = grep {$_ =~ /php4:/i} @phpyamlconf) { if ($ls[0] !~ /none/) { $status = 1; $version = "4.*"; } } unless ($phpbin =~ m[^/opt/alt/php]) { if ($status) {$phpconf{version} .= "$version ($phpbin),"} } $status = 1; if (my @ls = grep {$_ =~ /^enable_dl\s*=>\s*Off/i} @conf) { $status = 0; } if (my @ls = grep {$_ =~ /^disable_functions\s*=>.*dl.*/i} @conf) { $status = 0; } if ($status) {$phpconf{enable_dl} .= "$phpini ($phpbin),"} $status = 1; if (my @ls = grep {$_ =~ /^disable_functions\s*=>.*\,/i} @conf) { $status = 0; } if ($status) {$phpconf{disable_functions} .= "$phpini ($phpbin),"} $status = 1; if (my @ls = grep {$_ =~ /^disable_functions\s*=>.*ini_set.*/i} @conf) { $status = 0; } if ($status) {$phpconf{ini_set} .= "$phpini ($phpbin),"} my $oldver = "$mas.$maj"; if ($oldver < 5.4) { $status = 1; if (my @ls = grep {$_ =~ /^register_globals\s*=>\s*Off/i} @conf) { $status = 0; } if ($status) {$phpconf{register_globals} .= "$phpini ($phpbin),"} } } else { $status = 1; &addline($status,"Check php
[$phpbin]","Unable to examine PHP settings due to an error in the output from: [$phpbin -i]"); } } foreach my $key ("version","enable_dl","disable_functions","ini_set","register_globals") { my $values; foreach my $value (split(/\,/,$phpconf{$key})) { if ($value eq "") {next} $values .= "
$value\n"; } if ($key eq "version") { my $status = 0; if ($values ne "") {$status = 1} &addline($status,"Check php version","Any version of PHP older than v8.1.* is now obsolete and should be considered a security threat. You should upgrade to at least PHP v8.1+:
Affected PHP versions:$values"); } if ($key eq "enable_dl") { my $status = 0; if ($values ne "") {$status = 1} &addline($status,"Check php for enable_dl or disabled dl()","You should set:
enable_dl = Off
This prevents users from loading php modules that affect everyone on the server. Note that if use dynamic libraries, such as ioncube, you will have to load them directly in the PHP configuration:
Affected PHP versions:$values"); } if ($key eq "disable_functions") { my $status = 0; if ($values ne "") {$status = 1} &addline($status,"Check php for disable_functions","You should consider disabling commonly abused php functions, e.g.:
disable_functions = show_source, system, shell_exec, passthru, exec, popen, proc_open
Some client web scripts may break with some of these functions disabled, so you may have to remove them from this list:
Affected PHP versions:$values"); } if ($key eq "register_globals") { my $status = 0; if ($values ne "") {$status = 1} &addline($status,"Check php for register_globals","You should set:
register_globals = Off
unless it is absolutely necessary as it is seen as a significant security risk:
Affected PHP versions:$values"); } } return; } # end phpcheck ############################################################################### # start apachecheck sub apachecheck { &addtitle("Apache Check"); my $status = 0; my $mypid; my ($childin, $childout); my %ea4; if (-e "/usr/local/cpanel/version" and -e "/etc/cpanel/ea4/is_ea4" and -e "/etc/cpanel/ea4/paths.conf") { my @file = slurp("/etc/cpanel/ea4/paths.conf"); $ea4{enabled} = 1; foreach my $line (@file) { $line =~ s/$cleanreg//g; if ($line =~ /^(\s|\#|$)/) {next} if ($line !~ /=/) {next} my ($name,$value) = split (/=/,$line,2); $value =~ s/^\s+//g; $value =~ s/\s+$//g; $ea4{$name} = $value; } } if ($ea4{enabled}) { unless (-x $ea4{bin_httpd}) {&addline(1,"HTTP Binary","$ea4{bin_httpd} not found or not executable"); return} } elsif ($config{DIRECTADMIN}) { unless (-x "/usr/sbin/httpd") {&addline(1,"HTTP Binary","/usr/sbin/httpd not found or not executable"); return} } else { unless (-x "/usr/local/apache/bin/httpd") {&addline(1,"HTTP Binary","/usr/local/apache/bin/httpd not found or not executable"); return} } if ($ea4{enabled}) { $mypid = open3($childin, $childout, $childout, $ea4{bin_httpd},"-v"); } elsif ($config{DIRECTADMIN}) { $mypid = open3($childin, $childout, $childout, "/usr/sbin/httpd","-v"); } else { $mypid = open3($childin, $childout, $childout, "/usr/local/apache/bin/httpd","-v"); } my @version = <$childout>; waitpid ($mypid, 0); chomp @version; $version[0] =~ /Apache\/(\d+)\.(\d+)\.(\d+)/; my $mas = $1; my $maj = $2; my $min = $3; if ("$mas.$maj" < 2.2) {$status = 1} &addline($status,"Check apache version","You are running a legacy version of apache (v$mas.$maj.$min) and should consider upgrading to v2.2.* as recommended by the Apache developers"); unless ($config{DIRECTADMIN}) { my $ruid2 = 0; if ($ea4{enabled}) { $mypid = open3($childin, $childout, $childout, $ea4{bin_httpd},"-M"); } else { $mypid = open3($childin, $childout, $childout, "/usr/local/apache/bin/httpd","-M"); } my @modules = <$childout>; waitpid ($mypid, 0); chomp @modules; if (my @ls = grep {$_ =~ /ruid2_module/} @modules) {$ruid2 = 1} if (my @ls = grep {$_ =~ /mpm_itk_module/} @modules) {$ruid2 = 1} $status = 0; if (my @ls = grep {$_ =~ /security2_module/} @modules) {$status = 0} else {$status = 1} &addline($status,"Check apache for ModSecurity","You should install the ModSecurity apache module during the easyapache build process to help prevent exploitation of vulnerable web scripts, together with a set of rules"); $status = 0; if (my @ls = grep {$_ =~ /cloudflare_module/} @modules) {$status = 1} else {$status = 0} if ($config{CF_ENABLE}) {$status = 0} &addline($status,"Check apache for mod_cloudflare","This module logs the real users IP address to Apache. If this is reported to lfd via ModSecurity, cxs or some other vector through Apache it will lead to that IP being blocked, but because the IP is coming through the CloudFlare service the IP will not be blocked as so far as iptables is concerned the originating IP address is CloudFlare itself and the abuse will continue. To block these IP's in the CloudFlare Firewall look at using CF_ENABLE in csf.conf"); $status = 0; if (my @ls = grep {$_ =~ /frontpage_module/} @modules) {$status = 1} &addline($status,"Check apache for FrontPage","Microsoft Frontpage Extensions were EOL in 2006 and there is no support for bugs or security issues. For this reason, it should be considered a security risk to continue using them. You should rebuild apache through easyapache and deselect the option to build them"); my @conf; if (-e "/usr/local/apache/conf/httpd.conf") { open (my $IN, "<", "/usr/local/apache/conf/httpd.conf"); flock ($IN, LOCK_SH); @conf = <$IN>; close ($IN); chomp @conf; } if (-e "$ea4{file_conf}") { open (my $IN, "<", "$ea4{file_conf}"); flock ($IN, LOCK_SH); @conf = <$IN>; close ($IN); chomp @conf; } if (@conf) { $status = 0; my $ciphers; my $error; if (my @ls = grep {$_ =~ /^\s*SSLCipherSuite/} @conf) { $ls[0] =~ s/^\s+//g; (undef,$ciphers) = split(/\ /,$ls[0]); $ciphers =~ s/\s*|\"|\'//g; if ($ciphers eq "") { $status = 1; } else { if (-x "/usr/bin/openssl") { my ($childin, $childout); my $cmdpid = open3($childin, $childout, $childout, "/usr/bin/openssl","ciphers","-v",$ciphers); my @openssl = <$childout>; waitpid ($cmdpid, 0); chomp @openssl; if (my @ls = grep {$_ =~ /error/i} @openssl) {$error = $openssl[0]; $status=2} if (my @ls = grep {$_ =~ /SSLv2/} @openssl) {$status = 1} } } } else {$status = 1} if ($status == 2) { &addline($status,"Check Apache weak SSL/TLS Ciphers (SSLCipherSuite)","Unable to determine cipher list for [$ciphers] from openssl:
[$error]"); } &addline($status,"Check Apache weak SSL/TLS Ciphers (SSLCipherSuite)","Cipher list [$ciphers]. Due to weaknesses in the SSLv2 cipher you should disable SSLv2 in WHM > Apache Configuration > Global Configuration > SSLCipherSuite > Add -SSLv2 to SSLCipherSuite and/or remove +SSLv2. Do not forget to Save AND then Rebuild Configuration and Restart Apache, otherwise the changes will not take effect in httpd.conf"); $status = 0; if (my @ls = grep {$_ =~ /^\s*TraceEnable Off/} @conf) { $status = 0; } else {$status = 1} &addline($status,"Check apache for TraceEnable","You should set TraceEnable to Off in: WHM > Apache Configuration > Global Configuration > Trace Enable > Off. Do not forget to Save AND then Rebuild Configuration and Restart Apache, otherwise the changes will not take effect in httpd.conf"); $status = 0; if (my @ls = grep {$_ =~ /^\s*ServerSignature Off/} @conf) { $status = 0; } else {$status = 1} &addline($status,"Check apache for ServerSignature","You should set ServerSignature to Off in: WHM > Apache Configuration > Global Configuration > Server Signature > Off. Do not forget to Save AND then Rebuild Configuration and Restart Apache, otherwise the changes will not take effect in httpd.conf"); $status = 0; if (my @ls = grep {$_ =~ /^\s*ServerTokens ProductOnly/} @conf) { $status = 0; } else {$status = 1} &addline($status,"Check apache for ServerTokens","You should set ServerTokens to ProductOnly in: WHM > Apache Configuration > Global Configuration > Server Tokens > Product Only. Do not forget to Save AND then Rebuild Configuration and Restart Apache, otherwise the changes will not take effect in httpd.conf"); $status = 0; if (my @ls = grep {$_ =~ /^\s*FileETag None/} @conf) { $status = 0; } else {$status = 1} &addline($status,"Check apache for FileETag","You should set FileETag to None in: WHM > Apache Configuration > Global Configuration > File ETag > None. Do not forget to Save AND then Rebuild Configuration and Restart Apache, otherwise the changes will not take effect in httpd.conf"); } my @apacheconf; if (-e "/usr/local/apache/conf/php.conf.yaml") { open (my $IN, "<", "/usr/local/apache/conf/php.conf.yaml"); flock ($IN, LOCK_SH); @apacheconf = <$IN>; close ($IN); chomp @apacheconf; } if (-e "$ea4{dir_conf}/php.conf.yaml") { open (my $IN, "<", "$ea4{dir_conf}/php.conf.yaml"); flock ($IN, LOCK_SH); @apacheconf = <$IN>; close ($IN); chomp @apacheconf; } if (@apacheconf) { unless ($ruid2) { $status = 0; if (my @ls = grep {$_ =~ /suphp/} @apacheconf) { $status = 0; } else {$status = 1} &addline($status,"Check suPHP","To reduce the risk of hackers accessing all sites on the server from a compromised PHP web script, you should enable suPHP when you build apache/php. Note that there are sideeffects when enabling suPHP on a server and you should be aware of these before enabling it.
Don\'t forget to enable it as the default PHP handler in WHM > PHP 5 Handler"); $status = 0; unless ($cpconf->{userdirprotect}) {$status = 1} &addline($status,"Check mod_userdir protection","To prevents users from stealing bandwidth or hackers hiding access to your servers, you should check WHM > Security Center > mod_userdir Tweak"); $status = 1; if (my @ls = grep {$_ =~ /suexec_module/} @modules) {$status = 0} &addline($status,"Check Suexec","To reduce the risk of hackers accessing all sites on the server from a compromised CGI web script, you should set WHM > Suexec on"); } } } return; } # end apachecheck ############################################################################### # start sshtelnetcheck sub sshtelnetcheck { my $status = 0; &addtitle("SSH/Telnet Check"); if (-e "/etc/ssh/sshd_config") { open (my $IN, "<", "/etc/ssh/sshd_config"); flock ($IN, LOCK_SH); my @sshconf = <$IN>; close ($IN); chomp @sshconf; if (my @ls = grep {$_ =~ /^\s*Protocol/i} @sshconf) { if ($ls[0] =~ /1/) {$status = 1} } else {$status = 0} &addline($status,"Check SSHv1 is disabled","You should disable SSHv1 by editing /etc/ssh/sshd_config and setting:
Protocol 2"); $status = 0; my $sshport = "22"; if (my @ls = grep {$_ =~ /^\s*Port/i} @sshconf) { if ($ls[0] =~ /^\s*Port\s+(\d*)/i) { $sshport = $1; if ($sshport eq "22") {$status = 1} } else {$status = 1} } else {$status = 1} &addline($status,"Check SSH on non-standard port","You should consider moving SSH to a non-standard port [currently:$sshport] to evade basic SSH port scans. Don't forget to open the port in the firewall first if necessary"); $status = 0; if (my @ls = grep {$_ =~ /^\s*PasswordAuthentication/i} @sshconf) { if ($ls[0] =~ /\byes\b/i) {$status = 1} } else {$status = 1} &addline($status,"Check SSH PasswordAuthentication","You should disable PasswordAuthentication and only allow access using PubkeyAuthentication to improve brute-force SSH security"); $status = 0; if (my @ls = grep {$_ =~ /^\s*UseDNS/i} @sshconf) { if ($ls[0] !~ /\bno\b/i) {$status = 1} } else {$status = 1} &addline($status,"Check SSH UseDNS","You should disable UseDNS by editing /etc/ssh/sshd_config and setting:
UseDNS no
Otherwise, lfd will be unable to track SSHD login failures successfully as the log files will not report IP addresses"); } else {&addline(1,"Check SSH configuration","Unable to find /etc/ssh/sshd_config");} $status = 0; my $check = &getportinfo("23"); if ($check) {$status = 1} &addline($status,"Check telnet port 23 is not in use","It appears that something is listening on port 23 which is normally used for telnet. Telnet is an insecure protocol and you should disable the telnet daemon if it is running"); unless ($config{DNSONLY} or $config{GENERIC}) { unless ($config{VPS}) { if (-e "/etc/redhat-release") { open (my $IN, "<", "/etc/redhat-release"); flock ($IN, LOCK_SH); my $conf = <$IN>; close ($IN); chomp $conf; unless ($conf =~ /^CloudLinux/i) { if (-e "/etc/profile") { $status = 0; open (my $IN, "<", "/etc/profile"); flock ($IN, LOCK_SH); my @profile = <$IN>; close ($IN); chomp @profile; if (grep {$_ =~ /^LIMITUSER=\$USER/} @profile) { $status = 0; } else {$status = 1} &addline($status,"Check shell limits","You should enable shell resource limits to prevent shell users from consuming server resources - DOS exploits typically do this. A quick way to set this is to use WHM > Shell Fork Bomb Protection"); } else { &addline(1,"Check shell limits","Unable to find /etc/profile"); } } } } $status = 0; if (-e "/var/cpanel/killproc.conf") { open (my $IN, "<", "/var/cpanel/killproc.conf"); flock ($IN, LOCK_SH); my @proc = <$IN>; close ($IN); chomp @proc; if (@proc < 9) {$status = 1} &addline($status,"Check Background Process Killer","You should enable each item in the WHM > Background Process Killer"); } else {&addline(1,"Check Background Process Killer","You should enable each item in the WHM > Background Process Killer")} } return; } # end sshtelnetcheck ############################################################################### # start servicescheck sub servicescheck { my $systemctl = "/usr/bin/systemctl"; my $chkconfig = "/sbin/chkconfig"; my $servicebin = "/sbin/service"; if (-e "/bin/systemctl") {$systemctl = "/bin/systemctl"} if (-e "/usr/sbin/chkconfig") {$chkconfig = "/usr/sbin/chkconfig"} if (-e "/usr/sbin/service") {$servicebin = "/usr/sbin/service"} &addtitle("Server Services Check"); my @services = ("abrt-xorg", "abrtd", "alsa-state", "anacron", "avahi-daemon", "avahi-dnsconfd", "bluetooth", "bolt", "canna", "colord", "cups", "cups-config-daemon", "cupsd", "firewalld", "FreeWnn", "gdm", "gpm", "gssproxy", "hidd", "iiim", "ksmtuned", "mDNSResponder", "ModemManager", "nfslock", "nifd", "packagekit", "pcscd", "portreserve", "pulseaudio", "qpidd", "rpcbind", "rpcidmapd", "saslauthd", "sbadm", "wpa_supplicant", "xfs", "xinetd"); my $disable; my ($childin, $childout); my $mypid; if ($sysinit eq "init") { $disable = "$servicebin [service] stop
$chkconfig [service] off"; $mypid = open3($childin, $childout, $childout, $chkconfig,"--list"); } else { $disable = "$systemctl stop [service]
$systemctl disable [service]"; $mypid = open3($childin, $childout, $childout, $systemctl,"list-unit-files","--state=enabled","--no-pager","--no-legend"); } my @chkconfig = <$childout>; waitpid ($mypid, 0); chomp @chkconfig; my @enabled; foreach my $service (@services) { if ($service eq "xinetd" and $config{PLESK}) {next} if ($sysinit eq "init") { if (my @ls = grep {$_ =~ /^$service\b/} @chkconfig) { if ($ls[0] =~ /\:on/) {push @enabled, $service} } } else { if (my @ls = grep {$_ =~ /^$service\.service/} @chkconfig) {push @enabled, $service} } } if (scalar @enabled > 0) { my $list; foreach my $service (@enabled) { if (length($list) == 0) { $list = $service; } else { $list .= ",".$service; } } &addline("1","Check server services","On most servers the following services are not needed and should be stopped and disabled from starting unless used:

$list

\nEach service can usually be disabled using:
$disable"); } else { &addline("0","Check server services","On most servers the following services are not needed and should be stopped and disabled from starting unless used:

none found

\nEach service can usually be disabled using:
$disable"); } return; } # end servicescheck ############################################################################### # start getportinfo sub getportinfo { my $port = shift; my $hit = 0; foreach my $proto ("udp","tcp","udp6","tcp6") { open (my $IN, "<", "/proc/net/$proto"); flock ($IN, LOCK_SH); while (<$IN>) { my @rec = split(); if ($rec[9] =~ /uid/) {next} my (undef,$sport) = split(/:/,$rec[1]); if (hex($sport) == $port) {$hit = 1} } close ($IN); } return $hit; } # end getportinfo ############################################################################### 1; Config.pm000064400000042645151030020750006313 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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) { ## open (my $DOWNLOAD, "<", $downloadservers); ## flock ($DOWNLOAD, LOCK_SH); ## my @data = <$DOWNLOAD>; ## close ($DOWNLOAD); ## chomp @data; ## foreach my $line (@data) { ## if ($line =~ /^download/) {push @servers, $line} ## } 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;AbuseIP.pm000064400000005543151030020750006372 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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; URLGet.pm000064400000016570151030020750006206 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;LookUpIP.pm000064400000026642151030020750006547 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;Logger.pm000064400000003526151030020750006320 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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;cseUI.pm000064400000110041151030020750006100 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## no critic (RequireUseWarnings, ProhibitExplicitReturnUndef, ProhibitMixedBooleanOperators, RequireBriefOpen) package ConfigServer::cseUI; use strict; use Fcntl qw(:DEFAULT :flock); use File::Find; use File::Copy; use IPC::Open3; use Exporter qw(import); our $VERSION = 2.03; our @ISA = qw(Exporter); our @EXPORT_OK = qw(); umask(0177); our ($chart, $ipscidr6, $ipv6reg, $ipv4reg, %config, %ips, $mobile, %FORM, $script, $script_da, $images, $myv); our ($act, $destpath, $element, $extramessage, $fieldname, $fileinc, $filetemp, $message, $name, $origpath, $storepath, $tgid, $thisdir, $tuid, $value, $webpath, %ele, %header, @bits, @dirs, @filebodies, @filenames, @files, @months, @parts, @passrecs, @thisdirs, @thisfiles, $files); # ############################################################################### # start main sub main { my $FORM_ref = shift; %FORM = %{$FORM_ref}; $fileinc = shift; $script = shift; $script_da = shift; $images = shift; $myv = shift; $| = 1; &loadconfig; $webpath = '/'; if ($FORM{do} eq "view") { &view; exit; } print "Content-type: text/html\r\n\r\n"; my $bootstrapcss = ""; my $jqueryjs = ""; my $bootstrapjs = ""; print < ConfigServer Explorer $bootstrapcss $jqueryjs $bootstrapjs
EOF unless ($FORM{do} eq "console") { print "
\n"; print "
\n"; if ($config{UI_CXS} or $config{UI_CSE}) { print "
\n"; } print " cse Logout\n"; print "
\n"; print <

ConfigServer Explorer - cse

EOF } $message = ""; if ($fileinc) {&uploadfile} elsif ($FORM{do} eq "") {&browse} elsif ($FORM{quit} == 2) {&browse} elsif ($FORM{do} eq "b") {&browse} elsif ($FORM{do} eq "p") {&browse} elsif ($FORM{do} eq "o") {&browse} elsif ($FORM{do} eq "c") {&browse} elsif ($FORM{do} eq "m") {&browse} elsif ($FORM{do} eq "pw") {&browse} elsif ($FORM{do} eq "r") {&browse} elsif ($FORM{do} eq "newf") {&browse} elsif ($FORM{do} eq "newd") {&browse} elsif ($FORM{do} eq "cnewf") {&cnewf} elsif ($FORM{do} eq "cnewd") {&cnewd} elsif ($FORM{do} eq "ren") {&ren} elsif ($FORM{do} eq "del") {&del} elsif ($FORM{do} eq "setp") {&setp} elsif ($FORM{do} eq "seto") {&seto} elsif ($FORM{do} eq "cd") {&cd} elsif ($FORM{do} eq "console") {&console} elsif ($FORM{do} eq "edit") {&edit} elsif ($FORM{do} eq "Cancel") {&browse} elsif ($FORM{do} eq "Save") {&save} elsif ($FORM{do} eq "copyit") {©it} elsif ($FORM{do} eq "moveit") {&moveit} else {print "Invalid action"}; unless ($FORM{do} eq "console") { print "

©2006-2023, ConfigServer Services (Way to the Web Limited)

\n"; } print < EOF exit; } # end main ############################################################################### # start browse sub browse { my $extra; if ($FORM{c}) { if (-e "$webpath$FORM{c}") { $extra = "&c=$FORM{c}"; } else { $FORM{c} = ""; } } if ($FORM{m}) { if (-e "$webpath$FORM{m}") { $extra = "&m=$FORM{m}" } else { $FORM{m} = ""; } } print "\n"; $thisdir = $webpath; if ($thisdir !~ /\/$/) {$thisdir .= "/"} $thisdir .= $FORM{p}; $thisdir =~ s/\/+/\//g; @months = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); my $errordir = 0; opendir (DIR, "$thisdir") or $errordir = 1; while (my $file = readdir(DIR)) { if (-d "$thisdir/$file") { if ($file !~ /^\.$|^\.\.$/) {push (@thisdirs, $file)} } else { push (@thisfiles, $file); } } closedir (DIR); @thisdirs = sort @thisdirs; @thisfiles = sort @thisfiles; print "
\n"; print "WARNING! While this utility can be very useful it is also very dangerous indeed. You can easily render your server inoperable and unrecoverable by performing ill advised actions. No warranty or guarantee is provided with the product that protects against system damage.\n"; print "
\n"; if ($message) {print "

$message

\n";} print "\n"; print "\n"; if ($errordir) { print ""; } else { if (@thisdirs > 0) { print "\n"; print ""; print ""; print ""; print ""; print ""; print ""; print ""; print "\n"; } my $class = "tdshade2"; foreach my $dir (@thisdirs) { if ($dir =~/'|"|\||\`/) { print ""; next; } my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("$thisdir/$dir"); if ($size < 1024) { } elsif ($size < (1024 * 1024)) { $size = sprintf("%.1f",($size/1024)); $size .= "k"; } else { $size = sprintf("%.1f",($size/(1024 * 1024))); $size .= "M"; } $mode = sprintf "%04o", $mode & oct("07777"); $tgid = getgrgid($gid); if ($tgid eq "") {$tgid = $gid} $tuid = getpwuid($uid); if ($tuid eq "") {$tuid = $uid} my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($mtime); $year += 1900; my $time = sprintf "%02d:%02d:%02d", $hour, $min, $sec; $mday = sprintf "%02d", $mday; $mtime = "$mday-$months[$mon]-$year $time"; my $pp = ""; my $passfile = "$FORM{p}/$dir"; $passfile =~ s/\//\_/g; $passfile =~ s/\\/\_/g; $passfile =~ s/\:/\_/g; if (-e "$storepath/$passfile.htpasswd") { open (my $PASSFILE, "<","$storepath/$passfile.htpasswd") or die $!; flock ($PASSFILE, LOCK_SH); @passrecs = <$PASSFILE>; close ($PASSFILE); chomp @passrecs; if (@passrecs > 0) {$pp = "**"} } print ""; if ($FORM{do} eq "r" and ($FORM{f} eq $dir)) { print "\n"; print ""; print "\n"; } elsif (-r "$webpath$FORM{p}/$dir") { print ""; } else { print ""; } print ""; print ""; if ($FORM{do} eq "o" and ($FORM{f} eq $dir)) { print "\n"; print ""; print "\n"; } else { print ""; } if ($FORM{do} eq "p" and ($FORM{f} eq $dir)) { print "\n"; print ""; print "\n"; } else { print ""; } print ""; print ""; print "\n"; } if ($FORM{do} eq "newd") { print ""; print "\n"; print ""; print "\n"; print ""; print ""; print ""; print ""; print ""; print "\n"; } if (($FORM{do} eq "c") and (-d "$webpath$FORM{c}")) { my $newf = (split(/\//,$FORM{c}))[-1]; print ""; print "\n"; print ""; print "\n"; print ""; print ""; print ""; print ""; print ""; print "\n"; } if (($FORM{do} eq "m") and (-d "$webpath$FORM{m}")) { my $newf = (split(/\//,$FORM{m}))[-1]; print ""; print "\n"; print ""; print "\n"; print ""; print ""; print ""; print ""; print ""; print "\n"; } if (@thisfiles > 0) { print "\n"; print ""; print ""; print ""; print ""; print ""; print ""; print ""; print "\n"; } $class = "tdshade2"; foreach my $file (@thisfiles) { if ($file =~/'|"|\||\`/) { print ""; next; } my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("$thisdir/$file"); if ($size < 1024) { } elsif ($size < (1024 * 1024)) { $size = sprintf("%.1f",($size/1024)); $size .= "k"; } else { $size = sprintf("%.1f",($size/(1024 * 1024))); $size .= "M"; } $mode = sprintf "%03o", $mode & oct("00777"); $tgid = getgrgid($gid); if ($tgid eq "") {$tgid = $gid} $tuid = getpwuid($uid); if ($tuid eq "") {$tuid = $uid} my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($mtime); $year += 1900; my $time = sprintf "%02d:%02d:%02d", $hour, $min, $sec; $mday = sprintf "%02d", $mday; $mtime = "$mday-$months[$mon]-$year $time"; print ""; if ($FORM{do} eq "r" and ($FORM{f} eq $file)) { print "\n"; print ""; print "\n"; } else { $act = "$script?do=view&p=$FORM{p}&f=$file$extra\#new"; print ""; } print ""; print ""; if ($FORM{do} eq "o" and ($FORM{f} eq $file)) { print "\n"; print ""; print "\n"; } else { print ""; } if ($FORM{do} eq "p" and ($FORM{f} eq $file)) { print "\n"; print ""; print "\n"; } else { print ""; } my $ext = (split(/\./,$file))[-1]; if (-T "$webpath$FORM{p}/$file") { my $act = ""; print ""; } else { print ""; } print ""; print "\n"; } if ($FORM{do} eq "newf") { print ""; print "\n"; print ""; print "\n"; print ""; print ""; print ""; print ""; print ""; print "\n"; } if (($FORM{do} eq "c") and (-f "$webpath$FORM{c}")) { my $newf = (split(/\//,$FORM{c}))[-1]; print ""; print "\n"; print ""; print "\n"; print ""; print ""; print ""; print ""; print ""; print "\n"; } if (($FORM{do} eq "m") and (-f "$webpath$FORM{m}")) { my $newf = (split(/\//,$FORM{m}))[-1]; print ""; print "\n"; print ""; print "\n"; print ""; print ""; print ""; print ""; print ""; print "\n"; } } print "
"; print "[Home]"; my $path = ""; my $cnt = 2; my @path = split(/\//,$FORM{p}); foreach my $dir (@path) { if ($dir ne "" and ($dir ne "/")) { if ($cnt == @path) { print "/$dir"; } else { print "/$dir"; } $path .= "/$dir"; $cnt++; } } if ($FORM{c}) {print "    Copy buffer:$FORM{c} \n"} if ($FORM{m}) {print "    Move buffer:$FORM{m} \n"} print "
Permission Denied
Directory NameSizeDateUser(uid)/Group(gid)PermsActions
".quotemeta($dir)."Invalid directory name - ignored
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "$pp$dir$pp$dir$size$mtime
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "$tuid($uid)/$tgid($gid)
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "$mode "; print " "; print " "; print "
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "     
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "     
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "     
 
File NameSizeDateUser(uid)/Group(gid)PermsActions
".quotemeta($file)."Invalid file name - ignored
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "$file$size$mtime
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "$tuid($uid)/$tgid($gid)
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "$mode$act "; print " "; print " "; print "
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "     
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "     
"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "     
\n"; print "
All the following actions apply to the current directory
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
Search for filenames or directories
"; print " \n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n\n"; print "
Create New...
Create New DirectoryCreate Empty File
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
Upload Files...

\n"; print "
Mode:
\n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
Change Directory...
"; print "\n"; print "

\n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
Virtual Console $thisdir
"; print "\n"; print "

Command: \n"; print "

\n"; print "
Note: You cannot change directory within the console. Use the Change Directory feature above.
\n"; print "
\n"; print "
\n"; return; } # end browse ############################################################################### # start setp sub setp { my $status = 0; chmod (oct("0$FORM{newp}"),"$webpath$FORM{p}/$FORM{f}") or $status = $!; if ($status) {$message = "Operation Failed - $status"} else {$message = ""} &browse; return; } # end setp ############################################################################### # start seto sub seto { my $status = ""; my ($uid,$gid) = split (/\:/,$FORM{newo}); if ($uid !~ /^\d/) {$uid = (getpwnam($uid))[2]} if ($gid !~ /^\d/) {$gid = (getgrnam($gid))[2]} if ($uid eq "") {$message .= "No such user
\n"} if ($gid eq "") {$message .= "No such group
\n"} if ($message eq "") { chown ($uid,$gid,"$webpath$FORM{p}/$FORM{f}") or $status = $!; if ($status) {$message = "Operation Failed - $status"} else {$message = ""} } &browse; return; } # end seto ############################################################################### # start ren sub ren { my $status = 0; rename ("$webpath$FORM{p}/$FORM{f}","$webpath$FORM{p}/$FORM{newf}") or $status = $!; if ($status) {$message = "Operation Failed - $status"} else {$message = ""} &browse; return; } # end ren ############################################################################### # start moveit sub moveit { if ("$webpath$FORM{m}" eq "$webpath$FORM{p}/$FORM{newf}") { $message = "Move Failed - Cannot overwrite original"; } elsif ((-d "$webpath$FORM{m}") and ("$webpath$FORM{p}/$FORM{newf}" =~ /^$webpath$FORM{m}\//)) { $message = "Move Failed - Cannot move inside original"; } else { my $status = 0; rename ("$webpath$FORM{m}","$webpath$FORM{p}/$FORM{newf}") or $status = $!; if ($status) {$message = "Operation Failed - $status"} else {$message = ""} } if ($message eq "") {$FORM{m} = ""} &browse; return; } # end moveit ############################################################################### # start copyit sub copyit { if ("$webpath$FORM{c}" eq "$webpath$FORM{p}/$FORM{newf}") { $message = "Copy Failed - Cannot overwrite original"; } elsif ((-d "$webpath$FORM{c}") and ("$webpath$FORM{p}/$FORM{newf}" =~ /^$webpath$FORM{c}\//)) { $message = "Copy Failed - Cannot copy inside original"; } else { if (-d "$webpath$FORM{c}") { $origpath = "$webpath$FORM{c}"; $destpath = "$webpath$FORM{p}/$FORM{newf}"; find(\&mycopy, $origpath); } else { copy ("$webpath$FORM{c}","$webpath$FORM{p}/$FORM{newf}") or $message = "Copy Failed - $!"; if ($message eq "") { my $mode = sprintf "%04o", (stat("$webpath$FORM{c}"))[2] & oct("00777"); chmod (oct($mode),"$webpath$FORM{p}/$FORM{newf}") or $message = "Permission Change Failed - $!"; } } } if ($message eq "") {$FORM{c} = ""} &browse; return; } # end copyit ############################################################################### # start mycopy sub mycopy { my $file = $File::Find::name; (my $dest = $file) =~ s/^\Q$origpath/$destpath/; my $status = ""; if (-d $file) { my $err = (split(/\//,$dest))[-1]; mkpath ($dest) or $status = "Copy Failed Making New Dir [$err] - $!
\n"; } elsif (-f $file) { my $err = (split(/\//,$file))[-1]; copy ($file,$dest) or $status = "Copy Failed [$err] - $!
\n"; } if ($status eq "") { my $err = (split(/\//,$file))[-1]; my $mode = sprintf "%04o", (stat("$file"))[2] & oct("00777"); chmod (oct($mode),"$dest") or $message .= "Copy Failed Setting Perms [$err] - $!
\n"; } else { $message .= $status; } return; } # end mycopy ############################################################################### # start cnewd sub cnewd { my $status = 0; if ($FORM{newf} ne "") { mkdir ("$webpath$FORM{p}/$FORM{newf}",0777) or $status = $!; } if ($status) {$message = "Operation Failed - $status"} else {$message = ""} &browse; return; } # end cnewd ############################################################################### # start cnewf sub cnewf { my $status = 0; if ($FORM{newf} ne "") { if (-f "$webpath$FORM{p}/$FORM{newf}") { $status = "File exists"; } else { open (my $OUT, ">","$webpath$FORM{p}/$FORM{newf}") or $status = $!; flock ($OUT, LOCK_EX); close ($OUT); } } if ($status) {$message = "Operation Failed - $status"} else {$message = ""} &browse; return; } # end cnewf ############################################################################### # start del sub del { my $status = 0; if (-d "$webpath$FORM{p}/$FORM{f}") { rmtree("$webpath$FORM{p}/$FORM{f}", 0, 0) or $status = $!; } else { unlink ("$webpath$FORM{p}/$FORM{f}") or $status = $!; } if ($status) {$message = "Operation Failed - $status"} else {$message = ""} &browse; return; } # end del ############################################################################### # start view sub view { if (-e "$webpath$FORM{p}/$FORM{f}" ) { if (-T "$webpath$FORM{p}/$FORM{f}") { print "content-type: text/plain\r\n"; } else { print "content-type: application/octet-stream\r\n"; } print "content-disposition: attachment; filename=$FORM{f}\r\n\r\n"; open(my $IN,"<","$webpath$FORM{p}/$FORM{f}") or die $!; flock ($IN, LOCK_SH); while (<$IN>) {print} close($IN); }else{ print "content-type: text/html\r\n\r\n"; print "File [$webpath$FORM{p}/$FORM{f}] not found!"; } return; } # end view ############################################################################### # start console sub console { my $thisdir = "$webpath$FORM{p}"; $thisdir =~ s/\/+/\//g; print "

\n";
	print "root [$thisdir]# $FORM{cmd}\n";
	chdir $thisdir;

	$| = 1;
	my ($childin, $childout);
	my $cmdpid = open3($childin, $childout, $childout, $FORM{cmd});
	while (my $line = <$childout>) {
		$line =~ s/\/\>\;/g;
		print $line;
	}
	waitpid ($cmdpid, 0);
	print "root [$thisdir]# _

\n"; print ""; return; } # end console ############################################################################### # start cd sub cd { if (-d $FORM{directory}) { $FORM{p} = $FORM{directory}; } else { $message = "No such directory [$FORM{directory}]"; } &browse; return; } # end cd ############################################################################### # start edit sub edit { open (my $IN, "<","$webpath$FORM{p}/$FORM{f}") or die $!; flock ($IN, LOCK_SH); my @data = <$IN>; close ($IN); my $filedata; foreach my $line (@data) { $line =~ s/\/>/g; $filedata .= $line; } my $lf = 0; if ($filedata =~ /\r/) {$lf = 1} print "\n"; print "
\n"; print "\n"; print "\n"; print ""; print "
"; print "\n"; print "\n"; print "\n"; print "\n"; print "
"; print " \n"; print "\n"; print "
\n"; print "
\n"; return; } # end edit ############################################################################### # start save sub save { unless ($FORM{lf}) {$FORM{newf} =~ s/\r//g} my $status = 0; open (my $OUT, ">","$webpath$FORM{p}/$FORM{f}") or $status = $!; flock ($OUT, LOCK_EX); print $OUT $FORM{newf}; close ($OUT); if ($status) {$message = "Operation Failed - $status"} else {$message = ""} &browse; return; } # end save ############################################################################### # start uploadfile sub uploadfile { my $crlf = "\r\n"; my @data = split (/$crlf/,$fileinc); my $boundary = $data[0]; $boundary =~ s/\"//g; $boundary =~ s/$crlf//g; my $start = 0; my $part_cnt=-1; undef @parts; my $fileno = 0; foreach my $line (@data) { if ($line =~ /^$boundary--/) { last; } if ($line =~ /^$boundary/) { $part_cnt++; $start = 1; next; } if ($start) { $parts[$part_cnt] .= $line.$crlf; } } foreach my $part (@parts) { my @partdata = split(/$crlf/,$part); undef %header; my $body = ""; my $dobody = 0; my $lastfieldname = ""; foreach my $line (@partdata) { if (($line eq "") and !($dobody)) { $dobody = 1; next; } if ($dobody) { $body .= $line.$crlf; } else { if ($line =~ /^\s/) { $header{$lastfieldname} .= $line; } else { ($fieldname, $value) = split (/\:\s/,$line,2); $fieldname = lc $fieldname; $fieldname =~ s/-/_/g; $header{$fieldname} = $value; $lastfieldname = $fieldname; } } } my @elements = split(/\;/,$header{content_disposition}); foreach my $element (@elements) { $element =~ s/\s//g; $element =~ s/\"//g; ($name,$value) = split(/\=/,$element); $FORM{$value} = $body; $ele{$name} = $value; $ele{$ele{name}} = $value; if ($value =~ /^file(.*)$/) {$files = $1} } my $filename = $ele{"file$files"}; if ($filename ne "") { $fileno++; $filename =~ s/\"//g; $filename =~ s/\r//g; $filename =~ s/\n//g; @bits = split(/\\/,$filename); $filetemp=$bits[-1]; @bits = split(/\//,$filetemp); $filetemp=$bits[-1]; @bits = split(/\:/,$filetemp); $filetemp=$bits[-1]; @bits = split(/\"/,$filetemp); $filename=$bits[0]; push (@filenames, $filename); push (@filebodies, $body); } } $FORM{p} =~ s/\r//g; $FORM{p} =~ s/\n//g; $FORM{type} =~ s/\r//g; $FORM{type} =~ s/\n//g; $FORM{c} =~ s/\r//g; $FORM{c} =~ s/\n//g; $FORM{m} =~ s/\r//g; $FORM{m} =~ s/\n//g; $FORM{caller} =~ s/\r//g; $FORM{caller} =~ s/\n//g; for (my $x = 0;$x < @filenames ;$x++) { $filenames[$x] =~ s/\r//g; $filenames[$x] =~ s/\n//g; $filenames[$x] =~ s/^file-//g; $filenames[$x] = (split (/\\/,$filenames[$x]))[-1]; $filenames[$x] = (split (/\//,$filenames[$x]))[-1]; if ($FORM{type} eq "ascii") {$filebodies[$x] =~ s/\r//g} if (-e "$webpath$FORM{p}/$filenames[$x]") { $extramessage .= "
$filenames[$x] - Already exists, delete the original first"; $fileno--; next; } sysopen (my $OUT,"$webpath$FORM{p}/$filenames[$x]", O_WRONLY | O_CREAT); flock ($OUT, LOCK_EX); print $OUT $filebodies[$x]; close ($OUT); $extramessage .= "
$filenames[$x] - Uploaded"; } $message = "$fileno File(s) Uploaded".$extramessage; &browse; return; } # end uploadfile ############################################################################### # start countfiles sub countfiles { if (-d $File::Find::name) {push (@dirs, $File::Find::name)} else {push (@files, $File::Find::name)} return; } # end countfiles ############################################################################### # loadconfig sub loadconfig { sysopen (my $IN, "/etc/csf/csf.conf", O_RDWR | O_CREAT) or die "Unable to open file: $!"; flock ($IN, LOCK_SH); 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 { &error(__LINE__,"Invalid configuration line"); } $config{$name} = $value; } return; } # end loadconfig ############################################################################### 1; RBLCheck.pm000064400000015431151030020750006454 0ustar00############################################################################### # Copyright 2006-2023, Way to the Web Limited # URL: http://www.configserver.com # Email: sales@waytotheweb.com ############################################################################### ## 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+))/$1<\/a>/g; $rbltxt .= "${line}\n"; } $rbltxt =~ s/\n/
\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 .= "
OK
\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 .= "
Not Checked
\n"; if ($ui) {print $text} else {$output .= $text} } } } else { if ($verbose == 2) { &addtitle("Skipping $ip ($type)"); my $text; $text .= "
OK
\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 = "
$rbl"} if ($status) { $text .= "
\n"; $text .= "
$check
\n"; $text .= "
$comment
\n"; $text .= "
\n"; $failures ++; $ipresult .= $text; } elsif ($verbose) { $text .= "
\n"; $text .= "
$check
\n"; $text .= "
$comment
\n"; $text .= "
\n"; } if ($ui) {print $text} else {$output .= $text} return; } # end addline ############################################################################### # start addtitle sub addtitle { my $title = shift; my $text; $text .= "
$title
\n"; $ipresult .= $text; if ($ui) {print $text} else {$output .= $text} return; } # end addtitle ############################################################################### # start endoutput sub endoutput { if ($ui) {print "
\n"} else {$output .= "
\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;