IPTABLES : Introduction to Linux Firewall
Linux is the most-used open source operating system. Managing network traffic is one of the toughest jobs to deal with. For this, we must configure the firewall in such a way that it meets the system and users requirements without leaving the system vulnerable. The default firewall in most of the Linux distributions is IPTables.
IPTables is a standard firewall included in most Linux distributions by default (a modern variant called
nftables will begin to replace it). It is actually a front end to the kernel-level netfilter hooks that can manipulate the Linux network stack. It works by matching each packet that crosses the networking interface against a set of rules to decide what to do.
IPTables is used to manage packet filtering, DNAT(Destination Network Address Translation), SNAT(Source Network Address Translation) rules. IPTables comes with all Linux distributions.
IPTables might contain multiple tables and tables might contain multiple chains and chains contain multiple rules where rules are defined for the incoming and outgoing packets.
How Iptables works
The iptables firewall operates by comparing network traffic against a set of rules. The rules define the characteristics that a packet must have to match the rule, and the action that should be taken for matching packets.
There are many options to establish which packets match a specific rule. You can match the packet protocol type, the source or destination address or port, the interface that is being used, its relation to previous packets, etc.
When the defined pattern matches, the action that takes place is called a target. A target can be a final policy decision for the packet, such as accept, or drop. It can also be move the packet to a different chain for processing, or simply log the encounter. There are many options.
- ACCEPT: It means the packet will be allowed to pass through.
- DROP: It means that packet will not be allowed to pass through.
- RETURN: It means to skip the current chain and go back to the next rule from the chain it was called in.
These rules are organised into groups called chains. A chain is a set of rules that a packet is checked against sequentially. When the packet matches one of the rules, it executes the associated action and is not checked against the remaining rules in the chain.
A user can create chains as needed. There are three chains defined by default. They are:
- INPUT: This chain handles all packets that are addressed to your server.
- OUTPUT: This chain contains rules for traffic created by your server.
- FORWARD: This chain is used to deal with traffic destined for other servers that are not created on your server. This chain is basically a way to configure your server to route requests to other machines.
Each chain can contain zero or more rules, and has a default policy. The policy determines what happens when a packet drops through all of the rules in the chain and does not match any rule. You can either drop the packet or accept the packet if no rules match.
Through a module that can be loaded via rules, iptables can also track connections. This means you can create rules that define what happens to a packet based on its relationship to previous packets. We call this capability “state tracking”, “connection tracking”, or configuring the “state machine”.
For this guide, we are mainly going to be covering the configuration of the INPUT chain, since it contains the set of rules that will help us deny unwanted traffic directed at our server.
Installing Iptables Linux Firewall
Iptables comes pre-installed in almost all of the Linux distributions.
But if you don’t have it installed on Ubuntu/Debian system use:
sudo apt-get update sudo apt-get install iptables
Checking current Iptables status
With this command, you can check the status of your current Iptables configuration. Here -Loption is used to list all the rules and -v option is for a more tedious list. Please note that these options are case sensitive.
sudo iptables -L -v
Defining chain rules
Defining a rule means appending it to the list (chain). Here’s the Iptables command formatted with regular options. We don’t have to specify all of them.
sudo iptables -A -i <interface> -p <protocol (tcp/udp) > -s <source> –dport <port no.> -j <target>
- Here -A stands for append. The chain refers to the chain we want to append our rules.
- The interface is the network interface on which you want to filter the traffic.
- The protocol refers to the networking protocol of packets you want to filter.
- You can also specify the port, no of the port on which you want to filter the traffic.
Enabling traffic on localhost
We want all communications between applications and databases on the server to continue as usual.
sudo iptables -A INPUT -i lo -j ACCEPT
Chain INPUT (policy ACCEPT 7 packets, 488 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- lo any anywhere anywhere
Here -A option is used to append the rule to the INPUT chain, accept all connections on lo interface. lo means loopback interface. It is used for all the communications on the localhost, like communications between a database and a web application on the same machine.
Enabling connections on HTTP, SSH, and SSL port
We want our regular HTTP (port 80), https (port 443), ssh (port 22) connections to continue as usual. Enter the following commands to enable them. In the following commands, we have specified protocol with -p option and the corresponding port for each protocol with –dport (destination port) option.
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
Now all TCP protocol connections with specified ports will be accepted.
Filtering packets based on source
If you want to accept or reject packets based on the source IP address or the range of IP addresses you can specify it with -s option. For example to accept packets from address 192.168.1.3 –
sudo iptables -A INPUT -s 192.168.1.3 -j ACCEPT
You can drop packets from an IP address with a similar command with option DROP .
sudo iptables -A INPUT -s 192.168.1.3 -j DROP
If you want to drop packets from a range of IP addresses you have to use the Iprange module with -m option and specify the IP address range with –src-range.
sudo iptables -A INPUT -m iprange --src-range 192.168.1.100-192.168.1.200 -j DROP
Dropping all other traffic
Note: It is important to DROP all other traffic after defining the rules as it prevents unauthorized access to a server from other open ports.
sudo iptables -A INPUT -j DROP
This command drops all incoming traffic other than the ports mentioned in the above commands. You can check your set of rules now with:
sudo iptables -L -v
Deleting rules of iptables
If you want to remove all rules and start with a clean slate you can use the flush command.
sudo iptables -F
This command deletes all current rules. If you want to delete a specific rule you can do it with -D option. First, list all the rules with numbers by entering following command:
sudo iptables -L --line-numbers
Then you will get a list of rules with numbers.
Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- 192.168.0.9 anywhere 2 ACCEPT tcp -- anywhere anywhere tcp dpt:https 3 ACCEPT tcp -- anywhere anywhere tcp dpt:http 4 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
To delete a rule specify the number in the list and the chain of the rule. In our case INPUTchain and number 3.
sudo iptables -D INPUT 3
Save changes to iptables
Iptables rules we have created are saved in memory. That means we have to redefine them on reboot. To make these changes persistent after reboot, use the following command on Ubuntu/Debian systems:
This command saves current rules to system configuration file which is used to reconfigure the tables at the time of reboot. You should run this command everytime you make changes to the rules. To disable this firewall simply flush all the rules and make the changes persistent.
sudo iptables -F sudo /sbin/iptables-save