rss logo

OpenBSD Geo-Filtering with PacketFilter

OpenBSD Logo

I often use the robust and secure OpenBSD, along with the powerful PacketFilter firewall, to protect my services. Since many commercial solutions support Geo-Filtering, I found it interesting to implement it myself on this system.

By enabling Geo-Filtering, we can hide our services from certain parts of the world, and thus significantly improve security.

To do so, we will be using the PacketFilter tables and the Country IP blocks lists available on the website

Things to know

The lists of countries available on are available in the following URL format:

For example, if we want to access the list for the United States, which has the country code us, we need to go to

  • To download the list to the /etc/tables folder, we can use the wget command:
root@host:~# wget --no-check-certificate -O /etc/tables/
  • We can check the number of lines present in the file using the following command:
root@host:~# wc -l /etc/tables/ 65296 /etc/tables/

This number is quite important, but it is still under the default overall limit of the table-entries system, which is 200000 (see here).

PacketFilter rules

Now that we have our Geo-Filtering list we can add ou filtering rules.

  • For example here we allow only us addresses to access to our web server:
wan = "em0" # Assigns the network interface 'em0' to the variable 'wan' # Sets the maximum number of entries allowed in the PF table to 200,000 (which is already the default) set limit table-entries 200000 # Creates a new PF table named 'USA' and loads its contents from the file '/etc/tables/' table <USA> persist file "/etc/tables/" # Allows incoming HTTP traffic from the 'USA' table to the IP address on ports 80 and 443 pass in quick on { $wan } proto tcp from <USA> to port { 80, 443 } # Blocks incoming HTTP traffic from any source to the IP address on ports 80 and 443 block in quick on { $wan } proto tcp from any to port { 80, 443 }
  • Reload PacketFilter rule:
root# pfctl -f /etc/pf.conf

What Next?

We can add a crontab entry to automatically update the /etc/tables/ file. To do this, you can refer to my other tutorial here.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :

contact mail address