How does one lock down OS X Server using the PF firewall?

You should:

  1. understand pf basics - here is many guides on the Internet, you can safely read any Open/Free BSD guide. You must understand a few basic things:

    • with PF, last rule wins (opposite of IPFW's "first rule wins")
    • logging is in the pflog device if the 'tcpdump' format
    • check the pfctl command using man pfctl
    • also check man pf.conf
    • you can create many simple text files that contains IP addresses (called tables) and using them in the filtering rules - see the example below.
  2. AFTER this you can use two GUI frontends

    • IceFloor (instead of the WaterRoof)
    • Firewall builder (cross platform)

PF is not too hard if you have some knowledge about how firewalling works in general.

Fragment of pf.conf for table based filtering:

interface = "en0"
allowed_ports = "{ 80, 443 }"
table <badips> persist
table <noroute> const { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }
block in on $interface from { <noroute>, <badips> } to any
pass in on $interface inet proto tcp from <badips> to $interface port $allowed_ports

The above example contains:

  • some basic definitions, like your interface name and some ports
  • definition for two tables, noroute for nonroutable addresses (RFC 1918) and the second badips that can contain your Geo IP based IP addresses
  • filtering rule - blocking anything from these tables
  • allowing ports 80 and 443 from badips (last rule wins)

Doesn't serveradmin in 10.8 allow you to load address groups from command line? Like, for example:

$ sudo serveradmin settings < eu.txt

eu.txt:

ipfilter:ipAddressGroupsWithRules:_array_id:eu = create
ipfilter:ipAddressGroupsWithRules:_array_id:eu:allowAll = no
ipfilter:ipAddressGroupsWithRules:_array_id:eu:readOnly = no
ipfilter:ipAddressGroupsWithRules:_array_id:eu:name = "eu - Austria, Belgium, Croatia, Cyprus, Czech Republic, Denmark, European Union, Finland, France, Germany, Gibraltar, Greece, Holy See, Ireland, Italy, Luxembourg, Monaco, Netherlands, Norway, Poland, Slovakia, Slovenia, Spain, Sweden, Switzerland, United Kingdom"
ipfilter:ipAddressGroupsWithRules:_array_id:eu:addresses:_array_index:0 = "192.168.100.0/16"
ipfilter:ipAddressGroupsWithRules:_array_id:eu:addresses:_array_index:1 = "192.168.200.0/24"

Edit:

When serveradmin fails, use /Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin.