OpenBSD PF Firewall Script – /etc/pf.conf File
in Categories Firewall last updated May 10, 2009
Following script will protect collocated FreeBSD / OpenBSD / NetBSD server running PF firewall. My box has 2 interface one for VPN and other for public interface. I only run http, dns and ssh on public port. Read pf, rc.conf and pf.conf man page for details. Tested on FreeBSD and OpenBSD.
Sample /etc/pf.conf
- !/bin/bash
- A Linux Shell Script with common rules for IPTABLES Firewall.
- By default this script only open port 80, 22, 53 (input)
- All outgoing traffic is allowed (default - output)
- -------------------------------------------------------------------------
- Copyright (c) 2004 nixCraft project <http://cyberciti.biz/fb/>
- This script is licensed under GNU GPL version 2.0 or above
- -------------------------------------------------------------------------
- This script is part of nixCraft shell script collection (NSSC)
- Visit http://bash.cyberciti.biz/ for more information.
- -------------------------------------------------------------------------
IPT="/sbin/iptables"
SPAMLIST="blockedip"
SPAMDROPMSG="BLOCKED IP DROP"
echo "Starting IPv4 Wall..."
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
modprobe ip_conntrack
[ -f /root/scripts/blocked.ips.txt ] && BADIPS=$(egrep -v -E "^#|^$" /root/scripts/blocked.ips.txt)
PUB_IF="eth0"
- unlimited
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
- DROP all incomming traffic
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
if [ -f /root/scripts/blocked.ips.txt ];
then
- create a new iptables list
$IPT -N $SPAMLIST
for ipblock in $BADIPS
do
$IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
$IPT -A $SPAMLIST -s $ipblock -j DROP
done
$IPT -I INPUT -j $SPAMLIST
$IPT -I OUTPUT -j $SPAMLIST
$IPT -I FORWARD -j $SPAMLIST
fi
- Block sync
$IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Drop Sync"
$IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW -j DROP
- Block Fragments
$IPT -A INPUT -i ${PUB_IF} -f -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fragments Packets"
$IPT -A INPUT -i ${PUB_IF} -f -j DROP
- Block bad stuff
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL ALL -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "NULL Packets"
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -j DROP # NULL packets
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "XMAS Packets"
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP #XMAS
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fin Packets Scan"
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -j DROP # FIN packet scans
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
- Allow full outgoing connection but no incomming stuff
$IPT -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -o eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
- Allow ssh
$IPT -A INPUT -p tcp --destination-port 22 -j ACCEPT
- allow incomming ICMP ping pong stuff
$IPT -A INPUT -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p icmp --icmp-type 0 -m state --state ESTABLISHED,RELATED -j ACCEPT
- Allow port 53 tcp/udp (DNS Server)
$IPT -A INPUT -p udp --dport 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p udp --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p tcp --destination-port 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p tcp --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT
- Open port 80
$IPT -A INPUT -p tcp --destination-port 80 -j ACCEPT
- Add your rules below ######
- END your rules ############
- Do not log smb/windows sharing packets - too much logging
$IPT -A INPUT -p tcp -i eth0 --dport 137:139 -j REJECT
$IPT -A INPUT -p udp -i eth0 --dport 137:139 -j REJECT
- log everything else and drop
$IPT -A INPUT -j LOG
$IPT -A FORWARD -j LOG
$IPT -A INPUT -j DROP
exit 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
- !/bin/bash
- A Linux Shell Script with common rules for IPTABLES Firewall.
- By default this script only open port 80, 22, 53 (input)
- All outgoing traffic is allowed (default - output)
- -------------------------------------------------------------------------
- Copyright (c) 2004 nixCraft project <http://cyberciti.biz/fb/>
- This script is licensed under GNU GPL version 2.0 or above
- -------------------------------------------------------------------------
- This script is part of nixCraft shell script collection (NSSC)
- Visit http://bash.cyberciti.biz/ for more information.
- -------------------------------------------------------------------------
IPT="/sbin/iptables"
SPAMLIST="blockedip"
SPAMDROPMSG="BLOCKED IP DROP"
echo "Starting IPv4 Wall..."
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
modprobe ip_conntrack
[ -f /root/scripts/blocked.ips.txt ] && BADIPS=$(egrep -v -E "^#|^$" /root/scripts/blocked.ips.txt)
PUB_IF="eth0"
- unlimited
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
- DROP all incomming traffic
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
if [ -f /root/scripts/blocked.ips.txt ];
then
- create a new iptables list
$IPT -N $SPAMLIST
for ipblock in $BADIPS
do
$IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
$IPT -A $SPAMLIST -s $ipblock -j DROP
done
$IPT -I INPUT -j $SPAMLIST
$IPT -I OUTPUT -j $SPAMLIST
$IPT -I FORWARD -j $SPAMLIST
fi
- Block sync
$IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Drop Sync"
$IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW -j DROP
- Block Fragments
$IPT -A INPUT -i ${PUB_IF} -f -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fragments Packets"
$IPT -A INPUT -i ${PUB_IF} -f -j DROP
- Block bad stuff
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL ALL -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "NULL Packets"
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -j DROP # NULL packets
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "XMAS Packets"
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP #XMAS
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fin Packets Scan"
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -j DROP # FIN packet scans
$IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
- Allow full outgoing connection but no incomming stuff
$IPT -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -o eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
- Allow ssh
$IPT -A INPUT -p tcp --destination-port 22 -j ACCEPT
- allow incomming ICMP ping pong stuff
$IPT -A INPUT -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p icmp --icmp-type 0 -m state --state ESTABLISHED,RELATED -j ACCEPT
- Allow port 53 tcp/udp (DNS Server)
$IPT -A INPUT -p udp --dport 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p udp --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p tcp --destination-port 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p tcp --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT
- Open port 80
$IPT -A INPUT -p tcp --destination-port 80 -j ACCEPT
- Add your rules below ######
- END your rules ############
- Do not log smb/windows sharing packets - too much logging
$IPT -A INPUT -p tcp -i eth0 --dport 137:139 -j REJECT
$IPT -A INPUT -p udp -i eth0 --dport 137:139 -j REJECT
- log everything else and drop
$IPT -A INPUT -j LOG
$IPT -A FORWARD -j LOG
$IPT -A INPUT -j DROP
exit 0|}
- First declare a couple of variables ####
- Outgoing tcp / udp port ####
- 43 - whois, 22 - ssh ###
tcp_services = "{ ssh, smtp, domain, www, https, 22, ntp, 43,ftp, ftp-data}"
udp_services = "{ domain, ntp }"
- allow ping / pong ####
icmp_types = "{ echoreq, unreach }"
- define tables. add all subnets and ips to block
table <blockedip> persist file "/etc/pf.block.ip.conf"
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 }"
- admin server ranges ###
adminrange = "112.220.11.0/23"
- connected to internet
ext_if = "em1"
- connected to vpn / lan
int_if = "em0"
- ftp proxy
- proxy="127.0.0.1"
- proxyport="8021"
- Normalization
- scrub provides a measure of protection against certain kinds of attacks based on incorrect handling of packet fragments
scrub in all
- NAT and RDR start
- nat-anchor "ftp-proxy/*"
- rdr-anchor "ftp-proxy/*"
- redirect ftp traffic
- rdr pass proto tcp from any to any port ftp -> $proxy port $proxyport
- Drop incoming everything
block in all
block return
- keep stats of outgoing connections
pass out keep state
- We need to have an anchor for ftp-proxy
- anchor "ftp-proxy/*"
- unlimited traffic for loopback and lan / vpn
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 all ips
- pfctl -t blockedip -T show
block drop in log (all) quick on $ext_if from <blockedip> to any
block drop out log (all) quick on $ext_if from any to <blockedip>
- allow outgoing
pass out on $ext_if proto tcp to any port $tcp_services
pass out on $ext_if proto udp to any port $udp_services
- Allow trace route
pass out on $ext_if inet proto udp from any to any port 33433 >< 33626 keep state
- Allow admin to get into box
pass in on $int_if from $adminrange to any
- Allow incoming ssh, http, bind traffic
- pass in on $ext_if proto tcp from any to any port 25
pass in on $ext_if proto tcp from any to any port ssh flags S/SA synproxy state
pass in on $ext_if proto udp from any to any port domain
pass in on $ext_if proto tcp from any to any port domain flags S/SA synproxy state
pass in on $ext_if proto tcp from any to any port http flags S/SA synproxy modulate state
pass inet proto icmp all icmp-type $icmp_types keep state
- add your rule below ##
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
- First declare a couple of variables ####
- Outgoing tcp / udp port ####
- 43 - whois, 22 - ssh ###
tcp_services = "{ ssh, smtp, domain, www, https, 22, ntp, 43,ftp, ftp-data}"
udp_services = "{ domain, ntp }"
- allow ping / pong ####
icmp_types = "{ echoreq, unreach }"
- define tables. add all subnets and ips to block
table <blockedip> persist file "/etc/pf.block.ip.conf"
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 }"
- admin server ranges ###
adminrange = "112.220.11.0/23"
- connected to internet
ext_if = "em1"
- connected to vpn / lan
int_if = "em0"
- ftp proxy
- proxy="127.0.0.1"
- proxyport="8021"
- Normalization
- scrub provides a measure of protection against certain kinds of attacks based on incorrect handling of packet fragments
scrub in all
- NAT and RDR start
- nat-anchor "ftp-proxy/*"
- rdr-anchor "ftp-proxy/*"
- redirect ftp traffic
- rdr pass proto tcp from any to any port ftp -> $proxy port $proxyport
- Drop incoming everything
block in all
block return
- keep stats of outgoing connections
pass out keep state
- We need to have an anchor for ftp-proxy
- anchor "ftp-proxy/*"
- unlimited traffic for loopback and lan / vpn
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 all ips
- pfctl -t blockedip -T show
block drop in log (all) quick on $ext_if from <blockedip> to any
block drop out log (all) quick on $ext_if from any to <blockedip>
- allow outgoing
pass out on $ext_if proto tcp to any port $tcp_services
pass out on $ext_if proto udp to any port $udp_services
- Allow trace route
pass out on $ext_if inet proto udp from any to any port 33433 >< 33626 keep state
- Allow admin to get into box
pass in on $int_if from $adminrange to any
- Allow incoming ssh, http, bind traffic
- pass in on $ext_if proto tcp from any to any port 25
pass in on $ext_if proto tcp from any to any port ssh flags S/SA synproxy state
pass in on $ext_if proto udp from any to any port domain
pass in on $ext_if proto tcp from any to any port domain flags S/SA synproxy state
pass in on $ext_if proto tcp from any to any port http flags S/SA synproxy modulate state
pass inet proto icmp all icmp-type $icmp_types keep state
- add your rule below ##
|