Posted by Steve on Sun 17 Jul 2005 at 00:39
The iptables firewall has several useful extension modules which can be used to in addition to the basic firewall functionality. One of the more interesting of these extensions is the "recent" module which allows you to match recent connections, and perform simple throttling on incoming connections.
We've previously described keeping SSH access secure by limiting which users can connect, or just firewalling access so that only a small list of trusted IP addresses can connect. In most cases this is sufficient to protect your system.
However there are times when you have to allow arbitary incoming connections, when you are travelling for example.
In these situations you can open up your system to allow incoming connections and be the target of a dictionary attack - literally a machine trying to connect and login over and over again using usernames and passwords from a dictionary.
These attempts will be logged in your /var/log/auth.log file like this:
sshd[x]: Illegal user admin from aa.bb.cc.dd sshd[x]: Illegal user test from aa.bb.cc.dd sshd[x]: Illegal user guest from aa.bb.cc.dd
In this situation you can create a collection of firewalling rules which will deny access from remote clients who attempt to connect "too many" times.
If you have an existing firewall in place, using iptables, then adding the rules is very straightforward.
The way the recent module works is fairly straightforward, you basically add IP addresses to a list, which can then be used in the future to test connection attempts against. This allows you to limit the number of connections against either a number of seconds, or connection attempts. In our example we'll do both.
An example is probably the simplest way to illustrate how it works. The following two rules will limit incoming connections to port 22 to no more than 3 attemps in a minute - an more than that will be dropped:
iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \ --set iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \ --update --seconds 60 --hitcount 4 -j DROP
The --state flag takes a comma seperated list of connection states as an argument, by using "--state NEW" as we did we make sure that only new connections are managed by the module.
The --set parameter in the first line will make sure that the IP address of the host which initiated the connection will be added to the "recent list", where it can be tested and used again in the future i.e. in our second rule.
The second rule is where the magic actually happens. The --update flag tests whether the IP address is in the list of recent connections, in our case each new connection on port 22 will be in the list because we used the --set flag to add it in the preceeding rule.
Once that's done the --seconds flag is used to make sure that the IP address is only going to match if the last connection was within the timeframe given. The --hitcount flag works in a similar way - matching only if the given count of connection attempts is greater than or equal to the number given.
Together the second line will DROP an incoming connection if:
You can adjust the numbers yourself to limit connections further, so the following example will drop incoming connections which make more than 2 connection attempts upon port 22 within ten minutes:
iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \ --set iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \ --update --seconds 600 --hitcount 2 -j DROP
If you wish to test these rules you can script a number of connection attempts from an external host with the netcat package.
The following script attempts to connect to the IP address 192.168.1.1 5 times. The first couple of attempts you should see a welcome banner such as "SSH-2.0-OpenSSH_3.8.1p1 Debian-8.sarge.4" - after that the script will hang as it's packets are dropped and no response is sent:
#!/bin/bash for i in `seq 1 5` ; do echo 'exit' | nc 192.168.1.1 22 ; done
There's a lot of documentation on the netfilter/iptables firewall, and it's available modules which you can find in the Netfilter Extension HOWTO.
This HOWTO contains documentation on many different modules, along with examples. A recommended read if you're interested in Linux firewalling.
If you wish to experiment with rules and testing it's worth remembering how to remove all active rules. The following commands will flush your iptables filewall, and remove all currently active rules:
iptables -F iptables -X
In my experience "throttling" usually refers to slowing things down, rather than speeding things up - which is what I expect from TOS manipulations.
I think the title might be a little ambiguous though, so I'll change it based upon your suggestion. Thanks :)
Steve
-- Steve.org.uk
[ Parent ]
--
Serge van Ginderachter
[ Parent ]
This thread I found via Google seems to suggest mixing the rules into an existing Shorewall setup is possible.
I guess if you know which ethN device to use, and you're not using conflicting rules then there should be no real harm in it ..
Steve
-- Steve.org.uk
[ Parent ]
--
Serge van Ginderachter
[ Parent ]
[ Parent ]
I've seen lots of SSH activity on my home box. Someone at a LUG[1] meeting suggested the "MaxStartups" option which sets the number of unauthorised connections that SSHd will accept at any time. While it doesn't stop the attention, it does keep it down.
MaxStartups
Specifies the maximum number of concurrent unauthenticated connections to the sshd daemon. Additional connections will be dropped until authentication succeeds or the LoginGraceTime expires for a connection. The default is 10.
Alternatively, random early drop can be enabled by specifying the three colon separated values "start:rate:full" (e.g., "10:30:60"). sshd will refuse connection attempts with a probability of "rate/100" (30%) if there are currently "start" (10) unauthenticated connections. The probability increases linearly and all connection attempts are refused if the number of unauthenticated connections reaches "full" (60).
[1] Hants-LUG
--
"It's Not Magic, It's Work"
Adam
[ Parent ]
[ Parent ]
[ Parent ]
However there are times when you have to allow arbitary incoming connections, when you are travelling for example.
In these situations you can open up your system to allow incoming connections and be the target of a dictionary attack - literally a machine trying to connect and login over and over again using usernames and passwords from a dictionary.
Dictionary attacks against passwords are only possible if your SSH accepts password authentication. If you need to accept arbitrary connections, turn off password authentication and only allow something more secure, like DSA public keys.
[ Parent ]
This is true, but the intention of the article wasn't meant to be completely SSH specific.
There are other situations where it's possible to want to imagine the need to slow down and limit incoming connections..
Steve
-- Steve.org.uk
[ Parent ]
[ Parent ]
Nope, if you've added the correct rules it should just work.
Steve
-- Steve.org.uk
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
I have a question...
I've tried this on one of my boxen. It works perfectly for a few days, then it refuses to accept PuTTY connections from a work machine. If I reboot the system, it behaves okay again for several days, then stops working.
I've had a look at the number of packets in the "recent" log, and it's less than the trigger, yet the remote PuTTY connection fails. As far as I can tell the PuTTY connection is dropped before the packets should be explicitly dropped.
With the drop action off, I see only one new packet in the "recent" log, and the connection is accepted.
$IP $CHAIN --dport 22 -i eth0 -m state --state NEW -j LOG --log-prefix "New SSH Request " $IP $CHAIN --dport 22 -i eth0 -m state --state NEW -m recent --name cracker --set $IP $CHAIN --dport 22 -i eth0 -m state --state NEW -m recent --name cracker --update --seconds 60 --hitcount 4 -j DROP
Any suggestions...?
Debian Sarge, i386, kernel 2.6.8-2-686, eveything else is stock.
--
"It's Not Magic, It's Work"
Adam
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
iptables -N denylog iptables -A denylog -m limit -j LOG iptables -A denylog -j DROP iptables -N SSH_BRUTE iptables -I FORWARD -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -I FORWARD -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 20 --name SSH -j SSH_BRUTE iptables -I SSH_BRUTE -p tcp --dport 22 -m state --state NEW -m recent --update --hitcount 3 --name SSH -j denylogThe result is not the same but it works this way:
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROPthe end result will look like this:
Chain INPUT (policy ACCEPT)
target prot opt source destination
tcp -- anywhere anywhere tcp dpt:ssh state NEW recent: SET name: DEFAULT side: source
DROP tcp -- anywhere anywhere tcp dpt:ssh state NEW recent: UPDATE seconds: 60 hit_count: 4 name: DEFAULT side: source
Note the --set rule is first. Thomas[ Parent ]
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --setin order to get this configuration:
Chain INPUT (policy ACCEPT)
target prot opt source destination
tcp -- anywhere anywhere tcp dpt:ssh state NEW recent: SET name: DEFAULT side: source
DROP tcp -- anywhere anywhere tcp dpt:ssh state NEW recent: UPDATE seconds: 60 hit_count: 4 name: DEFAULT side: source
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
Many have not realized it yet, so I'm adding this note here.
The ipt_recent implementation in 2.6 kernels prior to 2.6.18 was considered bad if not broken code by several kernel hackers. Some of these vanilla kernels were also vulnerable to two related security issues, namely CVE-2005-2872 and CVE-2005-2873.
With 2.6.12, CVE-2005-2872 was fixed, however CVE-2005-2873 was not fixed before July 10th. It is unclear which was the first kernel version to contain both security fixes, it may have been fixed in a later 2.6.17 version - please check the linux changelogs. Linux 2.6.18 contains a complete rewrite of ipt_recent, which should be reliable and not vulnerable to these issues.
More information on blog.blackdown.de
[ Parent ]
[ Parent ]
[ Parent ]
You almost certainly want the fail2ban or denyhosts package - rather than an iptables based solution.
There are some simple ssh tips on this site which might be useful too.
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
#!/bin/sh
#
# Custom Iptables&n bsp;Script
###############################################################
.
.
.
# SSH Brute Force
iptables -A INPUT -i $INT_DEV -p tc p --dport 22 -m state --state NEW&n bsp;-m recent --set --name SSH
iptables -A INPUT -i $INT_DEV -p tc p --dport 22 -m state --state NEW&n bsp;-j SSH_WHITELIST
iptables -A INPUT -i $INT_DEV -p tc p --dport 22 -m state --state NEW&n bsp;-m recent --update --seconds 60 --hi tcount 4 --rttl --name SSH -j LOG&n bsp;--log-prefix 'SSH_brute_force '
iptables -A INPUT -i $INT_DEV -p tc p --dport 22 -m state --state NEW&n bsp;-m recent --update --seconds 60 --hi tcount 4 --rttl --name SSH -j DROP
.
.
.
[ Parent ]
[ Parent ]
Hello,
I have two interfaces. One for Data and one for voice.
The maximum number of connections i can establish is cat /proc/sys/net/netfilter/nf_conntrack_max 32768
I want to reserve some connections for voice interface to have a uninterrupted voice service. So i reserved 20 connections for voice by adding following iptables rules.
iptables -t filter -I FORWARD ! --in-interface voip --m conntrack --ctstate NEW -m connlimit --connlimit-mask 0 --connlimit-above 32748 -j DROP
iptables -t filter -I FORWARD ! --out-interface voip --m conntrack --ctstate NEW -m connlimit --connlimit-mask 0 --connlimit-above 32748 -j DROP
But when I test it, the system is not reserving 20 connections and the voice is getting interrupted.
Could anyone help me to understand what is wrong with the above commands?
Regards, Saravana
[ Parent ]
[ Parent ]
I am not so good in English, but when reading the title of your article, I thought that you were going to teach how to get the incoming connections faster (changing the TOS field, for example).
Isn't "Using iptables to limit incoming connections" a better title?
Beside this, it's a very good article. Really good.
Thank you and sorry if my English is wrong :-)
[ Parent ]