I would like to take a few minutes to discuss the very basics of iptables, which is the default firewall for most modern linux systems. There is MANY things you can do with iptables but to keep it simple we will discuss the basics like viewing current firewall rules, adding or removing rules to allow open ports, and a few other tidbits. If your new to iptables this will be a good primer, but absolutely NOT the definitive guide to iptables.
Before we go any further I would like to make sure anyone reading this understands that iptables rules are instantly enforced. This means it is possible to lock yourself out of the machine if you are doing this remotely. If you are working on a machine via SSH be very careful. It is suggested that you have physical access to the machine before changing any iptables rules unless you are sure you know what your doing.
First we will discuss some basic concepts of iptables and some of the basic commands.
Iptables is an IP filtering firewall that basically inspects IP traffic and matches it to rules that you specify. When IP packets match one of the specified rules, it then handles the packet with the action that you specify in the rule. An important thing to understand about iptables is it reads the rules starting at the first rule, and working it's way down. Once a packet meets a rule it is processed and the next one is inspected. For this reason it is always good to have a "catch all" in your iptables chain. We will talk more about a "catch all" later.
Iptables is made up of CHAINS, each chain holds RULES.
The default chains are:
NOTE: You can add user defined chains but these are the default.
- INPUT (Incoming traffic to this machine)
- FORWARD (Traffic going to or from a machine on the other side of this firewall)
- OUTPUT (Outgoing traffic from this machine).
Rules are then placed inside these chains in order to allow or deny specific traffic. There are three basic "ACTIONS" that a rule can take. Other rules exist, but these are the basic and most commonly used actions.
- ACCEPT (Allows the traffic through the firewall)
- DROP (The packet is dropped with no reply to sender)
- REJECT (Packet is dropped and an appropriate message is sent back to the sender.)
Now let's look at some basic commands used with iptables. Although iptables is not a traditional service, but we can interact with it like we would other services. For example to stop, start, or restart iptables we can use the following:
service iptables stop
service iptables start
service iptables restart
There is another very important command that you should know. When you modify iptables in any way it changes the current running configuration instantly, but it does not save it to a configuration file. Which means if you make changes and then restart iptables, or restart the machine, you will lose all your changes. After making changes and confirming they work as intended you should always save your configuration with the following command.
service iptables save
So now that you understand a little bit about what is going on under the hood, what basic configuration options we have and the basic commands used to control iptables, let's look at some other commands and even try opening a port for http traffic.
To list your current iptables configuration you can use the following command:
If you would like a little more information you can add the verbose switch:
iptables -L -v
For a full listing of all available options and switches use the following command:
Now let's take a look at adding a very basic rule. Let's say you have a webserver running and you want to open port 80 to serve your webpages, so you enter the following command:
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
Let's take a closer look at the above command. We know what the iptables is in the command, thats the binary or program itself, now let's look at the other options.
-I stands for insert. This will insert the rule at the top of the chain. You can also use -A for append, which will place the new rule at the end of the chain.
INPUT tells the iptables command which chain you want the rule entered into.
-p tcp tells the rule to match only packets using the TCP protocol.
--dport 80 says to match traffic headed for port 80, or http. --dport stands for destination port.
-j stands for JUMP to jump to the specified action or chain. In our case we are using -j ACCEPT so it will jump to the ACCEPT action and allow the traffic through.
You can also specify a source network or host in your rule. For example if we only wanted the machine named joe.local.lan to access our web server we could specify that in our rule like so.
NOTE: You can specify host by name or IP address using the -s switch, which stands for source.
iptables -I INPUT -p tcp -s joe.local.lan --dport 80 -j ACCEPT
Let's say you have a small network using the following IP subnet 192.168.1.0/24. You can limit access to your webserver to ONLY people in your LAN by specifying the network in the source.
iptables -I INPUT -p tcp -s 192.168.1.0/24 --dport 80 -j ACCEPT
One last thing I would like to discuss for our iptables basics lesson is called the chain default policy. Remember I mentioned earlier a "catch all"? Well using the chains default policy is a way of creating a catch all. For this example lets use the INPUT chain. If we set the default policy for the INPUT chain to ACCEPT, when packets come in that do not match any of our rules they will be ACCEPTED or allowed to pass through the firewall by default. This is a security risk since we would have to have a rule for every single type of traffic. It is much more efficient and secure to set the chain default policy to DROP or REJECT so if the traffic does not match any of our defined rules it is NOT allowed to pass through the firewall.
NOTE: DO NOT SET THE DEFAULT POLICY REMOTELY UNLESS YOU HAVE RULES TO ALLOW YOUR SSH SESSION. YOU CAN BE LOCKED OUT!
You can set the chain default policy using the -P switch. The command below sets the default policy for the INPUT chain to DROP.
iptables -P INPUT DROP
Another way to create a catch all for a chain it to make a rule that matches all traffic and drops it as the last rule in a chain. Remember that iptables processes rules from top to bottom first then exits? Creating a drop rule at the bottom of the chain will ensure that if a packet does not match any rules we defined for ACCEPT it will be dropped and not allow to pass. In my opinion this is less secure and more prone to errors. I would recommend using the default policy instead of a catch all rule at the end of a chain.
IPTables Man Page