Stateful OS X firewall

In the interest of security in depth, you should be running the firewall on your OS X system. I know, I know there are so few vulnerabilities on the Mac. That doesn’t mean that nasty stuff still doesn’t happen.

If you are feeling that the standard firewall settings aren’t quite good enough, you are in luck, OS X comes with a serious firewall, IPFW.

To go with the fancy new trick mentioned in the previous post, I thought you might like to have a basic IPFW firewall to get yourself going. As always I recommend checking man ipfw for more information.

This firewall basically allows outbound traffic and restricts inbound. It does some basic blocking of things that just shouldn’t be out there.

It automatically determines what the active interface is and sets up the firewall on that. Save this to /etc/rc.firewall to use with setup from this post.


#!/bin/sh

############## Start of IPFW rules file ##############

# Set rules command prefix
IPFW="ipfw -q add"

# Determine the external interface
if ( ifconfig en1 | grep -q "inet " ); then

  echo "EXT_INT is en1"
  EXT_INT="en1"

elif ( ifconfig en0 | grep -q "inet " ); then

  echo "EXT_INT is en0"
  EXT_INT="en0"
 
else

  echo "could not find any active interfaces"
  exit
 
fi

# Flush out the list before we begin.
ipfw -q -f flush


######################################################
# No restrictions on Loopback Interface
######################################################
$IPFW 00100 allow all from any to any via lo0

######################################################
# Allow the packet through if it has previous been 
# added to the the "dynamic" rules table by a allow 
# keep-state statement.
######################################################
$IPFW 00110 check-state

######################################################
# Outbound Allowed Rules 01000
######################################################

# Statefully allow all outbound traffic
$IPFW 01000 allow tcp \
  from any to any out \
  via $EXT_INT setup keep-state

$IPFW 01010 allow udp \
  from any to any out \
  via $EXT_INT keep-state

$IPFW 01030 allow icmp \
  from any to any out \
  via $EXT_INT keep-state

######################################################
# Outbound Denied Rules 02000
######################################################
# Deny miscellaneous multicast
$IPFW 02000 deny log all \
  from any to 239.255.255.253 427 out \
  via $EXT_INT

# Global outbound
$IPFW 02997 deny log tcp \
  from any to any out \
  via $EXT_INT
  
$IPFW 02998 deny log udp \
  from any to any out \
  via $EXT_INT
  
$IPFW 02999 deny log all \
  from any to any out \
  via $EXT_INT


######################################################
# Inbound Allow Rules 03000
######################################################

# Allow in useful ICMP types
$IPFW 03000 allow icmp \
  from any to any \
  icmptypes 3,4 \
  in via $EXT_INT

$IPFW 03010 allow icmp \
  from any to any \
  icmptypes 0,11 \
  in via $EXT_INT

# Allow in ssh
$IPFW 03020 allow \
  log tcp \
  from any to me 22 in \
  via $EXT_INT \
  setup limit src-addr 2

# iChat/AOL/Rendezvous
$IPFW 03030 allow tcp \
  from any to any 5190,5298 \
  in via $EXT_INT \
  setup keep-state
  
$IPFW 03040 allow udp \
  from any to any 5060,5190,5297,5298,5678 \
  in via $EXT_INT \
  keep-state
  
$IPFW 03050 allow udp \
  from any to any 16384-16403 \
  in via $EXT_INT \
  keep-state

#iTunes
$IPFW 03060 allow tcp \
  from any to any 3689 \
  in via $EXT_INT \
  setup keep-state

# Rendezvous multicast
$IPFW 03070 allow udp \
  from any 5353 to 224.0.0.251 5353 \
  in via $EXT_INT

# Allow in DHCP
$IPFW 03080 allow log udp \
  from any 67 to any 68 \
  in via $EXT_INT

######################################################
# Inbound Denied Rules 04000
######################################################

# Deny all inbound traffic from non-routable 
# reserved address spaces. Comment out any private 
# addresses you use.
$IPFW 04000 deny log all \
  from me to any \
  in via $EXT_INT     # Spoofing my address
  
# $IPFW 04010 deny all \
  from 192.168.0.0/16 to any \
  in via $EXT_INT  #RFC 1918 private IP
  
# $IPFW 04020 deny log all \
  from 172.16.0.0/12 to any \
  in via $EXT_INT     #RFC 1918 private IP
  
# $IPFW 04030 deny all \
  from 10.0.0.0/8 to any \
  in via $EXT_INT          #RFC 1918 private IP
  
# $IPFW 04040 deny log all \
  from 0.0.0.0/8 to any \
  in via $EXT_INT            #Broadcast
  
$IPFW 04050 deny log all \
  from 127.0.0.0/8 to any \
  in via $EXT_INT        #loopback
  
$IPFW 04060 deny log all \
  from 169.254.0.0/16 to any \
  in via $EXT_INT   #DHCP auto-config
  
$IPFW 04070 deny log all \
  from 192.0.2.0/24 to any \
  in via $EXT_INT       #reserved for docs
  
$IPFW 04080 deny log all \
  from 204.152.64.0/23 to any \
  in via $EXT_INT  #Sun cluster interconnect
  
$IPFW 04090 deny all \
  from any to 224.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04091 deny all \
  from any to 225.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04092 deny all \
  from any to 226.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04093 deny all \
  from any to 227.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04094 deny all \
  from any to 228.0.0.0/8 
  in via $EXT_INT         #Multicast
  
$IPFW 04095 deny all \
  from any to 229.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04096 deny all \
  from any to 230.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04097 deny all \
  from any to 231.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04098 deny all \
  from any to 232.0.0.0/8 \
  in via $EXT_INT         #Multicast

$IPFW 04099 deny all \
  from any to 233.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04100 deny all \
  from any to 234.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04101 deny all \
  from any to 235.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04102 deny all \
  from any to 236.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04103 deny all \
  from any to 237.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04104 deny all \
  from any to 238.0.0.0/8 \
  in via $EXT_INT         #Multicast
  
$IPFW 04105 deny all \
  from any to 239.0.0.0/8 \
  in via $EXT_INT         #Multicast
  

# ICMP
$IPFW 04120 deny log icmp \
  from any to any \
  in via $EXT_INT

# Deny all Netbios service. 
# 137=name, 138=datagram, 139=session
$IPFW 04130 deny all \
  from any to any 137 \
  in via $EXT_INT
  
$IPFW 04135 deny all \
  from any 137 to any \
  in via $EXT_INT
  
$IPFW 04140 deny all \
  from any to any 138 \
  in via $EXT_INT
  
$IPFW 04154 deny all \
  from any 138 to any \
  in via $EXT_INT
  
$IPFW 04150 deny all \
  from any to any 139 \
  in via $EXT_INT
  
$IPFW 04155 deny all \
  from any 139 to any \
  in via $EXT_INT
  
$IPFW 04160 deny all \
  from any to any 445 \
  in via $EXT_INT
  
$IPFW 04165 deny all \
  from any 445 to any \
  in via $EXT_INT

# Block MS/Windows hosts2 name server requests 81
$IPFW 04170 deny tcp \
  from any to any 81 \
  in via $EXT_INT

# Deny ident
$IPFW 04180 reset tcp \
  from any to any 113 \
  in via $EXT_INT

# Deny miscellaneous multicast
$IPFW 04190 deny all \
  from any to 239.255.255.253 427 \
  in via $EXT_INT

# Deny ACK packets that did not match the dynamic 
# rule table
# $IPFW 00332 deny log tcp \
  from any to any established \
  in via $EXT_INT

# Deny any fragmented packets
$IPFW 04200 deny log all \
  from any to any frag \
  in via $EXT_INT

# Deny EIGRP and other router traffic
$IPFW 04210 deny udp \
  from any to 224.0.0.2 1985 \
  in via $EXT_INT
  
$IPFW 04220 deny ip \
  from any to 224.0.0.10 \
  in via $EXT_INT


# Deny UDP (for logging purposes)
$IPFW 04230 deny log udp \
  from any to any \
  in via $EXT_INT

# Deny FP packets and not log them
$IPFW 04240 deny tcp \
  from any to any \
  in via $EXT_INT tcpflags fin,psh
  
$IPFW 04241 deny tcp \
  from any to any \
  in via $EXT_INT tcpflags fin

# Reject & Log all incoming connections from the outside
$IPFW 04999 deny log all \
  from any to any \
  in via $EXT_INT


######################################################
# Global Denied Rules 10000
######################################################

# Everything else is denied by default
# deny and log all packets that fell through to see what they are
$IPFW 10010 deny log all \
  from any to any


############# End of IPFW rules file #################

10 Responses to Stateful OS X firewall

  1. Dan Kumper says:

    But this ipfw set-up cannot avoid the message “Found your Private IP of xxx.xxx.xxx.xxx!” over at http://www.auditmypc.com/software_audit.asp (for my EXT_INT=”en0″)

    Any ipfw workaround available? (… or do we have to use Tor, Netshade, etc.)

    Anyway, thanks for sharing this!

  2. scrutin says:

    This page uses Java to determine your local IP and is more of a test of your browser’s security than your firewall. Unfortunately, Java and Javascript open you up to vulnerabilities that are very difficult for a firewall or Intrusion Detection/Prevention system to block. Basically you are letting a site download code to your computer and execute it which is inherently insecure. This can open you up to cross site scripting attacks as well.

    If you don’t have a need for it you should turn off Java under preferences –> Security in Safari or Preferences –> Web Features in Firefox. If you can live with it you can turn off Javascript as well, but unfortunately, many sites might not work when you do this.

    I doubt whether TOR or Netshade would prevent this from working since it is executing in your browser and passing your IP back to the server via a GET request.

    GET /audit.asp?a=xxx.xxx.xxx.xxx HTTP/1.1

    There are also some sites out there that claim to get your address via JavaScript, displaying your local address
    on the page and suggesting that you download their security application. In general your address is not leaving your network and the applications they are pitching are more spyware than security, but that is more of a problem for Windows users.

  3. Tony says:

    Hello,

    I’m using your ipfw rules. I notice that when I launch iChat successfuly from Snow Leopard, the ipfw.log shows – ichat is fully functioning ..I’m wondering how its still working if I got these Denied entries? Which rule in your ruleset let ichat out/in before these rules below – Thanks!

    4240 Deny TCP 64.12.202.117:5190 172.16.172.249:50522 in via en0
    2997 Deny TCP 172.16.172.249:50523 205.188.7.23:5190 out via en0
    4999 Deny TCP 205.188.7.23:5190 172.16.172.249:50523 in via en0

    • scrutin says:

      The rules that allow iChat are:

      # iChat/AOL/Rendezvous
      $IPFW 03030 allow tcp \
      from any to any 5190,5298 \
      in via $EXT_INT \
      setup keep-state

      $IPFW 03040 allow udp \
      from any to any 5060,5190,5297,5298,5678 \
      in via $EXT_INT \
      keep-state

      $IPFW 03050 allow udp \
      from any to any 16384-16403 \
      in via $EXT_INT \
      keep-state

      4240 Deny TCP 64.12.202.117:5190 172.16.172.249:50522 in via en0
      This is the firewall denying FIN packets to prevent a possible flood

      2997 Deny TCP 172.16.172.249:50523 205.188.7.23:5190 out via en0
      Not sure why this is hitting, I would guess this is a stale connection that the firewall is not seeing as established.

      4999 Deny TCP 205.188.7.23:5190 172.16.172.249:50523 in via en0
      Not sure on this one either, may be stale connections again. Are you seeing a lot of these?

  4. Tony says:

    once I launched iChat. I just got 1 – 4240 rule

    Firewall[60]: 4240 Deny TCP 205.188.251.44:5190 172.16.172.249:51261 in via en0

    Looks better now. Thanks! One thing I never understood was, is my Mac mail going through this firewall ruleset because I never see any entries in the log?

    Is this the rules that allows it out and back in? Thats after I edit it to make it log the entries.

    # Statefully allow all outbound traffic
    ${IPF} add 01000 allow tcp \
    from any to any out \
    via $EXT_INT setup keep-state

    ${IPF} add 01010 allow udp \
    from any to any out \
    via $EXT_INT keep-state

  5. Tony says:

    btw, the rule 4999 I was getting a lot was for Mac mail and not ichat earlier ..

    Now, when I do launch my mac mail using imap setup … i get 4-5 denies like the one below but stop, I guess they are also preventing flooding – any ideas?

    4999 Deny TCP 74.125.113.109:587 172.16.172.249:52628 in via en0

    • scrutin says:

      TCP 587 is an alternative SMTP port. Mac Mail is most likely trying to both 25 and 587 to see which port the server is responding on.

  6. Tony says:

    Hey Scrutin,

    I just installed both dansguardian and squid on my local machine for the kids. Doesn’t appear to broke anything with your ipfw rules. Browsing still works even though I have squid configured to listen on localhost 127.0.0.1:3128

    Do you know if dansguardian and squid are actually going in/out your ruleset? I see the ipfw rule loopback to always allow. Do I need to add additional rules to allow them to go through ipfw securely?

    Thanks!

Leave a comment