This section demonstrates how address blocks registered to whole countries can be blocked by the iptables or pf firewall. Firewall Builder makes generating configuration for this simple. This recipe follows the idea outlined in the HOWTO found on HowtoForge at http://www.howtoforge.com/blocking-ip-addresses-of-any-country-with-iptables and in this blog: http://blogama.org/node/62. The original HOWTO only applies to iptables but this recipe demonstrates how the same objects in Firewall Builder can be used to generate both iptables and PF configurations.
The blocking method described in the original HOWTO and in this recipe becomes possible because of the service provided by http://blogama.org where they make files with lists of IP addresses registered to different countries available for download using URLs such as
http://blogama.org/country_query.php?country=CCODE1,CCODE2,...
Here CCODE1, CCODE2 and so on are ISO 3166 country codes.
We start with creating Address Table object (See Section 5.2.14) with name "blocklist":
Since the object is configured as "run-time", the Firewall Builder policy compiler generates configuration in a such way that addresses will be read at the time when policy is activated on the firewall machine. This can be achieved in different ways, for example for the iptables compiler generates shell script fragment that reads addresses, or if the firewall supports iptables module "ipset", generated script will use it (Section 5.2.14.1). For PF, the generated configuration uses table which is loaded at run time using "file" option. You do not have to recompile policy if you use "Run time" Address Table object every time the list of IP addresses is updated. If generated script uses the ipset module with iptables or tables with PF, you only need to run the command on the firewall to reload addresses in the tables maintained by ipset or PF in memory. If the generated firewall uses a shell script that reads the file, as is the case with iptables firewall that does not have the module ipset, then the same script needs to be re-run to pick up changes.
Now we can use this object in the policy rules. To follow original HOWTO closely, I am added rules to control packets coming from the addresses in the list to the firewall, as well as packets going from the firewall to addresses in the list. My goal in this recipe was to reproduce rules found in the original HOWTO as close as possible.
In the rule #1 address table object is in source, the firewall object is in destination, the direction is "inbound", and the action is "deny". This rule matches and drops packets coming from the addresses in the list to the firewall. The second rule reverses source and destination and makes direction "outbound" to match packets sent by the firewall to addresses in the list.
Here is how the generated commands look like for the iptables firewall without module "ipset":
# Rule 1 (global) # echo "Rule 1 (global)" # grep -Ev '^#|^;|^\s*$' /tmp/iptables-blocklist.txt | while read L ; do set $L; at_blocklist=$1; $IPTABLES -A INPUT -i + -s $at_blocklist -j DROP done # # Rule 2 (global) # echo "Rule 2 (global)" # grep -Ev '^#|^;|^\s*$' /tmp/iptables-blocklist.txt | while read L ; do set $L; at_blocklist=$1; $IPTABLES -A OUTPUT -o + -d $at_blocklist -j DROP done
A few comments. The script generated by Firewall Builder assumes comments in the file that holds IP addresses can start with the characters '#', ';' or '*'. It also expects the file to hold one address per line and anything after the address on any line is assumed to be a comment too. This format is slightly expanded compared to the format of files produced by blogama.org which makes script commands slightly more complex. It is also possible that generated script can be somewhat optimized.
If the firewall supports the module ipset (See Section 5.2.14.1 for more details about that), the generated iptables commands look like this:
# Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A INPUT -m set --set blocklist src -j DROP # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -A OUTPUT -m set --set blocklist dst -j DROP #
Here is how exactly the same set of objects can be used to generate configuration for a PF firewall doing the same thing. First, we need to change firewall platform and host OS in the firewall object:
Now save the file and recompile configuration. Here is the result for PF (only relevant fragments of the generated .conf file are shown):
table <blocklist> persist file "/tmp/iptables-blocklist.txt" table <tbl.r9999.d> { 192.0.2.1 , 172.16.22.1 , 192.168.2.1 } # # Rule 1 (global) # # block in quick inet from <blocklist> to <tbl.r9999.d> label "RULE 1 -- DROP " # # Rule 2 (global) # # block out quick inet from <tbl.r9999.d> to <blocklist> label "RULE 2 -- DROP " #
The compiler created the table <blocklist> and associated it with the file "/tmp/iptables-blocklist.txt". (Pardon the name of the file, it carried over from the iptables example). The table <tbl.r9999.d> was created because compiler needed to put several ip addresses that belong to the firewall in this configuration in a single rule. In the end, this PF configuration performs the same operation as iptables configuration shown above.
Finally, to make this work and do something useful, we need to download the addresses of the countries we want to block and put them in the file "/tmp/iptables-blocklist.txt". As the author of the original HOWTO suggests in http://blogama.org/node/62 this can be done with wget. A simple script like this does the job:
COUNTRIES="AK,AR" wget -c --output-document=/tmp/iptables-blocklist.txt \ http://blogama.org/country_query.php?country=$COUNTRIES
This command should probably be put in a script which should run from cron once a month or so. The same script should also reload ip addresses in PF table or ipset list after it updates the address table file to make sure firewall picks up the change. To reload IP addresses from the file on the iptables with ipset module, run the script with command line option "reload_address_table":
/etc/fw/firewall.sh reload_address_table blocklist /etc/fw/blocklist_file.txt
To reload IP addresses on the PF firewall, use the command
pfctl -t blockist
If the firewall you use runs iptables and does not support module ipset, you just need to re-run the firewall script to update the rules with new ip addresses.
Copyright © 2000-2012 NetCitadel, Inc. All rights reserved.
Using free CSS Templates.