Assume I have ip blocks for China, Russia, North Korea etc. How would I configure pf to allow those IP addresses to only access ports 80 and 443, and be denied access to other ports?

I have an instance of OS X Server 2.1.1 (aka Mountain Lion) running in a data center with a static ip address exposed to the internet. So there is no hardware firewalls etc to protect the server against malicious users.

Looking through the logs, I noticed numerous failed attempts from countries like China, Russia to services necessary for me to remotely manage the server. Further, I noticed that ports were unnecessarily open to the internet.

Since OS X 10.6 Snow Leopard Server, I used the Server Admin to manage the firewall (ipfw). This has been removed in OS X Server 2.1.1 (Mountain Lion). And to make matters more interesting, the Apple documentation states that ipfw is deprecated and to use pf instead. Having read the man page, I'm a tad lost how to configure pf.

Googling "pf firewall tutorial" reveals tutorials aimed for NetBSD, FreeBSD and OpenBSD. Further filtering on "OS X" in that query reveals tutorials for "OS X", but it seems the authors assume some prior knowledge.


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

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 {,, }
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


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 = ""
ipfilter:ipAddressGroupsWithRules:_array_id:eu:addresses:_array_index:1 = ""


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

  • What do the last two lines exactly mean?
    – Lenar Hoyt
    Mar 2 '13 at 22:47
  • The last 2 lines are the IP addresses (network ranges in this case) that the group consists of.
    – Pro Backup
    Mar 3 '13 at 0:02
  • But these look like local IP addresses, not like addresses from europe?
    – Lenar Hoyt
    Mar 4 '13 at 18:15
  • 1
    The IP addresses are just an anonymised example, replace them with your own ranges. For ranges, you might want to look them up at countryipblocks.net/ip_aggregation_beta.php
    – Pro Backup
    Mar 4 '13 at 19:25

Try WaterRoof, it's IPFW with GUI: http://www.hanynet.com/waterroof/

  • IPFW is deprecated, starting with Mountain Lion.
    – bloudraak
    Oct 28 '12 at 8:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .