File: //etc/cron.hourly/update_modsec_localips
#! /usr/bin/env perl
use Sys::Syslog;
use strict;
use warnings;
my $conf = "/opt/mod_security/modsec_localips.txt";
my $time = time;
my $tmpname = "$conf.new.$time";
my @ips = qx(/sbin/ip addr) =~ /((?:\d+\.){3}\d+)/g;
if (-e '/var/cpanel/cpnat') {
my %seen = map { $_ => 1 } @ips;
for my $line (split /\n/, slurp('/var/cpanel/cpnat')) {
for my $ip (split /\s+/, $line) {
next unless $ip =~ /^(?:\d{1,3}\.){3}\d{1,3}$/;
push @ips, $ip unless $seen{$ip}++;
}
}
}
my $old = slurp($conf);
my $new = join("\n", map { "/$_/" } sort @ips)."\n";
exit if $old eq $new; # don't kick apache if local IPs haven't changed
open my $tmp, '>', $tmpname or die "Unable to open $tmpname for writing : $!";
chmod 0640, $tmpname;
print {$tmp} $new;
close $tmp && rename $tmpname => $conf;
restart_apache();
sub slurp {
my ($file) = @_;
local $/ = undef;
open my $f, '<', $file or warn "Unable to open $file for reading : $!";
my $content = <$f>;
close $f;
return $content
}
sub restart_apache {
openlog 'update_modsec_localips', 'cons,pid', 'LOG_USER';
syslog 'notice', 'local IPs changed, so httpd reloaded';
if ( -x '/usr/local/cpanel/bin/servers_queue' ) {
exec "/usr/local/cpanel/bin/servers_queue queue apache_restart >/dev/null";
} elsif ( -x '/usr/sbin/apachectl' ) {
exec "/usr/sbin/apachectl -t && /usr/sbin/apachectl -k graceful";
} else {
syslog 'notice', 'Apache binary not found. Failed to restart!';
}
return;
}