horns
GreasyDaemon.com - Your Guide to BSD Unix home - news - directory
FreeBSD OpenBSD NetBSD MacOS X Daemon News BSDvault

MacOS X: Firewall at Startup
08/28/2001
by Brennan Stehling

MacOS X keeps getting better and better the more I learn about it. Most recently I have figured out how edit the startup process. I am also customizing the settings for the ipfw firewall which is built into this new OS. By combining the startup process with some firewalling I was able to build my very own firewall system from scratch in minutes.

Traditional BSD: Background

First off, I had to figure out how to step into the startup process. In other Unix systems you typically use the rc.d method of controlling startup scripts. There are similar systems in the FreeBSD, NetBSD and OpenBSD world and they sometimes change to add more features. In fact, NetBSD gave an overhaul to their rc.d system earlier this year.

What is a Firewall?

A Firewall acts much like it sounds. Incoming and outgoing network traffic is filtered according to a set of rules which can deny or allow specific connections.

That system was mostly unchanged from it's 4.4BSD beginnings and now offers some features for flexibility, like setting the order in which the scripts run.

Flexibility can be important if you need MySQL to start up before Apache so the database is ready when Apache needs it. With FreeBSD I have startup scripts in /usr/local/etc/rc.d which run the startup process for my local customizations beyond what the typical BSD system does automatically, like configuring network interfaces.

In my rc.d directory I have a startup script called mysql-server.sh among many other scripts which are given the argument start during the booting process. Also in that directory I have my apache startup script which I always want to run last, so I call it xyz-apache.sh. The scripts are run in alphabetical order so this ensures that is run last. It is not the most sophisticated system but I am Unix administrator, not a ballet dancer, so I deal.

MacOS X: Today

Now with MacOS X they have taken this rc.d system to the next level and it is quite interesting. The startup folder is /Library/StartupItems and includes more than just a script. There is also an control file called StartupParameters.plist. The control file apparently allows you to set the ordering preference and add messages for when the script is starting and stopping. The control file for my Firewall script is displayed here:

{
  Description     = "Custom Firewall Rules";
  Provides        = ("Firewall");
  OrderPreference = "Last";
  Messages =
  {
    start = "Adding Firewall Rules";
    stop  = "Firewall Going Away";
  };
}

When preparing to add this Firewall script to my Startup Items I created a folder called Firewall in the StartupItems folder and added the control file and a script also called Firewall. Now I am set for this to work with a little flexibility. To do so I edit /etc/hostconfig which defines several Yes or No variables. These variables include the following. You may be interested to know the MacOS X web server and SSH server is Apache and OpenSSH. Below you see I have them turned off.

TIMESYNC=-YES-
QTSSERVER=-NO-
SSHSERVER=-NO-
WEBSERVER=-NO-

To keep my custom firewall system up to snuff with the existing Startup Items I also added my own variable.

FIREWALL=-YES-

Now I just have to set my shell script to account for this setting and I am ready to reboot.


      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
#!/bin/sh

##    
# Add Firewall Rules
##    

. /etc/rc.common
     
if [ "${FIREWALL:=-NO-}" = "-YES-" ]; then 
    ConsoleMessage "Adding Firewall Rules"
     
   ipdeny=`cat /Documents/Firewall/Firewall.deny | sort | uniq` 
   ipallow=`cat /Documents/Firewall/Firewall.allow | sort | uniq` 
     
   # allow first
   counter=2000
   for i in ${ipallow}; do
    ipfw add $counter allow all from $i to any
    counter=`expr $counter + 1`
   done    
     
   # deny second
   counter=`expr $counter + 1000` 
   for i in ${ipdeny}; do
    ipfw add $counter deny all from $i to any
    counter=`expr $counter + 1`
   done    
     
fi

Most of this script is similar to your standard rc.d startup script. On line 7 it starts by reading in the settings from the rc.common script which extracts settings from /etc/hostconfig file. This allows for the check on line 9 which only allows the firewall rules to be added if the FIREWALL variable is set to YES. If it is, the script reads in the deny and allow lists on lines 12 and 13 and proceeds to lines 18 and 24 where the script loops through each IP address in your list and either adds a allow or deny rule to your firewall. I increment the counter each time I get a new IP so each rule has it's own numerical ID. I also add the allow rules first so that I can always be sure I will have access to the servers I need to reach, like my mail server. After these changes are in place you can simply add any IP's you want to your allow and deny lists and reboot for them to take affect.

What does this gets you? What would I want to firewall? That depends on what you want to do. I created this strictly to block some banner ads that I was finding to be overly annoying. If you are a little creative, you can do all kinds of things with your allow and deny lists. If you know the ipfw firewall you will know you can also put any into your deny list instead of an IP and only the specific hosts specified in your allow list. This combination will allow those specific hosts in while it denies everything else. But for my purposes, it is great way to stop annoying banner ads.


Brennan Stehling is a consultant with Keane Inc and manages GreasyDaemon.com. He is also a long time BSD administrator and Mac user.


Comments? Contact us at macosx@greasydaemon.com.


GreasyDaemon.com


FreeBSD
Powered by
UdmSearch
Daemon News