Proactive Security

“The servers are secure”… it’s all too easy for those to become one’s famous last words. Especially nowadays, since attack attempts are constantly coming in from the millions of zombie Microsoft Windows machines that are out there and it’s all automated. For every bad guy that is out there, there’s an average of hundreds of thousands of compromised machines at his disposal. Gee thanks Mr. Gates!!

Gone are the glory days of there being someone behind the other terminal that is trying to break in because they are simply curious or because they had a specific reason to target your workstation or server. It’s big business now and your computers are coming under constant attack simply because they are there and breaking in to them is worth money to some people. Granted, that’s a little bit of an oversimplification, but that’s basically what it boils down to. Your system might have some useful data on it like your banking info, but even if it doesn’t, your system sure would be a handy thing for them to use to launch even more attacks against other systems or to send millions of spam messages with.

So while I like to think that the servers that are under my purview are locked down fairly well, (with only essential services running and those that are running being locked down as best as possible, such as SSH only accepting public keys), I’m not under any delusions that they are perfectly secure. Which means I’m not about to rest easy.

Instead of just sitting back and passively trying to parry each of their attempts I’ve initiated proactive measures to identify attacks on the fly and to act upon them. Hey, it’s not like the bad guys are the only ones who can leverage automation to their advantage.

A recent addition was having a daemon (denyhosts) keep close watch on the authentication logs looking for suspicious login attempts to SSH and to then deny their host access to SSH by adding it to /etc/hosts.deny as soon as it’s obvious that they are up to no good.

Then I decided to go one better by building upon the fact that I now know that these specific hosts are just out for trouble. So I wrote up a quick bash script that also injects a rule into iptables (that’s the system’s kernel level firewall) to drop all of the traffic from their host across the board. The end result being that any attempt at attacking the one and only process that the system allows for logins will strip them of their ability to talk to the server in any way whatsoever. Neat eh?

Eventually, I might daemon-ize it or perhaps even rewrite it in Perl with some additional functionality, but for the moment I’m just scheduling it to run regularly in cron.

Here’s the script for those of you who are extra curious:

#!/bin/bash
# banish.sh - Import and block /etc/hosts.deny entries with iptables
# Copyright (C)2009 ghendar
# All Rights Reserved.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

########################
#<--- DECLARATIONS --->#
########################

IPTABLES=/sbin/iptables

ROOT_UID=0
EX_NOPERM=77 #from /usr/include/sysexits.h
BLOCK_COUNT=0
BLOCK_FAIL_COUNT=0

#######################
#<--- BEGIN LOGIC --->#
#######################

if [[ "$UID" != "$ROOT_UID" ]]; then
    echo "Must be root to run this script."
    exit $EX_NOPERM
fi

#####################
#<--- FUNCTIONS --->#
#####################
function usage \
{
cat << EOF
usage: $0 -i

Block /etc/hosts.deny hosts in iptables

OPTIONS:
    -i       Import and block /etc/hosts.deny entries with iptables
    -v       Verbose
EOF
}

function say \
{
    if &#91;&#91;"$VERBOSE" == 1&#93;&#93;
    then
        echo $1
    fi
}

function deny \
{
    BLOCK_ADDRESS=$1

    say "Blocking $BLOCK_ADDRESS"
    `$IPTABLES -I INPUT -s $BLOCK_ADDRESS -j DROP`

    if &#91; $? != 0 &#93;; then
        say "BLOCK of $BLOCK_ADDRESS FAILED"
        echo "block did not work on $BLOCK_ADDRESS" >> /var/log/block.log
        $BLOCK_FAIL_COUNT=$BLOCK_FAIL_COUNT+1
    fi
    echo "$BLOCK_ADDRESS was blocked." >> /var/log/block.log
    $BLOCK_COUNT=$BLOCK_COUNT+1
    say "SUCCESS"
}

function import \
{
    say "Flushing iptables..."
    `$IPTABLES -F`

    if [[ -e '/var/log/block.log' ]]
    then
        say "Clearing and starting a new log at /var/log/block.log"
        echo "The following IPs are banished: " 1> /var/log/block.log
    else
        say "Creating log file /var/log/block.log"
        touch /var/log/block.log
        echo "The following IPs are banished: " 1> /var/log/block.log
    fi

    for x in `cat /etc/hosts.deny | grep -v ^# | cut -d ":" -f 2`;
    do
        deny $x
    done
    say "BLOCKED $BLOCK_COUNT hosts ($BLOCK_FAIL_COUNT failures)"
    say " "
    exit 0;
}

################
#<--- MAIN --->#
################

while getopts “i” OPTION
do
     case $OPTION in
         i)
             IMPORT=1
             ;;
         v)
             VERBOSE=1
             ;;
         ?)
             usage
             exit
             ;;
     esac
done

if [[ -z "$IMPORT" ]]
then
    usage
    exit 1
else
    import
fi

Advertisements

~ by ghendar on July 5, 2009.