Investigating the Leopard Firewall
Updated: See http://securosis.com/2007/11/15/ipfw-rules/.
I just spent entirely too much time digging into the Leopard firewall, and here’s what I’ve found. The less geeky version will be out on TidBITS (probably tomorrow); this is just the summary of actual behavior:
1. “Allow all incoming connections” allows all- no surprises.
2. In all firewall modes, if you don’t select Stealth mode, mDNS (Bonjour, 5353/udp) is open on a port scan.
3. “Block all incoming connections” does seem to block actual connections, but any shared ports are detected as “open/filtered” on a port scan.
4. In “Block all” mode with stealth mode enabled, those shared services no longer show on a port scan.
5. Once you connect to another computer (outbound), Kerberos (88/tcp) is open and stays open no matter what you change on the firewall, including enabling stealth mode. This disappears on reboot. Other services may exhibit this behavior.
6. If you choose “Set access for specific services and applications”, any time you launch a program which starts a listner, the system automatically pokes a hole in the firewall to reach it listeners, but only those in the Sharing preferences pane appear in the list of services. This rather defeats the purpose of the firewall, since any listener is automatically accessible!
7. That mode is labeled differently in the help file than on the screen. In the help file, it’s “Limit incoming connections to specific services and applications”. Just a nit, but that seems clearer to me. At least they warn us if you dig into the help:
IMPORTANT: Some programs have access through the firewall although they don’t appear in the list. These might include system applications, services, and processes (for example, those running as “root”). They can also include digitally signed programs that are opened automatically by other programs. You might be able to block these programs’ access through the firewall by adding them to the list.
8. “Set access” mode seems incredibly inconsistent- some applications require you to authorize network connectivity on launch, and others don’t. For example, Skype and Firefox asked me for access, but Colloquy and Twitteriffic didn’t.
9. If you are asked to authorize an application and let it connect to the network, the binary is automatically signed by the system if it wasn’t already. If that application changes, it breaks and won’t launch. You get no warning or indication that this is why your program no longer works. I only stumbled across an oblique reference in the console.
10. If you open Sharing, but set “Block all”, your computer still appears on the network via mDNS, but no one can connect. Annoying.
I feel like I’m missing something, but I think that’s it. In short, block mode seems to block inbound connections but ports show as open/filtered. Stealth mode works, partially, but some ports still show on a port scan no matter what (like Kerberos). Bonjour is ALWAYS accessible, unless you’re in stealth mode. Application (”Set access…”) mode is a mess- code signing breaks applications, and the behavior is inconsistent. Any launched services are authorized and you can’t change the settings in the firewall GUI.
The good news is that ipfw is still enabled and you can manually configure it or use a GUI like WaterRoof.
Looking at how all this works I can see what Apple was thinking, even though they made many bad decisions. When block all is enabled it does seem to block most traffic, but instead of leaving ports open/filtered it should close them, not show them as filtered (I suppose not everyone will agree; feel free to say so in the comments). Stealth works, mostly. It’s hard to tell without playing more, but I think the Kerberos issue is related to outbound services. I suspect (thinking back to how Kerberos works) that it must open an outbound port to authenticate a session when you connect to a remote server. The firewall allows this since it was initiated locally (thus implicitly trusted), but the Kerberos implementation probably doesn’t tear down the port when it’s finished and the firewall still sees it as authorized for return traffic. Just a guess, but this could also explain some behavior noted elsewhere.
This should address the findings in the heise security article which inspired this research. They just seemed to miss enabling stealth mode and I’ve added a bunch more on how application control works.
I’m done with the firewall for now- it took far too long to run all the scans in all the different modes just to come up with a few bullet points!








Alex Nov 1
One of the major problems with application control is that it allows all apple-signed programs by default (I believe you might still block them selectively). So one might use (for example) preinstalled nc to easily bypass firewall.
As far as I understood this is why Heise had their remote-shell alway available — they used nc to accept incoming connctions.
John Nov 2
Alex’s comment is correct. nc is trusted by the firewall but you can overwrite this if you wish (at least this is my understanding). I however coded my own listener, and when you launch it the UI asks you to allow it, which will in turn add an entry for you. I also tested this with a torrent client and the same behaviour was observed (as it bound a listening port I was asked to accept the connection).
The heise article seems under researched. It is true nc will be allowed through the firewall, but this does not mean _every_ binary punches holes through the fw without user approval.
I’m not saying this firewall is great, just that the information presented thus far has been inaccurate. Thanks for the post, at least it’s factual :)
hrbrmstr Nov 2
Did you do any tests with “Set access” and Dashboard widgets?
I’m still holding off installing Leopard due to time-constraints (cross-country move), otherwise i’d test it myself.
Nick Nov 2
Good Article, best i’ve read so far. (minimal on the FUD)
The firewall is here;
$ sudo /usr/libexec/ApplicationFirewall/socketfilterfw -d
which gives us an idea on how it works by the name.
seems there is no doco for ’socketfilterfw’ yet.
usage: /usr/libexec/ApplicationFirewall/socketfilterfw [-c] [-w] [-d] [-l] [-T] [-U] [-B] [-L] [-a listen or accept] [-s file to sign] [-v file to verify] [-p pid to write]
firewallapp is used to control Application Firewall socket filter.
The command takes the following options that are evaluated in order,
and several options may be combined:
-h display this help and exit
-t app set trusted app, e.g. -t app1 app2 app3
-i dump socket filter internal data info
-d turn on debugging
-l do logging and run in daemon mode
-k kill daemon
-a ask when listen or accept, ask “accept” or ask “listen”
-s file sign file
-v file verify file
-c check file
$ strings /usr/libexec/ApplicationFirewall/socketfilterfw
gives a good idea whats around, including the plist/bundle locations.
Nick.
Alex Nov 3
I set up a svn server on my Leopard (it works through launchd).
- FW set on “specific app” mode. The connection is not authorized yet for svnserve.
- When I try to connect, no popup message to ask if svnserve should be added. The connection is not allowed.
- Adding svnserve to the list of applications with “allow incoming connections” doesn’t allow them.
I still get this in the log:
Macintosh Firewall[39]: Deny svnserve connecting from 192.168.0.254:50890 uid = 0 proto=6
Conclusion: no way for me to connect to my svn server, but to open all connections. :-(
Juergen Schmidt Nov 3
You write:
—
4. In “Block all” mode with stealth mode enabled, those shared services no longer show on a port scan.
…
This should address the findings in the heise security article which inspired this research. They just seemed to miss enabling stealth mode …
—
This is only partly right.
All this so called stealth mode does, is blocking all ICMP traffic. You can check that with “sudo ipfw list”.
That means UDP port scanning does not work any more.
It relies on “ICMP port unreachable” packets.
So you are right, that the open ports don’t show up any more.
But the important thing is, what you don’t say — namely:
the port is still open and you can talk to the services. To check if a port is open you should try to talk to the service in question. That is what we did: we talked to ntpd using ntpdate and to nmbd using nmblookup.
This works even with stealth mode enabled because it does not need any ICMP.
So “stealth mode” is basicly meaningless. It is like turning off the light in front of your open door. You can’t see it any more but you can still walk through…
bye, ju
John@OC Nov 4
I’ve done some of my own testing and analysis (http://gp.darkproductions.com/2007/11/leopard-firewall-testing-analysis-and.html), and I think the FUD has been turned up too much. The firewall is not perfect, and Apple has not communicated sufficiently about it. But Leopard is still secure.
As I said in my own post, I’d like to see Apple make some changes to make it eacier for hardcore techies to love Leopard’s firewall config.
I do think this new way of configuring the firewall will be much easier for everyday users, and it might offer Apple a chance to provide some new functionality that ipfw might make difficult.
rmogull Nov 5
@nick- thanks for the details, that’s very cool.
@juergen- I think we’re getting different results. The services I started during testing were definitely not reachable with block all and stealth mode enabled. I didn’t just do a port scan, I made sure to attempt to connect to those services.
windexh8er Nov 5
“When block all is enabled it does seem to block most traffic, but instead of leaving ports open/filtered it should close them, not show them as filtered (I suppose not everyone will agree; feel free to say so in the comments).”
I disagree. :) Open/filtered (because we all know you’re using NMap, and probably a SYN scan…) just means that you’re getting a RST from the firewall. The firewall is telling you that you’re not allowed so NMap tells you that someone is allowed, just not you. This is good and bad, but it in no way really breaks any of the functionality of the mode of operation.
rmogull Nov 5
Of course I used NMap :)
But I ran multiple scans in multiple modes, including TCP connect. I also attempted direct connections to standard services, specifically file sharing and SSH.
I personally prefer closing/blocking over RST, but fully acknowledge that I’m a paranoid freak and it probably doesn’t matter much.
windexh8er Nov 6
So how about everyone constantly complaining about the crap-tastic new implementation of the Leopard firewall we baseline a good IPFW config? Here’s for starters:
00100 allow ip from any to any via lo*
00110 deny ip from 127.0.0.0/8 to any in
00120 deny ip from any to 127.0.0.0/8 in
00500 check-state
00501 deny log ip from any to any frag
00502 deny log tcp from any to any established in
01500 allow udp from 10.100.0.0/24 5353 to any dst-port 1024-65535 in
01700 allow icmp from any to any icmptypes 3
01701 allow icmp from any to any icmptypes 4
01702 allow icmp from any to any icmptypes 8 out
01703 allow icmp from any to any icmptypes 0 in
01704 allow icmp from any to any icmptypes 11 in
65500 allow tcp from me to any keep-state
65501 allow udp from me to any keep-state
65534 deny log ip from any to any
65535 allow ip from any to any
…this firewall configuration will do a number of things. First of all line 500 is key to checking the state table before we block any poser incoming connections. Line 502 blocks connections coming in that pretend they were established, but really weren’t. Line 501 is pretty self explanatory, blocking fragmented packets in. I know nothing I’m using is fragmenting, so YMMV.
Line 1500 is an example. Since Bonjour services cannot be tracked correctly in the state table we need to allow things back to 5353/UDP on the box (that is if you want to use it). But my example shows that I’m only allowing those services on my local network. Anytime I head to Panera or Starbucks I don’t have to worry about 5353 being “open”, unless of course those networks are using 10.100.0.0/24. Most of the time they’re not. But if I noticed that I would disable that rule for the time being.
Next we get to ICMP. What do these let us do? ICMP type 3 let’s path MTU in and out (i.e. PMTU — Path MTU Discovery). Many people don’t realize the advantages of PMTU, because they think ICMP is inherently evil. Try doing some performance engineering and PMTU becomes a great resource. Anyway, type 3 is not evil. Next, type 8 is source quench. It will tell my upstream gateway to “slow down” if need be. Again, not evil for the most part. The pros outweigh the cons anyway. Types 8 and 0 rely on each other. 8 lets me ping out and 0 lets that back in. BUT — people will not be able to ping me. Sneaky sneaky… The last one, type 11, will let me run traceroute.
So now 65500 and 65501 basically let my computer open any port out. In the essence of keeping this ruleset “set it and forget it” style this can be done better. Like specifying everything you need to let out and blocking everything else. But I can’t delve into that for “every” user, so this makes it a little more convenient.
65534 is our deny. Notice all the denies I setup have logging statements. I always have a terminal running tailing my firewall log. Then again, for those who don’t know how to respond maybe just keep that on the down low — you might get sick if you saw all of the traffic hitting your box depending on the network you’re connected to. :)
Rich — you should start a thread for whittling down the best default ruleset for IPFW on Tiger/Leopard and let’s do a writeup on how to implement it…
windexh8er Nov 6
Just a side note. The above configuration will not accept RST packets from non established connections. What does this mean for you? Remember Comcast in the news lately? Well if you have a few more lines in there specific to your BitTorrent traffic (to allow it in) if Comcast sees you start seeding and they send RST packets to you they’ll be rejected. Nice side effect to help keep your net neutrality (and/or sanity).
Anonymous Nov 6
@rmogull: If you tried to connect to the services, did you try to connect to ntpd? This was the one I claimed to be open and reachable, remember? It is simple. Use
sudo ntpdate [IP]
on an external machine.
Or try this one. Set your firewall to “block all incoming” and stealth.
Then start a little demo server like:
sudo nc -l 1414
and
connect from an external machine, using
nc [IP] 1414
The result:
Everything you enter on one side, will be echoed to the other. So TCP port 1414 is open, despite “Block all incoming connections” and stealth mode. This firewall simply does not do what it says.
bye, ju
John Nov 6
I did the tests that Jurgen outlined above, and had the same results. Despite having the settings set to “Deny All” and “stealth mode” it didn’t block other services that I’d started.
Some more details here: http://macsecure.com/?p=9
rmogull Nov 7
Yep- confirmed myself last night, but I’m checking to confirm some other things. Standard sharing is blocked, but some root services seem to bypass.
ConfusedLady Dec 4
So how about us ‘non’ techies? I miss Norton Firewall because I somehow felt protected - I don’t see anywhere in Leopard where it says Block All Incoming Connections - mine are
Allow All Incoming
Allow Only Essential Services
Set Access for Specific Services and Applications
So are you saying Stealth Mode is not worth using? And what do the logs mean anyway? that someone was trying to access the computer through any open ports? or didn’t get in?
I looked at the logs but can’t really define what they mean: as an example, here’s a couple - does this mean an attempt was made thru the Firewall? (I removed the name of the macbook pro so my real name wouldn’t show up there)
Dec 3 21:18:55 my-macbook-pro-15 Firewall[48]: krb5kdc is listening from 0.0.0.0:88 uid = 0 proto=6
Dec 3 21:21:14 my-macbook-pro-15 Firewall[47]: krb5kdc is listening from :::88 uid = 0 proto=6
Dec 3 21:21:14 my-macbook-pro-15 Firewall[47]: krb5kdc is listening from 0.0.0.0:88 uid = 0 proto=6
Dec 3 21:22:35 my-macbook-pro-15 Firewall[47]: Stealth Mode connection attempt to UDP 10.0.1.200:49187 from 10.0.1.1:53
Dec 3 21:40:24 my-macbook-pro-15 Firewall[47]: Stealth Mode connection attempt to TCP 10.0.1.200:49205 from 17.250.248.161:5354
Dec 3 21:55:44 my-macbook-pro-15 Firewall[47]: Stealth Mode connection attempt to UDP 10.0.1.200:49309 from 10.0.1.1:53
Dec 3 21:56:24 my-macbook-pro-15 Firewall[47]: Stealth Mode connection attempt to UDP 10.0.1.200:49318 from 10.0.1.1:53
Where can I get plain English information on what to use for the firewall settings and what will actually work? I don’t think WaterRoof is for folks like me with no technical understanding. I don’t know what kind of rules to set in it. I didn’t understand the automated ones with the questions ether. It was supposed to set it up automatically with asking a couple of questions but the answers don’t apply to me.
Is there actually firewall software that will do the trick to keep the mac secure? Thanks for your help. Perhaps I’m in the wrong area with these questions, but any help would be appreciated.
P