Introduction to iptables
Introduction
In this tutorial we will learn how to configure iptables which is a built-in Linux firewall. I will use Ubuntu 18.04 for demo, but you can use any other Linux distro. Before we get into actual configuration we will learn some theory behind iptables. iptables allows us to filter packets based on IP addresses, protocol(TCP or UDP) and port numbers .
Chains and rules
Each IP packet going to/from/through the Linux server will go through a series of chains. We will have a look at three predefined chains which are used most of all:
- INPUT chain – used for packets destined to the server itself
- OUTPUT chain – used for packets originating from the server itself
- FORWARD chain – used for packets going through the server (Linux server acts as a router)
Chains contain a list of ordered rules which are used for identifying traffic and taking actions on packets, based on IP address, protocol and port number. Most common actions usually taken by the rules are ACCEPT and DROP. The actions defined in the rules are called targets.
For example, we run a web server on our host and all traffic coming from the clients to the web server goes through INPUT chain. If we want to perform some action on that traffic we should add a rule to an INPUT chain. This rule may have information about port (in our case 80), protocol (in our case TCP), IP address (source and/or destination) and a desired target(action) – DROP or ACCEPT.
How to view iptables rules?
To view the content of iptables chains run sudo iptables -L
orkhans@matrix:~$ sudo iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
You can see that all chains have no rules, by default.
How to delete all iptables rules?
Another important command is sudo iptables -F, which deletes all iptables rules.
Configuration examples
Now that you know what chains and rules are and how to view and delete them we can start experimenting with iptables. The best way to learn how iptables works is through examples.
Example 1. Block PING packets.
Now we will block PING packets (ICMP protocol) from our Linux machine to 8.8.8.8 IP address.
Run the following command sudo iptables -A OUTPUT -p icmp -o wlp16s0 -d 8.8.8.8 -j DROP and then try to ping 8.8.8.8
orkhans@matrix:~$ sudo iptables -A OUTPUT -p icmp -o wlp16s0 -d 8.8.8.8 -j DROP orkhans@matrix:~$ ping 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. ping: sendmsg: Operation not permitted ping: sendmsg: Operation not permitted ping: sendmsg: Operation not permitted ^C --- 8.8.8.8 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2033ms orkhans@matrix:~$ ping 8.8.4.4 PING 8.8.4.4 (8.8.4.4) 56(84) bytes of data. 64 bytes from 8.8.4.4: icmp_seq=1 ttl=116 time=163 ms 64 bytes from 8.8.4.4: icmp_seq=2 ttl=116 time=187 ms ^C --- 8.8.4.4 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 163.847/175.478/187.110/11.639 ms
Below are the comments on how this rule works:
-A OUTPUT – append the rule to OUTPUT chain,because we want to match outgoing packets
-p icmp – match icmp protocol
-o wlp16s0 – match outgoing interface wlp16s0, which is the name of my network interface
-d 8.8.8.8 – match only destination IP address 8.8.8.8. We still can ping all other IP addresses, like 8.8.4.4 in the example above
-j DROP – drop the matched traffic
You can run sudo iptables -L to see the applied rule:
orkhans@matrix:~$ sudo iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination DROP icmp -- anywhere google-public-dns-a.google.com
Example 2. Block incoming HTTP traffic.
Before we start run sudo iptables -F to flush all existing rules.
In this example we will block incoming HTTP traffic to our web server. Run sudo python -m SimpleHTTPServer 80, so that we have an active server listening on port 80. You can make sure that it works by browsing to 127.0.0.1, where you are going to see the directory listing.
orkhans@matrix:~$ sudo python -m SimpleHTTPServer 80 Serving HTTP on 0.0.0.0 port 80 ...
Now run the following command to append a rule to the INPUT chain
orkhans@matrix:~$ sudo iptables -A INPUT -p tcp --destination-port 80 -j DROP
–destination-port 80 – match destination port 80
Now browser will not be able to open 127.0.0.1, because we have blocked the traffic going to 80 port. In real life traffic would come from another machine and not our local host, but the logic behind the blocking rule is still the same, because our HTTP request packets still hit the INPUT chain.
Example 3. Block all traffic from a specific IP address.
One of the most common things to do when configuring firewall is block all traffic from a specific IP address. Now we will create a rule which will drop all traffic coming from 8.8.8.8. You can ping it now, but you will not be able to ping it after we apply the rule.
Make sure you delete all existing rules and then apply the following rule:
orkhans@matrix:~$ sudo iptables -A INPUT -s 8.8.8.8 -j DROP
We append a rule to INPUT chain and only specify -s 8.8.8.8, which matches source IP address 8.8.8.8.
We could as well use FQDN of a remote host instead of IP address, like this:
orkhans@matrix:~$ sudo iptables -A INPUT -s abc.xyz -j DROP
Example 4. Block outgoing traffic to a specific web site or IP address.
The following rule will block all traffic originating from our Linux machine and going to facebook.com website. Again it is possible to use either IP address or FQDN with this rule:
orkhans@matrix:~$ sudo iptables -A OUTPUT -d facebook.com -j DROP
Notice that we use -A OUTPUT, because we append this rule to OUTPUT chain.
-d facebook.com – matches destination IP or destination hostname. In our case it is hostname facebook.com
Thank you for reading!