A Simple Firewall Setup for Mac Yosemite
2014-11-07 15:00
I run a bunch of web sites on a Mac Mini Colo. For years it was running Snow Leopard and I used the built in firewall service in the Mac OS X Server package (which also included smtp, chat, MySQL and a bunch of other stuff.) It had a nice little management UI that made it relatively hard to mess up and lock yourself out of your server.
When Yosemite came out, and I was 4 releases behind the current Mac OS, I figured it was time to bite the bullet and upgrade. As I expected, pretty much everything about my server that made it a server broke.
Kaboom.
No more MySQL, many CGI scripts dead, including Movable Type. Breakage galore.
It was no big deal except that the carefully crafted firewall was completely gone. It was the equivalent of one of those dreams where you show up to class and realize you're not wearing any clothes.
I found a nice article about using the built-in packet filter (pf). It made the process pretty clear, and I manage to craft a set of rules, only locking myself out of my server once. You should read it.
The key thing to remember if you are securing a remote host is to be careful with the "block everything" rules. You can get locked out. If you do lock yourself out, you'll need to tell the hands-on tech support person how to disable pf so you can start over. That command is "pfctl -d"
This sample ruleset is very simple: block almost everything coming in, and only allow specific things like ssh and web. If you want to be super careful, it's probably a good idea to only allow ssh from known good places where you will be. This can be a pain, however, because most people don't have static IP addresses at home.
# sample firewall rules
# to enable:
# pfctl -e -f com.billo.pf.rules
# to disable:
# pfctl -d
set block-policy drop
set fingerprints "/etc/pf.os"
set ruleset-optimization basic
set skip on lo0
# Normalization
# Scrub incoming packets
scrub in all no-df
# to add a host to the bad list
# pfctl -t badhosts -Tadd <IP ADDRESS HERE>
# to see the current bad hosts
# pfctl -t badhosts -T show
table <badhosts> persist
table <goodhosts> persist
# Block by default
block in log
# Block to/from illegal destinations or sources
block in log quick from no-route to any
# Allow critical system traffic
pass in quick inet proto udp from any port 67 to any port 68
# Allow ICMP from Mac Mini LAN
#pass in log proto icmp from 66.209.67.0/24
# Allow all lan traffic in (if you are on a LAN that is yours)
#pass in from 10.0.0.0/24 to any
# Allow all VPN traffic in (if there is a VPN LAN)
#pass in from 10.0.1.0/24 to any
# allow good places everything, if you want
#pass in from {<goodhosts>} to any
# Allow outgoing traffic
pass out proto tcp from any to any keep state
pass out proto udp from any to any keep state
# allow stuff you want
pass in proto tcp from any to any port 80
pass in proto tcp from any to any port 443
pass in proto tcp from any to any port 22
# block the jerks
block on en0 from {<badhosts>} to any
It's also a very good idea to test these rules on a Mac that is in your hands on your own network. So you can test what is blocked and not. (Of course you'll need another computer at home to test.)