Ssh – How to Block SSH Brute Force via Iptables and How does it work

firewalliptablesSecurityssh

I'm planning to add the following rules to iptables to stop ssh brute force attack which are common these days.

-A INPUT -i eth0.103 -p tcp -m tcp --dport 4522 -m state --state NEW -m recent --set --name SSH --rsource    
-A INPUT -i eth0.103 -p tcp -m tcp --dport 4522 -m recent --rcheck --seconds 30 --hitcount 4 --rttl --name SSH --rsource -j REJECT --reject-with tcp-reset    
-A INPUT -i eth0.103 -p tcp -m tcp --dport 4522 -m recent --rcheck --seconds 30 --hitcount 3 --rttl --name SSH --rsource -j LOG --log-prefix "SSH brute force "    
-A INPUT -i eth0.103 -p tcp -m tcp --dport 4522 -m recent --update --seconds 30 --hitcount 3 --rttl --name SSH --rsource -j REJECT --reject-with tcp-reset    
-A INPUT -i eth0.103 -p tcp -m tcp --dport 4522 -j ACCEPT

I understand that second, third, and forth rules are responsible from logging and blocking the attack coming from the same IP within 30 sec. interval.

Questions

  1. When the documentation says "log it to the system log once, then immediately reject it and forget about it" what do they mean by forget about it?
  2. Forget about it forever?
  3. Is there a blacklist that iptables check?
  4. If an IP is rejected but then tried another connection an hour later, will there be another 3 attempts from that IP?
  5. If it is the case then this is not blocking but slowing down the attacks as long as iptables doesn't have some blacklist count?

Best Answer

Question #1: When the documentation says "log it to the system log once, then immediately reject it and forget about it" what do they mean by forget about it?

Means that the message will show up in the logs, but only once, so your log won't get polluted with a continuous stream of messages every time the rule is triggered.

Question #2: Forget about it forever?

No not forever. There is a time period associated with how frequently these messages will occur in the logs.

Question #3: Is there a blacklist that iptables check?

No there is no blacklist that iptables "checks". It's dumb in the sense that it will only filter what you tell it to, and will allow only what you tell it to allow through.

Question #4: If an IP is rejected but then tried another connection an hour later, will there be another 3 attempts from that IP?

It depends on what's the over arching timeout. If additional attempts occur and the original timeout hasn't elapsed from the initial attempts, then no there should be no additional messaging in the logs, nor allowed connections. If that timeout has elapsed however, then yes you'll see additional messaging about these follow-on attempts.

I'd encourage you to take a look at the documentation for the Iptable's recent module for additional details on how it works.

Port Scanning

The length of time that an IP remains on the "badguy" list would be governed by a structuring of your rules like this:

iptables -A INPUT -i $OUTS -m recent --name badguys --update --seconds 3600 -j DROP
iptables ...
 .
 .
 .
iptables -A INPUT  -t filter -i $OUTS -j DROP -m recent --set --name badguys

The first rule would check to see if an incoming packet was already on the "badguy" list. If it were, then the clock would get "reset" by the --update switch and the badguy's IP would remain on this list for up to 1 hour (3600 seconds). Each subsequent attempt would reset this 1 hour window!

NOTE: With the rules structured like so, offenders would have to be completely silent for one hour in order to be able to communicate with us again

SSH

For SSH connections the tactic is slightly different. The timeout associated with IP's getting on our "badguy" list is still 1 hour, and still gets reset upon every reconnect within that 1 hour window.

For SSH we need to count each --syn connection. This is a TCP SYN packet, in the TCP 3 way handshake that occurs. By counting these we can "track" each connection attempt. If you try to connect to us more than say 2 times in a 30 second window, we drop you.

To get these IP's that continuously try to connect in the "badguy" list we can incorporate another rule that adds them if they attempt to connect to us say 6 times within a 5 minute window (300 seconds).

Here are the corresponding rules - their order is critical!:

iptables -N BADGUY
iptables -t filter -I BADGUY -m recent --set --name badguys

iptables -A INPUT -i $OUTS -p tcp --syn --dport ssh -m recent --name ssh --set
iptables -A INPUT -i $OUTS -p tcp --syn --dport ssh -m recent --name ssh --rcheck --seconds 300 --hitcount 6 -j BADGUY
iptables -A INPUT -i $OUTS -p tcp --syn --dport ssh -m recent --name ssh --rcheck --seconds  30 --hitcount 2 -j DROP

NOTE: You can see the "badguy" list under /proc/net/ipt_recent. There should be a file there with the name of the list, badguys.

Question #5: If it is the case then this is not blocking but slowing down the attacks as long as iptables doesn't have some blacklist count?

I think you'll find that in general there are 3 ways to deal with connection attempts from iptable's perspective.

  1. Allow traffic known to be acceptable
  2. Disallow traffic known to be unacceptable
  3. Traffic that is potentially bad, slow down and/or reject either indefinitely or for a "timeout" period. If said behavior has been dealt with using a "timeout", re-allow it, after the timeout has elapsed.

#3 is where most of the complexity comes from in setting up iptables and/or firewalls in general. Since much of the traffic on the internet is OK, to a point, and it's when that traffic exhibits "obsessive" behavior, in the sense that a single IP tries to connect to your server's port X number of times where it becomes an issue.

References