For many of us, the entirety of our legitimate traffic comes from a single country. There comes a point where the ideal of a borderless internet is no longer worth the headache of fending off attackers from China and Eastern Europe.
The pf firewall has a feature called tables, which allows us to create efficient firewall rules that apply to an entire database of IP blocks. The tables are simple text files of newline-separated address blocks in CIDR format.
Step 1: Download Per-Country IP and Bogon Lists
- Make a folder on your firewall to hold your IP lists. For this tutorial, we will use /etc/pf_tables.
- Download the per-country IP lists at Eggplant Systems.
- Extract the tarball from Eggplant Systems to your /etc/pf_tables folder.
- Download the plain text “fullbogon” lists at Team Cymru.
- Copy the fullbogon lists to your /etc/pf_tables folder.
Step 2: Update pf.conf
Here are the relevant sections to add to your pf.conf file:
# INTERFACE MACROS # NOTE: THESE ARE ALIASES FOR THE ACTUAL INTERFACE NAMES. # IN THIS EXAMPLE, igb1 IS MY IPv6 INTERFACE AND igb2 IS MY IPv4 INTERFACE. # YOU CAN USE THE INTERFACE NAMES DIRECTLY IN YOUR RULES IF YOU PREFER. WAN6_IF="igb1" WAN_IF="igb2" # TABLES # NOTE: THIS IS WHERE WE CREATE PF TABLES FROM TEXT FILES. # AFTER THESE LINES, YOU CAN REFER TO ALL OF THE ADDRESSES IN fullbogons-ipv4.txt # AS <bogons>. THE KEYWORD persist IS OPTIONAL. TRAILING BACKSLASHES # CAN BE USED TO CONTINUE A SINGLE STATEMENT ONTO ANOTHER LINE. table <bogons> persist file "/etc/pf_tables/fullbogons-ipv4.txt" table <bogonsv6> persist file "/etc/pf_tables/fullbogons-ipv6.txt" # THIS EXAMPLE BLOCKS RUSSIA AND CHINA. RIR COUNTRY CODES CAN # BE FOUND HERE: # https://www.nro.net/about-the-nro/list-of-country-codes-and-rirs-ordered-by-country-code table <gaijin> persist \ file "/etc/pf_tables/output/cidr_v4_ru.txt" \ file "/etc/pf_tables/output/cidr_v6_ru.txt" \ file "/etc/pf_tables/output/cidr_v4_cn.txt" \ file "/etc/pf_tables/output/cidr_v6_cn.txt" ## RULES # BLOCK BOGONS block in quick on $WAN_IF inet from <bogons> to any block in quick on $WAN6_IF inet6 from <bogonsv6> to any # BLOCK GAIJIN block in quick from <gaijin>
Step 3: Reload pf.conf
pfctl -vf /etc/pf.conf
Notes
- IP blocks are transferred on a regular basis, so both per-country IP and bogon lists will need to be updated regularly.
- The secret-sauce at Google and Bing is secret. They could start penalizing websites that geoblock at any time without warning. This could be mitigated by leaving port 80/tcp (HTTP) and port 443/tcp (HTTPS) wide-open while falling-back to your geoblocking tables for everything else (mail, ssh, vpn, etc).