Choosing Firewall Rules

The most critical part of setting up a firewall, and often the most difficult, is determining the Firewall Policy (what to allow and what to block). Firewall rules (to implement your firewall policy) which are too open will reduce the effectiveness of your firewall and rules which are too restrictive will create problems for firewall users and administrators alike. Unfortunately, there is no one-size-fits-all firewall policy--the policy for each firewall depends entirely on:

Without a good understanding of the above, it will be hard to come up with the tightest (and therefore most effective) firewall policy, but there may still be substantial value in less-than-optimum protection as long as exposure of clients to the internet-at-large is significantly reduced.

Ideally, you already know exactly what ports/services you need to export from the firewall's clients and you can restrict your firewall accordingly. Similarly, if you know the firewall's clients need only communicate with a handful of other hosts (or netblocks), you can explicitly list those hosts and/or netblocks (separated by spaces and/or commas) in the "accept only from these addrs" field in the rule-generator webpage.

Unfortunately, the ports needed for some proprietary applications aren't well documented. One or more of the methods below can be used to determine empirically which ports are used by an application:

  1. Starting with your firewall rules overly closed, you can syslog all blocked packets (set this on the rule generator webpage) and then look at what got blocked (run "rejfmt /var/log/syslog").

  2. Starting with your firewall rules overly open, you can list the established connection state (type "state") and see what ports are in use.

  3. Starting with your firewall rules overly open, you can sniff your firewall's traffic with "tcpdump" to see what ports are in use. (Type "man tcpdump" for instructions).

  4. On one of the firewall's clients, type "netstat -a" to see what ports that host is listening on and what connections are established. Presumably, some of these will be ports you'll want to allow and some will not (but this may not show you everything you need).

One simple starting point for firewall policy might be to allow all outbound connections but no inbound ones. To prevent the spread of worms on servers, you might consider blocking outbound connections on all ports you subsequently allow inbound. Remember too that any ports you leave open, which don't benefit you, can potentially benefit hackers and viruses and worms.

Inbound, Outbound and Connected State

Typically communication between computers requires packets be sent (and received) in both directions. From the firewall's perspective, the distinction between "inbound" and "outbound" connections is the direction of the first packet (which begins the exchange). The firewall rules generated by the webform utilize iptables' connected state tracking mechanism so one need only have a specific rule to accept or block the initial packet in an exchange and the remainder (both inbound and outbound) between that pair of hosts and ports can be handled by the catchall rule to accept packets in "connected" state. In essence, the first packet creates a temporary connected state which persists for some number of seconds (sufficient for ICMP, UDP and TCP's initial 3-way handshake. After TCP's 3-way handshake, TCP connected state persists until the connection closes).

Manually Editing Firewall Rules

If you need more control over rules than you can get using the Firewall Rules Generator webpage, you can manually edit rules into the "tables" file (on the firewall) and re-run it. The capability and syntax of these rules is documented in the "iptables" manpage (type "man iptables" for more information). Basically rules can accept or block based on any combination of source and/or destination address and source and/or destination port and protocol and connection state and a few flags. Chances are good that if you choose to manually add rules for exception cases, you will still be able to use the webpage to generate and maintain the core of your firewall rules. (See automatically preserving manual changes).

You'll probably want to use either "vi" or "fte" to edit the "/usr/local/sbin/tables" file on your Gibraltar system. The "fte" editor will probably be more intuitive for people familiar with Windows (ALT-F brings up the "file" menu, etc.). You can also "scp" the file elsewhere, edit it, and "scp" it back again. (But don't edit elsewhere and then use gui-paste to transfer your changed "tables" to the firewall or the mechanism which distinguishes what comes from the rule generator and what you've changed will break and your changes won't be automatically preserved for you). After you edit the "tables" file, you'll just need to type "tables" to run it.

In the rules you write, note that you should refer to firewall clients with their (real/private) 10. IP addresses. Hosts outside the firewall, of course, are specified with their (real/public) IP addresses as well.

If you need to add rules manually, you will probably find the best place to put them is just above the comment introducing the rules which are generated by the webform like this:

# ##########################################################################
# manually added exceptions to web-form-generated rules

# Use "$REJECT" or "$DROP" instead of "$ACCEPT" below to deny connectivity...

# for ftp servers which correctly source ftp data from source port 20...
# allow ftp data connection RELATED to non-passive ftp client control connection
iptables $FWD -p tcp --sport    20 -m state --state RELATED -j $ACCEPT # ftpdata

# for ftp servers which source from random ports, leave out "--sport 20" above

HOST1=10.1.2.3
# allow inbound ftp service on HOST1 from anywhere (no -s addr)
# and all conections inbound to HOST1 related to existing connections
iptables $FWD -p tcp --dport    21 $SYN  -d   $HOST1        -j $ACCEPT # ftp
iptables $FWD -m state --state RELATED   -d   $HOST1        -j $ACCEPT

HOST2=10.1.2.4
# allow inbound ssh and smtp service on HOST2 from anywhere (no -s addr)
iptables $FWD -p tcp --dport    22 $SYN  -d   $HOST2        -j $ACCEPT # ssh
iptables $FWD -p tcp --dport    25 $SYN  -d   $HOST2        -j $ACCEPT # smtp

XHOST=128.2.3.4
# allow all inbound TCP connections from one external host to all clients (no -d addr)
iptables $FWD -p tcp               $SYN  -s   $XHOST        -j $ACCEPT # from XHOST

# deny  all inbound TCP connections from one external host to all clients (no -d addr)
iptables $FWD -p tcp               $SYN  -s   $XHOST        -j $REJECT # from XHOST

# allow all outbound TCP connections to one external host from all clients (no -s addr)
iptables $FWD -p tcp               $SYN  -d   $XHOST        -j $ACCEPT # to

# allow all inbound TCP connections to just HOST2 from XHOST
iptables $FWD -p tcp   -d $HOST2   $SYN  -s   $XHOST        -j $ACCEPT # to HOST2

# below are the firewall rules generated by the web form
# ##########################################################################

You will probably find it best to do as much as possible using the webform and only manually add rules which are either more specific or more general than the main body of rules you're creating with the webform. Typically these would be rules with either source or destination address specified.


Corey Satten
Email -- corey @ u.washington.edu
Web -- http://staff.washington.edu/corey/
Date -- Mon Jan 28 12:26:38 PST 2008