12

I am using the "recent" module to prevent port scanning, such as:

-A INPUT -i eth0 -m recent --name PORTSCAN --update --seconds 60 -j DROP
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT         -m recent --name PORTSCAN --set -j DROP

The --update option, contrary to its name (i.e., update old value with new one), does not update the last-seen entry, but rather adds another one. In my simple setup, I am only interested in the last entry. I don't need the whole history of packets seen (i.e., for statistics).

Is there a way, I could only keep the last seen packet ? There used to be an option --reap, but AFAIK has been removed.

My concern is, that on a busy server, the PORTSCAN list could quickly grow pretty large. I don't know what the limit is, but I am sure there must be some limit.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
user1968963
  • 4,083

2 Answers2

15

If you take a look at the man page for iptables specifically the recent modules section there are a couple of parameters that look like they'll give you the control you're looking for:

excerpt from iptables recent module section

The module itself accepts parameters, defaults shown:

   ip_list_tot=100
          Number of addresses remembered per table.

   ip_pkt_list_tot=20
          Number of packets per address remembered.

So according to these two parameters you can control the number of IP addresses and the number packets that the recent module will "remember".

Remember this is a kernel module so to apply these settings you either need to set them at module load time like so:

/sbin/modprobe ipt_recent ip_list_tot=2000 ip_pkt_list_tot=255

On my Fedora 14 system the module is actually called xt_recent, you can see what types of parameters it can take using modinfo:

$ modinfo xt_recent
filename:       /lib/modules/2.6.35.14-106.fc14.x86_64/kernel/net/netfilter/xt_recent.ko
alias:          ip6t_recent
alias:          ipt_recent
license:        GPL
description:    Xtables: "recently-seen" host matching
author:         Jan Engelhardt <jengelh@medozas.de>
author:         Patrick McHardy <kaber@trash.net>
srcversion:     00B9A3AB999488BFEB4FA6A
depends:        
vermagic:       2.6.35.14-106.fc14.x86_64 SMP mod_unload 
parm:           ip_list_tot:number of IPs to remember per list (uint)
parm:           ip_pkt_list_tot:number of packets per IP address to remember (max. 255) (uint)
parm:           ip_list_hash_size:size of hash table used to look up IPs (uint)
parm:           ip_list_perms:permissions on /proc/net/xt_recent/* files (uint)
parm:           ip_list_uid:default owner of /proc/net/xt_recent/* files (uint)
parm:           ip_list_gid:default owning group of /proc/net/xt_recent/* files (uint)

Checking xt_recent settings

All the settings for this module are kept under the /sys/module/xt_recent. Specifically the parameters you pass into it are kept here:

$ ls -1 /sys/module/xt_recent/parameters/
ip_list_gid
ip_list_hash_size
ip_list_perms
ip_list_tot
ip_list_uid
ip_pkt_list_tot

Any of the parameters can be checked by simply cat'ing the files in this directory, for example:

cat /sys/module/xt_recent/parameters/ip_pkt_list_tot

So this tells us that the default value of for the parameter ip_pkt_list_tot is 20.

slm
  • 369,824
  • That works great. Thanks. I can now specify ip_pkt_list_tot=1 while loading the module. Regarding the other option, ip_list_tot, is there a way to find out what is the default/current value ? – user1968963 May 18 '13 at 12:29
  • OK, I see I can find the current values of the parameters in: /sys/module/xt_recent/parameters/* – user1968963 May 18 '13 at 13:12
  • Sorry I stepped out, just saw your question, yes you can see everything under /sys/module/xt_recent/*. I'll update the answer with this info as well. – slm May 18 '13 at 14:01
  • 1
    A nicer way to list the information in those files: head /sys/module/xt_recent/parameters/* – Hvisage Sep 20 '15 at 20:35
  • 1
    Great answer, wish the kernel settings interrogation information could get added to the man page for this module. – 111--- Nov 12 '20 at 18:29
  • It appears that as of kernel version 4.0, an ip_pkt_list_tot value of '0' (the new default) no longer enforces an arbitrary limit, but instead defers to the value of hit_count when checking for a match (with an overall max of 255). Was not able to find this behavior documented outside of the source. See: https://elixir.bootlin.com/linux/v4.0-rc1/source/net/netfilter/xt_recent.c#L63 – 111--- Nov 12 '20 at 20:25
2

In addition to the answer given above, I suggest you stuff an additional BADGUYS table before your PORTSCAN trap, and use it to prevent spilling over the latter.

Then, when the PORTSCAN is triggered, add a record to the BADGUYS table.

Something like this:

-A INPUT --name PORTSCAN --rcheck --seconds 60 --reap --hits 20 -j set_bad
-A INPUT --name BADGUYS --rcheck --seconds 3600 --reap -j noway
-A INPUT <trap case> --name PORTSCAN --set
-A set_bad --name BADGUYS --set
-A noway -p tcp -j REJECT --reject-with tcp-reset
-A noway -j DROP
AnrDaemon
  • 169