What is the most efficient way to block access to 8-10k IP addresses?

My server runs EngineX on Debian.

If possible, I would like to show all of the addresses an Internal Server Error (500).

The IP's are scattered and not under any particular subsets.

  • answer updated.
    – pQd
    Apr 13, 2010 at 6:17

3 Answers 3


if the addresses are grouped in one or few continuous subnets [ eg few /24s ] - i would create simple prerouting rule that would DNAT all traffic on port 80 from them to something listening on port 81 [ eg vhost from nginx ] that would just serve error page:

iptables -t nat -A PREROUTING -p tcp -s --dport 80 -j REDIRECT --to 81

if this is 8-10k unique ips scattered 'all around'... it'll be interesting ;-] - i would still go with above scenario but for matching i would use ipset. something like this:

ipset --create ban iphash
ipset --add ban
ipset --add ban
ipset --add ban
# ....
iptables -t nat -A PREROUTING -p tcp -m set --set ban src --dport 80 -j REDIRECT --to 81
  • The Port 81 vhost is a great idea. Unfortunately the IPs are scattered. Can ipset work in conjunction with iptables?
    – Miko
    Apr 10, 2010 at 23:01
  • yes - ipset works togetger with iptables, just check provided link.
    – pQd
    Apr 11, 2010 at 1:44
  • Could you please provide an example on how it would work with ipset? My experience with iptables is zero to none so I'm having a hard time wrapping my head around the proper format.
    – Miko
    Apr 12, 2010 at 22:34

Might take a look at: http://www.hipac.org/ It handles large numbers of rules quite well. If there is a pattern to the IPs you are trying to block, you could use the MATCH rule. pQd's prerouting rule would work well with nf-hipac which uses a hash table to store the rules and is considerably quicker than the default iptables lookups.

You could write the ruleset into deny lines in your location block. To make it simple, you could include a file that included your deny blocks and reload the config on an hourly basis. Since it would be within the nginx config file, it shouldn't impact performance too much.

  • It seems nf-HiPAC is no longer supported as the last updated was 5 years ago. The complication errors I ran into implied the software depends on libraries no longer being shipped with current releases.
    – Miko
    Apr 11, 2010 at 10:08

If you have a list of these addresses in a file, you can try the following in Nginx config:

1 Define an IP group using geo directive (inside http block):

http {
  geo $block {
    default 0;
    include blacklist; 

It means that variable $block will be set to 0 by default.

2 Prepare a blacklist file to look like this: 1; 1; 1;

That is, set variable $block to 1 for these addresses.

3 Inside the `location' block, check this variable and report 500 error if it's 1:

 if ($block = 1) {
   return 500;

PS: The efficiency of this solution is arguable, since the connections from banned IPs are accept()ed and passed to the web server. However, if this tiny overhead is not critical for your host, I would rather do it with Nginx, not with iptables.

You must log in to answer this question.

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