# [solved] Stop the SSH attacks (iptables recent module patch)

## toneus

SOLUTION: Needed to compile in the RECENT module option in my kernel.

Hello great keepers of information, and Happy New Year!

I'm reaching out to you because I'm tired of getting ssh attacked by the "bad people" on the Internet, and I need some help. Recently I noticed an attack that lasted 6 days! This has driven me researching iptables and the rules I might add to stop the connection attempts.

First question: Should I be using iptables or another method to stop attacks like these?

I've found many rules out there that all fail to apply because of the lack of the Recent module. It appears that my iptables install does not have support for Recent. http://www.snowman.net/projects/ipt_recent/

Second question: Can I just add a use flag and build it in?

I've found these, but I don't see a Recent.

Module/Match 	Description 	Extended options

mac                  Matching extension for incoming packets mac address. 	--mac-source

state                 Enables stateful inspection 	--state (states are ESTABLISHED,RELATED, INVALID, NEW)

limit                  Rate matching limiting 	--limit, --limit-burst

owner               Attempt to match various characteristics of the packet creator 	--uid-owner userid --gid-owner groupid --pid-owner processid --sid-owner sessionid

unclean             Various random sanity checks on packets 	

```
# uname -a

Linux zeus 2.6.38-gentoo-r6 #1 SMP Thu Jan 5 10:56:27 EST 2012 x86_64 AMD Athlon(tm) 64 X2 Dual Core Processor 6000+ AuthenticAMD GNU/Linux

# iptables -V

iptables v1.4.12.1
```

I'm trying to apply these rules.

```
#!/bin/bash

 ### Set Path ###

 IPT=/sbin/iptables

$IPT -A INPUT -i eth+ -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH

$IPT -A INPUT -i eth+ -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl  -j DROP

exit 0
```

I've tracked it down to the RECENT option is causing me these errors.

```
# ./iptables.drop.8.sh 

iptables: No chain/target/match by that name.

iptables: No chain/target/match by that name.
```

Direction or assistance is greatly appreciated.

Cheers!

TonyLast edited by toneus on Fri Jan 06, 2012 7:51 pm; edited 2 times in total

----------

## Yuu

Hi toneus,

If you don't want to add CONFIG_NETFILTER_XT_MATCH_RECENT support to your kernel; cf :

```
$ zgrep CONFIG_NETFILTER_XT_MATCH_RECENT /proc/config.gz 

CONFIG_NETFILTER_XT_MATCH_RECENT=y
```

Then there's some other ways.. but maybe not as nice as iptables' recent :a) create a public/private SSH key and only allow this authentification method

b) change SSH port : will just stop automated bots, but if someones really wants to find your SSH port, he'll find-it.

c) use app-admin/denyhosts

d) use fail2ban : nice solution; it just ban the IP after N unsuccessfull attempts (ban for at least one week or forever)

e) block all incoming SSH attempts except your IP : maybe the best solution, but you need to have a static IP (don't forget to add another static IP in case the first IP comes unusable)

For me, iptables recent and e) are the best solutions :}

Good luck :]

----------

## harivolker

Howdy,

you might want to try out fail2ban:

```
# emerge -av net-analyzer/fail2ban
```

It does exactly what you're trying to do.  :Wink: 

Regards, Volker

----------

## NeddySeagoon

toneus,

There are several solutions to the problem.  The easiest is to turn off root logins and enforce the use strong passwords.

That stops peole getting in but not the logspam.

Better is to turn off password login altogether and use key based login. Still turn off root logins - that way, when someone becomes root, its logged, so you know who.

Users can now only log in if their public key is in ~/.ssh/authorized.keys. Lots of security and lots of logspam because sshd still goes through the password login ritual before it denys the login.

iptables is th linux firewall, however on its own it does nothing - it needs rules to operate by.

There are lots of packages to geneate rule sets. Rules can be both static and dynamic or a mix.

I use shorewall for static rules. That may be overkill if you just want to set up a static firewall to permit a few staic IPs to access ssh and deny all other IPs.

That are packages like fail2ban which sets a dynamic rule based on login failures. I think it uses IP tables but I've never tried it.

You can set such a dynamic rule to have a lifetime in case it was genuine user error, or just add to a growing list of banned IPs.

Banning or permitting individual IPs can lead to some very long lists. Every now and again, I look at my logs and set DROP for the entire IP range that any attacker comes from.

Do 

```
whois IP_of_attacker
```

Typically they are China, Korea and that area. I don't have any users there, so thats safe for me.  You get the odd attacker from a range you do have a real user on. Report the abuse to ISPs abuse address in that case - providing log extracts. Most ISPs take it very seriously.

----------

## toneus

Excellent information all. To tie this whole thing up with a bow, I am using these rules in conjunction with other IP banning rules (http://www.cyberciti.biz/faq/block-entier-country-using-iptables/). These two should get rid of 99% of my problem. I wasn't aware of the fail2ban, but will give it a review.

It wasn't clear to me that an unselected kernel module was limiting the compile. Genkernel user, so I enabled the module in the Net Filter area.

```
In Genkernel

<M>   "recent" match support
```

A quick rebuild and reboot, and now the rules are now processed and list as expected.

```
zeus bin # iptables -L

Chain INPUT (policy ACCEPT)

target     prot opt source               destination         

countrydrop  all  --  anywhere             anywhere            

           tcp  --  anywhere             anywhere             tcp dpt:ssh state NEW recent: SET name: SSH side: source

DROP       tcp  --  anywhere             anywhere             tcp dpt:ssh state NEW recent: UPDATE seconds: 60 hit_count: 8 TTL-Match name: DEFAULT side: source

```

Thanks much, have a great day!

Now if I can just figure out my nagging KERNEL PANIC.

----------

## Jacekalex

You can also use hashlimit, works very well:

example:

```
iptables -I INPUT -m hashlimit -m tcp -p tcp --dport 22 --hashlimit 3/hour --hashlimit-mode srcip --hashlimit-name ssh -m state --state NEW -j ACCEPT
```

Kernel config:

```
zgrep -i hashlimit /proc/config.gz 

CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
```

Source:

http://www.zolv.eu/node/60

Sshd config:

You can also disable the login password for root account

```
grep -i root /etc/ssh/sshd_config | grep -v '#'

PermitRootLogin without-password
```

You can also disable the login password for root account.

In this setting the root account you will be able to log in using only the encryption key rsa | dsa | ecdsa.

Before you configure and test login using ssh keys.

http://en.wikipedia.org/wiki/Ssh-keygen

http://en.gentoo-wiki.com/wiki/SSH_Public_Key_Authentication

Well also change the default ssh port to another - which by default does not use any service, for example, port 11986 - no such port on a network robot will not be looking for the ssh server, the number of attacks decreased significantly with the change.

Cheers 

 :Cool: 

----------

## Bones McCracker

 *toneus wrote:*   

> Excellent information all. To tie this whole thing up with a bow, I am using these rules in conjunction with other IP banning rules (http://www.cyberciti.biz/faq/block-entier-country-using-iptables/). These two should get rid of 99% of my problem. I wasn't aware of the fail2ban, but will give it a review.
> 
> It wasn't clear to me that an unselected kernel module was limiting the compile. Genkernel user, so I enabled the module in the Net Filter area.
> 
> ```
> ...

 

That countrydrop approach adds a lot of iptables rules (have you looked at how long the list is?) and is really poor advice, in my opinion.

If you really want to block entire countries (which is of questionable value but seems to be popular) here's an alternative you may want to try.  It's a similar approach to what you're doing, except instead of creating thousands of iptables rules, it creates something called an 'ipset' containing those addresses, and just creates one iptables to check connection attempts against the ipset.  It's much more efficient.

https://forums.gentoo.org/viewtopic-t-863121.html

Another simpler approach, which is what I think NeddySeagoon was steering you toward, is simply to create a rule which accepts SSH connections to your SSH port from each IP address you want to allow, followed by another rule which drops without logging all other attempts to connect to SSH.  If you're using public key encryption, or at least strong passwords, as he suggested, then really all these connection attempts are just noise you can ignore.

There are also far more secure (and complex) methods, including port-knocking, VPN, and single-packet authentication.  There's a single-packet authentication package called FWKNOP which you can install from the overlays, or if you like to tinker, you can build your own like I did:

https://forums.gentoo.org/viewtopic-t-687956.html

----------

## py-ro

Simplest Solution, just use another port...

----------

## toneus

Still more great information, thanks all. I'm not saying I know the best route, or the fastest. I do know that I hate the bad guys on the inet.

I've used the key approach, but that caused me more havoc when I wasn't carrying my key with me and I needed to get on my system.

Root login via ssh is disabled on my box.

The ipset is intriguing. BoneKracker, you've obviously spent some time in this area. I definitely don't want to slow down my inet speeds, and this info will likely cause me to spend multiple hours tomorrow redoing everything.

Yes I could move ssh to another port, but the bad guys out there will find it anyway.

Cheers!

----------

## Bones McCracker

 *toneus wrote:*   

> The ipset is intriguing. BoneKracker, you've obviously spent some time in this area. I definitely don't want to slow down my inet speeds, and this info will likely cause me to spend multiple hours tomorrow redoing everything.

 

Since you're only checking SYN packets (new connection attempts), having thousands of unnecessary rules won't really slow you down noticeably unless you process a lot of connection attempts (like if you're running a server that gets a lot of exposure or is an attractive target for some reason).  If this is just your machine at home or something, that approach with the gazillion rules should be fine; it's just not very elegant.

----------

## wswartzendruber

I have TCP 22 wide open to everyone.  I disabled root logons and password authentication.  Private keys only.

----------

## Bones McCracker

 *wswartzendruber wrote:*   

> I have TCP 22 wide open to everyone.  I disabled root logons and password authentication.  Private keys only.

 

Yeah, but that's because you enjoy watching the AUTH log scroll by.  :P

----------

## wswartzendruber

 *BoneKracker wrote:*   

>  *wswartzendruber wrote:*   I have TCP 22 wide open to everyone.  I disabled root logons and password authentication.  Private keys only. 
> 
> Yeah, but that's because you enjoy watching the AUTH log scroll by.  

 

Meh.  I've never even checked it.

Oh yeah, I also set "AllowUsers" and disabled PAM.

----------

