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 #################

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

Leave a Reply