headerimage
david-halliday.co.uk

firewall & iptables notes

Introduction

A quick warning (& disclaimer): This is my own notes on what I have done, I'm not finished yet! so there may well be gaps in my security. While for obvious reasons I am aiming to have good security I would recommend anyone looking at this to check with other sources as I may have something wrong... If I do have something wrong pop a note to me on my contact page.

After working with Linux for some time and saying on my personal website that due to the nature of my setup (for the rockhopper project) I was less interested in security I have decided to delve into the world of security after setting up a Debian box at home with a collection of services available to the outside world including:

  • ftp
  • http
  • ssh

Since I have open stuff on my machine I figured that I had better look into security more. The box is primarily protected by a ADSL modem which doubles as a router, NAT box and firewall. This box has a good firewall and has only got the required ports open and set to forward onto my Debian server box. So I am already well protected so this is an exercise in education primarily. 

My aim

This is important to point out as I am demonstrating a specific scenario rather than a full "how to". If your situation is different then you can use this as a guide but will need to look at the other links from here to make sure that you have included everything you need.

As previously stated my box is fairly well protected. I want to achieve the following goals in my strengthening of security:

  1. Only allow requests on the ports/services that I want people to access:
    • SSH
    • FTP
    • HTTP
    • SAMBA
  2. Block all other incoming traffic to keep secure.
  3. Allow the box full access to the outside world for updates and users on the system.
  4. Anything else I can think of that needs doing.

Further reading & resources

Now I have explained my situation I will provide links to other things that are probably of more (or at least good for comparison and further reading) help for now:

firestarter
This is a firewall GUI application which makes rules for iptables automatically. In most cases it is a first step and does most of the hard work for you. 
iptables man page
While you can type in at a command line:
man iptables
it is often easier to read something online.
Linux iptables HOWTO
A short guide that I have used in my research. It explains all the background, how things work and why. Section 6 actually explains the commands.
Quick HOWTO : Ch14 : Linux Firewalls Using iptables
A full guide with lots of examples. Handy for lots of common scenarios.

Basic rule & command layout

I will quickly cover the rules and layout of the commands here. More can be found in the man page and the above links. To start with all commands will use the same application/command at the prompt:

iptables

This command takes a wide variety of arguments which build on each other. For a full list of initial commands have a look at the commands section of the man page I will copy the main ones here for reference (below is stolen from the man page):

-L, --list
List all rules in the selected chain. If no chain is selected, all chains are listed. It is legal to specify the -Z (zero) option as well, in which case the chain(s) will be atomically listed and zeroed. The exact output is effected by the other arguments given.
-A, --append
Append one or more rules to the end of the selected chain. When the source and/or destination names resolve to more than one address, a rule will be added for each possible address combination.
-I, --insert
Similar to -A except rule is inserted at the top of the list.
-D, --delete
Delete one or more rules from the selected chain. There are two versions of this command: the rule can be specified as a number in the chain (starting at 1 for the first rule) or a rule to match.

The list command can be issued on its own like below. This is usefull for seeing where you are in your configuration and what is happening on your box:

iptables -L

Both the append and delete commands require arguments. and a further understanding of iptables. Here is more detail on the command.

Firs a quick look at the synopsis of the command, this is listed in full on the man page.

iptables -[ADC] chain rule-specification [options] 

Lets break this down a little:

iptables
this is the basic command. Does what it says on the tin.
-[ADC]
The three different options it must be given one of. For now we are only interested in "-A" Add/Append and "-D" Delete.
chain
This is the "chain" or group of rules you are adding the rule to. There are three different Chains (groups):
input: these are connections coming into the computer.
output: Commands going out of the system, to restrict your users.
forward: If you want the system to ignore packets and pass them on to another system.
rule-specification
These are the details of the rule you are working with. The full list of parameters you can use are also documented in the parameters section of the man page. You can use as many or as few as you like to make a rule more or less specific.
[options]
This is another "does what it says on the tin" section of the command. In some ways this appears to merge with the rule-specification parts. The most common option is the -j (jump) which is used often to decide what to do with a packet.

The next step is to think about what we want to do with a packet that comes in. Do we want to allow, deny or forward it? This is done with one of the options the -j (jump) parameter. For now we will only worry about 2 alternatives:

accept
allow the packet to pass to its destination.
drop
drop the packet as if there isn't a computer system at the target location (good for if you don't want someone having access to a computer or port. They will get the idea that there is no computer there).

An example

Now I have covered the command syntax it is time for an example. Here is the command to accept incoming connections to port 80 (the HTTP/www server):

iptables -A INPUT -j ACCEPT -p tcp --destination-port www

You can restrict the IP range that can access your machine with the "-s" option. So to restrict access to systems on my lan I can make the command as below:

iptables -A INPUT -j ACCEPT -p tcp -s 192.168.1.0/24 --destination-port www 

This command appends (-A) a rule to the input (INPUT) chain to accept (-j ACCEPT) tcp (-p tcp) packets to port 80 the www port (--destination-port www). Then if we want we can say "and nothing else is allowed in" (be careful with this as it will block more than you probably want). by saying append a rule (-A) to the input chain (INPUT) to drop (-j DROP) all tcp (-p tcp) packets. Thus blocking and ignoring anything that isn't in an above rule:

iptables -A INPUT -j DROP -p tcp

Warning: don't use the above rule over SSH without allowing SSH as this will block you off.

Warning Warning Warning Warning Warning

Changing iptables settings is potentially the easiest way to lock yourself out of a system! If you are doing this from remote and don't have physical access to the system it is embarrassing to have to contact someone who does.

It is good practise to reset & blank the firewall configuration every 5 or 10 mins so that if you lock yourself out you only have 5 - 10 mins before you can get back in while you are testing. Obviously comment the lines out of crontab once you are finished.

crontab -e

#for when you are updating the iptables config
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /sbin/iptables -F
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /etc/init.d/firewall stop
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /root/stopfirewall.sh

 

/root/stopfirewall.sh

#!/bin/sh
/sbin/iptables -P OUTPUT ACCEPT
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables -P INPUT ACCEPT
/sbin/iptables -F

 

Implementing my rules

As discussed above I have a collection of things I want to achieve. First of all I want to allow (at least for now) all users complete freedom to go outside the box. This is covered by adding this rule:

iptables -A OUTPUT -j ACCEPT

Blanket accept all outgoing connections.

Next I want to add a rule to allow ssh (as I'm doing this work over a SSH connection):

iptables -A INPUT -j ACCEPT -p tcp -s 192.168.1.0/24 --destination-port ssh

Now a blanket rule to block everything incoming (good for total security):

iptables -A INPUT -j DROP -p tcp

These insertion commands can open up various things to allow access to the listed services. Note that the LAN access only sections are for services like samba that I want to access over the LAN (from my main home desktop) but I don't want open to the world from outside. But the WAN access is for services that I want to be able to get to from the big bad world over the internet for remote administration like SSH and HTTP:

SSH - LAN access only
iptables -I INPUT -j ACCEPT -p tcp -s 192.168.1.0/24 --destination-port ssh
SSH - WAN access
iptables -I INPUT -j ACCEPT -p tcp --destination-port ssh
WWW (HTTP) - LAN access only
iptables -I INPUT -j ACCEPT -p tcp -s 192.168.1.0/24 --destination-port www
WWW (HTTP) - WAN access
iptables -I INPUT -j ACCEPT -p tcp --destination-port www
FTP - LAN access only
iptables -I INPUT -j ACCEPT -p tcp -s 192.168.1.0/24 --destination-port ftp
FTP - WAN access
iptables -I INPUT -j ACCEPT -p tcp --destination-port ftp
SAMBA - LAN access only
iptables -I INPUT -j ACCEPT -p tcp -s 192.168.1.0/24 --destination-port netbios-ns
iptables -I INPUT -j ACCEPT -p udp -s 192.168.1.0/24 --destination-port netbios-ns
iptables -I INPUT -j ACCEPT -p tcp -s 192.168.1.0/24 --destination-port netbios-dgm
iptables -I INPUT -j ACCEPT -p udp -s 192.168.1.0/24 --destination-port netbios-dgm
iptables -I INPUT -j ACCEPT -p tcp -s 192.168.1.0/24 --destination-port netbios-ssn
iptables -I INPUT -j ACCEPT -p udp -s 192.168.1.0/24 --destination-port netbios-ssn
allow local host access to the system
Required for apt-proxy.
iptables -I INPUT -j ACCEPT -p tcp -s 127.0.0.1
Allow all established connections
iptables -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED
Allow FTP passive access.
iptables -A INPUT  -j ACCEPT -p tcp --source-port 21 --destination-port 1024:65535
iptables -A OUTPUT -j ACCEPT -p tcp --source-port 1024:65535 --destination-port 21
iptables -A INPUT -j ACCEPT -p tcp --source-port 1024:65535 --destination-port 1024:65535 -m state --state RELATED,ESTABLISHED
iptables -A OUTPUT -j ACCEPT -p tcp --source-port 1024:65535 --destination-port 1024:65535 -m state --state RELATED,ESTABLISHED