≡ Menu

BSD PF IPv6 and IPv4 /etc/pf.conf Firewall Script

This is my working IPv6 and IPv4 dual stack script from FreeBSD 7.1 server. It should work with any latest PF version under OpenBSD / FreeBSD / NetBSD without a problem.

You need to add following lines to /etc/rc.conf under FreeBSD to turn on PF firewall:

pf_enable="YES"
pflog_enable="YES"
pflog_logfile="/var/log/pflog"
pf_rules="/etc/pf.conf"

Next create /etc/pf.conf file as follows. Replace variable with appropriate values.

  1. By default firewall drops all incoming and outgoing connections for both IPv4 and IPv6.
  2. By default IPv4 and IPv6 outgoing allowed for ssh, smtp, domain / dns, www, https, ntp, ping and whois requests.
  3. By default IPv4 and IPv6 incoming allowed for ssh, smtp, domain / dns, www, https, and ping only.
#### S0.1 First declare a couple of variables ####
# Created by Vivek Gite 
# See more info @
# http://bash.cyberciti.biz/firewall/pf-ipv6-ipv4-firewall-for-freebsd-openbsd-netbsd/
tcp_services = "{ ssh, smtp, domain, www, https, 122, ntp, 43}"
udp_services = "{ domain, ntp }"
icmp_types = "{ echoreq, unreach }"
mail_ports = "{ smtp, imaps }"
### define tables
table  persist file "/etc/pf.drop.lasso.conf"
table  persist file "/etc/pf.block.ip.conf"
### IPv4 ranges
martians = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 0.0.0.0/8, 240.0.0.0/4, 255.255.255.255/32 }"
http_servers = "{ 208.xx.yyy.zzz }"
mail_servers = "{ 208.xx.yyy.zzz}"
dns_servers = "{ 208.xx.yyy.zzz }"
adminrange = "66.228.118.0/23"
### ipv6 ranges
adminrange6 = "{ 2607:F0D0:2000:0000::/48 }"
http_servers6 = "{ 260z:xxx.. }"
mail_servers6 = "{ 260z:xxx.. }"
dns_servers6 = "{ 260z:xxx.. }"
IPV6LAN = "{ 260z:xxx../64 }"
IPV6MAIN = "{ 260z:xxx.. }"
### Interfaces
ext_if = "em1"
int_if = "em0"
## S0.2: Options
set block-policy return
set loginterface $ext_if
#### S0.3: Normliaztion
#scrub provides a measure of protection against certain kinds of attacks based on incorrect handling of packet fragments
scrub in all
#### S0.4: NAT and RDR start
# Drop ALL incomming everything
block log all
# Try to block nmap scans
block in log quick on $ext_if inet proto tcp from any to any flags FUP/FUP
#IPv6 - pass in/out all IPv6 ICMP traffic
pass in quick proto icmp6 all
# unlimited traffic for vpn and loopback
set skip on {lo0, $int_if}
# activate spoofing protection for all interfaces
block in quick from urpf-failed
#antispoof is a common special case of filtering and blocking. This mechanism protects against activity from spoofed or forged IP addresses
antispoof log for $ext_if
#Block RFC 1918 addresses
block drop in log (all)  quick on $ext_if from $martians to any
block drop out log (all) quick on $ext_if from any to $martians
#Block DROP LASSO
#block log (all) all
# pfctl -t droplasso -T show
block drop in log (all)  quick on $ext_if from  to any
block drop out log (all) quick on $ext_if from any to 
# pfctl -t blockedip -T show
block drop in log (all)  quick on $ext_if from  to any
block drop out log (all) quick on $ext_if from any to 
# allow outgoing via ssh, smtp, domain, www, https, 122
pass out on $ext_if proto tcp to any port $tcp_services
pass out on $ext_if proto udp to any port $udp_services
# trace route
pass out on $ext_if inet proto udp from any to any port 33433 >< 33626 keep state
# SL admin allow 66.228.118.0/255.255.254.0 (23)
pass in on $int_if from $adminrange to any
# pass in  on $ext_if proto tcp from any to any port 25
pass in on $ext_if inet proto tcp from 72.xx.yyy.zzz to 208.xx.yyy.zzz port ssh flags S/SA synproxy state
pass in on $ext_if inet proto udp from any to $dns_servers  port domain
pass in on $ext_if inet proto tcp from any to $dns_servers  port domain flags S/SA synproxy state
pass in on $ext_if inet proto tcp from any to $http_servers port http flags S/SA synproxy state
pass in on $ext_if inet proto tcp from any to 208.43.79.236 port https flags S/SA synproxy state
pass in on $ext_if inet proto tcp from any to $mail_servers port $mail_ports flags S/SA synproxy state
# ping pong
pass inet proto icmp all icmp-type $icmp_types keep state
# Outgoing ftp
pass out on $ext_if inet proto tcp from any to any port ftp
pass out on $ext_if inet proto tcp from any to any port >1023
###### IPv6 rules #############
# Allow outgoing services
pass out on $ext_if inet6 proto tcp to any port $tcp_services
pass out on $ext_if inet6 proto udp to any port $udp_services
# Trace route out
pass out on $ext_if inet6 proto udp from any to any port 33433 >< 33626 keep state
# SL Admin in
pass in on $ext_if inet6 from $adminrange6 to any
# Open ports out
pass in on $ext_if inet6 proto udp from any to $dns_servers6 port domain
pass in on $ext_if inet6 proto tcp from any to $dns_servers6 port domain keep state
pass in on $ext_if inet6 proto tcp from any to $http_servers6 port http keep state
pass in on $ext_if inet6 proto tcp from any to $mail_servers6 port $mail_ports keep state
# Ftp out
pass out on $ext_if inet6 proto tcp from any to any port ftp
pass out on $ext_if inet6 proto tcp from any to any port >1023
# Allow ping pong out
pass out on $ext_if inet6 proto icmp6 all icmp6-type echoreq keep state
# ND solicitation out
pass out on $ext_if inet6 proto icmp6 all icmp6-type {neighbradv, neighbrsol}
# ND advertisement in
pass in on $ext_if inet6 proto icmp6 all icmp6-type {neighbradv, neighbrsol}
# Router advertisement out
pass out on $ext_if inet6 proto icmp6 all icmp6-type routeradv
# Router solicitation in
pass in on $ext_if inet6 proto icmp6 all icmp6-type routersol
# Allow Ping pong in
pass in on $ext_if inet6 proto icmp6 all icmp6-type echoreq

You also need to create /etc/pf.block.ip.conf file with list of IPs and subnet to block manually as follows:

202.54.1.2
191.10.1.0/29

This script also supports Spamhaus database to block SMTP / WWW spam bots. Download Shell Script To Update Spamhaus Lasso Spam Database for PF .

{ 5 comments… add one }
  • Tekki July 28, 2011, 6:54 pm

    Hi there! I would like to know if this configuration can help me block IPv6 domain like https facebook? I have a problem blocking Https facebook.

  • Vivek Gite March 27, 2009, 4:15 pm

    Yes, it passes all ICMP6 traffic. Feel free to modify pf.conf it as per your requirements and setup.

  • Roberto Greiner March 26, 2009, 7:34 pm

    Hi, I think i got a small security problem.

    At the end of the script you have a few lines controlling what of icmp6 can get in. But at the start of the script you have

    #IPv6 – pass in/out all IPv6 ICMP traffic
    pass in quick proto icmp6 all

    which lets all icmp6 traffic in. Or did I get something wrong?

  • Vivek Gite February 2, 2009, 9:38 pm

    Thanks for the heads up.

  • xcezzz February 2, 2009, 6:25 pm

    There should be a correction on the line below, of where to put pf_enable=”YES”

    You need to add following lines to /etc/pf.conf under FreeBSD to turn on PF firewall:

    It should be rc.conf?

    You need to add following lines to /etc/rc.conf under FreeBSD to turn on PF firewall:

Security: Are you a robot or human?

Leave a Comment