<!doctype linuxdoc system>

<article>
	<title>The Mason HOWTO
	<author>William Stearns
	<tt><htmlurl url="mailto:wstearns@pobox.com" name="wstearns@pobox.com"></tt>
	<date>v1.0.0, May 2002
	<abstract>
		This describes the basic operation of Mason and its use in
		creating firewalls under Linux.
	</abstract>
	<toc>

<sect>Formalities

<sect1>Disclaimer
<p>---------------If you read nothing else, please read this----------------

	This program offers an aid to creating firewall rules.  It offers
ABSOLUTELY NO intelligence in deciding what should be allowed or
disallowed.  It has ABSOLUTELY NO ability to understand your security
policy and implement it.  YOU are responsible for reviewing the rules and
massaging them to fit your needs.

	While this documentation attempts to provide some general
guidelines on how to use Mason, please remember:  the author has no
knowledge of what you want your firewall to do and has not tailored the
documentation or program to specially fit your needs.  If there is ever a
discrepancy between your needs and the program output or your needs and
the documentation, the program and/or documentation are _dead_ _wrong_. 

<sect1>Copyleft
<p>	Mason interactively creates a Linux packet filtering firewall.

	Copyright (C) 1998-2002 William Stearns <htmlurl url="mailto:wstearns@pobox.com" name="wstearns@pobox.com">

	This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

	This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

	The author can also be reached at:
<descrip>
<tag>email</tag><htmlurl url="mailto:wstearns@pobox.com" name="wstearns@pobox.com">           (preferred)
<tag>web</tag><htmlurl url="http://www.stearns.org/mason/" name="http://www.stearns.org/mason/">
<tag>snail</tag><verb>
William Stearns
6 Manchester Dr.
Lebanon NH, 03766, USA
</verb>
</descrip>

	This code is entirely owned by William Stearns
(<htmlurl url="mailto:wstearns@pobox.com" name="wstearns@pobox.com">)
and has no relation to any employer or employer sponsored project.

<sect>Introduction
<p><quote>
"If you have not checked out Mason, I highly recommend it. Mason is a
Linux based firewall, but none like you've ever used.
	In short, you put Mason into learning mode and run the services to the
Internet you wish to support. Mason will then take these log entries and
turn them into a set of packet filtering rules. Pretty cool eh? No ACK
compliment rules to worry about, no "what was that service port again?"
decisions to worry about, simply plug it in, let it learn and off you
go. :)"</quote>
- - Chris Brenton, <htmlurl url="mailto:cbrenton@sover.net" name="cbrenton@sover.net">

<p>	The Mason script interactively builds a (fire)wall on a Linux
machine. For more details about how this is done, please read on for
background, theory of operation, a quick start, and additional
documentation on firewalls and firewall gotcha's. 

	mason.txt and related documentation should have been installed to
/usr/doc/mason-{version}/ .  If they are missing or you would like to make
sure you have the latest version, please go to
<htmlurl url="http://www.stearns.org/mason/" name="http://www.stearns.org/mason/"> .

	The impatient should go right to the <ref id="quickstart" Name="Quickstart">.

<sect1>Background and motivation
<p>	The built-in firewall features of the Linux kernel offer a
powerful set of packet filtering features that can be used to build a
firewall.  The various pieces of available documentation provide an
introduction on how to configure the firewall for simple setups, but can't
possibly explain how to configure a firewall for more complex setups,
including fine-grained allow and deny lists.  This is especially obvious
when trying to create a firewall with a default policy of deny.

	Someone looking to configure a linux firewall is simultaneously
hit with the complexity of trying to understand the ipfwadm syntax, trying
to understand the structure of TCP/IP connections, and trying to create
and implement a security policy.  No wonder firewalls are daunting!

	The Mason application attempts to handle the first two problems by
dynamically creating the firewall based on the traffic flowing through it. 
For example, if you start up a telnet session through your firewall from a
machine on your LAN to a machine out on the WAN while mason is running,
mason will create all the rules necessary to allow this traffic. 

	Conversely, if you're looking to block incoming NFS requests,
simply launch mason, select a "deny" or "reject" policy, and make the NFS
connection.  When the firewall is restarted, voila!  No more incoming NFS. 

	Creating a firewall no longer requires understanding the
ipfwadm,  ipchains or iptables syntax.  Even novices can create a
firewall under Linux.   _HOWEVER_, creating a _good_ firewall _still_
requires some understanding  of TCP/IP protocols and packet filtering. 
Many good books cover this.   Check out O'Reilly and Associates (
<htmlurl url="http://www.ora.com" name="http://www.ora.com"> or  
<htmlurl url="http://www.oreilly.com" name="http://www.oreilly.com"> )
for some excellent general coverage of firewall designs. 

	One last novice's mistake I'd like to see Mason users avoid is the
false sense of security that a firewall can provide.  _Truly_ securing a
system or network requires _much_ more than simply filtering packets.  
The aforementioned books provide a great background in general security.

<sect1>Basic theory of operation

<p>	Before starting, if the user has some rules that he or she
knows should be used in this machine, these can be added to 
/var/lib/mason/baserules.  As part of the process of running Mason, 
we'll add rules that log all other packets to /var/log/messages.  The 
"tail" command is used to feed these log messages into Mason, which 
converts each log entry into the corresponding command necessary to 
allow that kind of traffic.  In the previous telnet example, 6 different 
firewall rules would be created on the firewall, three for the original 
request packet, 3 for the response back from the server (just 1 or 2 in
iptables firewalls):

<verb>
pkt 1:	Allow telnet request in from LAN
pkt 1:	Forward request through firewall
pkt 1:	Allow request to exit to WAN
pkt 2:	Allow telnet response back into firewall from WAN
pkt 2:	Forward response through system
pkt 2:	Allow response to exit back to the original machine on the LAN.
</verb>

	All packets from 3 on are handled by these rules.  There may be a
short delay in the initial connection as the rules are created.

	The script creates the actual ipfwadm/ipchains/iptables commands
to accomodate the packet flow.  When the command is executed the new
rule is inserted at the head of the existing rules so that future
packets of this type no longer reach the logging rule at the bottom. 

	The rules are also echoed to the console so that you can see the
rules as they are executed or redirect them to a file.  This process is 
handled automatically by mason-gui-text.

	If any of this is unclear, take a look at the 
<ref id="quickstart" Name="Quickstart"> which walks you through actually 
running it.  It'll make more sense when you see it in action.

<sect1>Compatibility and requirements
<p>
<itemize>
<item>Distributions
	<itemize>
	<item>Heavily tested on RedHat 5.x, 6.x, and 7.x
	<item>Compatible with Debian 2.x
	<item>Probably works with Slackware
	<item>Probably works with Suse, but you need to choose between the default /etc/rc.d/init.d/firewall and the one included with Mason
	</itemize>
<item>Requirements
	<itemize>
	<item>Bash 1.x or 2.x
	<item>Standard system utilities: awk, cat, chmod, cut, grep, head, ifconfig, mkdir, ps, route, sed, sleep, sort, tail, touch, tr, true, uniq and wc
	<item>A kernel that supports packet filtering and packet logging (kernel 2.0's ipfwadm, kernel 2.2's ipchains, or 2.4's iptables)
	<item>The ipchains, ipfwadm or iptables binaries.
	</itemize>
<item>Things Mason doesn't care about
	<itemize>
	<item>Hardware architecture (i386, Axp, Sparc...)
	<item>Number or type of interfaces
	<item>Whether the machine is a router or end-node (a normal server or workstation).
	</itemize>
</itemize>


<sect1>Features
<p>Mason supports the following: (see the release notes for additional features)
<itemize>
<item>It accepts any mix of ipchains, ipfwadm or iptables log entries as
input.
<item>It can run on an ipfwadm, ipchains or iptables kernel.
<item>It can spit out ipfwadm, ipchains or iptables output.
<item>In theory, the above 3 are independent from each other.  Mason
can, for example, accept ipchains and ipfwadm log entries, run on an
ipfwadm host, and output ipchains rules.  Unfortunately, the structure
and design of an iptables firewall is sufficiently different from
ipfwadm and ipchains firewalls that you can't automatically convert back
and forth.
<item>It will run on the firewall machine or on another machine, using
the firewall's packet logs as input.
<item>It can run as the traffic is flowing through the machine or be fed
the firewall logs later.
<item>While there are some advantages to running as root, it can be run
as a non-root user.
<item>Mason will put in a macro for dynamic IP addresses, usually for
your ppp link.
<item>It supports any kind of interface that can carry TCP/IP traffic.
<item>It recognizes any protocol listed in /etc/services and commonly
used icmp protocols.
<item>It automatically handles setups such as cable modem or satellite
where the packets go out on one interface and come back on another.
<item>It automatically handles masquerading on the firewall and the
strange rules that can require.
<item>It allows you to put in any rules you may know you need and fills
in the rest, or just builds the entire thing for you if you prefer.  It
can also be used after a firewall has been created to fill in some new
rules or new protocols.

<item>It automatically generalizes the firewall rules in the following ways:
	<itemize>
	<item>Any local IP addresses are converted to the corresponding
	local network.  Special IP's (0.0.0.0, 127.0.0.1,
	255.255.255.255) are handled appropriately.  Mason can also be 
	configured to leave addresses alone or convert them to
	hostnames.  This gives you the ability to either treat all
	machines in a subnet as having equal access rights or create
	fine-grained access rules for individual servers, as you choose.
	<item>Non-local IP's are converted to 0/0 (anywhere).
	<item>Port numbers in /etc/services are converted to the
	corresponding service name.
	<item>High port numbers are generalized to 1024:65535.  The
	special port needs of ssh, traceroute, nfs, ip masquerading,
	irc, x, openwindows, and vnc are handled automatically.
	</itemize>
<item>The ack flag is set for all tcp connections except for ftp.
<item>The TOS (type Of Service) flag is set for ftp, ftp-data, imap,
irc, nntp, pop, ssh, snmp, and telnet to improve interactive performance
by queuing interactive packets ahead of bulk transfer packets.
<item>Each output line is commented to give you an idea of what it's for
and allow for easy grouping via sort.
<item>The rule policy can be changed on the fly without having to stop
Mason.
<item>Because Mason is a shell script, it can run on any system with
bash and basic GNU tools (sed, awk, grep, etc.).  Actually creating the
firewall log entries, interactively building  the firewall, or
implementing the finished firewall needs requires a Linux system with 
appropriate kernel (generally 2.0.0 and up, including 2.1.x and 2.2.x)
with firewalling and firewall packet logging built in.
<item>Thanks to Don Howard <htmlurl
url="mailto:howarddj@bigvax.alfred.edu"
name="howarddj@bigvax.alfred.edu">,  Mason 0.12.0 and above have initial
support for creating Cisco ACL's.  The support is not truly complete,
and hence untested.  It needs someone that's interested in working with
me on the project before it's complete.
<item>A rather extensive manual/howto/notes file covers operating  Mason
and some issued associated with packet filtering firewalls.  Good
reading for anyone trying to understand some of the more advanced topics
in packet filtering firewalls.
<item>automatically makes masq rules for reserved addresses
<item>icmp subcodes
<item>support for ip tunneling, cipe and a number of other protocols
<item>removal of the namecache (no longer needed)
<item>mason now stops logging packets quickly while it does the main
processing
<item>stop using ipcalc to calculate broadcast
<item>don't touch /etc/hosts or /etc/services
<item>more Debian integration and two man pages (Thanks, Jeff!)
<item>support for ipchains-save output format
<item>support for --sport and --dport (Thanks, Rusty!)
<item>major documentation updates
<item>the ability to add packet counts to each rule, sorting the most
commonly used rules to the top (ipfwadm and ipchains only; iptables no
longer requires this).
<item>misc. bug fixes and performance improvements
<item>fixes to the Cisco output format
<item>the ability to generalize the ack rules for tcp connections,
cutting 25%-35% of the rules
<item>an internal checkpointing ability to help in debugging
<item>Mason can find the smallest subnet that encompasses the ips found
on a dynamic interface 
<item>and no_outgoing_ protocols
</itemize>

<sect>Quickstart<label id="quickstart">

<p>	This document is designed to help people who are unfamiliar with 
Mason build a firewall using it.  A novice user should be able to start 
building a basic firewall using these instructions in 20 minutes. 
<code>
#include <disclaimer.h>
</code>

<sect1>Make sure the system is already pretty secure.

<p>	See the Linux security sites and the Linux Administrators Security 
Guide for more info.  A strict packet filtering firewall is useless if 
someone can get root access somehow; they can just turn off the firewall.
<!-- #FIXME add urls to security references -->

<sect1>	Install the Mason package
<p>	5 minutes or less.

	If you're using an rpm-based system, type just
<code>
rpm -Uvh ftp://www.stearns.org/pub/wstearns/mason/mason-1.0.0-0.noarch.rpm
</code>

	Otherwise, download the latest version to /usr/src, 
<code>
cd /usr/src<Enter>
tar -xzvf mason...tar.gz<Enter>
cd mason...<Enter>
make install<Enter>	
</code>

<sect1>	Prepare /etc/services

<p>	Probably mostly done!

	Mason depends on a few setup details to be able to provide a 
firewall that works in the way you intended.  Make sure that 
/etc/services includes the server port names for all services you intend 
to work with, whether those services are running on the firewall machine 
or on some other machine.

	For example, if you intend to use ssh to connect to another system, 
make sure that the line
<verb>
ssh	22/tcp
</verb>

is in /etc/services.  Entries that might be missing include:
<verb>
ftp-data	20/tcp
ssh		22/tcp		#Secure shell
linuxconf	98/tcp
squid		3128/tcp	#Squid proxy cache requests
icp		3130/udp	#Inter Cache Protocol, used in squid
</verb>

	It is not necessary to include entries for services that you 
don't use.  Also, do _not_ place entries for _client_ ports in this 
file; Mason assumes anything referenced in this file is a server port.  
For example, even though one of the client ports used for ssh is 
1022/tcp, you would _not_ place this in /etc/services.  Doing so would 
cause Mason to provide incorrect rules.

	If you're not sure which ports are being used as servers on the 
firewall or on other machines on your network, use the 
"netstat -an | less"
command on Linux/Unix systems and look for lines with "LISTEN".


<sect1>	Prepare /etc/hosts

<p>	Probably mostly done!

	Try to place short names first.  You don't have to do this, but the
firewall will be much more readable in the end if you do.

	Make sure that your /etc/hosts file has at least entries for:
<itemize>
<item>locahost
<item>the ip addresses of all interfaces on your firewall
<item>all the networks in your routing table except 0.0.0.0.
<item>all dns servers
<item>any other hosts that Mason might treat specially
</itemize>

For example:
<verb>
127.0.0.1		localhost
172.16.0.1		fwall-inside	bastion	bastion.mydomain.org
12.13.14.15		fwall-outside
172.16.0.0		INSIDE			#I use all caps to distinguish networks from normal IP's.
12.13.14.0		OUTSIDE
12.13.16.10		myisp-dns1
12.13.16.11		myisp-dns2
12.13.14.44		ntp		bonzo	bonzo.mydomain.org
</verb>

<sect1>Prepare the routing table and interfaces

<p>	Probably already done!

	Mason assumes that the routing table and interfaces are set up to 
match the way the final firewall will run.  If you're running this on 
the actual firewall machine and all the interfaces and networks have 
been configured, proceed to the next step.

	Edit /etc/masonrc on the machine on which Mason will run.  Edit the 
line (or add it if it's not there)
<verb>
NETWORKS="....."
</verb>
Inside the quotes, place the following:

<itemize>
<item>All ip addresses of all interfaces for the firewall, each followed by 
/32 .
<item>The ip's of any hosts that shouldn't be treated identically to the
other machines on their respective networks.
<item>All networks whose machines the firewall should treat identically.
</itemize>

	For example, if the firewall had IP address 172.16.0.1 on network 
172.16.0.0/255.255.0.0 and IP address 12.13.14.15 on network 
12.13.14.0/255.255.255.0, I would add the following line to /etc/networks 
if I was building the firewall on another machine:
<verb>
NETWORKS="127.0.0.1/32 172.16.0.1/32 12.13.14.15/32 172.16.0.0/16 12.13.14.0/24"
</verb>

<sect1>Check the configuration file

<p>	5 minutes, more if you want to customize.

	The configuration choices in /etc/masonrc are ordered so that the 
fields you'll most likely need to edit are at the top and the really 
obscure ones are at the bottom.

	There are a few setting you must set for Mason to work at all: 
NEWRULEPOLICY, DEFAULTPOLICY, and FLUSHEDPOLICY.  If you have no 
firewall at all and are creating one for the first time, set each to
"ACCEPT".  During the learning process, you will have no protection at 
all (all packets will be accepted), but note that this is no _less_ 
secure than a system without a firewall.

	If you want to make the creation process a little more secure, you 
might consider setting one of these to DENY or REJECT; see the comments 
in /etc/masonrc and mason.txt for more info on this.  In 
particular, if you are building this remotely via a telnet or ssh session, 
note that setting one of the above to something other than ACCEPT before 
Mason knows about the telnet or ssh traffic almost guarantees that you 
will lose the ability to telnet or ssh to the box until it is rebooted 
from the console.

	If you're in a rush to try out Mason, feel free to set just these 
three fields and continue.  The more of the settings you set to match 
your needs, the better the firewall will be at matching your security 
policy in the end.


<sect1>Place any known rules in /var/lib/mason/baserules

<p>	No time for most people.

	If you know some rules you'll need already, put them in this file.  
For example, if you know you'll need to masquerade all traffic from the 
172.16.0.0/255.255.0.0 network, a sample rule for this is already in 
baserules.

	If you don't know of any, no problem.


<sect1>Run mason-gui-text

<p>	This (admittedly rudimentary) interface helps you build the firewall.
Choose "BL" (begin learning) and watch mason start to spit out the 
firewall rules that perfectly match your system's network traffic.

	Check that stopwatch - you're building a firewall less than 20 
minutes from when you started!  Give yourself a pat on the back.  Mason 
will do a great deal of the rest in the background while you're doing 
your day to day work.

	Do all of the things you want this firewall to support.  If you want
to allow mail to be sent through it, send mail through it.  if you want
to be able to ping it, ping it.  If you want to be able to traceroute 
from it, traceroute from it....  You get the idea.

	Mason will present the new rules that match your networks
traffic.  For each rule you'll be given the chance to modify the rule or
commit the rule.  Here are the modify choices:


<itemize>
<item>Edit        manually Edit the rule.  You can make any changes
you'd like to the rule before committing it to the permanent ruleset.
<item>Jot         Jot a note at the end of the rule.  You can enter a
comment to be placed at the end of the rule.
<item>Accept      change policy to Accept and commit.  Without changing
any of the rest of the rule, this changes the rule action to Accept (let
the packet pass) and commits it to the permanent ruleset.
<item>Deny        change policy to Deny and commit.  Like the above, but
change the policy to Deny (or drop, as appropriate for the firewall
type; deny and drop discard the packet without sending any error message
back to the original sender).
<item>Masq        change policy to Masquerade and commit.  Like the
above, but change the policy to Masquerade.  Masquerading allows
multiple machines to share a single IP address; the more general term is
"many-to-one NAT".
<item>Reject      change policy to Reject and commit.  Like the above,
but Reject the packet.  Like Deny/Drop, the packet is discarded, but
Reject sends back an error message to the original sender.
</itemize>

<p>	Here are the commit choices:

<itemize>
<item>Postpone    Postpone choice.  If you can't decide what to do with
a rule, or don't have the time to decide, choose postpone.  This saves
it to the "newrules" file, which is not used in the firewall at boot
time.  You'll be asked later about any rule choices you postponed.
<item>Throw away  Throw away line.  Forget the rule entirely.
<item>Blockedhost make this host a BLOCKEDHOST and delete the rule. 
Good if someone's attacking you and you want to shun them entirely.
<item>Noincoming  make this port a NOINCOMING port and delete the rule. 
This is good for ports that should never be allowed in to your network.
<item>Commit      Commit to the permanent firewall set.  Commit the rule verbatim.
<item>Quit        postpone any remaining rules and Quit.  Oops, time for
lunch!  Use this to postpone the current rule and any others in the
queue.
</itemize>

	Once you're happy with a firewall ruleset, stop learning.  From
the main menu you can either Edit the Base ruleset with "EB" or Quit. 
Edit New and Merge Rules are generally not needed and will be removed in
a future version.

	Baserules is reserved for rules that you are _sure_ are correct;
only these rules get loaded at boot time if you've enabled the firewall 
(run "ntsysv" in RedHat and enable the firewall service, or make the
appropriate symlink from /etc/rc.d/init.d/firewall to 
/etc/rc.d/rc3.d/S92firewall for other distributions).

	The goal is to have a baserules file that has all of the rules
you've approved and an empty newrules file.  Keep in mind that the
firewall that will normally be started at boot time _only_ uses rules
from baserules.

	If you need to step away from the firewall for a minute, choose "LC"
(lock console) from the main menu.  Mason will keep on learning and
you'll still see the new rules, but that console will be locked.  You'll
need to enter the root password to return to the main menu.


<sect1>Tell your boss that you're going to need a few weeks to build this.

<p>	Then head off to Bermuda and bask in the sun while Mason does its
learning.

	And make sure you have a penguin typing away in your chair so no-one
is suspicious.

	*grin*


<sect1>Implement the final firewall.

<p>	Once you've let Mason run in the background for a couple of days,
are confident that you've gotten all of the traffic types this machine
needs to support, have merged all of the rules to baserules, and are
confident they are what you want, lock down the firewall.

	In /etc/masonrc, change DEFAULTPOLICY to DENY.  If you want to keep
Mason running to see if any stragglers show up, you'll probably want to
change NEWRULEPOLICY to DENY as well; this has the effect of creating
rules for new packet types, but they are DENY rules now.

	Otherwise, just start the standard firewall with:
/etc/rc.d/init.d/firewall start

	If you've made the symlink in step 7, the firewall will be started
automatically at boot time.


<sect>Special considerations
<sect1>Kernel
<p>	(Please note that most kernels provide the support necessary; it's
probably safe to check back with this section only if you have problems.)

	IP firewalling and firewall packet logging have to be compiled
into the kernel.  To see if IP firewalling is compiled into your kernel,
type the command: 
<code>
ls -al /proc/net/ip_fwchains /proc/net/ip_input
</code>

	If ip_fwchains exists, you have ipchains compiled into your
kernel.  If ip_input exists, you have ipfwadmin firewalling compiled into
your kernel.  If neither file exists, one of the following is true:

<itemize>
<item>Your kernel is too old.  It appears that linux firewalling switched from
the old "ipfw" firewalling in 1.3.66, but some features require 2.0.0.

<item>Your kernel is missing the proc filesystem or it's not mounted 
("mount /proc" will probably fix the latter).  If your kernel truly doesn't
support the proc filesystem, reboot into the kernel that came with your
distribution, which almost certainly does.

<item>You have the right version of the kernel, but firewalling is not
enabled.  You must recompile the kernel and turn on firewalling.  See the
HOWTO's at 
<htmlurl url="http://metalab.unc.edu/linux/HOWTO/" name="http://metalab.unc.edu/linux/HOWTO/">
to see how this is done.  In
particular, see the masquerading and kernel HOWTO's.  

<item>Your 2.4 kernel has iptables, which doesn't have a flag file like
ipfwadm and ipchains.

</itemize>

	When you recompile the kernel, I recommend you have all of the
following enabled: network firewalls, ip firewalling, firewall packet
logging, always defragment, proc filesystem, transparent proxy support, IP
masquerading, and icmp masquerading.

	To see if firewall packet logging is enabled in your kernel, type
one of the following commands: 
<code>
/sbin/ipfwadm -a deny -F -S 127.12.2.3/32 -o &lt;Enter&gt;
/sbin/ipchains -A forward -s 127.12.2.3/32 -l &lt;Enter&gt;
/sbin/iptables -A FORWARD -s 127.12.2.3/32 -j LOG&lt;Enter&gt;
</code>

	The "-o" or "-l" at the end tells the kernel to log this particular 
packet type (one which should never show up).  If your kernel does not 
support logging, I _think_ you would get an error.  On the other hand, 
I've never had a kernel that has firewalling but does not have logging.  
The solution is the same - recompile your kernel to include both 
firewalling _and_ firewall packet logging. 

	(If recompiling a kernel is too daunting, try my automated kernel
builder, "buildkernel", which can be found at
<htmlurl url="http://www.stearns.org/buildkernel/" name="http://www.stearns.org/buildkernel/">).

<sect1>Ipfw, Ipfwadm, Ipchains, and Iptables

<p>	Current versions of Mason handle ipfwadm, ipchains and iptables. 
It will accept log entries created under all three firewall types
automatically.  Mason automatically detects which kind of rule to
create, although this can be overridden with environment variables set
in /etc/masonrc.  The masonrc file has comments describing these
fields.

	Make sure you have the ipfwadm, ipchains or iptables executable
- one of these should be included with your distribution.

	Mason has no support for ipfw firewalls (the firewalling used in
kernels prior to 1.3.66).  I don't intend to pursue this type of
firewalling, but am not against integrating a patch if someone feels like
adding the support.  Does anyone still use this?

<sect1>DNS
<p>	Mason does not try to look up the hostnames of any machines involved 
in DNS requests (unless they're in /etc/hosts).  If it did, Mason could
enter a situation where it issues a steady flow of DNS requests to 
resolve the machine names and each DNS request requires a new rule, 
which in turn requires more DNS requests... ugh.

	The easy way to get machine names into your DNS rules is to make 
sure all your DNS servers are listed in /etc/hosts .  If they're not 
listed there, Mason will just leave them as IP's.


<sect1>Rule order
<p>	When a packet needs to be processed (at entry, forwarding, or
exit), the firewall scans the existing list of rules to decide whether to
allow, deny or reject the packet.  As this scans stops at the first rule
that matches the packet, the order in which your final firewall rules are
executed can make a difference.  This document only provides basic
coverage of how to order your rules - sorry.  The best place to find out
more about this is in the O'Reilly and associates books.

	(If anyone would like to provide additional general guidelines as
to how this is done, I would be glad to place them here with the
appropriate disclaimers).

<sect1>Generalization
<p>	The packets Mason processes are data transfers between specific
ports on specific machines.  For example, here's a response packet from a
specific FTP server (linux.kernel.org) to what is probably a machine on
your LAN:
<code>
/sbin/ipfwadm -i accept -W ppp0 -I -P tcp -S linux.kernel.org/32 ftp -D \
devel1.goober.net/32 1024:65535 # ftp/tcp
</code>

	The rule above (possibly along with others) would only allow
devel1 to reach only linux.kernel.org, making for a ridiculously large
ruleset if other machines wanted to ftp out to linux.kernel.org or
wanted to reach  other ftp servers.

	By default, Mason _generalizes_ the source and destination IP 
addresses.  For example, devel1.goober.net/32 is replaced with 
210.134.12.0/24 (the fictitious network address block of which devel1 
is a part).  Since linux.kernel.org is not a part of any local network 
blocks, linux.kernel.org is replaced with 0/0 (which matches any machine
anywhere).

	This automatic generalization can be disabled by setting 
IPCONV="HOST" in /etc/masonrc.

	Mason also does some generalization on the source and destination 
ports.  Irc, X, realaudio, traceroute, and others use ranges of ports; 
Mason knows how to generalize many protocols to the appropriate range.

	For the standard tcp and udp services, Mason generalizes the client 
port to 1024:65535.  The connection that prompted this rule might have been,
for example, port 1745 on devel1.  As Mason didn't recognize 1745 as some
special server, it assumed that the next connection might be from, say,
port 1788.  By using the entire range of high ports ("1024:65535" in the
above rule), Mason uses a pretty standard approach to packet filtering to
reduce the number of rules.

<sect1>Router or end node
<p>	This program was originally intended for use on a traditional
firewall - a packet filtering router (linux box that connects 2 or more
networks through one or more interfaces).  It works equally well on Linux
boxes with only one interface.  These could be workstations on a LAN,
servers outside of your firewall, or even slip or ppp connected
workstations.  The number of interfaces and their type and speed are
irrelevant to the firewall creation process. 

	This would be great for locking down a web or mail server
outside your firewall, for example.  Start up Mason and make sure you
make one of every kind of connection you want to that machine.  Mason
will create the corresponding rules.  Generalize these and add a default
policy of "deny".  _Only_ the connection types you specified will be
allowed to that machine.  The difficulty of setting up the rules has
been the major impediment to this kind of hardened end node in the past. 
Now that Mason is here, there's no reason why every machine on your LAN
can't have packet filtering enabled and active. 

	Note that on an end node (Linux box with a single NIC connected to
a single IP network) you should never see forwarding rules created - this
makes sense if you think about it. 

	You could technically create a firewall on a machine with only the
loopback interface, but this would be more for instructional value about
internal tcp connections than for any security goal.  On the other hand,
if you wanted to stop shell account users from getting to an internal Web
server, you certainly could; just make sure you put in blocking rules for
all interfaces, not just the loopback interface.

<sect1>Slow machines or fast nics

<p>	As a shell script, Mason is much less efficient at its work than
a C app would be.  On a slow machine, it can take a couple of seconds
from the time the log entry is fed into it until the firewall rule is
implemented.  If the system is slow, if it has a lot of packets
traveling through it, or if it simply has a great deal of log file
traffic it can take Mason a long time to catch up.  If this is the case,
start slow.  Try one connection type at a time and give the system a
chance to settle before you move on.

	If Mason _cannot_ catch up, choose the "EL" (End Learning) option in
mason-gui-text.  Wait until Mason stops, then restart learning.

<sect1>Active hacking while mason running
<p>	If at all possible, try to set up these rules in a controlled
environment.  Hook up your firewall to machines that simulate the routers
and networks that will be used in its final location.  It is not a good
idea to create a firewall in an environment not completely under your
control.  

	If you must create the firewall rules in a live environment, be
warned: Mason simply creates rules based on what traffic is passing
through it.  IT CANNOT DISTINGUISH BETWEEN THE TRAFFIC YOU'RE CREATING TO
TEACH IT AND SOMEONE ACTIVELY TRYING TO HACK THROUGH YOUR FIREWALL.  IF
THIS HAPPENS, MASON WILL CREATE RULES THAT _SPECIFICALLY_ _ALLOW_ PEOPLE
TO GET BACK IN LATER.  _Please_ read and try to understand the rules
before you put them to use in a production environment. 

	(I hate all caps too, but the "boldface" button on my keyboard is
jammed :-).

	The "hacker" mentioned above does not need to be a computer
criminal in a far-off country looking to crash your machines.  This
individual could be someone in accounting that is (without malicious
intent) connecting to an Internet IRC server, when this doesn't fit in the
security policy you're trying to implement.  If you don't read and
understand the rules Mason spits out, you may very well leave an explicit
opening for this user's future IRC use.

	One more time: Mason _does_ _not_ understand the traffic flowing
through your firewall; it just creates the rules that you can later use to
specifically allow or disallow this traffic.  This is why it is a good 
idea to delete any rules that look even vaguely suspicious.  If it turns
out these rules are needed for normal operation, they will be relearned
when you restart Mason.

<sect1>Masquerading
<p>	One of the common uses for Linux firewalling is to act not only as
a packet filter but also as a masquerading host, allowing multiple
machines to share a single IP address.  

	As of Mason 0.13.0, Mason will automatically masquerade traffic from 
RFC 1918 (also called "reserved") addresses.  Since you probably don't 
want to masquerade between internal lans, you need to list all the 
interfaces leading _out_ to the real world (_not_ the interfaces that 
use these reserved addresses).

<sect1>Offline and non-root creation
<p>	If you are especially cautious, you might not want Mason actively
creating rules on your production server.  Or maybe you think you've
created a good firewall, but keep getting log messages and don't know how
to keep your log files from filling your disk.  Or perhaps your CPU can't
keep up.  Or maybe you just don't trust Mason's author - no offense taken
:-).  In all of the above circumstances, Mason can create the commands
without actually being fed the log messages live.  For example, if you
have packet logging entries in /var/log/messages, try this:
<code>
cat /var/log/messages | grep ' I=' | DOCOMMAND="none" mason &lt;Enter&gt;
</code>

	The output can, of course, be tee'd, redirected to a file, piped
to less, etc.  "... | sort | uniq" can be useful too when you're not
converting it live. 

	Obviously, the source file can be one that has been transferred
from another machine. 

	There is one caveat to the offline approach.  The specific case is
when one has a "deny" or "reject" policy in place for the input logging
rule.  Let's say I try to telnet through the firewall.  My packet arrives
at the firewall, is stopped and logged (so Mason can successfully create
the correct input rule later).  The firewall never has a rule implemented
that allows me to get any further than that, however, so there is never a
log entry created for any of the remaining 5 packet checks. 

	One way around this might be to use a policy of "accept" on your
logging rules while you're creating /var/log/messages for later
consumption by Mason.  I'm not saying this is appropriate for you, but
might be one way to handle this.  Be warned; this can create very large
log files as every packet passing through the system can create 6 log
entries!

	One final use for this technique is creating the rules when you're
not root.  Simply edit /etc/masonrc to set DOCOMMAND="NO" and the script 
will still output the appropriate ipfwadm/ipchains commands but won't 
try to execute them, allowing non-root users to create the firewall rules.  
Note that you still need to be root long enough to turn on some kind of 
logging, or /var/log/messages will never contain any entries to convert.  
Root privileges are also required to implement the rules once you've 
created them. 


<sect1>/etc/services and special ports
<p>	Mason converts the protocol number and type (i.e. 53, udp) into
the more common name (domain, in this example).  It uses the /etc/services
file to do make this conversion.  Before you start, make sure all the
protocols you will work with are listed there.  If a particular protocol
is not in that file, Mason will have serious problems producing accurate 
rules.

	Having this entry is especially important if you are working with
services whose ports are >= 1024 (nfs, X, squid, irc, vdolive, etc.).  If
a service >= 1024 is not found in /etc/services, it will be automatically
(and incorrectly) generalized to the port range of 1024-65535.  If your
favourite service isn't in there, simply edit the file and add it in the
same format as the other entries. 

	These services whose ports are >=1024 can occasionally show up in
your rules where Mason should have used 1024:65535 instead.  Well, you
know how to fix this, right?  Just delete the rule, add the service to 
/etc/services, and relearn it.

	The entries in /etc/services should only be for well-known server
ports.  Client ports (which are usually just random ports between 1024 and
65535 anyways) should not be listed in here.  The specific example of
something that should be missing is the ssh client port.

	If you plan to do the conversion on one machine and actually run
the firewall on another, make sure all of the protocols used are listed in
the /etc/services on both machines. 

	The authoritative source for these ports is the Internet Assigned
Numbers Authority (IANA).  A list of these ports can be found at: 
ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers .  Mason 
includes what seems to be an even more up-to-date reference; see 
/var/lib/mason/nmap-services.  Many thanks to the authors of nmap.

<sect1>Insert vs. append
<p>	Ipfwadm has two ways of adding rules: at the beginning of the rule
list using insert ("-i"), or at the end of the list using append ("-a"). 
The usual way of creating the firewall is to flush the existing rules and
then add each of the rules using append so they will be scanned in the
same order in which they were implemented.  For this reason, the rules
that Mason spits out to stdout use "append" so they can easily be put in a
shell script.

	Mason needs some way to tell the kernel to not log already logged
packets anymore.  The way to do this is to put a matching rule before the
logging rule.  Unfortunately, that means one of two things: deleting the
logging rule at the end, implementing the new rule at the end, and
reinstating the logging rule, or simply inserting the new rule at the top
of the list.  The first option is tricky to do well. It's also a bad
choice because the user using Mason may not be logging everything, so
mason doesn't know what logging rule to reinstate.  That leaves using "-i"
to insert the rule at the very top of the list.

	The end effect is that the rules that Mason displays use "-a" to
match how that would be put into a rule file, but the rules that are
actually implemented while Mason is running use "-i" to avoid relogging
those packets again in this Mason run. 

	The major side effect of this approach is that the rule set in
memory as Mason is running is almost certainly _not_ in the order you'd
want.  The final firewall rule set you put in place should flush whatever
is in memory before starting so as to clean out these incorrectly ordered
rules.

	As ipchains and iptables support additional user defined chains,
we can throw all the temporary rules in user defined chains (called
inputN, outputN, and forwardN; the "N" stands for Nolog).  These chains
get called just before  the logging rules.

<sect1>Allow versus deny and reject
<p>	During the course of a Mason run, it's quite reasonable that the
firewall creator might want to spend some time working with traffic types
that he/she wants to allow, and then switch over to other traffic types
that he/she wants to reject or deny (see man ipfwadm for the subtle
difference between deny and reject).  If you change any settings
by choosing "Change Settings" in mason-gui-text, it will automatically
signal a running Mason to re-read its configuration file.  You can 
do the same if running mason manually by typing "killall -USR1 mason".

	Changing the target of a single rule to Accept, Deny, Reject, or
Masquerade can be done right in the menu under that rule without having
to go back to the main menu and changing the global settings.

<sect1>Input, Output, and Forwarding
<p>	To implement packet filtering, the Linux kernel needs to inspect
each packet at at least one of the following three times: when the packet
enters the system, as it passes through the system on the way to its exit
interface, and as it leaves the system. 

	At each of those three times, the kernel can decide to allow or
deny/reject the packet.  The rules can be different at each stage - it's
perfectly legal to, for example, allow it in, allow it to be forwarded,
but then block it at the last second before it leaves the system.

	A simple firewall could be implemented using just, say, input
rules(*).  It's when you get complex firewalls that having rules at all
three stages is useful.  You might want to allow hosts from eth0 to get to
a pop-3 server on eth1, but not allow hosts from eth2 to get to the same
server.  This kind of restriction might be impossible to do without
forwarding rules, especially if eth2 hosts _should_ be allowed to get to a
pop-3 server on eth0.

	For simpler firewalls, or if you want less than the imposing
grandeur of a firewall ruleset that goes on for pages and pages, Mason can
accomodate you.  If you just want input rules, add the following to 
/var/lib/mason/baserules :
<code>
if [ -f /proc/net/ip_fwchains ]; then
       /sbin/ipchains -A forward -j ACCEPT
       /sbin/ipchains -A output -j ACCEPT
elif [ -f /proc/net/ip_input ]; then
       /sbin/ipfwadm -F -a accept
       /sbin/ipfwadm -O -a accept
fi
</code>

	Place any general traffic types you don't care about in baserules.

	Please note that I am _not_ advocating the above, but pointing out
that the technique is available for those that feel the reduced 
security is appropriate for them.

(*) The exceptions to this are the special rules for redirecting packets
(which must be done as an input rule), and masquerading packets, (which
must be done as a forwarding rule).  Even in the cases where you wish to
use these facilities, it's still legal to implement packet filtering using
another rule type. 

	Please note that the above does not apply to iptables.  In
iptables, packets are not inspected multiple times in multiple chains.

<sect1>Remote firewall creation - Telnet/ssh lockout
<p>	If you're creating this firewall rule set and you're telnetting,
ssh'ing, or rsh'ing (collectively, "telnetting") in to the firewall, be
careful.  Some of the first rules to be created will be for the telnet
packet flow you're using.  If you are so unfortunate as to start this
process with a policy of deny, guess what packet flow will be stopped
almost immediately?  That's right, your telnet session(s).  Your machine
will be completely locked down with no way to remotely reach it.  (Now
where were my car keys? &lt;grrrr&gt;) 

	If you want to put the rules allowing your remote access before
starting Mason, great.  If not, just make sure that your startup policy is
allow or it's remote reboot time!  Logging in on any of the console's
virtual terminals does not require TCP/IP packets, so you can never lock
yourself out completely. 

	You did read the section above on "simulating the working
environment under controlled conditions", didn't you?  Are you still sure
you want to be creating a firewall not directly under your control? 
Just a thought...

<sect1>Ack flag
<p>	Let's look at some standard rules that allows a telnet connection
to a server somewhere (these are only two of the 6 possible rules).
<verb>
allow	LAN_IP's, ports 1024-65535 -> Outside_world_IP's, port 23
allow	Outside_world_IP's, port 23 -> LAN_IP's, ports 1024-65535
</verb>

	It looks pretty safe, right?  Hmmm....

	Let's say that one of your LAN machines runs a squid server.  This
sits waiting for connections on port 3128.  Additionally, consider the
possibility that the root user on some Outside_world_IP machine writes
some program that starts a connection _from_ port 23.  This user starts
this program and connects to your LANs squid server. 

	All with your firewalls full consent.  Ugh.

	The way to avoid this problem is to be able to identify the
_direction_ in which the connection is created.  We want to allow
connections that start _from_ LAN:1024-65535 _to_ Outside:23, but block
connections that start _from_ Outside:23 _to_ LAN:1024-65535.

	The TCP ACK flag comes to the rescue.  The first packet in a
connection does _not_ have this flag set.  Every packet after the first 
_does_ have this flag set.  If we require all packets coming from the 
server port have their ACK flag set, we can stop the bogus connection 
from port 23 back to port 3128.

	In short, by requiring all packets from a server port have their
ACK flag set, we block connections that originate from those server ports.

	Three notes.  Only TCP uses ACK flags, so we can't use this to
control the direction in which icmp or udp conversations are initiated.
Secondly, DNS may be a problem.  Tcp domain transfers and large dns
requests can be  from port 53 to port 53, depending on what dns software
you're using.  FTP-data connections do not have their ACK flag set
because they can be created in either direction.  Finally, there may be
issues from ssh low ports if /etc/services has entries up near 1023.

	Mason is able to automatically set the ack flag if your 
/etc/services lists all of the services you use.

	I specifically avoided the "-b" (bidirectional) flag so that I
could use "-k" to control the direction.

	Iptables uses the state of the connection as a more dependable
way of handling the above problem.  I'd generally encourage you to use
the "-m state --state ESTABLISHED,RELATED" lines in baserules.  If you
do, then Mason hands you a single rule for any given type of traffic;
the opening packet.  The ESTABLISHED,RELATED lines handle all the other
packets.


<sect1>Limitations, Ideas and future enhancements

<p>
<itemize>
<item>group foreign machines into additional rule? (Document how.)
<item>Document the living hell of NFS.
</itemize>

<sect>Configuring Mason
<p>	Most of the configuration is set via environment variables.  For
permanent changes, try 
<code>
export VARIABLE=value
</code>

For one time settings, just put the variables on the command line just
before calling the program.  For example:
<code>
tail -f --lines=0 /var/log/messages | ECHOCOMMAND=ipchains mason
</code>

	If you set a variable both on the command line and in /etc/masonrc, 
be warned that /etc/masonrc wins.

<itemize>
<item>ECHOCOMMAND=ipchains|ipfwadm|none #Autodetected if unset or invalid

<p>	Which kind of command should Mason display?  This does _not_
have to match the firewalling in the current kernel; this lets you
create an ipfwadm firewall ruleset on an ipchains kernel and vice-versa. 
(Remember that iptables can't take part in this cross-creation.)

	The following two commands will spit out an ipfwadm firewall and
an ipchains firewall, respectively, from the same input:
cat /var/log/messages | grep ' L=' | ECHOCOMMAND=ipfwadm mason >ipfwadm-wall
cat /var/log/messages | grep ' L=' | ECHOCOMMAND=ipchains mason >ipchains-wall

	Both kinds of firewall log entries have L= in them; this is a
reasonably good filter to keep Mason from having to process _all_ the junk
entries.

<item>DOCOMMAND=ipchains|ipfwadm|none  #Autodetected if unset or invalid

<p>	Which kind of command should Mason run to prevent that type of
traffic from being logged in the future?  Set to none if you're processing
the log entries later, or on another machine.

	Unless you're forcing it to "none", probably best to let Mason
autodetect.

<item>HEARTBEAT=yes|no

	If yes, mason displays a "." or "-" when it processes an input
line that has been handled by one of the recently implemented rules.  The
heartbeat character is sent to stderr so it doesn't screw up logging to a
file or piping to some other program.

<item>DYNIF="ppp0 sl0"

	If your machine has interfaces whose entries change IP address,
put the interface name(s) in quotes, separated by spaces.  Mason will
handle these interfaces specially by handing you a line that will
assign that interfaces IP address to an environment variable when
executed, and uses that variable throughout the ruleset.

	If your Ethernet IP address is assigned via DHCP, BOOTP, or RARP,
_and_ _changes_ from time to time, you might even want to put your
Ethernet interface name(s) in the list.  If the addresses are assigned via
one of those tools, but _never_ _change_ (those protocols are supposed to
try to give you the same address you had last time if at all possible),
don't put the Ethernet interface(s) in there.

	Make sure you re-run your firewall ruleset (or at least the rules
with dynamic IP entries) when the address changes.  For ppp interfaces,
restart your firewall inside /etc/ppp/ip-up.  I think DHCP has a similar
ability to run commands when the address changes; consult the DHCP
documentation.

</itemize>

	The main documentation for all the configurable fields is 
conveniently in /etc/masonrc .

<sect>IP protocols and their firewall characteristics

<sect1>Standard TCP and UDP protocols

<p>Most of the connections made in tcp/ip follow a standard form.  The 
client machine picks a random port between 1024 and 65535.  The packets 
are sent to a fixed, known port that's below 1024.

	For example, I need to send an email message from mybox.office.com to 
mailserver.office.com.  Since email goes to tcp port 25 (see /etc/services
for some of these), the tcp/ip code on mybox picks a random tcp port, 
such as 1931.  Packets flow from mybox port 1931 to port 25 on mailserver.
Packets also flow <em>back</em> from mailserver port 25 to mybox port 1931.

	Here are some of the protocols that follow this form:
<itemize>
<item>23/TCP - telnet
<item>25/TCP - SMTP
<item>80/TCP - HTTP
<item>110/TCP - POP3
<item>143/TCP - IMAP
<item>512/UDP - BIFF
</itemize>

<sect1>ICMP
<p>	ICMP doesn't use source and destination ports, but it has icmp codes and 
subcodes, each a number between 0 and 15.

<sect1>DNS
<p>	If the firewall or one of the machines behind it is a DNS server,
you have a situation where mason issues a steady flow of DNS requests to
resolve the machine names and each DNS request requires a new rule, which
in turn requires more DNS requests... ugh.

	Mason no longer does DNS lookups on machines involved in DNS lookups.
If you have the names and IP addresses of your DNS servers, add them to 
/etc/hosts.

<sect1>FTP
<p>	Ahhh, yes, ftp.  The scourge of firewall creators everywhere.  

	If you're using iptables, have the ip_conntrack_ftp module
loaded and have uncommented the "-m state --state ESTABLISHED,RELATED"
lines in baserules, the problem I'm about to describe does not apply to
you.  Since iptables is a stateful firewall, this problem has been
solved in an elegant and now hassle-free way.

	Ftp starts off well because the client opens a connection from a
high port (1024-65535) to the ftp control port 21.  This part of the
connection follows the same model as other tcp protocols: client uses a
random high port and connects to a fixed low port. 

	The problem arises when it's time to actually transmit data.  The
client and server exchange directory listings and files over additional
tcp connections that are between a random high port at the client end and
a random high port at the server end.

	Remember that packet filtering firewalls depend on being able to
identify connections by their (fixed and generally low) server port.  Here
we have connections that need to be allowed if ftp is going to work, but
can't be identified this way. 

	It really comes down to a choice: does the firewall allow ftp
traffic (leaving at least one high to high rule which is a generally
considered a security risk), or do we block ftp?  You'll need to decide. 

	Mason creates these rules as transparently as any others.  It
opens up the ports for the control channel and the high to high rule
(called the data channel).  A single ftp connection could therefore open
12 rules.  You'll need to decide whether these high to high rules are too
much of a security risk. 

	If you do choose to open up ftp rules, you might want to do these
last.  This allows you to put in more specific rules first.

<sect1>Netbios
<p>For those hoping to come here for a simple set of rules for 
firewalling netbios, sorry. This one is all over the map.

	Mason comes in <em>really</em> handy for netbios because 
it works with whatever netbios throws at it.  The netbios ports are
135, 137, 138, and 139 - both tcp and udp.  Connections can be 
from one of these low ports to itself, from a high port to one of 
these ports, or from a high port to a high port.

	In short, good luck trying to do this <em>without</em> Mason.

	By the way, allowing netbios traffic in from and out to the
Internet may be a very bad idea.

<sect1>NTP
<p>	NTP is one of the few protocols that uses the same port at both the 
client and server end.  In this case, it is port 123/udp.

<sect1>SSH
<p>	SSH (server port 22/tcp) has one minor note about its operation. 
When installed by root (setuid), it may not use a random high port
between 1024 and 65535 for the client end.  The first client session may
use port 1023, the next uses 1022, etc.  No real problem for Mason, but
you might be surprised at the client ports used. 

	These client ports should NOT be listed in /etc/services, even
though it might seem to make identification easier.  The reason is that
Mason uses this file to identify _server_ ports in the process of deciding
whether to use the ACK flag check.

<sect1>Other IP protocols
<p>The other protocols, such as ipip, igmp, ospf, etc (see /etc/protocols), 
don't use port numbers.  For this reason, Mason only creates rules between
individual machines for these.

<sect>Version summary (out of date, sorry)
<p>
<itemize>
<item>0.9.0
<p>	_Lots_ of good new stuff.  Mason handles log entries from 
ipchains or ipfwadm automatically.  The command it runs can be either
an ipchain or ipfwadm command, and it can output either an ipchain or 
ipfwadm command.  All independently.  See the ECHCOMMAND=... and
DOCOMMAND=... parameters, above.

	_Major_ speedup!  Keep reading lines until the 7th-13th fields
are different from the previous line; this probably quadruples Mason's
throughput or better.  Bonus points to the readers who can read morse 
code from the heartbeat output...  Oh, and I added heartbeat output to 
show that Mason hasn't just crashed. :-)

	Mason handles interfaces whose IP address changes automatically;
see the DYNIF=... parameter, above.

	Note:  additional ipchains fields are:
<verb>
L=Total length
S=TOS
I=ip->id?
F=Fragment offset
T=TTL
</verb>

<item>0.8.0
<p>	-k added to control the direction in which connections are made.
Unfortunately, the ftp-data port doesn't honor the simple rule for -k; I
suspect this is a consequence of PASV vs. "active?" ftp opening the data
connection in one direction of the other.  Hmmm... This was released to 
the world as 0.7.9.

<item>0.7.0
<p> (6/21/98) 20% speed improvement by changing read command.  Local
name cache added.  On the fly policy changing.  Comments.  Major
documentation updates.  Another 20% performance improvement by replacing
some sed's with bash internal pattern deletion.  6% more by using ${#..}
instead of wc --bytes to size strings.  Cut time necessary to process
non-firewall lines in third by using && instead of -a.

<item>0.6.0
<p>	(6/4/98) Documentation added

<item>0.5.0
<p>	(6/2/98) Bare code, almost no documentation, ipfwadm support only.
</itemize>


<sect>Advanced scenarios
<sect1>General approach
<p>	Once you've gone through the Quick Start, what now?  Now we learn
how to use this to match your security policy.

	The first lesson to learn about packet filtering rules is that
they are only useful if you have a mix of accept and deny (equivalent to
reject in this discussion) rules.  Think about it.  If all of your rules
are allow rules and your default policy is also allow, this setup is no
different from having no rules at all; the system is completely open. 

	At the other end of the spectrum, if all of your rules are deny
and the default policy is also deny, well, it's going to be pretty hard to
use TCP/IP at all.  :-)

	This means that putting a firewall together involves deciding what
should be allowed _and_ what should not be allowed.  

	The first thing for you to decide is what your default policy
should be.  In the next few minutes we'll be looking at what you
specifically want to allow and what you specifically want to disallow.
What should the firewall do with the rest of the packets?  That depends on
how you view your firewall. 

	If you primarily want your firewall to block a relatively small
amount of malicious things, but want users on both sides of the firewall
to have relatively unencumbered access to the opposite side, you'd
probably want to use a default policy of accept.  This tends to be a good
choice in the case where there are a large number of types of TCP/IP
traffic that should be allowed to pass through the firewall. 

	If, on the other hand, you tend more toward the paranoid and want
very fine grained control over _exactly_ what passes through your
firewall, you'll probably want to use a default policy of deny.  This
tends to work well when there are a relatively small number of protocols
that should be allowed. 

	Choosing a policy becomes difficult when you want fine grained
control but there are a large number of protocols used by your users.
You'll still choose a default policy of deny, but you'll have to create a
large number of rules to accomodate them.  Good thing you've got Mason to
give you a hand!

	Now that you've chosen a policy, what goes next?  Here's where you
can become an artist. 

	With the help of Mason, your job is to decide what should be
allowed and what should not be allowed.  

	[More to be added as time allows...]

<sect1>Ordering rules
<p>	Here are a couple of guidelines about how to order your rules.  I
refer to policy below; for this discussion, there are 6 possible policies:
accept, deny, reject, accept and log, deny and log, and reject and log.  

	As there is no way that input rules and output rules could ever
overlap, the rulesets for those can be considered seperately.  The same
logic holds true for input and forwarding and output and forwarding. 
Effectvely, even though you might have them all mixed together in your
firewall creation shell script, you can work with the input rules
according to the principles below, then come back and work with the
forwarding rules, and then come back one last time for the output rules. 

<itemize>
<item>I suggest placing dns (also called domain; port 53/tcp and 53/udp)
rules at the top of your firewall if you're using the default mode of 
HOSTLOOKUP=FULL.  The other rules in your firewall may require dns 
lookups; if those requests can't get through because the dns rules 
aren't in place yet, the early rules may not get put in place. 

<item>If your ruleset contains a block of 2 or more rules with the
same policy (accept, deny, or reject) that immediately follow each other,
the order of the rules in that block has no functional difference to the
operation of the firewall.  If you are very concerned about performance,
you might want to put the rules that process the largest number of packets
at the top of this block and the rules that process the least number of
packets near the bottom of this block.  See the SORTMODE option in 
/etc/masonrc (not available in iptables).

<item>If two consecutive rules do not have any overlapping cases in
the patterns they match, they can appear in either order without affecting
the operation of the firewall.  As long as no two rules in the set
overlap, this can be extended to a set with more than two rules.

<item>If two rules overlap in the patterns they match and have
different policies, they _cannot_ be reordered without affecting the
functional operation of the firewall.  Specifically, the packets in the
overlapping case will have their policy changed. 

<item>If two consecutive rules have the same policy and one is subset
of the other, the more specific rule can be discarded and the more general
rule can be kept without affecting the functional operation of the
firewall. 

	One common case of this is when your default policy is, say,
accept, and the last rule just before the default policy rule also has a
policy of accept.  This more specific rule (not the policy, of course) can
be discarded.

<item>Your default policy always comes at the end.
</itemize>

	I've referred to discarding rules above.  One reason why you might
_not_ want to discard a particular rule rule is when you're using your
firewall to do accounting as well as blocking.  You might want to be able
to have seperate accounting for the packet traffic in the rule that would
have been discarded. 

<sect1>Tips and tricks
<p>	The following are tools and techniques I use.  They may not be appropriate
for you.  Please consider whether they are appropriate for you before using 
them.

<itemize>
<item>If you want to see which rules in your running firewall are actually
carrying traffic, try this:
<code>
( ipfwadm -lenI ; ipfwadm -lenF ; ipfwadm -lenO ) | grep -v '^ *0 *0 ' | less -S
</code>
or
<code>
ipchains -L -n -x -v | grep -v '^ *0 *0 ' | less -S
</code>
or
<code>
iptables -L -n -x -v | grep -v '^ *0 *0 ' | less -S
</code>

	The "grep -v ..." removes all packets with 0's in the count and bytes 
columns.

	If the number of rules returned is still too large, flush the firewall
and restart it; this clears out all the packet counts.  Then you can 
rerun whatever test you've been doing and run the above command again to 
see what rules are carrying your traffic.  This is especialy useful if
you've got a deny rule somewhere blocking a certain connection:
<!-- #FIXME - add the egrep format for ipfwadm -->
<code>
( ipfwadm -lenI ; ipfwadm -lenF ; ipfwadm -lenO ) | grep -v '^ *0 *0 ' | less -S
</code>
or
<code>
ipchains -L -n -x -v | grep -v '^ *0 *0 ' | egrep '(Chain|target|DENY|REJECT)' | less -S
</code>

<item>If you don't want to go through the above process, but just want to
convert a few log entries to rules, you can do the feed yourself.  For example:
<code>
tail --lines=1000 /var/log/messages | grep 'kernel.*I=' | DOCOMMAND="none" mason >afewrules
</code>

	Any other options can be placed on the command line or in /etc/masonrc.

<item>If you want rules that will run under ipfwadm and ipchains kernels,
you have two good choices.  Create ipfwadm rules no matter
what kind of kernel you have (put ECHOCOMMAND="ipchains" in /etc/masonrc
or on the command line).  The first choice is to use the ipfwadm-wrapper (part of the 
ipchains-scripts package) as a front end to either ipfwadm or ipchains,
as appropriate.  The second choice is to take all of the ipfwadm rules
and create the following file as your real firewall:
<code>
if [ -f /proc/net/ip_fwchains ]; then
	#Convert your ipfwadm rules to ipchains rules and place the converted rules here.
	/sbin/ipchains...
elif [ -f /proc/net/ip_input ]; then
	#Place your ipfwadm rules here:
	/sbin/ipfwadm....
fi
</code>

	The above conversion is actually darn simple:
<code>
cat ipfwadmfile | ipfwadm2ipchains >ipchainsfile
</code>

	The ipfwadm2ipchains script is available at <htmlurl
url="http://www.stearns.org/i2i/" name="http://www.stearns.org/i2i/"> . 
This site also holds ipchains2iptables, a similar script that gives a
first pass output in iptables format from a given ipchains firewall. 
Note that this output won't use any of the advanced features of
iptables, but you can add these.

<item>If you have a number of interfaces that all get the same rules, replace
the if0, if1, if2, etc rules with if+ .  I believe this is ipchains only.

<item>(Diald users only).  The packets leaving your system on sl+ (or tap+) 
may have different source addresses (0.0.0.0/32, some dummy ip address, an
old ppp address...).  You might want to replace them with 0/0 to say I don't
care what the source address is.

<item>To see what program is using a particular port, try:
<code>
ps axf | grep "^ *`fuser port_number/proto | awk '{print $2}'` "
</code>
</itemize>

<sect>Notes about Mason itself
<sect1>File descriptions
<p>


<descrip>
<tag>COPYING</tag> The GNU General Public License.
<tag>Makefile</tag> Used in packaging and distribution.
<tag>baserules</tag> The baserules file is one of two files that hold your firewall rules.  baserules holds the rules that
you've checked over and are sure should be part of your final firewall.
<tag>baserules.sample</tag> A few possible rules for use as a starting point.
<tag>firewall</tag> The boot time script for use in /etc/rc.d/init.d.
<tag>index.html</tag> The Mason web page.
<tag>mason</tag> The actual mason script.
<tag>mason-gui-text</tag> The rudimentary interface to running Mason and building a firewall.
<tag>mason-gui-text.1</tag> man page for mason-gui-text.
<tag>mason.1</tag> man page for mason.
<tag>mason.html</tag> The primary documentation for the package, in hypertext.
<tag>mason.lsm</tag> The Linux Software Map entry.
<tag>mason.sgml</tag> The primary documentation for the package.  The sgml format is designed to allow easy conversion to more readable formats.
<tag>mason.spec</tag> The RPM spec file.
<tag>mason.txt</tag> The primary documentation for the package, in a flat text file.
<tag>masonlib</tag> A library of functions used by a number of the other files.
<tag>masonrc</tag> The main configuration file.  There are intelligent defaults for all of these fields.
<tag>moreservices</tag> The services file I use, good as a reference if you don't recognize a protocol.
<tag>nmap-services</tag> The additional services file includes with the nmap tool.  An even better reference.
<tag>newrules</tag> newrules is the other file that holds firewall rules.  It holds rules created by mason
that you haven't looked over yet.  Think about what would happen if you were port scanned while Mason was running; if you only
had one file to hold rules, all of these portscan rules you don't want would be mixed in with the rules you do want. 

	An important note - rules in newrules are <em>not</em> part of your regular firewall - they are only used during the 
learning process.  This is why you need to merge rules from newrules to baserules once you're sure of them.

</descrip>

<!-- #FIXME - add sect1 section of programming notes? -->

<sect>Additional resources
<p>
<itemize>
<item><htmlurl url="http://www.netfilter.org" name="http://www.netfilter.org">Netfilter/iptables for 2.4.x kernels.
<item><htmlurl url="http://www.rustcorp.com/linux/ipchains" name="http://www.rustcorp.com/linux/ipchains"> Linux IP firewalling 
chains for 2.2.x kernels.
<item><htmlurl url="http://ipmasq.cjb.net" name="http://ipmasq.cjb.net"> The Linux IP Masquerade Resource.
<item><htmlurl url="http://www.xos.nl/linux/" name="http://www.xos.nl/linux/"> Experts in Open Systems; specifically, Jos Vos, one 
of the firewall code authors.
<item><htmlurl url="http://metalab.unc.edu/linux/HOWTO/HOWTO-INDEX-3.html" name="http://metalab.unc.edu/linux/HOWTO/HOWTO-INDEX-3.html">
The Linux HOWTO index, part of the:
<item><htmlurl url="http://metalab.unc.edu/linux/" name="http://metalab.unc.edu/linux/"> Linux Documentation Project.
<item><htmlurl url="http://metalab.unc.edu/linux/HOWTO/mini/IP-Masquerade.html" name="http://metalab.unc.edu/linux/HOWTO/mini/IP-Masquerade.html">
The IP Masquerade HOWTO.  Useful information on ipfwadm and masquerading.
<item><htmlurl url="http://www.ecst.csuchico.edu/~dranch/LINUX/index-linux.html" name="http://www.ecst.csuchico.edu/~dranch/LINUX/index-linux.html">
David Ranch's <em>excellent</em> networking resource.  Check out the "Trinity OS" document and the IP Masquerade
Howto, co-authored with Ambrose Au.  Both are comprehensive documents about Linux networking - well worth reading.
</itemize>

<sect>Authors, credits, feedback, copyright, how to help!
<p>	Once again, the linux kernel and firewall developers deserve all 
the credit.  Mason is simply a front end to a fast, powerful, stable 
firewall implementation in the linux kernel.  Many thanks to all the linux 
firewall developers.

	The name "Mason" comes from two sources; first of all, it builds 
a (fire)wall.  Second, it's my nephew's name.  Mason lives in Brooklyn with 
my sister and her husband and my niece Eve.  He's a great guy!


	If you have comments, suggestions, problems, ideas, flames,
patches, whatever, I'd like to hear them. I'd even be interested in
hearing where Mason fell short for your needs.  My permanent email
address is  <htmlurl url="mailto:wstearns@pobox.com"
name="wstearns@pobox.com">.  The permanent web site for the software is 
<htmlurl url="http://www.pobox.com/~wstearns/mason/"
name="http://www.pobox.com/~wstearns/mason/">.

	<htmlurl url="mailto:jeff@luci.org" name="Jeff Licquia"> has
kindly offered to package up Mason into a Debian package.  The Debian
requirements are helping to make a better program for  all
distributions.

	<htmlurl url="mailto:jkn@dde.dk" name="Jens Knudsen"> wrote 
<htmlurl url="http://www.linuxzone.dk/nicerules" name="nicerules">, a
wrapper script for Mason.   It's a simple script that takes the
"newrules" output, sorts and orders the firewall rules in a way that
makes it easier to review security, and produces a "standalone" firewall
script and a firewall.disable script. The script probably has many
"bugs", use it as an aid, but don't blame him for any problems it may
cause you. There is more information in the actual script which is also
heavily commented. Have fun.

	If you choose to send me actual mason firewall rules and choose
to hide the IP addresses and/or networks for security reason, that's
fine, but please replace them with something that describes their
general use so I can make sense of them.  For example:

<code>
cat myrules | sed -e 's@11.22.33.44/32@fw-outside@' \
                  -e 's@192.168.1.1/32@fw-inside@' \
                  -e 's@192.168.1.0/24@inside-net@' \
>myrules.mailable
</code>
 - or something like that.

	There are a number of things you can do to help this project:
<itemize>
<item>Send in bug reports.
<item>Send in suggestions or fixes.
<item>Organize the documentation.
<item>Design a logo.
<item>Take over the announcement process.
<item>Help integrate Mason into your distribution.  Heck, just letting me know under which distributions Mason works is helpful!
<item>Organize the Web site into a more useful resource.
<item>Set up mailing lists for developers, announcements, and users.
</itemize>

	The files in the Mason package are Copyright (c) 1998-2002 by 
William Stearns <htmlurl url="mailto:wstearns@pobox.com"
name="wstearns@pobox.com"> or  <htmlurl url="mailto:jeff@luci.org"
name="Jeff Licquia">.  They are  released under the GNU GPL, which is
included in the package.  If you did not recieve a  copy of this
license, please contact the author for a copy (see the top of the Mason 
script for contact information for the author and the Free Software
Foundation).

	<htmlurl url="http://www.stearns.org/" name="William"> is also
the author of  <htmlurl url="http://www.stearns.org/buildkernel/"
name="buildkernel">, the automated Linux  kernel builder, and <htmlurl
url="http://www.stearns.org/" name="other minor shell scripts">.

<sect1>Thanks
<p>

	Chris Brenton deserves <em>very</em> special thanks for spending
an evening with me discussing  a number of questions I've had about
packet filtering.  He was very kind to share his  knowledge with me.  I
owe him a pizza sometime. :-)

	Chris has written some excellent networking texts - I'm about
halfway through Mastering Network Security and am very impressed with
the writing and content:
<htmlurl url="http://www.amazon.com/exec/obidos/ASIN/0782120822/geekspeaknet" name="Multiprotocol Network Design & Troubleshooting">,
<htmlurl url="http://www.amazon.com/exec/obidos/ASIN/0782123430/geekspeaknet" name="Mastering Network Security">.
The above plug was not requested, but is well deserved.

	Thanks to Nathan Bailey who took the time to remind me that
there is a Perl Module that's  also called Mason.  Thanks also to
<htmlurl url="mailto:swartz@transbay.net" name="Jonathan Swartz">, the 
author of <htmlurl url="http://www.masonhq.com" name="HTML::Mason"> who
graciously agreed to share the name and pointers with me.

	Many thanks to Dave Stern, who has offered suggestions on how to
improve Mason and helped  with beta testing early versions.  Maybe
someday I'll tell him they were prerelease versions... :-)

	Thanks to all of the people who have sent in questions, bug
reports, fixes, improvements, and six foot long lizards.

	The new section of masonrc with a <em>boatload</em> of backdoor
ports is courtesy of the  authors of and contributors to snort. 
Specifically, Nick Rogness, Jim Forster and Martin Markgraf are credited
with the work on the ports - many thanks, guys.

	Snort can be found at  <htmlurl url="http://www.snort.org"
name="http://www.snort.org">. It's a <em>really</em> cool intrusion
detection tool.  Thanks to Marty <htmlurl url="mailto:roesch@clark.net"
name="roesch@clark.net"> for the tool.

	A special thank you to all the authors in the Linux movement. 
In a small way, the code I return to the  community is my way of paying
back my incredible debt to the people who came before me.

	As always, many thanks to my wife Debbie, who has shown amazing
patience with my Linux related projects.   Many thanks, my love.

</sect>
</article>
