I have a site that is only relevant to US visitors and would like to block all non-us visitors from accessing the site. What is the best way to do this with iptables given that I have a CIDR list of US ip blocks?

  • possible duplicate of Allow a range of IP's with IPTABLES from a file – Bryan May 16 '12 at 21:45
  • 5
    You hould be carefull. THis is a BAD approach - what about Canada? Oh, you say not relevant - what about Montreal, which is RIGHT across the border. Poeople LIVE there and work in the USA ;) What about Panama, where quite some americans live? Even when it is only relevant for the USA; a lot of people live close or across the border. I for example (europe) live in Poland. I am german. I am a LOT in germany. I live not even 10km over the border (fora lot of reasons, including a LOT lower taxes). I do most of my shopping in germany ;) – TomTom May 17 '12 at 4:27
  • 2
    I am might be moving to America soon. I live in Australia. What if I need to research whatever information is on your site? Also, what about people in America, but their ISP has them located in Canada? Peer1 does this. Put a server in their New York DC and you might just end up with a Canadian IP address. – Mark Henderson May 17 '12 at 6:03
  • 1
    Not necessarily a bad idea, depends on the circumstances. I am using a server for teaching purposes, all my students are in the US, no need for me to provide access to people outside this area - anything that will help limit hacking attacks. – Levon Oct 5 '17 at 12:29

The easiest way would be to block all traffic by default and then only allow the US ranges. I've used this website in the past to get the IP ranges of various countries. In iptables you crease an accept rule of $US_IPS and then have them defined. Just as a warning, this is a lot of IPs and could slow down your firewall depending on the hardware specs and the amount of traffic coming in due to the rule having to look through so many IPs each time. If there is some specific IPs that hit your firewall a lot, you may want to put that rule above this accept rule so it won't have to process the huge IP list each time.


  • 2
    Not "could slow", "will slow" - but the output is FAR from optimized, e.g. – symcbean May 17 '12 at 12:01
  • You can use an ipset to avoid some of the slowdown caused by having such a massive list of rules: xmodulo.com/block-unwanted-ip-addresses-linux.html – Ponyboy47 Mar 5 '18 at 20:35

Although it might be easier to block all by default, this also means any newly assigned U.S. addresses would be blocked too unless you were diligent about keeping your tables up-to-date.

  • You don't have to be diligent if you setup automatic updates to your local maxmind db. (Which of course you should.) – bshea Apr 17 '20 at 15:20

You should look into xtables-addons, a project that writes kernel modules for the netfilter (firewall) code that enhance/expand upon its capabilities.

One such module is xt_geoip, which can match country codes against a binary database downloaded from various sources, particularly MaxMind's GeoIPCountry database (free).

Benefits? Much, much simpler firewall rules and, depending on your setup, considerably better performance. Cost? It takes some patience and troubleshooting skills to get it working.

Once you have this module built and loaded, and the binary database stored in /usr/share/xt_geoip, you can write a single rule to accomplish your task, such as

iptables -I INPUT 1 -m geoip ! --src-cc US -j DROP

Any traffic not from the source country code of the US will be dropped (you get the idea).

This page gives an overview of the process:


Caveat emptor: I've found the process to be very particular about kernel versions - for me, getting this working on CentOS 6 required finding and running an older (1.37) version of the module and disabling a number of features in the mconfig file before ./configure; make as they were not supported in my older distro.

Also, MaxMind (the GeoIP data vendor) has changed their files and layout around, so the scripts (even the latest version) don't work. I got things working by leveraging a public docker image containing an updated version of the data conversion script:


Note that before delving into all of this, you should check to see if xtables-addons and xt_geoip have been accepted into the kernel used by your distro. I expect that at some point, it will really be just a matter of maybe updating the data by running a script and then simply adding the rule described above.

  • Probably best answer with lowest overhead - upvoted. For Debian/Ubuntu: After getting Maxmind DB setup just use: sudo apt install xtables-addons-common for XT addons including geoip. – bshea Apr 17 '20 at 15:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.