Matching autonomous system numbers in iptables

Not long ago I was given the task of blocking Facebook on certain days of the week in a small office. The firewall in use was a Linux firewall using iptables. Simple, right?

This is easy enough to do:

  • First, find all of Facebook’s IP address ranges.
  • Then write an iptables rule for each one.

Finding all the IP address ranges is straightforward, too, if you know where to look:

  • Query any of Facebook’s IP addresses in RADB and get their ASN (autonomous system number).
  • Query the ASN in RADB and get a list of all the IP address ranges for that ASN.

Turning this into iptables rules is as straightforward as grep, awk and echo.

But one problem remains: the routes returned from RADB are not aggregated. You will very commonly get back subnet routes which are already included in another listed route. Which means your iptables rules will have rules which never hit because another rule also covers them. This may slow down your firewall as those rules still have to be processed every time.

Now, because I figured I would eventually have to do this again, I wrote a script to take an ASN, aggregate all the returned routes, and spit out iptables rules. will, when given an ASN, output firewall rules in mostly whatever manner you wish. Run the script with no options for a usage statement.


The only required options are -a to specify the ASN to look up, and -c to specify the name of the iptables chain to generate. Once the chain is generated, you can refer to it in any other chain in your firewall in order to use the rules.

By default generated rules will be sent to the REJECT target. To change the rule target, use the -t option.

To create rules with the IP addresses as source addresses, use the -s option. To create rules with the IP addresses as destination addresses, use the -d option, or omit it as it is the default.

To specify custom match parameters to iptables, use the -m option. However, it may be more performant to specify the match targets in your rule which calls the generated chain.

Note that defaults to generating IPv6 firewall rules. If you need IPv4 rules, also specify the -4 option. To generate both IPv4 and IPv6 rules, run it twice, once with -4 and once without.


To generate firewall rules which block all outgoing access to Facebook: -a AS32934 -c Block-Facebook -4 -a AS32934 -c Block-Facebook

To specify a custom target: -a AS32934 -c Block-Facebook -t "REJECT --reject-with icmp6-adm-prohibited" -4 -a AS32934 -c Block-Facebook -t "REJECT --reject-with icmp-admin-prohibited"

To match incoming traffic, e.g. to accept traffic from a partner network: -a AS8075 -s -c Allow-Microsoft -t ACCEPT -4 -a AS8075 -s -c Allow-Microsoft -t ACCEPT

To match IPSec traffic from a partner network: -a AS8075 -s -c Allow-Microsoft-IPSec -m "--proto esp" -t ACCEPT -4 -a AS8075 -s -c Allow-Microsoft-IPSec -m "--proto esp" -t ACCEPT

Once you have generated your chain, call it from whichever iptables chain you want to use, and with whatever options. For example:

ip6tables -I INPUT -m tcp -p tcp --dport 22 -j Allow-Partners
iptables -I INPUT -m tcp -p tcp --dport 22 -j Allow-Partners

Requirements requires the GNU jwhois utility to be installed. This is the default whois on most Linux distributions, so it should not be much of an issue.

In order to perform route aggregation, either aggregate (recommended for performance) or sipcalc (currently required for IPv6 aggregation) must be installed. If you are working with both IPv4 and IPv6 routes, install both. If neither is installed, the script will continue to work, but will not summarize routes.

These are only required to be on the system on which you generate the firewall rules. They do not need to be installed on the destination system to which you apply the rules.


  1. Hello Michael,

    Thanks for your script, It’s very useful !!

    But I had to modify the aggregate function. Is’t very to slow for 30,000 routes. Instead, I used aggregate (apt-get install aggregate or yum install aggregate). 5 to 10 seconds to reduce 30,000 to 1800.

    Have a nice day,


    1. Yves, do you have a modified aggregate function to work with aggregate? – I spend 27 minutes waiting for rules to be aggregated by sipcalc 🙁

    2. Can you share the modified version with “aggregate” ?

    3. I’ve now published an updated version of the script that uses aggregate when available.

      Note that aggregate doesn’t seem to handle IPv6 routes, so it falls back to sipcalc when IPv6 is requested.

  2. Thanks! I was just about to make my own when I found this – and it works perfectly.

  3. Thanks for the script! All of AS4134 is now blocked from my network.

    Your optargs string has a colon after the ‘s’ that causes problems if -s arg is specified right before -a.

    Also, I found that using returns many more results than

Leave a Comment

Your email address will not be published. Required fields are marked *