0

I've recently upgraded my Raspberry Pi from Raspbian 8 (Jessie) to 9 (Stretch). The Pi in accessible on my LAN both via IPv4 and IPv6. I have applied some iptables rules (IPv4 only) to block hosts that fail to authenticate multiple times via SSH. There are no iptables rules for IPv6 (yet).

But now iptables (on IPv4) blocks SSH connections from my workstation to the Pi if I try to connect more than one time. Specifically: I can successfully open a first SSH session via IPv4, but when I try to open another session simultaneously it locks me out. I can then only connect via IPv6, or I have to wait until the block time is over (10 minutes).

So far I wasn't able to find the cause of this problem. iptables is set up in a way that it logs all failed connection attempts in syslog, using the keyword "iptables denied". There I can see failed connections on my SSH port, which look like this:

$ tail -f syslog | grep "iptables denied" | grep "DPT=22"
Mar 29 15:39:45 raspberry kernel: [  179.988501] iptables denied: IN=wlan0 OUT= MAC=b8:27:eb:16:b3:1d:e4:b3:18:e3:47:f7:08:00 SRC=192.168.133.51 DST=192.168.133.50 LEN=52 TOS=0x00 PREC=0x00 TTL=128 ID=32145 DF PROTO=TCP SPT=58723 DPT=22 WINDOW=64240 RES=0x00 SYN URGP=0

This is the ruleset for iptables:

$ cat rules.v4
# Generated by iptables-save v1.6.0 on Mon Mar 26 22:54:58 2018
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:LOG_AND_DROP - [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 ! -i lo -j REJECT --reject-with icmp-port-unreachable
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --mask 255.255.255.255 --rsource
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 600 --hitcount 4 --name DEFAULT --mask 255.255.255.255 --rsource -j LOG_AND_DROP
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -s 192.168.133.0/24 -p igmp -m addrtype --dst-type MULTICAST -j ACCEPT
-A INPUT -s 192.168.133.1/32 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 192.168.133.0/24 -p udp -m udp --dport 137:138 -m addrtype --dst-type BROADCAST -j ACCEPT
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
-A INPUT -j DROP
-A FORWARD -j DROP
-A OUTPUT -j ACCEPT
-A LOG_AND_DROP -j LOG --log-prefix "iptables denied: " --log-level 7
-A LOG_AND_DROP -j DROP
COMMIT
# Completed on Mon Mar 26 22:54:58 2018

If you guys wish I can provide a full transcript of a successful SSH session (with maximum debug verbosity "-vvv") and also a failed connection attempt (if this helps debugging).

  • The rules won't decipher successful or unsuccessful logins, but rather block more that 4 connections from the same ip address every 10 minutes. You need to monitor how many connections are being spawned every time you connect. An easier solution would be to look at installing and IDS like fail2ban – Raman Sailopal Mar 29 '18 at 14:33
0

From your ipv4 iptables rules, you should allow 4 connections per 10 minute window.

You expect only one connection, the one you attempted yourself. But, other connection attempts could hit on port 22 (this is a quite common target for port scans!). Is your Raspberry Pi exposed with a public ipv4 address on interface wlan0?

  • Well, to be honest my SSH isn't actually running on port 22. I reconfigured this to a different port for security reasons. Just for the sake of convenience I changed it to standard port in this example. What I tried to do here is to block unsuccessful logins using a technique described in this blog post: blog.bigdinosaur.org/securing-ssh-with-iptables If this is the wrong approach, then my question would be: how must I change the rules to reflect what I'm trying to achieve? – el.com Mar 29 '18 at 15:47
0

See iptables hashlimit module, or google "iptables rate limit source address"

As something more concrete, found this as an example:

iptables -I INPUT -m hashlimit -m tcp -p tcp --dport 80 --hashlimit-above 20/sec --hashlimit-mode srcip --hashlimit-name http -m state --state NEW -j DROP 

Customise to your port, rate, etc etc.

Or use fail2ban, this can be a really good solution, I only use it for SSH myself but it can protect other resources by "failed login count", so you wont trip your own rate limit with legal logins. Though you'd probably have to customise the config to work on a non standard port :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.