FreeBSD / OpenBSD: PF Firewall Filter Large Number Of Subnets and IP Address

by on July 10, 2008 · 4 comments· LAST UPDATED August 31, 2008

in , ,

Q. How do I filter larger number of subnets and IPs using OpenBSD's pf firewall under FreeBSD 7.x server? How do I log all dropped packets from such ips? How do I block upto 10000 IPs or subnet without any performance penalty?

A. You can easily filter large number of IPs or subnets using pf firewall. PF provides tables to hold large number of IPv4 and IPv6 address. Lookups against a table are very fast and consume less memory and processor time. Tables are created in pf.conf file. Tables can also be populated from text files containing a list of IP addresses and networks.

How do I configure tables to drop large number of IPs?

Open pf.conf file, enter:
# vi /etc/pf.conf
Add following code:
table <blockedips> persist file "/etc/pf.blocked.ip.conf"
ext_if="em1" # interface connected to internet

Add following code to drop and log all ips / subnet listed in /etc/pf.blocked.ip.conf, file
block drop in log (all) quick on $ext_if from <blockedips> to any
Save and close the file. Now create file /etc/pf.blocked.ip.conf file using vi text editor, enter:
vi /etc/pf.blocked.ip.conf
Sample output:

192.168.1.0/24
202.54.1.5
# 202.54.4.5

The file /etc/pf.blocked.ip.conf should contain a list of IP addresses and/or CIDR network blocks, one per line. Any line beginning with # is treated as a comment and ignored by pf. To load new rules, simply type:
# pfctl -nf /etc/pf.conf
# pfctl -f /etc/pf.conf

How do I view all IP address listed in tables?

Type the following command
# pfctl -t blockedips -T show
Sample output:

   58.65.232.0/21
   58.83.12.0/22
   64.28.176.0/20
   64.255.128.0/19
   66.231.64.0/20
   67.213.128.0/20
   69.8.176.0/20

How do I add subnet called 91.196.232.0/22 on the fly?

Use pfctl command itself, to add CIDR or IP on fly, enter:
# pfctl -t blockedips -T add 202.54.11.11
# pfctl -t blockedips -T add 91.196.232.0/22

How do I delete subnet called 91.196.232.0/22 on the fly?

Type the command as follows:
# pfctl -t blockedips -T delete 91.196.232.0/22
Please note that all changes made using pfct are dynamic. You need to update your file on disk to save the changes.

How do I see statistics for each IP / CIDR?

The -v option can display statistics for each table entry (IP/CIDR), enter:
# pfctl -t blockedips -T show -v
Sample output:

   216.243.240.0/20
        Cleared:     Thu Jul 10 03:01:01 2008
        In/Block:    [ Packets: 0                  Bytes: 0                  ]
        In/Pass:     [ Packets: 0                  Bytes: 0                  ]
        Out/Block:   [ Packets: 0                  Bytes: 0                  ]
        Out/Pass:    [ Packets: 0                  Bytes: 0                  ]
   216.255.176.0/20
        Cleared:     Thu Jul 10 03:01:01 2008
        In/Block:    [ Packets: 0                  Bytes: 0                  ]
        In/Pass:     [ Packets: 0                  Bytes: 0                  ]
        Out/Block:   [ Packets: 0                  Bytes: 0                  ]
        Out/Pass:    [ Packets: 0                  Bytes: 0                  ]

How do I view log of dropped IP from default /var/log/pflog file?

Use tcpdump command to read a log file:
# tcpdump -n -e -ttt -r /var/log/pflog
# tcpdump -n -e -ttt -r /var/log/pflog port 80
# tcpdump -n -e -ttt -r /var/log/pflog and host 202.33.1.2

You can also view log in real time, enter:
# tcpdump -n -e -ttt -i pflog0
# tcpdump -n -e -ttt -i pflog0 port 80
# tcpdump -n -e -ttt -i pflog0 host 202.33.1.2

Further readings:

  • man pages - pf.conf, pfctl, tcpdump, pf
TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 4 comments… read them below or add one }

1 shake faidzal November 27, 2008 at 3:30 am

hi,
i’ve tried the command lines n created the table as ordered, however it doesn’t block the ip’s that i want to filter from access outside internet. FYI, “pfctl -t blockedips -T show” does show the list of ip’s that i key-in. really apreciate if u could spare me some ideas..tq

Reply

2 Ray January 12, 2009 at 2:28 am

I’ve also tried using the above but the IP’s aren’t being blocked. Any ideas?

Reply

3 CDSU April 16, 2009 at 3:41 pm

You have to enable PF first. there are several steps needed in order to complete this task. It may include rebuilding the kernel and adding some options. FreeBSD 7.x or better should have pf enabled in the kernel. the following steps need to be made in order to get pf working
1. edit the /etc/rc.conf file and add the following
pf_enable=”YES” # Enable PF (load module if required)
pf_rules=”/etc/pf.conf” # rules definition file for pf
pf_flags=”” # additional flags for pfctl startup
pflog_enable=”YES” # start pflogd(8)
pflog_logfile=”/var/log/pflog” # where pflogd should store the logfile
pflog_flags=”” # additional flags for pflogd startup’

if you cannot afford to reboot the device you can enable and disable via CLI

pfctl -d Disable the packet filter.

pfctl -e Enable the packet filter.

it is always good to test your rules before you go live.

–CDSY

Reply

4 ko September 18, 2012 at 6:39 am

block drop in log (all) quick on $ext_if from to any

should be write in pf.conf

It works fine with openBSD also

Reply

Leave a Comment

Tagged as: , , , , , , , , ,

Previous Faq:

Next Faq: