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?
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.
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.