Shorewall Quickstart Guide

Written by Bob Proulx <bob@proulx.com>

License

Copyright (C) 2003, 2004 Bob Proulx

This document is free; 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 document 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 can get a copy of the GNU GPL at at .

The purpose of this document

This document was written because when I first installed Shorewall I spent a couple of clueless hours reading all of the details in the documentation before any understanding finally came to me. Out of the 40+ files installed and 25+ configuration files in /etc/shorewall you typically only need to edit three or four of them. But which ones? How did things work? I did not even know where to start. I imagine this must have happened many times to people, I can't be the only clueless one out there, can I? But of course once you know the configuration you no longer need the guide and so one is never written. I wanted to change that.

The purpose of this quickstart guide is to lead you through the setup for the most basic of configurations. Even if you are building a more complex multiported router with NAT and DMZ and other features you should start with a small standalone configuration. In astronomy I learned that it is easier in total to grind a 4 inch lens first and then grind a 6 inch lens using what you learned from grinding the smaller lens than to start out trying to grind a 6 inch lens as a first attempt. The same truth applies to firewalls. Start small and work up from there.

The Debian Shorewall package does not include any configuration by default. You must edit the text files and specify your configuration. The files all have copius documentation in them which you are encouraged to read. But you can hopefully just insert these lines specified here into your files in the places indicated by the comments there and that will be sufficient.

Shorewall includes a feature that allows you to test a trial configuration and revert to the previous configuration if the trial one does not work out. That provides a small amount of safety in the case that you make a mistake. This is a good feature. But until you have a previous configuration to fall back to this does not work. So initially I just describe the configuration in the live and final locations. But do become familiar with the 'shorewall try DIR TIMEOUT' feature because it is very useful. Couple this with 'screen' and you will improve your chances considerably of recovery from a bad configuration.

Are you on the system console or at least have quick access to the system console? If the firewall is misconfigured it WILL LOCK OUT ALL REMOTE CONNECTIONS! I cannot stress this enough. You must have physical access to the system console or you may find yourself firewalled out of the system and unable to recover. Do not complain that the firewall locked you out of the system. YOU HAVE BEEN WARNED!

Let's assume a typical simple standalone configuration. One network connection to the Evil Internet. Your first and only network interface is typically "eth0". This will connect to the 'net'.

Edit the /etc/shorewall/zones file and install a 'net' zone. This definition may already exist in the file by default. This file defines zones which will be used throughout the rest of the configuration. The four typical zones are 'fw' or the firewall host itself (predefined for you so you never define it), 'net' usually indicating the WAN or Internet, 'loc' usually indicating a NAT'd private network behind the firewall and 'dmz' usually indicating an inbound suspect network. For the simple standalone configuration we only need 'net' defined so just define that one zone for the moment.

Edit /etc/shorewall/zones and specify your zones.

#ZONE   DISPLAY         COMMENTS
net     Net             Internet
You have a firewall to keep the blackhats out. But sometimes the attacks come from viruses and other automated systems which can overwhelm your logging. Your /var/log partition could easily become filled up with logs of dropped packets by a virulent round of MS SQLslammer or another worm. You will undoubtedly want to avoid logging some of the really common MS viruses. After a day on the Internet audit your logs and determine what the current weather is on the net and update this file with the current strains of virus which are running rampant on MS machines at the moment. Remember, this is one of the reasons you are installing a firewall.

Edit /etc/shorewall/blacklist and add these as a start.

0.0.0.0/0               tcp             1433  # MS SQL SQLslammer
0.0.0.0/0               udp             1434  # MS SQL SQLslammer
0.0.0.0/0               tcp             6129  # Dameware Remote Admin
0.0.0.0/0               tcp             17300 # W32/Spybot.worm.gen

Edit the /etc/shorewall/interfaces file and specify what network interfaces these zones we just defined will be using. Also how those interfaces are configured. The 'dhcp' option is typical for a dhcp setup. If you have a static address then leave that out of the options. Using the dhcp option even on a static IP is safe, however, just less efficient. The blacklist option refers to the blacklist file listed above and will drop all of the blacklisted services.

Edit /etc/shorewall/interfaces and specify your network interfaces.

#ZONE    INTERFACE      BROADCAST       OPTIONS
net      eth0           detect          dhcp,blacklist

Edit the /etc/shorewall/policy file and specify your default policies for connections in and out of your firwall. If this is a standalone host which will need to access the internet, typical for a single desktop on a cable modem or DSL modem, then you will want to make the default policy ACCEPT for all connections from the firewall ('fw') to the internet ('net') and log and DROP for all connections from the internet ('net') to anywhere else ('all').

Edit /etc/shorewall/policy and specify your default policies.

#SOURCE         DEST            POLICY          LOG             LIMIT:BURST
fw              net             ACCEPT
net             all             DROP            info
all             all             REJECT          info

Edit the /etc/shorewall/rules file and specify what network connections you will allow into your firewall (desktop?). If you are a pure client then you will NOT need to add anything to this file. But if you are wishing to offer publicly accessible services such as SSH or HTTP or SMTP then add them to this file. Again, if you are not offering any inbound services then DO NOT put anything in this file. Remember that every inbound service is a potential security crack. You must keep all servers accepting inbound connections up to date with all security updates.

Edit /etc/shorewall/rules and specify your allowed connections.

#ACTION  SOURCE         DEST            PROTO   DEST
ACCEPT   net            fw              tcp     ssh
ACCEPT   net            fw              tcp     smtp
ACCEPT   net            fw              tcp     http
ACCEPT   net            fw              tcp     https

If you desire to allow ping and traceroute then you will need to add a ACCEPT line for each of those. Be aware that the upstream policies for those have changed from release to release. Double check that this is still required in case this documentation is out of date.

ACCEPT   net            fw              icmp    echo-request
ACCEPT   net            fw              icmp    time-exceeded

By default the Linux kernel logs all kernel messages to the console. This can be set by the system administrator to whatever logging level is desired. Some systems such as Debian do not override the kernel default. Other systems such as Red Hat set this to a lower value than the kernel default. Red Hat systems set this in the rc.sysinit script to the value of LOGLEVEL specified in /etc/syscontrol/init, usually 3. So out of the box Red Hat logs to the console at a much lower level than the linux kernel default. If you are not running on Red Hat, such as on Debian, you may see a lot more console messages logged. On the Evil Internet with logging of dropped and rejected packets this will make the text console virtually unusable. Use the 'dmesg -n6' command to set the logging level to avoid KERN_INFO messages from the firewall. You may desire to set it quieter such as 'dmesg -n3'. I am currently using 'dmesg -n5'. Regardless this does not affect logging to the files in /var/log and all messages will still be available in /var/log/syslog. See the footnotes below for more details on this.

Edit /etc/shorewall/init and add 'dmesg -n6' or lower.

dmesg -n5

The firewall is now configured. Now it is time to test it. Are you on the console? If the firewall is misconfigured it WILL LOCK OUT ALL REMOTE CONNECTIONS! I cannot stress this enough. You must have physical access to the system console or you may find yourself firewalled out of the system and unable to recover. YOU HAVE BEEN WARNED! (The 'shorewall try DIR TIMEOUT' feature can help here. But it is more complex so I included it as a footnote.)

Test it using 'shorewall check' then 'shorewall start' or 'shorewall restart'. It is always safe to 'restart' it so I will be lazy and always 'restart' it instead of using 'start' the first time and 'restart' afterward.

shorewall check
shorewall restart

Is your firewall functional? Test normal activities. Are the right things allowed and the wrong things blocked? At this time you should have a functional standalone firewall.

I highly recommend the 'nmap' utility to port scan your host. See the nmap documentation for more details. If you have a second host on the network that can port scan your host then doing so will be a useful and responsible test of your security. But be careful. Many people see port scanning as an admission of being a cracker instead of as a tool in the security toolbox. Make sure you have permission to make the scans you are making. Your ISP may be looking for scans and may block the participating hosts. A responsible ISP will be able to help you with your testing.

Now that the firewall is configured AND TESTED you will need to enable it for automatic start at system boot time. The default is not to run at system boot time as a protection against someone installing but not configuring Shorewall.

Edit /etc/default/shorewall and set startup to 1.

startup=1

You are done!

Setting up NAT/Masquerading

A very common configuration is a two NIC system where the first interface is on the Internet and the second is on a private local network behind the firewall. NAT, also known as masquerading, is used on the firewall between the two interfaces.

This section builds upon the above standalone configuration and configures a dual NIC system for NAT/masquerading a private network. This builds upon the previous section and as you will see the changes are very small. So there will be very little explanation.

Don't start here. Start with the first section and walk through it to set up a standalone system. Do that first. Then after you are comfortable with Shorewall's operation you can reconfigure as a NAT system.

This does not cover one-to-one NAT or DNAT or any of the more complex configurations. This section only covers the very common case where you have a private network behind your firewall which uses NAT to access the Internet.

Edit the /etc/shorewall/zones file and add a 'loc' zone for your local private network. This definition may already exist in the file by default.

Edit /etc/shorewall/zones and specify your zones.

net     Net             Internet
loc     Local           Local networks

Edit the /etc/shorewall/interfaces file and add the interface hosting the 'loc' zone.

Edit /etc/shorewall/interfaces and specify your network interfaces.

#ZONE    INTERFACE      BROADCAST       OPTIONS
net      eth0           detect          dhcp
loc      eth1           detect

Edit the /etc/shorewall/policy file and specify your default policies for the local network. Typically you will want to allow all outgoing traffic originating from your local private network.

Edit /etc/shorewall/policy and specify your default policies.

#SOURCE         DEST            POLICY          LOG             LIMIT:BURST
fw              net             ACCEPT
loc             net             ACCEPT
net             all             DROP            info
all             all             REJECT          info

No changes to your /etc/shorewall/rules file is needed. The default policy of ACCEPT above allows all outgoing traffic from your network.

Edit the /etc/shorewall/masq file and specify which interfaces will be doing masquerading. The first column specifies the outgoing interface. This will be your WAN interface to the Internet. The second is the interface which is masqueraded. This will be your LAN interface to your private local network.

Edit /etc/shorewall/masq and specify that your LAN interface will be masqueraded through your WAN interface.

#INTERFACE              SUBNET          ADDRESS
eth0                    eth1

Edit the /etc/shorewall/init file and enable forwarding.

# Enable IP forwarding in the linux kernel.
echo 1 > /proc/sys/net/ipv4/ip_forward

Edit the /etc/shorewall/routestopped file and specify any networks which you want accessible when your firewall is stopped. When your firewall is operating traffic will be forwarded between the interfaces. If you bring your firewall down 'shorewall stop' you definitely want to block all WAN packets. But you probably want to continue to allow connectivity between your local private network and your firewall.

Edit /etc/shorewall/routestopped file and specify any routes to keep up when your firewall is stopped.

#INTERFACE      HOST(S)
eth1

Test your configuration using 'shorewall check' then 'shorewall start' or 'shorewall restart'.

shorewall check
shorewall restart

You are done!

Footnotes

I am using Debian GNU/Linux but except for a very few places this guide is generic to any GNU/Linux distribution. This document was written for shorewall-1.4.8 but an attempt was made to keep it fairly neutral of feature changes between versions. I am using the latest shorewall available at the momement. Since it is script based it is not track specific and the 'unstable' version can be installed on a stable machine without need for newer libraries. However it does require a recent version of iproute. I pulled iproute from www.backports.org for use on woody and I recommend that you do the same if you are running 'stable'.

  deb http://www.backports.org/debian stable iptables shorewall

If you are here you have already installed Shorewall. But you may not know that the documentation is in a separate Debian package in order to keep the size of the core small. If you wish to install both shorewall and its documentation package then the following will install both.

apt-get update && apt-get install shorewall shorewall-doc

The man page for dmesg currently available to me only poorly documents the -nNUMBER option. Looking at the source I see that it calls the klogctl() routine. Searching for that I was able to find a klogctl.3 man page on the net. Reproducing that snippet here.

The following is taken from

http://www.die.net/doc/linux/man/man3/klogctl.3.html

The loglevel

The kernel routine printk() will only print a message on the
console, if it has a loglevel less than the value of the variable
console_loglevel (initially DEFAULT_CONSOLE_LOGLEVEL (7), but set
to 10 if the kernel commandline contains the word `debug', and to
15 in case of a kernel fault - the 10 and 15 are just silly, and
equivalent to 8). This variable is set (to a value in the range
1-8) by the call syslog (8,dummy,value). The calls syslog
(type,dummy,idummy) with type equal to 6 or 7, set it to 1 (kernel
panics only) or 7 (all except debugging messages), respectively.

Every text line in a message has its own loglevel. This level is
DEFAULT_MESSAGE_LOGLEVEL - 1 (6) unless the line starts with 
where d is a digit in the range 1-7, in which case the level is
d. The conventional meaning of the loglevel is defined in
 as follows:

#define KERN_EMERG   "<0>" /* system is unusable                    */
#define KERN_ALERT   "<1>" /* action must be taken immediately      */
#define KERN_CRIT    "<2>" /* critical conditions                   */
#define KERN_ERR     "<3>" /* error conditions                      */
#define KERN_WARNING "<4>" /* warning conditions                    */
#define KERN_NOTICE  "<5>" /* normal but significant condition      */
#define KERN_INFO    "<6>" /* informational                         */
#define KERN_DEBUG   "<7>" /* debug-level messages                  */

Therefore to avoid logging of firewall messages from the kernel you need to set it to 6 or lower.

On Red Hat systems /etc/sysconfig/init sets this to LOGLEVEL=1 and the console there will not display any messages excepts kernel panics. On newer Red Hat systems (RH7.3) LOGLEVEL was changed to 3 and at least displays critical kernel messages. The value of LOGLEVEL is used as 'dmesg -n$LOGLEVEL' in rc.sysinit which is called by init as specified in /etc/inittab.

On Debian the kernel console logging level is not set and linux kernel default is used. You may override the kernel default and set it by any method you prefer. Since the firewall is often the only reason to change this putting this in the Shorewall 'init' script is reasonable. The shorewall author's site recommends the 'start' script. But 'start' runs after the firewall is started and so there is still a window of time when messages may be written to the console. But 'init' runs before the firewall is active and prevents that race condition.