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.
asn-to-iptables.sh 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
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.
asn-to-iptables.sh 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:
asn-to-iptables.sh -a AS32934 -c Block-Facebook
asn-to-iptables.sh -4 -a AS32934 -c Block-Facebook
To specify a custom target:
asn-to-iptables.sh -a AS32934 -c Block-Facebook -t "REJECT --reject-with icmp6-adm-prohibited"
asn-to-iptables.sh -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:
asn-to-iptables.sh -a AS8075 -s -c Allow-Microsoft -t ACCEPT
asn-to-iptables.sh -4 -a AS8075 -s -c Allow-Microsoft -t ACCEPT
To match IPSec traffic from a partner network:
asn-to-iptables.sh -a AS8075 -s -c Allow-Microsoft-IPSec -m "--proto esp" -t ACCEPT
asn-to-iptables.sh -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
asn-to-iptables.sh 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.