Using IPTables to Prevent SSH Brute Force Attacks

If you have a server with a world facing ssh server, you’ve probably seen brute force attacks in your logs. Some machine starts hammering your ssh server, trying all sorts of logins (staff, root, a, admin, etc…) over and over and over again.

This is bad on a lot of fronts.

I use two simple iptables rules to block any IP address who has made more than 3 ssh connections or attempted connections within the past 3 minutes. So your would-be brute force attacker, gets three tries, and then is locked out for a minimum of three minutes. However, since 99% of the attacks are run by an automated bot, it will either: give up after the connection is refused multiple times, or it will keep hammering away on the closed door, which keeps the running count of attempted connections in the past 3 minutes over 3, keeping the door closed.

First:


iptables -I INPUT -i eth1 -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --rsource

Then run:


iptables -I INPUT -i eth1 -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 4 --name DEFAULT --rsource -j DROP

I’d also recommend using the script in my post on blocking IP addresses using iptables to deal with any persistent folks, or people poking too hard on your web site, or other services.


Posted

in

,

by

Comments

31 responses to “Using IPTables to Prevent SSH Brute Force Attacks”

  1. Branitar Avatar

    Is this an immediate measure or do you also have it in a script somewhere so it is started with your server?

  2. Devon Avatar

    I save my iptables rules and have them loaded at startup using the commands here:

    http://172.31.20.105/tech-blog/debian/how-to-block-an-ip-in-linux.html

    As for the block, it’s just for a few minutes (in case I lock myself out – which I’ve done before), but totally breaks any brute-force attempt, since they never stop trying, and hence stay blocked out until they’ve given up.

    Does that answer your question?

  3. Branitar Avatar

    Ahh I guess I figured it out. To make the rules above permanent I just have to save them to a file (as you did in the script in the other article) and edit the interfaces file to load my rules file.

    Thanks a lot! I’m very new to the iptables business and reading through the manual pages I dint really get how to do the 3 attempts thing. So your blog was kind of a live-safer :)

  4. Andries Louw Wolthuizen Avatar

    Why would you run SSH on port 22? Running sSH on a other port is a simple solution, that keeps most of the attempts out.

  5. Devon Avatar

    @Andreis: Good question.

    A few answers:

    1) a different port is a good idea for part of a security solution, but you should still have measures in place to prevent brute force attacks. Port scanning to identify ssh server ports isn’t hard. You might duck a large number of automated scanners, but it won’t do anything for a targeted attack. My solution will. So you should do the above anyhow:)

    2) one of the main reasons I don’t run on a different port myself is convenience. I ssh in from a large number of other servers, and scp files frequently. Having to specify a port every time I do any of that would be a pain.

  6. Tim Avatar

    Thnx this helps me out a lot, I was looking for something like this already.

    @Andries
    Still some clients (like on iphone) don’t support different ports then 22

  7. […] Wired Threat Level has posted an interview with the hacker who recently broke into several high profile twitter accounts, such as Fox News, and Barack Obama. Since we know how much you all love twitter, we thought you might want to learn more about it. Apparently he used a brute force method to get into a member of the support team. The password was “happiness” which was cracked pretty quickly. This might be a good time to review your own strategies to prevent brute force attacks. […]

  8. […] Wired Threat Level has posted an interview with the hacker who recently broke into several high profile twitter accounts, such as Fox News, and Barack Obama. Since we know how much you all love twitter, we thought you might want to learn more about it. Apparently he used a brute force method to get into a member of the support team. The password was “happiness” which was cracked pretty quickly. This might be a good time to review your own strategies to prevent brute force attacks. […]

  9. James Avatar
    James

    Is this not similar (if a little simpler) to the denyhosts service?

    1. Devon Avatar

      @James: Yes, it’s a similar approach. However there are a few reasons you might want to consider using the iptables rules instead of the denyhosts service:

      DenyHosts runs periodically (either via cron or as a deamon), and in the FAQ the author recommends running it every 10 minutes. Your server will take a very high number of brute force attempts in 10 minutes. The iptables rule will block after 4 attempts, much more quickly than denyhosts, and hence reduces the chances of a successful brute forcing attempt.

      I don’t like running processes as root, like DenyHosts. The only real advantage of DenyHosts is the new synchronization mode, which would let you block servers that haven’t even attacked you yet, saving your the four attempts the iptables rule would allow. However, running a python script as root, that pulls data from a 3rd party non-SSL server and then uses that data to modify my server’s hosts.deny file. Doubly so when that data is already being collected from other users of this 3rd party service. I’m not sure what prevents a malicious user of the service from submitting perfectly legit IPs or IP ranges and having the synchronization service push that data out to all the other users. I.e. I could submit all Comcast IPs and have them get blocked by users of the service, even though they are legit. Also, with the lack of SSL, I’d worry about the possibility of cache poisoning or DNS poisoning attacks being another vector to poison the data going into the hosts.deny file.

      The hosts.deny file is used for ALL services, not just SSH. This would prevent people with infected PCs from visiting your websites.

      The hosts.deny file is only read by tcpwrappers, and not all programs use it, so if I really did want to block all services, it might not suffice.

      Mostly it comes down to me liking the control that iptables gives me, and being somewhat paranoid:)

      1. tx Avatar
        tx

        Denyhosts can be run in daemon mode which will actively monitor ssh logins and update hosts.deny immediately. Further it is possible to run the daemon as a non-root user (see http://denyhosts.sourceforge.net/faq.html#3_1). And lastly it is possible to tell denyhosts to block only a specified service instead of all services. Personally, I would rather block all communication from a compromised host.

        1. Devon Avatar

          Good to know. It looks like the deamon mode is new-ish. However it defeats the non-root aspect you mention:

          If you are running DenyHosts in daemon mode then yes you must run DenyHosts as root.

  10. questionablemoose Avatar

    Instead of spending 15 minutes checking auth.log, I now spend about 30 seconds. Works brilliantly as far as I’m concerned. Thanks!

  11. amdrew Avatar
    amdrew

    yea a simple solution, thanks for this great post :)

  12. JD Avatar
    JD

    Thanks, great article!
    How would you go about adding these blocks to a separate log file, say /var/log/iptables.log?

  13. Kevin Avatar

    What do you think about using a ruby script like this:

    http://github.com/nazar/report-hack-isp

    in tandem with your iptables solution? I see iptables as protecting your server (or mine) and the script being proactive about protecting the web a little more by alerting the ISP in charge. Thoughts?

    1. Devon Avatar

      Kevin,

      looks good! Being a better net citizen is always good.

  14. […] Also, rather than using Denyhosts or fail2ban you could use iptables itself to block bad repeated attempts at SSH. […]

  15. […] Also, rather than using Denyhosts or fail2ban you could use iptables itself to block bad repeated attempts at SSH. […]

  16. Mark Avatar
    Mark

    Thanks for this. I didn’t even realize I had a problem until my /var volume filled up due to a tremendously large /var/log/btmp file. Combining this with blocking a few frequent ip addresses, and the problem seems to be under control.

  17. ZenData Avatar
    ZenData

    Thanks … saved alot of time ….

  18. computer_freak_8 Avatar
    computer_freak_8

    Question:
    So, say I’m having a bad day, and can’t remember my password. I try it five times in one minute, all failing to be correct. Am I locked out from whatever IP I’m at until I remove myself from the IPTables block list, or will it let me in if I get it correct after waiting a couple minutes?

    1. Devon Avatar

      Just wait more than 3 minutes without trying to login, then you should be fine.

      1. computer_freak_8 Avatar
        computer_freak_8

        Okay, cool, thanks! I just tried it, though, and it never locks me out to start with. I intentionally put in a wrong password five times in a row (all within about a minute), and it let me in on try number six (even though I didn’t wait at all for it).

        1. computer_freak_8 Avatar
          computer_freak_8

          Oh, hey, it does lock me out… is just let me in once before locking me out. Interesting.

  19. alow Avatar
    alow

    Thanks for this post.

    I was trying to find a way to view the ips that are currently in the block list, however there doesn’t seem to be an iptables command that I could find. The ‘DEFAULT’ list referenced in the rules seems to be located here though: /proc/net/xt_recent/DEFAULT; I’m not sure if you know of a better way?

    1. Devon Avatar

      Alow,

      I’m not sure. I’ve switched to using CSF to manage my IPTables rules. It has handy commands to see the list of temp or perm blocked IPs, etc…

      http://configserver.com/cp/csf.html

      Devon

    2. Nick Coleman Avatar
      Nick Coleman

      You can set up another chain and let it do LOG and DROP. The log entries are in syslog and dmesg. If you have a smart logger (Debian can use rsyslog), you can specify those entries to go into their own file such as iptables.log.

      Google for “iptables ssh log”, there are plenty of examples. They follow the same principle as here with a bit extra for the logging.

  20. nuri huri Avatar
    nuri huri

    on first command i get error “iptables: No chain/target/match by that name.”
    pls advice.

  21. RC Avatar
    RC

    I cannot get this to work – with just these two rules (the first of which does not specify ACCEPT), I cannot connect over SSH at all. If I add the ACCEPT target to the first rule, I can still bomb my server over and over and the DROP rule never comes into effect.

    1. Devon Avatar

      The first rule shouldn’t have an Accept. You’ll need to have port 22 opened on your FW already. That rule is to start tracking SSH connections.

Leave a Reply

Your email address will not be published. Required fields are marked *

PHP Code Snippets Powered By : XYZScripts.com