Firewall (iptables) configuration on Glued Linux


Using/Configuring a Firewall with Glued Linux

The standard glued linux setup has a firewall but leaves it set wide open. This document describes how to set up and use a firewall on glued linux. It is hoped that some of the scripts will be adopted into the standard glued linux distribution so that set up becomes trivial.

The firewall configuration described to prevent unwanted access to your machine at an early stage. Although the pre-cursors of this have been used successfully in Physics for several years now, including in some atypical scenarios, the above philosophy has been the motivating factor. There is no facility in this firewall configuration to block outgoing traffic, and forwarding of packets is simply denied in all cases. These scenarios did not arise in Physics, and we have little experience with such. However, you should be able to customize for some or all of this if desired, but if so you are going beyond my experiences.

Even if you stay within the blocking unwanted access realm, this configuration is currently beta. Hopefully, it will become standard glue when beta testing is done. But you are also warned that a misconfigured firewall can cause a lot of confusing problems, and some may take a while to be uncovered. So show care when customizing.

Overview

The basis of the firewall setup is the iptables firewall currently used in linux. The assorted files to be added to glue attempt to make the exact firewalling software modular, but only iptables is currently supported.

Iptables has the nice feature that is can operate in a stateful mode. This means it remembers a bit about the history of the network traffic. In particular, we make use of this to have the firewall allow any network traffic from another machine that is in response to something our machine sent out. This allows a few simple firewall rules to essentially shut down all ports to incoming traffic, but still let the web connection I made to www.somewebpage.com to go through, or to allow me to ssh or telnet to various hosts. Basically, an user on glued linux box with this firewall configuration can connect to anyplace he wants with whatever protocol he wants, and the traffic will be allowed to flow both ways. (Note: this is really only true if the protocol is either known to iptables or does not do wierd things in terms of switching ports. But it seems to work reasonably well.)

The other side of the firewall is to allow connections for those services we wish to offer. This configuration makes use of the fact that most services in Glue are controlled by the hostinfo variables, so we punch holes based on which services hostinfo says should be running. Generally, the holes are open to the entire internet, but in some cases for services which are believed to only be legitimately used locally, the hole might only be open to campus or the subnet the machine is on. This can be overridden in rc.machine if necessary.

The is room for special customization in the rc.machine file as well, so the firewall configuration has shown to be fairly flexible in our experiences.

Installation and Setting Up

Hesiod Configuration

In keeping with the general Glue philosophy, the firewall is controlled by hostinfo variables set in the hesiod configuration tree. There are three main variables controlling the firewall and its setup at this time:

Usually, one only needs define the hostinfo variable FIREWALL to iptables. If you do not want any firewall (e.g. a wide open firewall, or you have a custom kernel without firewalling), define FIREWALL to NONE. Other values are not defined, and this just provides a mechanism to allow for a choice of firewalls if other alternatives become available in the future.

The IPTABLES_MIN_CONFIG and IPTABLES_CONFIG are specific to the iptables firewall, and are just hooks in case extreme customization is needed. They have not been needed in Physics, and have been only minimally tested. Be aware of the fact that the file referred to be IPTABLES_MIN_CONFIG must be local to the system, as the script that invokes it is generally called before networking is up.

NOTE: In a typical setup, the firewall is configured before the network interfaces are brought up, so that the firewall protects the system as soon as the interfaces are up. Because Glue systems use hostinfo variables through hesiod to determine which services will be running, we split the firewall configuration into two parts: an initial minimal configuration which is generally quite restrictive but will allow us to do what is necessary to be part of Glue (and in particular to update the hostinfo variables via hesiod), and the full-fledged configuration that is based on hostinfo variables. The initial, minimal configuration of the firewall will generally occur before the hostinfo variables are updated via hesiod, and so will typically be using stale values. However, since this initial configuration is dependent only on the FIREWALL, and in rare cases IPTABLES_MIN_CONFIG hostinfo variables, and it is expected that these should change very rarely, this should normally not be a problem. Especially as a change in the actual firewall being run often requires a kernel modification.

However, if you plan to change the FIREWALL variable, you should update the hostinfo variables on disk before the reboot (and after your changes have propagated through hesiod). You can do this with the command /etc/glue/init.d/hostconfig start at some point before rebooting and after the hostinfo changes have propagated through hesiod.

Run /etc/glue/init.d/hostconfig start before rebooting after any changes to FIREWALL have propagated through hesiod.

Description of start up when part of standard Glue distro

This section describes how the firewall would get started as part of the standard Glue distribution. The files are not currently installed, but hopefully will be once beta testing is finished.

The first step is when S08firewall is called in the rc.d initialization directory for run levels 2, 3, and 5. This is just before the network interfaces are brought up, so that any firewall protection is active from the very beginning. (This would replace the standard S08ipchains or S08iptables init.d script.) This script checks the copy of hostinfo on the disk (which is stale, most likely from the previous boot, because without a network interface we cannot get the current one). It will then start up whatever firewall is requested (or none if none requested). Currently only iptables (and no firewall) are supported.

In the case of NO firewall, the firewall script in init.d just exits. This should leave the firewall in the kernel in a wide open position.

In the case the variable FIREWALL is iptables, the command /etc/init.d/iptables start is run, and then either the script pointed to by IPTABLES_MIN_CONFIG (if it is defined and exists) or /etc/glue/config/config_iptables_minimal is called. In the former case, it is recommended that config_iptables_minimal be called from the user defined script, or that it otherwise makes sure that the standard chains are created.

config_iptables_minimal first deletes anything in the iptables rules, and then builds the basic structure of the r ulesets. This includes setting the policies on the default chains, creating the Glue standard chains existing-connections, glue-required, glue-optional, and machine-optional. These are then linked into the standard INPUT chain, and the chains existing-connections and glue-required are populated. The other two are left empty, as their contents depends on hostinfo variables, and we want to wait until fresh values are available.

The next step in the process is to fill in the glue-optional chain. This step is delayed until after the hostinfo variables are refreshed from the hesiod database, but preferably should occur before any network services are started (not absolutely required, but any services started before this are not really up because not visible from other machines on the network). Typically this would be done in S40setup (NOTE: current glue rc5.d has the setup script at 57, after the inetsvc script at 50. Probably need to push back hostconfig and setup to before 50?).

The S480setup init.d script should check the hostinfo variable IPTABLES_CONFIG, and if defined and pointing to a valid script, execute that script. Otherwise, it should execute /etc/glue/config/config_iptables. This script should open up all the the ports needed to access servers started up in the standard Glue init.d sequence, i. e. those servers started up based on hostinfo variables.

The final step is /etc/rc.machine. This script can do any additional customization of the firewall needed (and indeed, all customizations needed by physics in past couple of years were able to be done here, without needing custom IPTABLES_MIN_CONFIG or IPTABLES_CONFIG scripts). If necessary, you can delete firewall rules defined earlier from here. But more commonly, you will add holes for any additional services started. Since these services are typically started in this file, it is quite natural. E. g., if your linux box is to be a foo server, just before the line in /etc/rc.machine that starts up the foo daemon, just punch holes for the ports that it will be accessed by in the firewall.

Installation notes for beta testers, etc.

At this point in time, the firewalling stuff is not part of the standard Glue linux distribution. It is currently undergoing beta testing (and hopefully will be part of the standard distribution after successful beta testing). If you wish to beta test, or otherwise want to use it before it is part of the standard package, here's where we tell you how.

The first step is to set the FIREWALL hostinfo variable, and wait until it propagates through hesiod and your local hostinfo scripts are current. (Or if you are impatient, just hand edit it into /etc/glue/hostinfo/hostinfo.sh, only the Bourne shell version is used for firewalling currently).

Next, you need to run the following two scripts, in order:

  1. /dept/phys/software/linux/OIT-linux/firewall/glue-config/config_iptables_minimal
  2. /dept/phys/software/linux/OIT-linux/firewall/glue-config/config_iptables
I normally put this into /etc/rc.machine for my machine, though it is safest to run them manually first, and hold off on entering into rc.machine until satisfied nothing is broken (this way a reboot will set things straight).

If you need to turn firewalling off (i.e., make the firewall wide open), the commands iptables -P INPUT ACCEPT followed by iptables -F should do it.

Note that if the machine is running any services that are not part of the standard Glue set (i. e. are not controlled by hostinfo variables and started in standard init.d files), they are almost certainly not going to work after the firewall is turned on. You will need to punch holes for these explicitly. See the section on customization.

Hopefully standard Glue services (controlled by hostinfo variables and started in standard init.d files) will continue to work.

The firewall should allow for your machine to access almost any service as a client; as long as your machine initiates the conversation with the remote host, and nothing too funky is going on with changing the ports it should just work.

Starting the firewall this way means that the network interface is up for a little while before the firewall is tightened down. That is why becoming part of the standard init.d process is desired. But late is better than never.

Overview of the Chains

This section discusses the innards of the firewall ruleset. You probably want to at least skim it before making any customizations.

Built into iptables are three standard chains:

Because this firewall configuration is intended to keep unwanted traffic out, it really only deals with the INPUT chain. The OUTPUT chain is left wide open, so nothing is blocking traffic leaving this machine. The FORWARD chain is left tightly closed because unless we really know what we are doing we probably should not be routing.

We create four Glue-defined chains, and have the INPUT chain call them one by one. If a rule in any of these chains accepts a packet, it is allowed in, otherwise go to the next rule, then the next chain, etc. When we run out of rules and chains, the packet gets dropped.

The configuration takes the policy to simply drop unaccepted packets, that is act like it never happened. This is the most secure option, because a potential hacker would have no idea from that whether or not there is even a machine there. This likely can also be quite confusing to a legitimate sysadmin who tries something and gets no response back. I tried using somewhat more sysadmin friendly actions instead of simply dropping the packet (like returning some sort of ICMP host unreachable packet), but I am not entirely sure what response makes the most sense, and some of these odd ICMP responses confuse scanning software generating as much if not more sysadmin confusion. If you really want to get a different response, just add a rule to the end of INPUT that rejects the packet in the desired manner.

The four Glue-defined chains are, in order of calling:

  1. existing-connections
  2. glue-required
  3. glue-optional
  4. machine-optional

existing-connections is the chain that is responsible for accepting the remote half of any conversations you initiated. It accepts any packet received on the loopback interface (very nasty things happen if you prevent the system from talking to itself), and also makes use of the statefulness of iptables to accept ESTABLISHED or RELATED packets on all interfaces. ESTABLISHED connections are those that have seen packets in both directions. This means if your machine starts a conversation with machine B (e. g. makes a http request), and machine B replies (e. g. sends a web page back), it is allowed. RELATED is for some protocols like ftp wherein the server starts a new connection back to the client. Iptables knows about the more common of those sort of oddities, and can handle it. Stateful firewalls are nice. This chain is set up in config_iptables_minimal

glue-required is the chain that makes sure there are enough holes in the firewall for your box to function as a Glue machine. The absolute minimum needed for functioning; the sort of thing that if you block this, what's the point of being in Glue. It opens up the ports needed for:

The stuff no Glue machine can do without. This chain is set up in config_iptables_minimal.

glue-optional is the chain that pokes holes in the firewall for any standard Glue services that might be running on the box. By standard Glue service, I mean a service which is started/controlled according to hostinfo variables, and is started in standard Glue init.d scripts. Because the presence of the service on a particular machine depends on hostinfo variables, we use the same variables to poke holes for the service. This chain is created as empty in config_iptables_minimal, and filled in config_iptables. The delay in filling is that it depends on a lot of hostinfo variables, and we want to make sure we are using fresh values. As the name implies, the stuff in here is optional, in that someone, somewhere might want a system without any one item. Also included in here are a few other optional holes not associated with a service, like whether or not the machine should respond to pings.

machine-optional is created as empty in config_iptables_minimal, and nothing is put into it in general. It exists for per machine customizations of the firewall, typically from rc.machine script. E. g., if your machine should be running a foo server on port 666, just before you start the foo server in rc.machine you should poke a hole in the firewall for it. This is discussed in more detail in the next section.

Customizing the firewall rules

Naturally, for certain machines the standard configuration will not suffice. The initialization scripts provide plenty of places for customization to occur:

  1. By replacing the default config_iptables_minimal script. This is done by defining the hostinfo variable IPTABLES_MIN_CONFIG to point to a replacement script. Remember, it may take a second reboot to take effect because the hostinfo variables used at that point of the boot process are stale. Also, the named script must be on a local filesystem because networking is not yet up. It is advised that your script call the standard config_iptables_minimal script and then modify the rules as needed.
  2. By replacing the main config_iptables script. This is done if the hostinfo variable IPTABLES_CONFIG is defined and points to a script. You may wish to call the standard version within your version in this case as well.
  3. By adding rules to the chain machine-optional in your rc.machine script. This is the preferred way, and is actually fairly nice because most services for which additional firewall rules would be needed would started up there anyhow.

Method 3 is the preferred way, and despite having some rather non-standard configurations, all customization for Physics in the past couple of years has been done in /etc/rc.machine.

The difficult step in customizing is to figure out what ports need to have holes punched in the firewall. If you know the protocol, that is usually fairly straight forward. In other cases, you may need run a packet sniffer while the protocol is going on to see where things are being blocked. If you run into difficulties in determining whether the firewall is blocking things or the daemon is just not working, you can issue the command /sbin/iptables -F which will clear all the firewall rules (leaving you completely exposed, but that can be useful for testing a new service). The firewall rules can be re-enabled by rebooting or running the configuration scripts /etc/glue/config/config_iptables_minimal and /etc/glue/config/config_iptables. (NOTE: these expect to be run in a Bourne shell, so you may need to run as sh script.

When adding rules in your /etc/rc.machine script, you may find it helpful to source /etc/glue/config/iptable_utilities.sh. These have some helpful routines for enabling a service to the world, just to campus, just to your subnet, or just to a few specified hosts. These are described in more detail in an appendix.

use


Main Physics Dept site Main UMD site


Valid HTML 4.01! Valid CSS!