Building A Linux Firewall With iptables
For a newcomer to Linux, building a good firewall script is not an easy task. There are GUI tools out there that can help you design your firewall in a point-and-click fashion but the common newbie distros do not usually install them by default. Also, a lot of new Linux users are eager to display their newly learned skills and tend to plunge forward developing scripts that can sometimes open serious security holes in their systems.
Before you start designing your Linux firewall you need to determine whether or not you are building a firewall to protect a single computer or your entire network. You also need to decide if anyone out on the Internet will need to connect to your computer or network. You should also think about if you want to block access to certain services on the Internet. You might want to block outgoing traffic bound for certain peer-to-peer file sharing services or maybe the Windows file sharing services. Researching all of this can take a good deal of time, especially if you are new to Linux and are unfamiliar with using the command line and iptables. When beginning your research you probably want to start with a visit to the iptables home page and also take some time to read the Linux Network Administrator's Guide at the Linux Documentation Project.
After you finish your research you will probably want to start writing your ruleset. A beginner who wants to protect a single computer might end up with something like the following after some research at the sites mentioned above:
iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP
iptables --append INPUT -i lo -j ACCEPT
iptables --append OUTPUT -o lo -j ACCEPT
iptables --append INPUT -m state --state \
ESTABLISHED,RELATED -j ACCEPT
iptables --append OUTPUT -m state --state \
NEW,ESTABLISHED,RELATED -j ACCEPT
The above code is a simple yet effective firewall. You could use this simple code listing as the base for a more complex firewall or just copy the code and save it into a script to be launched on startup. Now let's step through the script line by line.
The first line is obvious, the ubiquitous "hash bang" that tells the shell which interpreter to use when running the script. The next line flushes out any iptables rules that might already be loaded. Please note that this only flushes the rules in the filter table. There might be more advanced rules in the mangle and nat tables that will not be cleared using this rule. Most distros do not load any iptables rules by default so you probably do not have to worry about these other tables right now.
The next three lines set the default filter policies. These three rules tell the kernel that it should drop any packets that are inbound, outbound or being forwarded. This is known as a "deny-by-default" configuration and if you stopped adding rules at this point you would not be able to access the Internet or any other computers on your network. You could also set your default policies to
REJECT. If they were set to
ACCEPT then your firewall would accept everything by default. Setting the policies to
REJECT is similar to
DENY but the kernel sends a response to the that sent the packet rather than silently dropping them. By setting your firewall to deny by default you are operating in what could be called "stealth" mode. If someone were to scan your computer from the Internet it would appear as though there is no computer there at all.
Lines five and six allow traffic to flow freely to and from the loopback interface that all computers have. Certain services can break if loopback traffic is blocked and if you are running a service such as tor you will have problems.
The final two lines of the script are probably the most important, and most advanced. You will notice that no interface is specified. These rules apply to all interfaces on your computer including ethernet cards, wireless adapters or dial-up adapters.
These rules introduce the stateful inspection feature of iptables. For instance, when you try connecting to a web site the first packet sent to establish the connection to the server is sent in the NEW state. Once the connection is made further packets are marked as
ESTABLISHED. Certain protocols such as ftp and dcc often used on irc are a bit trickier and communicate using more than one port. As a result when using these protocols certain packets are marked as
RELATED to another already established connection.
You will notice that the last two lines are very similar with one subtle difference. The
OUTPUT rule allows for
NEW connections as well as
RELATED connection states. This allows you to access services on the Internet while the
INPUT rule preceeding it only allows the necessary return traffic. This means someone trying to portscan or ping you from the Internet will get no response but you can still surf the web or send e-mail.
Now that you have a firewall script how do you go about launching it when you boot your computer? First, save the above script to a file such as
firewall.sh and make the script executable. Since iptables can only be run as root you will need to launch the script as root. On Ubuntu you can do this using sudo:
You can view your newly loaded iptables rules using:
Now that you have your firewall loaded you can use the init script that came with your distro to save your rules and configure it to launch them on startup.
update-rc.d add iptables defaults
Now you are all set. The next time you reboot your computer your firewall will load for you automatically.
The above example is only a small part of what can be accomplished with iptables. With a little more time and effort the above script can be turned into a more complex firewall that can protect an entire network and allow access to services on the network. You could also experiment with some of the newer extensions available. The important thing to keep in mind is to work from simple to complex. By doing this you will avoid mistakes and develop a more thorough understanding of how the software works.