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 <Enter> /sbin/ipchains -A forward -s 127.12.2.3/32 -l <Enter> /sbin/iptables -A FORWARD -s 127.12.2.3/32 -j LOG<Enter> </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 <Enter> </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? <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... <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>