How will you spend your lunch hour?

How about building a packet filtering firewall?

OK, there are more interesting things to do. Like, maybe, eating lunch. *smile* But we'll find time for that too. Grab a grinder, and I'll show you how it's done. In fact, you'll create one on your own machine.

To say this is simple is an understatement. Mason's going to do the dirty work for you. While you're making all kinds of tcp/ip connections, Mason will create firewall rules that match those kinds of traffic. When we've finished learning, we'll tell the system to block everything that Mason didn't already learn. This creates a very strict firewall that exactly matches what this machine will need to do in the future.

Trust me, you can do this.

Let's look at the setup. You'll need a Linux computer. It needs bash and a bunch of standard system tools (cat, grep, ifconfig, awk, etc) - ones that would be included in a distribution. If you have RedHat, Suse, Caldera, Mandrake, or Debian, the tools were included on your CD. In fact, if any are missing, Mason will warn you before it starts so you can install them.

This machine can be of any architecture. It can have any number of network interfaces of any type.

A traditional firewall is usually constructed on a machine that's already a router, but Mason is equally usable on a router or just a normal workstation or server. You might want to try Mason out on your own workstation first to get a feel for it.

Let's install Mason. First, log in as root. If you're using an rpm-based distribution, type:

rpm -Uvh ftp://mason.stearns.org/pub/mason/mason-0.13.0.92-0.noarch.rpm

If this method has problems or your system is not rpm-based, this ftp site has .tar.gz and .deb files as well.

Mason depends on the /etc/services file to know what ports are server ports. I already know that this system uses ssh and squid and that /etc/services doesn't have those ports listed. I'll add the following lines to that file:

ssh             22/tcp                          # SSH Remote Login Protocol
squid           3128/tcp
squid-icp       3130/udp

Mason makes much more readable output if /etc/services has entries for all the IP addresses on this machine and the network addresses for all locally connected networks. I'm also going to add my ISP's nameservers to /etc/hosts. Obviously, the following is just an example.

172.16.0.0      OFFICE-LAN		#I use all caps to indicate a network
172.16.0.1      mybox-lan
12.13.14.1      cisco-eth
12.13.14.2      mybox-outside
12.13.16.10     myisp-dns1
12.13.16.11     myisp-dns2

There's only one more configuration change to make. The following lines should be added to /etc/masonrc. I suggest uncommenting the lines that are already in that file to reduce the chance of typos.

NEWRULEPOLICY="accept"
DEFAULTPOLICY="accept"
FLUSHEDPOLICY="accept"

At this point, we're ready to start building. While Mason has a large number of things that can be tweaked, you can come back to them when you need to. Type:

mason-gui-text

At the main menu, type the letters BL to begin learning.

Now what? Well, first, grab a bite of that grinder. Don't worry, I'll wait.

Mason's in learning mode. It's waiting for packets to start flowing through the system. If there is active network traffic on this machine already, Mason will immediately start learning from it. What you'll see is a combination of ipfwadm or ipchains rules and what looks like Morse code, which is Mason's way of telling you it's working on new packets.

You'll need a little patience now; if your CPU is too slow to process the initial onslaught of packets, it may take a few seconds to a few minutes to catch up. You'll know Mason is ready to continue when it hasn't printed any Morse code for 5 seconds or so. Have a few more bites while you're waiting.

Open up another terminal and try this:

ping mason.stearns.org

You may see some DNS lookup lines, then at least one echo request line and echo reply line.

Here's the easiest part of the process. All you need to do now is, well, all the things you'd normally do on this machine! Do you read mail from here? Pull down your mail! Do you read web pages with Lynx or Netscape? Pull down a fresh page! Do you make SQL queries or LDAP lookups? Make a few. Again, if your processor is slow, wait for Mason's screen to settle down before continuing on to the next thing.

Don't forget things like ping, traceroute, whois, etc. If this machine acts as a web server, retrieve a web page. If it's a mailserver, send a mail message to it or retrieve your mail from it. Likewise, make use of the other services running on it.

If this is a router, you'll need to go to some of the machines that use this as a router. Read web pages, read mail, make an ssh connection, connect to irc, etc. Have the people in your office do all the stuff they need to do.

Try to think of all the things you do with this machine - Mason can only create rules based on the things you do with this system. If you forget something, it will be blocked in the firewall and you'll have to come back to Mason later to learn it.

All this time, we haven't even touched the terminal where Mason's running. Mason has just been creating firewall rules for this system. When you're all done, press Enter once on the keyboard. In a moment, you'll come back the main menu. Type EL to stop the learning process. Choose EN to Edit the Newrules file. If you scroll to the right, you'll see the protocol names for each rule.

Check the rules. Feel free to delete any rules that look suspicious. This is just a shell script with ipfwadm or ipchains commands; if you're comfortable editing these rules, feel free.

Once you've pared the rules down to ones you like, save and exit. When you get back to the main menu, choose MR to Merge Rules from the newrules file to the baserules file, where the final firewall rules are stored. It'll ask you how much to merge; respond "all" to put all of the rules in the final firewall file.

We're almost done. Have a couple more bites and we'll finish up.

Choose CS to change settings. This is the /etc/masonrc file that holds the configuration for the Mason package. Don't be concerned about the size; you have the ability to change these settings if your configuration requires it, but Mason picks intelligent defaults for basically everything you leave unset.

Scroll down to the line the currently reads:

DEFAULTPOLICY="accept"

and change it to

DEFAULTPOLICY="deny"

Save your changes and exit the editor. Now choose Q to quit. Not only are you done with the learning process, but the new firewall will be put into place as you leave.

Hey, not bad, you just built a firewall! Give yourself a pat on the back.

Now try doing all the things you did earlier - if everything worked as planned, you'll be able to do all the things you need to do now.

Not only is it important to make sure that you could do all the things you were able to do before, it's also important to make sure that everything else is blocked. We need to find a service that's not one Mason knows about. For example, let's say you never made a telnet connection when you were teaching Mason (if you did, pick another protocol, perhaps gopher?).

Try to make a connection to a server of that type. If all goes well, you'll see something like "connection refused" or it will look like your application isn't doing anything. Kill the connection.

Shut the firewall down by typing:

/etc/rc.d/init.d/firewall stop

Try that connection again. This time, you should be able to make that connection successfully. Now manually start the firewall back up with:

/etc/rc.d/init.d/firewall start

Try that connection one more time. It should fail again.


Where do we go from here?

If you're happy with the firewall, you can tell your system to start it up at each boot. On RedHat, run the "ntsysv" program and enable the "firewall" service. This will implement the rules you've placed in /var/lib/mason/baserules each time the system is booted. On other systems it may be necessary to create a symlink from /etc/rc.d/init.d/firewall to /etc/rc.d/rc3.d/S18firewall - see the documentation for your distribution to see how this is best done. At worst case, place this line in /etc/rc.d/rc.local:

/etc/rc.d/init.d/firewall start

If now, or at some point in the future, you realize that you forgot some protocol or program, simply rerun "mason-gui-text". While Mason is learning, run that program and follow the above steps again. Make sure you choose to merge the rules when you're done; only the baserules file is used to create the finished firewall.

If you ever suspect that the firewall is causing problems, you can immediately check to see if this is the case; shut it off with:

/etc/rc.d/init.d/firewall stop

If the problem persists, it's not the firewall's fault. If it goes away, that probably means Mason never had a chance to learn about it; startup mason-gui-text again to give Mason a chance to learn.

Where do you go for more information?

The first place to look is the Mason documentation, in the form of the Mason-HOWTO in /usr/doc/mason-0.13.0.92/. It's available in .txt and .html format (and even .pdb format for Palm Pilot users). In addition to documentation on Mason and firewalling, it includes pointers to web sites, mailing lists, and other resources available to you.

Make sure you sign up for the mason-announce list at the Mason web site so I can keep you posted on new versions of the program and and security problems that might show up at some point in the future.


Additional resources

William is an Open-Source developer, enthusiast, and advocate from Vermont, USA.