Features:
The pf.conf file:
A test load of the rules with
- Default policy is to block and log all traffic that is not specifically allowed. This also affects the outgoing connections initiated by the server, for example DNS lookups. For performance reasons the default policy rule is the last rule. Be careful not to accidentally delete it.
- If for some reason something is being blocked, you can run tcpdump(1) on the pflog(4) device to see what is going on:
Code:[cmd]# tcpdump -eni pflog0[/cmd] [noparse]tcpdump: WARNING: pflog0: no IPv4 address assigned tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 65535 bytes 13:49:39.025997 rule 17..16777216/0(match): block in on re0: 31.3.237.245.56167 > w.x.y.z.445: Flags [S], seq 14 74166783, win 512, length 0 13:54:13.874479 rule 17..16777216/0(match): block in on re0: 109.203.120.115.54579 > w.x.y.z.445: Flags [S], seq 424673279, win 512, length 0 13:55:31.353017 rule 17..16777216/0(match): block in on re0: 31.3.237.245.51122 > w.x.y.z.445: Flags [S], seq 51 8389759, win 512, length 0[/noparse]
- To review the log file:
# tcpdump -tttt -nr /var/log/pflog | less
To enable logging you need this in /etc/rc.conf:
Code:pflog_enable="YES"
- The rules only specify IPv4 traffic through the inet keyword.
- Not for security through obscurity, but only to prevent clogging the /var/log/auth.log with unsuccessful ssh connection attempts another port than the default port 22 is being used.
- The rules are logically ordered by direction (in/out) and protocol (TCP, UDP and ICMP).
- The quick keyword is used to defeat pf's last matching rule wins strategy.
- Because pf keeps state by default, the keep state option is not needed anymore.
The pf.conf file:
Code:
# ----------------------- simple server pf.conf ----------------------
# For FreeBSD 9.1
# j65nko 2011, 2012, 2013
#
# If you adapt this ruleset for a resolving caching name server please
# make sure you don't allow the whole world to use your name server
# Creating an open resolving name server can allow the bad guys to use your nameserver
# in an DNS amplification attack
ext_if="re0"
icmp_types="echoreq"
# Custom port for ssh
SSH_CUSTOM = xxxx
scrub in on $ext_if all fragment reassemble
set skip on lo0
#set skip on lo1
antispoof for $ext_if
# --- EXTERNAL INTERFACE
# --- INCOMING -------------------------------------------------------------------
# --- TCP
pass in quick on $ext_if inet proto tcp from any to $ext_if port http
pass in quick on $ext_if inet proto tcp from any to $ext_if port https
pass in quick on $ext_if inet proto tcp from any to $ext_if port $SSH_CUSTOM
# --- for authoritative DNS server
#pass in quick on $ext_if inet proto udp from any to $ext_if port domain
# --- UDP
# --- for authoritative DNS server
#pass in quick on $ext_if inet proto udp from any to $ext_if port domain
# --- ICMP
pass in quick on $ext_if inet proto icmp from any to $ext_if icmp-type $icmp_types
# --- EXTERNAL INTERFACE
# --- OUTGOING --------------------------------------------------------------------
anchor TMP
# --- TCP
pass out quick log on $ext_if inet proto tcp from $ext_if to any port smtp
pass out quick on $ext_if inet proto tcp from $ext_if to any port domain
pass out quick on $ext_if inet proto tcp from $ext_if to any port http
pass out quick on $ext_if inet proto tcp from $ext_if to any port https
pass out quick on $ext_if inet proto tcp from $ext_if to any port whois
pass out quick on $ext_if inet proto tcp from $ext_if to any port $SSH_CUSTOM
# --- UDP
pass out quick on $ext_if inet proto udp from $ext_if to any port domain
pass out quick on $ext_if inet proto udp from $ext_if to any port ntp
# --- ICMP
pass out quick on $ext_if inet proto icmp from $ext_if to any
# ------------------------------------------------------
# --- DEFAULT POLICY
# ------------------------------------------------------
block log all
# ----- end of pf.conf
A test load of the rules with
# pfctl -vvnf /etc/pf.conf
:
Code:
ext_if = "re0"
icmp_types = "echoreq"
SSH_CUSTOM = "xxxx"
set skip on { lo0 }
@0 scrub in on re0 all fragment reassemble
@0 block drop in on ! re0 inet from w.x.y.z/27 to any
@1 block drop in inet from w.x.y.z to any
@2 block drop in on re0 inet6 from fe80::21d:92ff:fe63:4195 to any
@3 pass in quick on re0 inet proto tcp from any to w.x.y.z port = http flags S/SA keep state
@4 pass in quick on re0 inet proto tcp from any to w.x.y.z port = https flags S/SA keep state
@5 pass in quick on re0 inet proto tcp from any to w.x.y.z port = xxxx flags S/SA keep state
@6 pass in quick on re0 inet proto icmp from any to w.x.y.z icmp-type echoreq keep state
@7 anchor "TMP" all
@8 pass out log quick on re0 inet proto tcp from w.x.y.z to any port = smtp flags S/SA keep state
@9 pass out quick on re0 inet proto tcp from w.x.y.z to any port = domain flags S/SA keep state
@10 pass out quick on re0 inet proto tcp from w.x.y.z to any port = http flags S/SA keep state
@11 pass out quick on re0 inet proto tcp from w.x.y.z to any port = https flags S/SA keep state
@12 pass out quick on re0 inet proto tcp from w.x.y.z to any port = nicname flags S/SA keep state
@13 pass out quick on re0 inet proto tcp from w.x.y.z to any port = xxxx flags S/SA keep state
@14 pass out quick on re0 inet proto udp from w.x.y.z to any port = domain keep state
@15 pass out quick on re0 inet proto udp from w.x.y.z to any port = ntp keep state
@16 pass out quick on re0 inet proto icmp from w.x.y.z to any keep state
@17 block drop log all
Last edited: