OS X features a software firewall for typical users but also includes ipfw, a fully featured firewall capable of facilitating all the traffic routing needs of clients and servers alike.
I had a situation today where a server needed to route traffic from the outside world to a web server accessible only within the internal network.
As a result we had to add a rule to divert traffic from the localhost on port 80 to an IP address on port 8080. The rule required was as follows…
ipfw add 201 fwd 127.0.0.1,8080 tcp from any to 10.1.2.3 80 in
In order to get the Mac to add this rule to ipfw automatically when it started up I could have added a shell script with lots of complex logic and ipfw rules to lock down everything other than DHCP broadcasts but as we only needed to add one rule to our ipfw configuration I opted for something a little simpler.
The following file was created at /Library/LaunchDaemons/com.theonlyjames.ipfw.plist…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.theonlyjames.ipfw</string> <key>ProgramArguments</key> <array> <string>/sbin/ipfw</string> <string>add 201 fwd 127.0.0.1,8080 tcp from any to 10.1.2.3 80 in</string> </array> <key>RunAtLoad</key> <true/> <key>UserName</key> <string>root</string> </dict> </plist> |
The permissions on the file have to be right for this to work. The following command fixes the permissions for us…
# chown root /Library/LaunchDaemons # chmod 755 /Library/LaunchDaemons/com.theonlyjames.ipfw.plist
A couple of points worth mentioning here. The ProgramArguments include the full path to ipfw, which is typically /sbin/ipfw. Then the rules are added as arguments after the ipfw command.
We specify the UserName key in order to execute ipfw as root. We also need to specify RunAtLoad as true. This means we only run this rule when we boot and not repeatedly afterwards.
Whenever the Mac boots launchd will add our one rule. For multiple rules we need to use a shell script rather than calling ipfw directly.







