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

by on January 23, 2009 · 5 comments

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:

  1. pf_enable="YES"
  2. pflog_enable="YES"
  3. pflog_logfile="/var/log/pflog"
  4. 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.
  1. #### S0.1 First declare a couple of variables ####
  2. # Created by Vivek Gite <vivek@nixcraft.com>
  3. # See more info @
  4. # http://bash.cyberciti.biz/firewall/pf-ipv6-ipv4-firewall-for-freebsd-openbsd-netbsd/
  5. tcp_services = "{ ssh, smtp, domain, www, https, 122, ntp, 43}"
  6. udp_services = "{ domain, ntp }"
  7. icmp_types = "{ echoreq, unreach }"
  8. mail_ports = "{ smtp, imaps }"
  9.  
  10. ### define tables
  11. table <droplasso> persist file "/etc/pf.drop.lasso.conf"
  12. table <blockedip> persist file "/etc/pf.block.ip.conf"
  13.  
  14. ### IPv4 ranges
  15. 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 }"
  16. http_servers = "{ 208.xx.yyy.zzz }"
  17. mail_servers = "{ 208.xx.yyy.zzz}"
  18. dns_servers = "{ 208.xx.yyy.zzz }"
  19.  
  20. adminrange = "66.228.118.0/23"
  21.  
  22. ### ipv6 ranges
  23. adminrange6 = "{ 2607:F0D0:2000:0000::/48 }"
  24. http_servers6 = "{ 260z:xxx.. }"
  25. mail_servers6 = "{ 260z:xxx.. }"
  26. dns_servers6 = "{ 260z:xxx.. }"
  27.  
  28. IPV6LAN = "{ 260z:xxx../64 }"
  29. IPV6MAIN = "{ 260z:xxx.. }"
  30.  
  31. ### Interfaces
  32. ext_if = "em1"
  33. int_if = "em0"
  34.  
  35. ## S0.2: Options
  36. set block-policy return
  37. set loginterface $ext_if
  38.  
  39. #### S0.3: Normliaztion
  40. #scrub provides a measure of protection against certain kinds of attacks based on incorrect handling of packet fragments
  41. scrub in all
  42.  
  43. #### S0.4: NAT and RDR start
  44.  
  45. # Drop ALL incomming everything
  46. block log all
  47.  
  48. # Try to block nmap scans
  49. block in log quick on $ext_if inet proto tcp from any to any flags FUP/FUP
  50.  
  51. #IPv6 - pass in/out all IPv6 ICMP traffic
  52. pass in quick proto icmp6 all
  53.  
  54. # unlimited traffic for vpn and loopback
  55. set skip on {lo0, $int_if}
  56.  
  57. # activate spoofing protection for all interfaces
  58. block in quick from urpf-failed
  59. #antispoof is a common special case of filtering and blocking. This mechanism protects against activity from spoofed or forged IP addresses
  60. antispoof log for $ext_if
  61.  
  62. #Block RFC 1918 addresses
  63. block drop in log (all) quick on $ext_if from $martians to any
  64. block drop out log (all) quick on $ext_if from any to $martians
  65.  
  66. #Block DROP LASSO
  67. #block log (all) all
  68. # pfctl -t droplasso -T show
  69. block drop in log (all) quick on $ext_if from <droplasso> to any
  70. block drop out log (all) quick on $ext_if from any to <droplasso>
  71.  
  72. # pfctl -t blockedip -T show
  73. block drop in log (all) quick on $ext_if from <blockedip> to any
  74. block drop out log (all) quick on $ext_if from any to <blockedip>
  75.  
  76. # allow outgoing via ssh, smtp, domain, www, https, 122
  77. pass out on $ext_if proto tcp to any port $tcp_services
  78. pass out on $ext_if proto udp to any port $udp_services
  79.  
  80. # trace route
  81. pass out on $ext_if inet proto udp from any to any port 33433 >< 33626 keep state
  82.  
  83. # SL admin allow 66.228.118.0/255.255.254.0 (23)
  84. pass in on $int_if from $adminrange to any
  85.  
  86. # pass in on $ext_if proto tcp from any to any port 25
  87. 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
  88. pass in on $ext_if inet proto udp from any to $dns_servers port domain
  89. pass in on $ext_if inet proto tcp from any to $dns_servers port domain flags S/SA synproxy state
  90. pass in on $ext_if inet proto tcp from any to $http_servers port http flags S/SA synproxy state
  91. pass in on $ext_if inet proto tcp from any to 208.43.79.236 port https flags S/SA synproxy state
  92. pass in on $ext_if inet proto tcp from any to $mail_servers port $mail_ports flags S/SA synproxy state
  93.  
  94. # ping pong
  95. pass inet proto icmp all icmp-type $icmp_types keep state
  96.  
  97. # Outgoing ftp
  98. pass out on $ext_if inet proto tcp from any to any port ftp
  99. pass out on $ext_if inet proto tcp from any to any port >1023
  100.  
  101. ###### IPv6 rules #############
  102. # Allow outgoing services
  103. pass out on $ext_if inet6 proto tcp to any port $tcp_services
  104. pass out on $ext_if inet6 proto udp to any port $udp_services
  105.  
  106. # Trace route out
  107. pass out on $ext_if inet6 proto udp from any to any port 33433 >< 33626 keep state
  108.  
  109. # SL Admin in
  110. pass in on $ext_if inet6 from $adminrange6 to any
  111.  
  112. # Open ports out
  113. pass in on $ext_if inet6 proto udp from any to $dns_servers6 port domain
  114. pass in on $ext_if inet6 proto tcp from any to $dns_servers6 port domain keep state
  115. pass in on $ext_if inet6 proto tcp from any to $http_servers6 port http keep state
  116. pass in on $ext_if inet6 proto tcp from any to $mail_servers6 port $mail_ports keep state
  117.  
  118. # Ftp out
  119. pass out on $ext_if inet6 proto tcp from any to any port ftp
  120. pass out on $ext_if inet6 proto tcp from any to any port >1023
  121.  
  122. # Allow ping pong out
  123. pass out on $ext_if inet6 proto icmp6 all icmp6-type echoreq keep state
  124.  
  125. # ND solicitation out
  126. pass out on $ext_if inet6 proto icmp6 all icmp6-type {neighbradv, neighbrsol}
  127.  
  128. # ND advertisement in
  129. pass in on $ext_if inet6 proto icmp6 all icmp6-type {neighbradv, neighbrsol}
  130.  
  131. # Router advertisement out
  132. pass out on $ext_if inet6 proto icmp6 all icmp6-type routeradv
  133.  
  134. # Router solicitation in
  135. pass in on $ext_if inet6 proto icmp6 all icmp6-type routersol
  136.  
  137. # Allow Ping pong in
  138. 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 .



4000+ howtos and counting! If you enjoyed this article, join 45000+ others and get free email updates!

Click here to subscribe via email.

  • xcezzz

    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:

  • http://www.cyberciti.biz/ Vivek Gite

    Thanks for the heads up.

  • Roberto Greiner

    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?

  • http://www.cyberciti.biz/ Vivek Gite

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

  • Tekki

    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.

Previous Script:

Next Script: