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:
- Only allow requests on the ports/services that I want people to access:
- SSH
- FTP
- HTTP
- SAMBA
- Block all other incoming traffic to keep secure.
- Allow the box full access to the outside world for updates and users on the system.
- 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 |
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 |