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


Copyleft:
    Mason interactively creates a Linux packet filtering firewall.
    Copyright (C) 1998 William Stearns <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:
        William Stearns
email:  wstearns@pobox.com              (preferred)
web:    http://www.pobox.com/~wstearns
snail:  544 Winchester Place
        Colchester VT, 05446, USA


        This code is entirely owned by William Stearns
(wstearns@pobox.com) and has no relation to any employer or employer
sponsored project.

------------------------------ Mason ------------------------------
        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
http://www.pobox.com/~wstearns/mason/ .


- Bill Stearns



	The impatient can find a "Quick Start" section near the end.


Background and motivation:
	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, and generalize the provided rules.  When the firewall is
restarted, voila!  No more incoming NFS. 
	Creating a firewall no longer requires understanding the ipfwadm
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 (www.ora.com or 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
network requires _much_ more than simply filtering packets.  The
aforementioned books provide a great background in general security.


Basic theory of operation:
	Before starting, if the user has some rules that he or she knows
should be used in this machine, the user can implement them.  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 the log messages
in this script.  The script 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:

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.

	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 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.  I prefer the
latter; this allows me to go back later to review the rules and massage
them.  I actually use the "tee" command in the Quick Start section to do
both. 
	If any of this is unclear, take a look at the Quick Start section
which walks you through actually running it.  It'll make more sense when
you see it in action.


Special considerations:
Kernel:
	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: 
ls -al /proc/net/ip_fwchains /proc/net/ip_input
	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 three is true:

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

- Your kernel is missing the proc filesystem.  I honestly don't know if
this is a problem; I've never had a kernel without it!  

- 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 http://sunsite.unc.edu/linux/HOWTO to see how this is done.  In
particular, see the masquerading and kernel HOWTO's.  
	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
the following command: 
/sbin/ipfwadm -a deny -F -S 127.12.2.3/32 -o<Enter>
	The "-o" 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, "buldkernel", which can be found at
http://www.pobox.com/~wstearns/buildkernel/). 


Ipfwadm vs. Ipchains:
	Mason supported only ipfwadm firewalls until version 0.8.0.
Starting with 0.9.0, Mason handles both types.  It will accept logentries
created under either firewall type automatically.  Two environment
variables set which kind of command is displayed and which command is run.
See the XXXXX
	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.
	Make sure you have the ipfwadm or ipchains executable - one or
both should be included with your distribution.



DNS:
	Mason does not try to look up the hostnames of any machines involved 
in DNS requests (unless they're in /etc/hosts).  In some configurations
this could lead to 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.
	The easy way to get machine names into your DNS rules is to make 
sure all your DNS servers are listed in /etc/hosts .


Rule order:
	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).


Generalization:
	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:

/sbin/ipfwadm -i accept -W ppp0 -I -P tcp -S linux.kernel.org/32 ftp -D \
devel1.goober.net/32 1024:65535 # ftp/tcp

	The rule above (along with 4 or 5 other) 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.


Router or end node:
	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 implement them with 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.


Slow machines or fast nics:
	As a shell script, Mason is much less efficient at its work than a
C app would be.  On my 486sx-33, it can take a couple of seconds from the
time the log entry is fed into it until the ipfwadm 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.
	In the step by step instructions below, I suggest turning on
packet logging for input, forward, and output filters at the same time
(see the three almost identical ipfwadm lines below with the "-o" at the
end).  If Mason is having trouble keeping up, you might want to start off
with just one of those lines (say "input" or "-I").  Run Mason for a
little while to build up the input rules.  Then turn on the "forward" 
rules, etc.  If you take this approach, make sure you run the same kinds
of traffic through the system at every step. 


Active hacking while mason running:
	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.


Masquerading:
	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).


Offline and non-root creation:
	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:

cat /var/log/messages | grep ' I=' | mason<Enter>

	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. 


/etc/services and special ports:
	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? 
	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.  See the ssh
section for more info.

	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


(Note: earlier versions of this document had protocol-specific 
information here.  This information has been moved to protocols.txt)


Insert vs. append:
	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 supports 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.


Allow versus deny and reject:
	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).  Mason allows you to change the
policy inserted into the ipfwadm command on the fly without having to stop
and restart Mason. 


Input, Output, and Forwarding:
	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, follow the instructions
below, but only run the logging rule for input ("/sbin/ipfwadm -I -a deny
-o"). If you just want input and forwarding rules, just log input and
forwarded packets.
	You might even take an approach such as allowing unrestricted
access between the hosts on eth0 and eth1 and the firewall itself, but
wanting tight control over what passes in and out of eth2.  Instead of
taking one of the canned logging rules below, make up your own, such as: 

/sbin/ipfwadm -I -W eth2 -a deny -o
/sbin/ipfwadm -O -W eth2 -a deny -o

	Mason will only create rules corresponding to what you're actively
logging, allowing you room to be a firewall artist.

(*) 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. 


Remote firewall creation - Telnet/ssh lockout:
	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? <grrrr>) 
	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...


Ack flag:
	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).

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

	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.  I'm not sure if tcp domain transfers are
ever from port 53 to port 53.  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.


Limitations, Ideas and future enhancements:

- Don't hold your breath for ipfw rules; is there anyone that is actively
creating firewalls based on these?

- group foreign machines into additional rule? (Document how.)

- CL option to use whatever the log entry had.

- Document the living hell of NFS.

Quick start:  

- compile a kernel with firewall and firewall logging enabled, boot into
it.  See above for more info. 

- run the following ONLY IF you want to start with an empty set of rules
(if you simply want to fill in the gaps of your current rule set, do NOT
run the next three commands which erase all existing rules): 
	/sbin/ipfwadm -I -f
	/sbin/ipfwadm -O -f
	/sbin/ipfwadm -F -f

- Set any custom firewall rules you wish.  Here is where you might put in
a masquerading forwarding rule if that is one of the uses of this
firewall. 

- If you have not already put in rules for allowing DNS requests through
your firewall, put them in now.  I offer the following rules as a general
way to allow DNS requests through, but as I mentioned above, these are
almost certainly way too general for security.  Note that these rules
would allow someone from the outside world to make requests of a
nameserver running on your firewall or on your LAN.  A cracker with root
access could actually use the following rules to get to arbitrary services
on your LAN or the firewall.  Please think about what you really want to
accomplish before using these in the final production environment.

	/sbin/ipfwadm -I -i accept -S 0/0 53 -P udp
	/sbin/ipfwadm -I -i accept -D 0/0 53 -P udp
	/sbin/ipfwadm -O -i accept -S 0/0 53 -P udp
	/sbin/ipfwadm -O -i accept -D 0/0 53 -P udp
	/sbin/ipfwadm -F -i accept -S 0/0 53 -P udp
	/sbin/ipfwadm -F -i accept -D 0/0 53 -P udp

#	/sbin/ipfwadm -O -i accept -W ppp0 -P udp -D 0/0 53
#	/sbin/ipfwadm -I -i accept -W ppp0 -P udp -S 0/0 53


- in one window, do
tail --lines=0 -f /var/log/messages | mason | tee -a newrules
	At this point, Mason will be ready to start converting packet log
entries into ipfwadm rules, but will probably sit idle until you tell the
kernel to start logging packets in the next section.

- To actually start logging packets, switch to another window and run:
	/sbin/ipfwadm -I -a deny -o
	/sbin/ipfwadm -F -a deny -o
	/sbin/ipfwadm -O -a deny -o

(see the section "Input, Output, and Forwarding" for examples of how to
get a smaller set of rules or only rules of a certain type). 

	This will start the kernel logging packets into /var/log/messages. 
Since no other rules (except for masquerading and DNS and any other rules
you've already implemented) have been defined, _all_ other packets will be
logged.  See the above documentation if your machine is too slow to keep
up with the initial flood of logged packets;  you may wish to execute
these one at a time, waiting for the load to settle a bit before
implementing the next. 
	When a packet is logged, the corresponding ipfwadm rule will be
simultaneously executed, displayed on the terminal, and appended to
newrules for later editing. 

- To watch the fireworks, do:
	tail -f --lines=0 /var/log/messages newrules
in another window.

- At this point, start making the connections of the type that you'd like
to allow in the production environment.  Mason will spit out the
appropriate rules for the traffic you're creating. 
	Don't forget to make any appropriate connections to and from the
firewall machine itself.  Connections _through_ the firewall are not the
only ones that open up TCP/IP connections. 

- When you've gotten all the rules you want, press Ctrl-C in the window
running mason.  If you're going to be working on these rules for a while
and don't want to fill up your logs with additional messages, you might
want to either delete the logging rules or flush the firewall entirely(*). 
These are done, respectively, with the following commands: 
        /sbin/ipfwadm -I -d deny -o
        /sbin/ipfwadm -F -d deny -o
        /sbin/ipfwadm -O -d deny -o
or(*)
        /sbin/ipfwadm -I -f
        /sbin/ipfwadm -O -f
        /sbin/ipfwadm -F -f

* Probably a poor choice if you already have rules on this machine that
you want to keep there. 

- I find the upcoming editing to be easier if similar rules are placed
next to each other.  Here's how:

cat newrules | sort -t '#' +1 | uniq >>edited_rules

	Strictly speaking, this sorts the rules according to the comments
at the end of the line.  This has the effect of placing similar rules
together as the comments indicate the rule type.  Make sure you run this
after adding any new rules to "newrules". 
	Edit the edited_rules file to generalize and reorder the rules. 
	If this is the complete set of rules for your environment, you
might be able to get away with creating the following wrapper script to
create a full firewall:

---- cut here ---- firewall.run ---- cut here ----
#!/bin/bash
/sbin/ipfwadm -I -f
/sbin/ipfwadm -O -f
/sbin/ipfwadm -F -f
/sbin/ipfwadm -I -p def_policy*
/sbin/ipfwadm -O -p def_policy*
/sbin/ipfwadm -F -p def_policy*

[place any rules you want to appear before the generated rules here. 
These might include the masquerading rule and/or DNS rules]

. ./edited_rules

[place any rules you want to appear after the generated rules here.  These
might include any logging rules]

---- cut here ---- firewall.run ---- cut here ----

* def_policy is either deny, accept or reject, as appropriate for your
firewall. 

	All three of the files should be hidden from public view by
executing: 
chmod 700 firewall.run edited_rules newrules<Enter>
	The firewall can be started automatically at boot time by adding
the following line to /etc/rc.d/rc.local (or the appropriate boot script
for your linux): 

/path/to/firewall.run


Configuring Mason:
	Most of the configuration is set via environment variables.  For
permanent changes, try 
export VARIABLE=value
For one time settings, just put the variables on the command line just
before calling the program.  For example:
tail -f --lines=0 /var/log/messages | ECHOCOMMAND=ipchains mason

ECHCOMMAND=ipchains|ipfwadm|none #Autodetected if unset or invalid
	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.
	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.

DOCOMMAND=ipchains|ipfwadm|none  #Autodetected if unset or invalid
	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.

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.

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.


Version summary:

0.9.0	_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:
L=Total length
S=TOS
I=ip->id?
F=Fragment offset
T=TTL


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

0.7.0	(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.

0.6.0	(6/4/98) Documentation added

0.5.0	(6/2/98) Bare code, almost no documentation, ipfwadm support only.



- Bill Stearns



Advanced scenarios:

	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 should be added here...]



Ordering rules:
	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. 

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

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

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

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

	- Your default policy always comes at the end.



	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. 


Credits:
	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!


