Technical (Development, Security, etc.) > General Security Information

Using Dynamic DNS to evade SSH bruteforce attacks

(1/3) > >>

nslay:
I used to employ a firewall rule that would detect spurious connects on port 22 (ssh) and place both the offending IP on a badguys table and flush the state table for said IP (Meaning, anything connected with that source IP was no longer treated as connected by the firewall).  A cron job would then cleanup old entries from the badguys table.  For years, this worked remarkably!  My auth log would show 3 attempts and then activity from the source ceased.  Unfortunately, the bot nets got smarter.  I started seeing several hundreds of bots attempting a password every several minutes which isn't spurious.  As a consequence, my auth log would be flooded with annoying password failures!  So, I opted to block everything except address blocks of known locations (e.g. cafe, work, school, etc...) on top of the spurious connect rule.  This works well most of the time but did not fare so well with friends' or acquaintances' houses, airports, or new public WiFi locations in general (which I use my SSH server as a secure tunnel).  As I'm to travel soon, the thought of dynamic DNS came to mind.  Simply keep a list of dynamic domains and have a cron job resolve each one and add it to the goodguys table (and delete the previous resolutions if they differ).  I don't claim it's a new idea, but it's certainly ANOTHER solution.

Too Long Didn't Read

* Block ALL incoming (at least) SSH connections with your firewall.
* Add an exception rule for incoming SSH connections for any address on the goodguys table.
* Make a Dynamic DNS hostname (e.g. no-ip.com) for each trusted mobile computer.
* Install a Dynamic Update Client on each trusted mobile computer.
* Add a cron job (every 5 minutes) that resolves a list of dynamic hostnames and adds their corresponding IPs to the goodguys table (preferably deleting old different resolutions).
* Enjoy boiled peanuts (Very necessary, it won't work otherwise).
Here's an example of a Bourne shell script to do step 5 (for pf(4) on FreeBSD) (an updated version can be found here)

--- Code: ---#!/bin/sh

GOODGUYS=/root/goodguys.txt
TABLE=goodguys

while read host
do
        hostfile="/tmp/goodguys.${host}"
        oldip=""

        if [ -s "${hostfile}" ]
        then
                read oldip < ${hostfile}
        fi

        str=`host -t A $host 2>/dev/null`
        if [ $? -eq 0 ]
        then
                ip=`echo "${str}" | awk '{ print $NF; exit }'`
                echo "${ip}" > ${hostfile}
        else
                ip=""
                rm -f ${hostfile}
        fi

        if [ -n "${oldip}" -a "${oldip}" != "${ip}" ]
        then
                /sbin/pfctl -t $TABLE -T del ${oldip} > /dev/null 2>&1
        fi

        if [ -n "${ip}" ]
        then
                /sbin/pfctl -t $TABLE -T add ${ip} > /dev/null 2>&1
        fi
done < $GOODGUYS

--- End code ---

This reads a list of hostnames from /root/goodguys.txt and adds each resolved address to the table goodguys and stores the result in /tmp for later use. If the previous address is different than the current resolved address, the previous address is deleted from the goodguys table.

Place it in, say /root/bin/goodguys.sh

And here's what you'd add to /etc/crontab to do this every 5 minutes:

--- Code: ---#minute hour    mday    month   wday    who     command
*/5     *       *       *       *       root    /root/bin/goodguys.sh

--- End code ---

Voila! I find this to be the best solution of all the bruteforce solutions. Everyone is blocked except for you and friends ... granted you and your friends are using their own machines. No special software or firewall rules needed and most importantly NO ANNOYING AUTH LOG FAILURE MESSAGES!

Caveats

* It may take several minutes before you can ssh to your server.
* If your dynamic hostname expires, said hostname may resolve to the dynamic DNS provider.

Blaze:
Would disabling passwords in general and using private/public keys exclusively be a solution to this?

Sidoh:
Cool!  I like this, nslay.  thanks for sharing.

Blaze, I'm not really sure why it's desirable, but I don't think you'd avoid having your auth logs flooded with that solution.  I certainly do that, though.  I like keys more anyway. :)

Newby:
So basically a whitelist instead of a blacklist? Good idea, I suppose. I'd rather just do the IPs. What if your machine becomes compromised and resolves those domains to something wrong? Or the DynDNS account is compromised and bad IPs are added? (Granted, it would require that the attacker know about your setup, but it's something to consider. At the very least it would result in a DoS for legitimate users.)

Blaze:
I'm not too worried about keeping pretty auth logs, I was just asking since I almost never look at my auth logs, and wanted to make sure that I'm probably fine doing what I'm doing.  :)

I also enjoyed the article, nslay.  Do post more if have spare time and have come up with cool solutions to stuff.  :)

Navigation

[0] Message Index

[#] Next page

Go to full version