Alternative Solution, with iptables and perl below.
You send the magic string to any tcp port and it'll instantly kill all SSH logins and disable the root shell. Send the string again and the process is reversed. Caveat: if your syslog contains trigger entries more than a year old this will blow up.
I also recommend you disable root logins and password authentication, but if you insist on enabling them, this may work for you. Modify as necessary.
iptables -t raw -A PREROUTING -p tcp -m string --algo bm --string "_-()ThisIsAReallyLongAndComplicatedRandomStringToMatchOn()-_" --from 0 --to lengthofthelongstring -j LOG --log-prefix "29CharacterMaxTriggerString "
#!/usr/bin/perl
# sentinel - disable root based on a syslog trigger
# Copyright (C) 2011 Peter Willis <peterwwillis@yahoo.com>
use strict;
use POSIX qw(mktime);
my $LOG = "/var/log/syslog";
my $LOCKED = 0;
my $TRIGGER = "29CharacterMaxTriggerString";
my %M = ( "jan"=>0, "feb"=>1, "mar"=>2, "apr"=>3, "may"=>4, "jun"=>5, "jul"=>6, "aug"=>7, "sep"=>8, "oct"=>9, "nov"=>10, "dec"=>11 );
for ( ;; ) {
sleep(1);
open(F, "<$LOG") || die "Error: $!";
for ( ;; ) {
sleep(1);
while ( <F> ) {
select(undef, undef, undef, 0.001);
#print STDERR "Reading \"$_\"\n";
if ( /^(\w+) (\d+) (\d+):(\d+):(\d+) \w+ kernel: $TRIGGER / ) {
my $time = time();
my $stamp = mktime($5, $4, $3, $2, $M{lc $1}, (localtime($time))[5]);
if ( $stamp > $^T ) {
#print STDERR "Found Trigger\n";
trigger();
} else {
#print STDERR "Error: found trigger but timestamp $stamp is before script begin time $^T\n";
}
}
}
}
close(F);
}
sub trigger {
if ( $LOCKED ) {
system("/usr/bin/chsh -s /bin/bash root");
$LOCKED=0;
} else {
my @procs = map { @_=split(/\s+/,$_); $_[1] } grep(/^root\s+.*sshd:/, `ps -aux 2>/dev/null`);
#print STDERR "Killing processes: @procs\n";
kill(15, @procs);
kill(9, @procs);
system("/usr/bin/chsh -s /bin/false root");
$LOCKED=1;
}
}
You send the magic string to any tcp port and it'll instantly kill all SSH logins and disable the root shell. Send the string again and the process is reversed. Caveat: if your syslog contains trigger entries more than a year old this will blow up.
I also recommend you disable root logins and password authentication, but if you insist on enabling them, this may work for you. Modify as necessary.