Like most servers (I assume), we have people trying to brute force our services 24/7. I have cpHulk blacklist their IP's, but it seems like it'd be better if they didn't get that far in the first place. Myself and my host are the only ones who connect to the server on ports other than 80, so I'd like to block connections from all countries outside the US, except for port 80. I contacted my host to set this up, but they were hesitant because they said it would create an exceptionally high server load. It's a dedicated Xeon 1230 server with 32GB RAM running CentOS 6.6 and iptables.

First, any reason not to do this? Second, is what my host told me correct? Third, is there any way to accomplish this without a high performance impact?

  • 12
    It's unfortunate that your hosting contact didn't mention "But there's an industry standard way to do the same thing you want with much less maintenance, better security, and low server load called Explicit Deny All. Get me the list of IPs you need whitelisted and I'll have it set up for you in 20 minutes." - That's what I'd expect to hear from any sysadmin worth the chair they sit in.
    – corsiKa
    Commented Feb 13, 2015 at 21:42
  • just block them when they abuse ... maintenance is minimal this way ... with a full table you have to keep it updated
    – Skaperen
    Commented Feb 14, 2015 at 12:44

6 Answers 6


Setting up specific rules to block every IP range (by listing every range) is the wrong approach.

Set the default rules in iptables to drop all traffic to your management ports. Then add rules to only allow access from your trusted IPs (yours and your host).

Blocking everything by default, and allowing only approved traffic is usually called "explicit deny all", and is considered a best-practice. In this case also does help to avoid the performance impact your host is concerned about.

  • Why, if you know, is it an explicit deny all when you're implicitly denying everyone by explicitly allowing only a few IPs in through the firewall?
    – Ben
    Commented Feb 14, 2015 at 1:04
  • There's nothing implicit about it really ...
    – mr-sk
    Commented Feb 14, 2015 at 10:08
  • One potential concern for whitelisting is remote access. You'll need a reliable VPN (separate from this server) and allow its IP range too.
    – Foo Bar
    Commented Feb 14, 2015 at 19:33

In order to do this, you would have to add tens of thousands of firewall rules, one for each netblock, where a country may have anywhere from one to several thousand netblocks associated with it.

When a request comes in, it would have to be checked against every single rule, which takes very little time for a few dozen or maybe even a few hundred rules, but with as many rules as you would need to use, (1) every request will be slowed down significantly and (2) it will use a lot of CPU.

The way to do this without a significant performance impact is by doing what you're already doing: blocking only those specific addresses which are being problematic.

  • Thank you for the reply, Michael. Isn't there a way to only allow US-based IP's, thereby only needing to check one rule?
    – Big Iron
    Commented Feb 13, 2015 at 16:12
  • 2
    @BigIron Of course not. There are also tens of thousands of netblocks in the US. You lose either way. Commented Feb 13, 2015 at 16:24
  • 1
    @SamuelEdwinWard No, it doesn't. Despite them being spread out all over the place, generally such blocklists don't number more than a few hundred entries. Commented Feb 13, 2015 at 19:52
  • 1
    Do you have a reference for how significant the slowdown is? A linear search though all rulesets sounds awfully inefficient, at the very least a binary search would mean the searching a 60,000 rule table would only take 16 probes into the table, and that could be faster than letting the traffic pass through to the webserver that might have to execute disk I/O to serve the request. I couldn't find any metrics on large rulesets in iptables.
    – Johnny
    Commented Feb 13, 2015 at 20:08
  • 1
    @Johnny netfilter (iptables) processes it's rules linearly unfortunately: serverfault.com/questions/334885/…
    – Ross Ridge
    Commented Feb 14, 2015 at 23:12

What you need is a tool called ipsets

IP sets are a framework inside the Linux kernel, which can be administered by the ipset utility. Depending on the type, currently an IP set may store IP addresses, (TCP/UDP) port numbers or IP addresses with MAC addresses in a way, which ensures lightning speed when matching an entry against a set.

the important thing to note here is that it is lightning fast! That is because huge number of ip networks can be represented by a single hash instead of hundreds or thousands of lines of iptables rules.

For blocking countries see this example:


Ignoring the bit about whether or not doing it this way is a good idea, you can do what you asked for with the GeoIP module for iptables.

After building and installing the module (and keeping your IP lists updated monthly), you can do stuff like this to block individual countries:

iptables -I INPUT -m geoip --src-cc CN -j DROP

Or use --src-cc US -j ACCEPT and so on if you prefer to specify those countries that you want to keep.

  • Wouldn't that be a performance disaster even if using "explicit deny all" and allowing only a single country ?
    – user186340
    Commented Feb 15, 2015 at 17:47
  • @AndréDaniel, I admit that I haven't looked at the GeoIP code itself, but assuming that they use a non-naive implementation that is smarter than sequentially comparing a bunch of netblocks (eg. a trie), it need not be. Commented Feb 15, 2015 at 17:56
  • And if you're talking about IPv4 and you have 512 Mb to spare per rule, a theoretical implementation using a lookup table could get the job done in O(1). Commented Feb 15, 2015 at 18:16

If you wanted to retain the ability to connect from anywhere without maintaining a geo-location blacklist/whitelist, you could implement port-knocking. It would stop most automated attempts while allowing you to still connect from any address.

Note: Don't put the port to knock adjacent to the port to open, otherwise a sequential port scan will activate your rule.


On the off-chance that you have a BGP-enabled router or two in your stack AND have some kind of idea what the hell it is you're doing/work with someone who knows what the hell it is they are doing, or are maybe behind a DDoS prevention provider cool enough to assist in the implementation of this, there's a relatively fresh method for restricting traffic to geographical regions called selective blackholing which I think is worth a look.




As this method works on manipulation of the routes, it bypasses any server load issues.

You must log in to answer this question.

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