Login  |  Register  |  Contact

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.
  1. “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.
  2. 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.
  3. 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!

—Rich

No Related Posts
Previous entry: Leopard Firewall + Code Signing Breaks Skype (And Other Applications) | | Next entry: Heading to San Francisco

Comments:

If you like to leave comments, and aren't a spammer, register for the site and email us at info@securosis.com and we'll turn off moderation for your account.

By Alex  on  11/01  at  06:25 AM

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.

By Matasano Chargen » Excellent Explanation of  on  11/01  at  07:15 AM

[...] of Rich Mogull’s new writeup on what the 10.5 firewall does seems to refute Heise’s article: without [...]

By John  on  11/01  at  12:04 PM

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 :)

By Liquidmatrix Security Digest » Security Brie  on  11/01  at  03:12 PM

[...] Investigating the Leopard Firewall [...]

By Investigating the Leopard firewall « Celciuz  on  11/01  at  09:06 PM

[...] [Rich Mogull] has been flipping the switches on Leopard’s new firewall and scanning it to see what’s actually going on. There is some good and some bad. The new application signing is a mixed bag. It breaks Skype and a [...]

By hrbrmstr  on  11/01  at  09:26 PM

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.

By mcwresearch.com » Upgrade to Leopard  on  11/02  at  12:17 AM

[...] post-upgrade. UPDATE: Leopard’s implementation of a firewall is depressing to say the least. here is a very good run-down on its [...]

By Nick  on  11/02  at  04:57 AM

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.

By Leopard rocks? at philippe::niquille  on  11/02  at  06:30 PM

[...] Leopard (and some Vista comparison). What is all the heise fuss about the Leopard firewall (see 1, 2)? Currently I am not to happy about the left-aligned dock, meaning I don’t understand when [...]

By Alex  on  11/02  at  10:35 PM

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. :-(

By Juergen Schmidt  on  11/03  at  01:58 AM

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

By Marigold.cz » Zběsilá jízda na Leopardu 2  on  11/03  at  03:15 PM

[...] materiály a odkazy k firewallu Leoparda třeba zde. Nebo [...]

By John@OC  on  11/03  at  10:38 PM

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.

By Mac OS X 10.5 Leopard Firewall Failures - Starcraf  on  11/03  at  10:52 PM

[...] elsewhere already… ( http://www.pcworld.com/article/id,139231-c,firewalls/article.html http://securosis.com/2007/11/01/investigating-the-leopard-firewall [...]

By The Leopard Experience « The lost outpost  on  11/04  at  07:20 PM

[...] wasn’t impressed to discover that the firewall is switched off by default, either. Soon fixed that (once I did realise, anyway!). Oh, and I’ve switched off the 3D [...]

By rmogull  on  11/04  at  07:53 PM

@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.

By TidBITS Article on Leopard Up | securosis.com  on  11/05  at  03:06 AM

[...] week it’s more on the Leopard firewall. It’s less technical than my summary here, but goes into a little more [...]

By windexh8er  on  11/05  at  03:49 AM

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.

By rmogull  on  11/05  at  03:52 AM

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.

By Apple schlampt bei der Sicherheit  on  11/05  at  02:06 PM

[...] Firewall von außen auf Systemdienste zurückgreifen können, was auch Rich Mogull beschreibt. Allerdings beurteilt er Leopards Firewall ein wenig positiver: Wenn das Prorgramm in einem [...]

By windexh8er  on  11/05  at  07:33 PM

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…

By windexh8er  on  11/05  at  07:38 PM

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).

By  on  11/05  at  09:02 PM

@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

By MacSecure.com » Blog Archive » Leopard  on  11/06  at  09:00 AM

[...] firewall configuration options. And as I started to write it up, I found that I’ve been beaten to the punch.  I did quite a few of the same tests that Rich Mogull did, but based on comments posted by Jurgen [...]

By John  on  11/06  at  09:07 AM

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

Name:

Email:

Remember my personal information

Notify me of follow-up comments?