Iptables Tutorial – Securing Ubuntu VPS with Linux Firewall
Iptables Linux firewall is for monitoring incoming and outgoing traffic to a server, then filtering it depending on the user-defined rules which prevent people from accessing the system. With the help of Iptables, you will be able to define rules which should allow only specific traffic on your server. In this iptables guide, we will teach you how you can secure your web application using Iptables.
For this guide, you will require the following:
– A local machine with the SSH client installed.
– VPS running Ubuntu 16.04
All data is sent in the form of packets over the internet. The Linux kernel gives an interface which you can use to filter both incoming and outgoing traffic packets using tables of packet filters. Iptables is a command line application and a Linux firewall which you can use to set up, maintain, and inspect those tables. Several tables can be defined. Every table can contain several chains. A chain is nothing but a set of rules, and every rule will define what to do with the packet if it matches with that packet.
Once the packet is matched, it is granted a TARGET. A target could be another chain to match with or one of the following special values:
- ACCEPT: This means that the packet is going be allowed to pass through.
- DROP: This means that the packet will not be allowed to pass through.
- RETURN: This means it will skip the current chain and go to the next rule from the chain it was called in.
For the scope of this iptables tutorial, we will be working with one of the default tables called filter. The filters table has three chains (sets of rules).
- INPUT – This chain is used to control incoming packets to the server. You have the option to block/allow connections based on port, protocol, or source IP address.
- FORWARD – This chain is made to filter packets that are incoming to the server but are to be forwarded somewhere else.
- OUTPUT – This chain is made to filter packets that are going out from your server.
Step 1 – Installing Iptables Linux Firewall
- Installing Iptables
Iptables is going to come pre-installed in every Linux distribution. However, if you don’t have it installed on Ubuntu/Debian, run the commands below:
sudo apt-get update
sudo apt-get install iptables
- Checking current Iptables status
Using the command below, you could verify the status of your current Iptables configurations. The –L option is used to list all of the rules and the –v option is a bit more tedious of a list. Reminder that those options are case sensitive.
sudo iptables -L -v
You should receive an output similar to the one below:
Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
This should be the output of the command above. In the output every chain is set to default ACCEPt olicy. There are no rules for any of the chains.
To ensure this Iptables guide is more practical, we are going to edit the INPUT chain to filter the incoming traffic.
Step 2 – Defining chain rules
Defining a rule means adding it to the list (chain) This is the iptables command formatted with regular option. We won’t need to specify every one.
sudo iptables -A -i <interface> -p <protocol (tcp/udp) > -s <source> --dport <port no.> -j <target>
-A stands for append. The chain refers to the chain we are aiming to append to the rules. The interface is the network interface on which you’d like to filter the traffic. The protocol refers to the networking protocol of packets you’d like to filter. You could also specify the port number of the port on which you’d like to filter the traffic.
Enabling traffic on localhost
It’s good if the communication between all applications and databases on the server proceed to work as usual.
sudo iptables -A INPUT -i lo -j ACCEPT
Example output: 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
In the output above, the –A option is made to add the rule to the input chain, which accepts every connection on a lo interface. Lo means loopback interface. It’s used for all the communications on the localhost, such as communications between a database and a web application on the same machine.
Enabling connections on HTTP, SSH, and SSL port
We need our default HTTP (port 80), https (port 443), and ssh (port 22) connections to proceed as normal. Type in the commands below to enable them. With the commands below, we will specify the protocol with the –p option and the corresponding port for each protocol with the –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 every TCP protocol connection with the specified ports is going to be accepted.
Filtering packets based on source
If you’d like to accept or deny packets depending on the source of the IP address or the range of IP addresses, you can specify this using the –s option. For example, to accept packets from the 192.168.1.3 address:
sudo iptables -A INPUT -s 192.168.1.3 -j ACCEPT
You could drop packets from an IP address using a similar command with the DROP option.
sudo iptables -A INPUT -s 192.168.1.3 -j DROP
If you’d like for the packets to drop from a range of IP addresses, you’d need to use the iprange module with the –m option then 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
Reminder that it is important to DROP every other kind of traffic once you define the rules, since this stops unauthorized access to a server from other open ports.
sudo iptables -A INPUT -j DROP
The command above will drop every incoming traffic with the exception of the ports mentioned in the above commands. You could check your set of rules now with:
sudo iptables -L -v
If you’d like to delete all rules and start over with a clean state you could simply use the flush command.
sudo iptables -F
The command above will get rid of all the current rules. If you’d like to remove a specific rule, you could do it with the –D option. Begin by listing all of the rules with numbers by typing the next command:
sudo iptables -L --line-numbers
You will then receive a list of rules with numbers.
Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- 192.168.0.4 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 remove a rule, specify the number in the list and the chain of the rule. In this case, INPUT chain and number 3.
sudo iptables -D INPUT 3
Step 3 – Persisting changes
Iptables rules we’ve made are saved in memory. Which means we need to redefine them on reboot. To ensure those changes stay after reboot. Use the following command on Ubuntu/Debian systems:
This command will save the current rules to the system configuration file which is made to reconfigure the tables at the time of reboot. We suggest to run this command each time you do any 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
In this iptables tutorial, we have used iptables Linux firewall to only grant traffic on particular ports. We’ve also ensured that our rules are saved after we reboot. This Linux firewall will drop unwanted packets, but there is a caveat here that iptables can govern only ipv4 traffic. In the case that your VPS box has enabled ipv6 networking, you’ll need to set different rules for that traffic with ip6tables.