/ Server / Openbsd Pf Rules For Webservers
Published:2014-03-03T13:23:24Z Edited:2016-08-10T13:23:24Z
OpenBSD pf make a magnificent job to simplifing packet filtering for writing network packet filters ( aka firewalls ), its quite powerful and it's syntax looks very natural. In this article We'll learn how to secure a web server with openbsd pf, if you look for firewall for linux then check iptables iptables for securing webservers.
Whats Openbsd PF?
Openbsd pf is network packets filtering pseudo device /dev/pf , which enables programs to allow/disallow packets ( internet connections for simplicity ) incoming/outgoing in simple and dynamic way.
How pf differs from iptables?
pf differs from iptables as follows:
- pf runs on BSDs only ( openbsd, freebsd, dragonflybsd ..etc) , while iptables runs on linux only ( debian, centos, gentoo ..etc)
- pf has all rules of ipv4/ipv6 on the same config file, iptables need a different command to manage ipv6 named ip6tables.
- pf has realtime logging facility on pseudo interface pflog, as I'm aware iptables has logging but not in realtime ( it logs to syslog by default ).
- pf's Syntax is quite simple, powerful and very human-friendly, iptables's syntax is more complicated, less powerful and not human-friendly.
- pf can prioritise packets and net traffic, iptables cannot ( need different command, on linux tc )
- pf last rule matches will win, iptables first rule matches will win.
Before We begin
packet filtering can become a complex topic and if you're working on a remote system you may be blocked from accessing your system, therefore our approach for configuring our packet filter (pf) for KISS sake will be careful and easy.
pf rules
We'll work on /etc/pf.conf
- First lest set some macros:
- For interfaces, lo0 is our internal loopback interface, em0 is the external interface
in_if = "lo0" ex_if = "em0"
- For allowed ports for: ssh (22), mail server (25), web server (80 443):
ports = "{ 22 25 80 443 }"
- For allowed protocols : tcp, udp icmp:
protocols = "{ tcp udp icmp }"
- For interfaces, lo0 is our internal loopback interface, em0 is the external interface
- Set configuration settings:
- Let the default blocking method to drop unpermitted connection without any notice
set block-policy drop
- Let Skip packet filtering on internal interface since all connections are from/to localhost
set skip on $in_if
- Sanitise all traffic
match in all scrub (no-df random-id)
- Block spoofed ip addreses
antispoof quick for $in_if
- Let the default blocking method to drop unpermitted connection without any notice
- Pass/Block rules started here, remember that pf apply last matching rule So we need to define the fallback rule, then allowed rules:
- Fallback rule will apply unless "pass" rule match later
block all
- Let traffic of allowed protocols and ports we defined above to pass
pass in on $ex_if inet proto $protocols from any to any port $ports keep state pass in on $ex_if inet6 proto $protocols from any to any port $ports keep state
- Allow all outgoing traffic from allowed protocols only
pass out on $ex_if inet proto $protocols from any to any pass out on $ex_if inet6 proto $protocols from any to any
- Malformed connections need to be dropped:
block in from no-route to any block in from urpf-failed to any
- Fallback rule will apply unless "pass" rule match later
- The final content of /etc/pf.conf may look like the following:
# macros # lo0 internal # em0 external in_if = "lo0" ex_if = "em0" # ssh (22), mail server (25), web server (80 443) ports = "{ 22 25 80 443 }" # allowed protocols : tcp, udp icmp protocols = "{ tcp udp icmp }" # config set block-policy drop set skip on $in_if match in all scrub (no-df random-id) antispoof quick for $in_if # fallback block all # allow incoming traffic pass in on $ex_if inet proto $protocols from any to any port $ports keep state pass in on $ex_if inet6 proto $protocols from any to any port $ports keep state # allow outgoing traffic pass out on $ex_if inet proto $protocols from any to any pass out on $ex_if inet6 proto $protocols from any to any\n # finally drop some known-bad traffic block in from no-route to any block in from urpf-failed to any
- Check /etc/pf.conf for any error and reload it
pfctl -n -f /etc/pf.conf && pfctl -f /etc/pf.conf
Thats it
I hope I gave you some taste of pf syntax, there's always room for enhancments, but as I said earlier better test your filtering rules maybe on some staging server before you apply'em on production server and get fired :)
if you run manage linux webservers on some of your computer check iptables for linux
Next
Debian Router - DHCP server setup Previous
Jorgee the kidbot Tags