As with all the major upgrades to OS X, Apple has made much of the many enhancements and new features available in Tiger. Under the banner of improved stability and security was an upgrade to the firewall software,
ipfw. More than bug fixes and polish, this update introduced a whole new firewall called
ipfw2. It works just the like the old firewall, but has some new features that allow greater flexibility and more control. In this article I'll show you some of the new features and how you can use them to make managing your firewall easier.
Against our better judgement, there are times when we just want to turn the firewall off for a moment and then turn it back on. The old firewall provided no means to do this other than to shut down the firewall and then bring it back up again. A firewall with a lot of rules did not load very quickly. With
ipfw2 we can disable the firewall without shutting it down and turn it back on in an instant. First, to turn it off:
sudo ipfw disable firewall
All the rules are still loaded, but now all traffic is passing through on the default rule 65535 that lets everything in. If you are sharing your internet connection over another port, then this too will have stopped working as Internet Sharing adds a rule to the firewall so that it can divert traffic between your AirPort and your Ethernet port. With the firewall disabled, you will no longer be sharing your internet connection. To turn it back on:
sudo ipfw enable firewall
Everything is now back the way it was.
When the firewall is disabled, there is no easily visible indication. If you run
sudo ipfw show it will list the all the rules despite none of them being active. To check whether the firewall is up or down you need to examine a
sysctl variable to see what value it returns:
sysctl net.inet.ip.fw.enablenet.inet.ip.fw.enable: 0
A value of 0 indicates that the firewall is disabled, and a 1 that it's enabled.
When creating your own rules, you'll probably be thinking of your various rules as being members of a set ("these are the ports I must open for the services I am running" or "these are the IP addresses of the hackers that I wish to block"). To implement this with the old firewall, the best you could do was group the rules by their numbers; there was little you could do to manipulate them beyond that.
ipfw2 introduces the concept of sets and allows sets of rules to be manipulated as a group. So, assuming all your services were in set 4, you could turn off access by simply issuing the command:
sudo ipfw set disable 4
If we look at our rules we can see that they are disabled. The
-S option makes
ipfw display the set numbers. By default
ipfw does not display set numbers, and without
-S it would not list the disabled rules at all.
sudo ipfw -S show... # DISABLED 50000 set 4 allow tcp from any to any dst-port 22 in # DISABLED 50001 set 4 allow tcp from any to any dst-port 80 in # DISABLED 50002 set 4 allow tcp from any to any dst-port 443 in via en1 # DISABLED 50003 set 4 allow tcp from any to any dst-port 123 in via en1 ...
To turn them back on again you just need to issue the following:
sudo ipfw set enable 4
This means you can stop any new connections accessing your services without having to stop services or break any established connections. If you suspect that the addresses you are blocking are causing some problems, you can turn that set off for a quick test to track the problem down without having to take the whole firewall down. However there is a little bug with the enable command, nothing serious, just an inconvenience. I'll come to it later.
You can organize your rules into 32 sets for easier management. These are numbered 0 to 31 with set 31 being special. Rules in set 31 are not removed when you flush the firewall. By default, rule 65535 (the rule that is always there) is a member of set 31. With sets you can quickly change the configuration of your firewall without having to stop and start. You could select an empty set (21 for argument), disable set 21, add the new rules to the set and then enable it. This way you can bring all the new rules on line at once without having to impact the rest of the configuration. To see which sets are enabled and which are not, just issue this command:
sudo ipfw set showdisable 12 enable 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
This shows that set 12 is disabled and all the rest are enabled. Set 31 is not listed. Set 31 is always enabled. Just ignore it. These are not the droids you are looking for.
Best to get this over with. There were bugs in the old firewall and there are bugs in the new firewall. These are new bugs in the new features, and I'm sure that someone is beavering away to get them fixed (some people get all the fun jobs). They affect how we can use the firewall but, at least with the ones that I have found, they do not compromise the firewall.
First, the bug when enabling a set. The problem is that the first command needs to be a disable. So I actually issued the following command:
sudo ipfw set disable 12 enable 4
On my computer, set 12 has no rules in it, so I can disable it all I want. That gets around the enable bug. Ugly and annoying yes, but we can live with it.
If you read the man page for the firewall (
man ipfw), you'll notice that you should be able to delete sets of rules and move rules in and out of different sets. First let's try and delete a set of rules:
sudo ipfw delete set 4ipfw: rule 4: setsockopt(IP_FW_DEL): Invalid argument
Obviously someone has yet to get round to coding that up, so you can't delete sets. Just disable the set and then delete each rule individually. Inconvenient but not fatal.
However this move is one to avoid:
sudo ipfw set move rule 60000 to 13
This should move rule 60000 from its existing set into set 13. No such luck, rule 60000 just disappears. In effect this is a strange syntax for a delete. Avoid this one, as you will lose rules from your firewall if you use it. Now that you know about these bugs, they should not bite you.
In the old firewall, you just had to enable
net.inet.ip.fw.verbose and all the rules flagged with a log statement would start writing their output to
/var/log/system.log. A quick change in
/etc/syslog.conf, and our log lines would be written out to
/var/log/ipfw.log. Well, that has all changed,
ipfw2 now has its own logger process and the
syslog.conf file supplied with Tiger is set up correctly to log to
If you are using the firewall as supplied by Tiger, then the Firewall pane under Sharing in System Preferences now has an Advanced button that will allow you to turn on logging, plus a couple of other small security features. However if we have written our own rules, then the Firewall pane will be unavailable and we will have to turn this on ourselves:
sudo sysctl -w net.inet.ip.fw.verbose=2
To disable logging we just need to set
net.inet.ip.fw.verbose to 0. There is no real harm in leaving
ipfwloggerd running although you would not really want to have more than one running (which is what will happen if you run the first line repeatedly).
ipfw2 improves upon the previous version and introduces some new features, some of which actually work. Sets may not seem a big deal, but they are very useful for managing your firewall. If you go through the man page, you will see many convenient extensions to the rule syntax that make setting up a firewall less verbose. These can make a great deal of difference to how understandable your rules are and therefore how likely you are to notice any mistakes you might have made.
Editor's note: This article is current as of Mac OS X 10.4.2. On the day that I was editing it, Apple released Mac OS X 10.4.3. From what I can tell, there aren't any changes to the Firewall in this update. But if you notice something, please note it in the Talkbacks below to assist other readers. You also might want to read Peter's Exploring the Mac OS X Firewall. It covers the Panther version of the software, but still has some good general info.
Peter Hickman is currently working as a programmer for Semantico, which specializes in online reference works and Access Control Systems. When not programming or reading about programming he can be found sleeping.
Return to the Mac DevCenter
Copyright © 2009 O'Reilly Media, Inc.