#!/bin/sh
## Boot Script for firewall
# bil hays, last update 12/09
#
# thanks and acknowledgements for examples and explanations to 
# barijaona 
# (see http://homepage.mac.com/barijaona/macintosh/osxpb4.html)
# daniel co^te'
# (http://www3.sympatico.ca/dccote/firewall.html)
# Dru Lavigne
# (http://www.onlamp.com/pub/a/bsd/2001/04/25/FreeBSD_Basics.html)
# and brian hill 
# (see http://personalpages.tds.net/~brian_hill/brickhouse.html), 
# I recommend brian's brickhouse for purchase if you're going to 
# do a lot of firewall configuration, it's a great product
# 
# Also see http://www.macdevcenter.com/pub/a/mac/2002/12/27/macosx_firewall.html
# for additional information
#
# Finally, ipfw uses the /subnet mask denotation for declaring network ranges
# For example, 152.2.0.0/16 is the same as 152.2.0.0 with a 255.255.0.0, the 
# /16 means that 16 bits of the 32 possible bits are masked.
# Basically, the smaller the /index, the larger the range of addresses encompassed
# This system is somewhat confusing to some folks, but there's a good online 
# subnet calculator you can use to figure out what ranges are covered 
# http://ccna.exampointers.com/subnet.htm
#
# Non-stateful, can't get stateful working under tiger
# 
# This version is designed to work with Timelox versions of ssh
# and TheHand
#


. /etc/rc.common; # include the file with support for the service functions
 
########
# Set Variables
########

# Decide how to call ipfw (so you can run in test mode, etc, as you like)
IPFW="/sbin/ipfw -f";

# Set up a trusted hosts range
# These numbers represent the main CS networks at UNC
# You should use your own numbers here
TrustedHosts="152.2.128.0/20, 204.85.191.0/24, 10.2.128.0/20, 192.168.243.0/24";

# Set up a range of hosts you trust somewhat, but not so much
# In this example, we're looking at the main unc.edu subnets
NotSoTrustedHosts="152.2.0.0/16, 152.19.0.0/16, 152.23.0.0/16";

   
 StartService ()
   {
   echo "Starting Firewall"

   ########
   # Enable Logging
   ########
   #
   # Logged entries go into /var/log/system.log
   # But there's no point in logging unless you're going to check the 
   # entries. In this script, all deny are tagged with a log 
   
   if [ `/usr/sbin/sysctl -n net.inet.ip.fw.verbose` == 0 ] ; then
         /usr/sbin/sysctl -w net.inet.ip.fw.verbose=1
   fi
   
   # To disable logging, comment out the above lines and 
   # uncomment the following:
   #/usr/sbin/sysctl -w net.inet.ip.fw.verbose=0
   
   
   /usr/sbin/sysctl -w net.inet.ip.fw.dyn_max=8192 > /dev/null;
   /usr/sbin/sysctl -w net.inet.ip.fw.dyn_buckets=512 > /dev/null;
   /usr/sbin/sysctl -w net.inet.ip.fw.dyn_ack_lifetime=300 > /dev/null;
   /usr/sbin/sysctl -w net.inet.ip.fw.dyn_syn_lifetime=20 > /dev/null;
   /usr/sbin/sysctl -w net.inet.ip.fw.dyn_fin_lifetime=5 > /dev/null;
   /usr/sbin/sysctl -w net.inet.ip.fw.dyn_rst_lifetime=5> /dev/null;
   /usr/sbin/sysctl -w net.inet.ip.fw.dyn_short_lifetime=10 > /dev/null;
   
   ########
   # Flush
   ########
   
   # Purge existing rules, this blanks any existing rules
   ${IPFW} flush;
   
   ########
   # Localhost Settings
   ########
   
   # User verify reverse path to stop spoofed packets
   ${IPFW} add deny log ip from any to any not verrevpath in;
   
   # Allow everything on the localhost (127.0.0.1)
   # This way the machine can connect to itself via the localhost interface
   
   ${IPFW} add allow ip from me to me;
   
   # Now check for spoofing attacks via localhost and source routed
   # deny and log 
   ${IPFW} add deny log ip from 127.0.0.0/8 to any in;
   ${IPFW} add deny log ip from any to 127.0.0.0/8 in;
   ${IPFW} add deny log ip from any to any ipoptions ssrr,lsrr in;
      
   # Allow multicasts that are local
   ${IPFW} add allow ip from ${TrustedHosts} to 224.0.0.0/3 in;
   
   # Deny tcp packets sent to multicast 
   # (that makes some sense as multicasts are UDP)
   ${IPFW} add deny log tcp from any to 224.0.0.0/3 in;
   
   # Deny multicasts in 
   # For most users this is fine, but it will disable some media software
   # and some CIFS server functions
   #${IPFW} add deny log ip from 224.0.0.0/3 to any in;
   
   # This one blocks scanning for port 0 to see if machine is there 
   ${IPFW} add deny tcp from any to any 0 in;

   ########
   # Minimal Requirements
   ########
   
   # This version is stateful.
   # Also set the rule number here high, that way timelox generated 
   # firewall rules have room (by default, TheHand puts them in 
   # starting at 500)
   ${IPFW} add 25000 allow tcp from any to any established;
   
   # Allow all outbound
   ${IPFW} add allow ip from any to any out keep-state;
   
   # Trusted Hosts
   ${IPFW} add allow ip from ${TrustedHosts} to any in;
   
   ########
   # ICMP
   ########
   
   # Allow outbound icmp
   ${IPFW} add allow icmp from any to any out; 
   
   # If you want to allow anyone to ping you, or run a tracroute to you
   # uncomment this
   #${IPFW} add allow icmp from any to any in;
   
   # This lets this machine receive ping replies and 
   # the icmp errors that traceroute depends upon
   ${IPFW} add allow icmp from any to me icmptypes 0,3,11 in 
   
   # ICMP settings, this rules allow ICMP from any of the main unc network ranges.
   # Allow ICMP (ping and traceroute) from main unc hosts
   # For unc folks this is a good way to limit it.
   ${IPFW} add allow icmp from ${NotSoTrustedHosts} to any in;
   
   ########
   # Core Services
   ########
   
   # This section holds rules that govern services your machine must have 
   # working to use the internet.
   
   # DHCP Settings
   #
   # Allow DHCP from any server
   # This is needed because OS X doesn't deal with dhcp well
   # You can comment this out for desktops if the dhcp servers 
   # are part of the trusted hosts range. But you need to leave
   # this fu
   ${IPFW} add allow udp from any 67 to any 68 in;
   # If the above doesn't work, you might need to uncomment these
   #${IPFW} add allow udp from any 68 to 255.255.255.255 67 out 
   #${IPFW} add allow udp from any 67 to 255.255.255.255 68 in 
   
   # DNS Settings
   # Shouldn't be needed since we're checking state, but left in the file in;
   # case anyone has problems. If you boot, and can't get host or nslookup to 
   # resolve names, try uncommenting this.
   # This rule opens the firewall to any DNS server, so 
   # if you have a laptop that
   # moves from network to network, this may be the best rule to use.
   #${IPFW} add allow udp from any 53 to any in;
   # These rules allow DNS only from known servers. The first two lines are the dns servers for CS.
   # Users outside of CS should use the main unc servers, 152.2.21.1 and 152.2.253.100
   #${IPFW} add allow udp from 152.2.131.228 53 to any in;
   #${IPFW} add allow udp from 152.2.131.227 53 to any in;
   #${IPFW} add allow udp from 152.2.21.1 53 to any in;
   #${IPFW} add allow udp from 152.2.253.100 53 to any in;
   
   # NTP (Network Time)
   # Again, this shouldn't be needed since we're tracking state, but 
   # if you can't get a time server to work, uncomment this.
   # This rule allows this machine to use any NTP server
   # ${IPFW} add allow udp from any to any 123 in;
   # Or if you what the time server is, you can restrict it.
   #${IPFW} add allow udp from 152.2.21.1 to any 53 in;
   
   
   ########
   # Standard Services
   ########
   
   # Don't open these unless you want to run the service.
   # Also consider who would need access, for example, it's very unlikely 
   # you'll need to allow ssh from the entire internet. But most
   # folks want the web server wide open
   #
   # Most of these are set up such that it's the ${NotSoTrustedHosts} range
   # to which a service is open. Remember, ${TrustedHosts} 
   # are allow to connect to all ports
      
   # Allow web service from anywhere
   #${IPFW} add allow tcp from any to any 80  setup;
   #${IPFW} add allow tcp from any to any 443  setup;
   
   # SSH
   ${IPFW} add allow tcp from ${NotSoTrustedHosts} to any 22 in setup;
   #${IPFW} add allow tcp from any to any 22 in setup;
   
   # AppleShare File Sharing   
   ${IPFW} add allow tcp from ${NotSoTrustedHosts} to any 548 in setup;
   ${IPFW} add allow tcp from ${NotSoTrustedHosts} to any 427 in setup;
   
   # SMB/CIFS (windows networking)
   ${IPFW} add allow ip from ${NotSoTrustedHosts} to any 137-139 in ;
   
   # LDAP (in case you run an ldap server)
   #${IPFW} add  allow tcp from ${NotSoTrustedHosts} to any 389 setup
   #${IPFW} add  allow udp from ${NotSoTrustedHosts} to any 389 
      
   # Quicktime Streaming Service 
   # Allow QTSS from anywhere
   #${IPFW} add allow tcp from any to any 545 in  setup;
   # Allow RTSP from anywhere (part of QTSS)
   #${IPFW} add allow tcp from any to any 554  setup;
   # Allow UDP RTSP data from any where
   #${IPFW} add allow udp from any to any 6970-6999 in ;
      
   # iTunes 
   # Allow iTunes sharing from unc.edu addresses
   ${IPFW} add  allow ip from ${NotSoTrustedHosts} to any 3689;
   
   # Allow Rendevous 
   ${IPFW} add allow udp from ${NotSoTrustedHosts} to any 5353 in;
   ${IPFW} add allow udp from ${NotSoTrustedHosts} 5353 to me in;
   
   #######
   # Closing up
   #######
   
   # Block and log all ip packets not matched by a prior rule
   # so basically we're defaulting to deny rather than accept
   # In terms of udp reject is stealthier
   # since the way you scan for UDP ports is to look for ports that
   # don't send you an error on connect
   ${IPFW} add 65530 reject udp from any to any in; 
   ${IPFW} add 65531 deny tcp from any to any in;
   ${IPFW} add 65532 deny ip from any to any in;

} # end of StartService

StopService ()
   {
   ${IPFW} flush;
   ERROR_NUMBER=${?};
   if [[ ${ERROR_NUMBER} == "0" ]] 
   then 
      ConsoleMessage "Firewall has been stopped";
   else
      ConsoleMessage "There was a problem stopping the Firewall";
      exit 1;
   fi
   }

RestartService ()
   {
   StopService
   StartService
   }
   
RunService "${1:-start}";

