23

Someone told me this is possible, but I can't find anything on google or man pages.

I need to ban IPs for a certain amount of time, and then have them unbanned automatically.

8 Answers 8

20

If you mean for iptables to completely remove the rule by itself you won't be able to do it, as far as I know. What's the purpose of this? If you need some kind of automatic temporary banning the standard solution is fail2ban.

Alternatively you can use a cron job to remove the rule you're adding, or, better if you want to do it interactively, an at job:

iptables -I INPUT -s 192.168.1.100 -j DROP
echo "iptables -D INPUT -s 192.168.1.100 -j DROP" | at @10pm 

Also take a look at the recent module of iptables. This with its --seconds option may be of help, depending on your actual needs. man iptables for more information.

2
  • oh wow the 'at' job looks great. Can I combine it with nohup and &? How? May 24, 2011 at 18:40
  • 1
    No need to use nohup - the at job is executed independently from the terminal you used to create it. This means it's run in a shell that doesn't inherit your environment variables, by the way, and it's /bin/sh by default. But that probably won't be a problem in this case. May 24, 2011 at 18:43
14

Put a comment with a timestamp (probably seconds since the epoch) in the rules. Periodically sweep for expired rules.

Note that the most recent linux kernel has support for dynamic loading of IP addresses into a cache consulted by iptable rules instead of as direct iptables rules.

Example:

iptables  -A INPUT -s 192.168.200.100/32 -m comment --comment "expire=`date -d '+ 5 min' +%s`" -j DROP 
iptables -L INPUT -n --line-numbers | tac | perl -ne 'next unless /(^\d+).*expire=(\d+)/; if ($2 < time) { print "iptables -D INPUT $1\n"; }'

You can of course iptables -D INPUT $1 instead of printing the command.

5
  • great idea. Not sure how to do the sweeping part though, I'll be thinking.. May 24, 2011 at 18:44
  • +1 Very good idea, maybe not the simplest but definitely neat.
    – Kyle Smith
    May 24, 2011 at 18:45
  • 1
    @HappyDeveloper: Provided example for add/sweep May 24, 2011 at 18:58
  • 1
    Haha I just had to do this as well, I used awk for my cleanup: iptables -L FORWARD --line-numbers | sort -r | awk 'substr($8,1,4) == "exp@" && substr($8,5) < systime() { systems("iptables -D FORWARD " $1) }' where rules are made like: iptables -A FORWARD -j DROP -m comment --comment "exp@EPOCH"
    – Kyle Smith
    May 24, 2011 at 19:00
  • My 2 cents in perl: iptables -L FORWARD --line-numbers | tac | perl -walne 'system "iptables -D FORWARD $F[0]" if $F[-2] =~ /^expire=(\d+)$/ and $1<time()'
    – tuomassalo
    Oct 9, 2016 at 6:10
8

iptables has a method for automatically adding IP addresses to a list if user defined conditions are met. I use the following to help avoid automated hack attempts to my ssh port:

iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name ssh --seconds 60 --reap -j DROP

This helps to limit automated attempts to gain access to the server by limiting connection attempts from the same IP address to one every 60 seconds.

If you want to allow a set number of attempts in a time frame, such as 4 in 5 minutes, and on failure then blacklist them for a longer period, such as 24 hours, you can do something like:

iptables -X black
iptables -N black
iptables -A black   -m recent --set   --name blacklist   -j DROP

iptables -X ssh
iptables -N ssh
iptables -I ssh 1   -m recent --update    --name blacklist   --reap   --seconds 86400     -j DROP
iptables -I ssh 2   -m recent --update    --name timer       --reap   --seconds   600     --hitcount 4   -j black
iptables -I ssh 3   -m recent --set       --name timer   -j ACCEPT

iptables -A INPUT   -p TCP --dport ssh   -m state --state NEW -j ssh

In the above, we create 2 chains; "ssh" and "black", and 2 lists; "timer", and "blacklist".

Briefly; the last chain shown above is the "doorway" into the ssh chain.

  • Rule 1 in the ssh chain checks to see if the source IP is in the list "blacklist". If so, the connection is dropped and the 24 hour blacklist timer is restarted. If rule 1 is false, then we go to rule 2.
  • Rule 2 in the ssh chain checks to see if the source IP has made more than 4 connection attempts in 5 minutes. If so, it sends the packet to the chain "black" where it is added to the list "blacklist". The chain "black" then DROPs the connection, and we're done.
  • Rule 3 in the chain "ssh" is only reached if rules 1 and 2 are false. If so, the packet is ACCEPTed and the source IP is added to the list "timer" so we can monitor connection attempt frequency.

The "--reap" option tells the kernel to search through the list and purge any items that are older than the set time limit; 5 minutes for the list "timer", and 24 hours for the list "blacklist".

note: the extra spaces are for readability, and are optional in your shell script.

4

IPTables has a feature made expressly for this: IP Set. You make the rule once and it persists as usual but it checks in a set of ips (or ports) for matches. The cool thing is that this set can be dynamically and efficiently updated without disturbing the rest of the firewall.

The main website, examples.

So, to use it, you would still have to use at or cron to schedule the removal.

4

As someone already said: You should use ipset for this feature.

ipset can add ip address with timeout value. When timeout ends, record would be automatically removed from ipset.

timeout All set types supports the optional timeout parameter when creating a set and adding entries. The value of the timeout parameter for the create command means the default timeout value (in seconds) for new entries. If a set is created with timeout support, then the same timeout option can be used to specify non-default timeout values when adding entries. Zero timeout value means the entry is added permanent to the set. The timeout value of already added elements can be changed by readding the element using the -exist option. Example: ipset create test hash:ip timeout 300 ipset add test 192.168.0.1 timeout 60 ipset -exist add test 192.168.0.1 timeout 600

http://ipset.netfilter.org/ipset.man.html

This is preferable way to control this behavior.

2
  • This would have been my answer! That's certainly the best way to go for such. Nov 3, 2022 at 16:34
  • If you added a list of ips to iptables using ipset, it doesn't rmeove it from iptables when timeout expired, or does it ?
    – adrianTNT
    Jan 2 at 3:05
2

You can use fail2ban to ban ip addresses and configure the length of time an address will be banned for.

1

I need to ban IPs for a certain amount of time, and then have then unbanned automatically.

You could try the following one

# iptables -I INTPUT -s xxx.xxx.xxx.xxx -m time --utc --datestart 2013-09-09T15:00 --datestop 2013-09-09T15:30 -j DROP
1

Depending on what exactly you want to accomplish either the netfilter recent or time modules could be used to accomplish this.

Both are documented in the iptables man page.

1
  • This is certainly the best solution since recent does most everything necessary under the sun. Nov 3, 2022 at 16:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .