try.directtry.direct
Article preview image

How to Protect Servers Using Iptables

A firewall is a tool that enhances the network security of a server. It plays a significant role in monitoring incoming and outgoing traffic. As such, it becomes an essential element for anyone who uses the internet. There are many firewall tools available on Linux/Unix operating systems, such as UFW, firewalld, Shorewall, iptables, etc. Among all of these, iptables is one of the oldest and most preferred tools used by many Linux users and system administrators. In this tutorial, you will learn how to protect servers using iptables, basic iptables commands, and their application on Rocky Linux 8/CentOS 8.


1. Prerequisites


  • A server running Rocky Linux 8
  • A root user

2. Install Iptables

As you can not run firewalld and iptables at the same time, first check the firewalld service status on the server by following command:


sudo systemctl status firewalld

Output:

iptables.service - IPv4 firewall with iptables
Loaded: loaded (/usr/lib/systemd/system/iptables.service; enabled; vendor preset: disabled)
Active: active (exit) since Sat 2021-11-20 11:44:43 UTC; 11s ago
Main PID: 15015 (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 4738)
Memory: 0B
CGroup: /system.slice/iptables.service
Nov 20 11:44:43 rockylinux-8 systemd[1]: Starting IPv4 firewall with iptables...
Nov 20 11:44:43 rockylinux-8 iptables.init[15015]: iptables: Applying firewall rules: [ OK ]
Nov 20 11:44:43 rockylinux-8 systemd[1]: Started IPv4 firewall with iptables.

If firewalld service is running on the server, then you should stop and disable the service. Then, enter the below command in the terminal:


# sudo systemctl stop firewalld# sudo systemctl disable firewalld

Next, mask the firewalld service, so it can't be started by the other services. To do so, use the given command:


sudo systemctl mask firewalld

Now install iptables by executing the following command:


sudo dnf -y install iptables-services

Start iptables, enable it at startup and then check iptables service status by executing the following command:


sudo systemctl start iptables
sudo systemctl enable iptables
sudo systemctl status iptables

3. Basic Understating of the Packet Flow


The function of the iptables tool is packet filtering.

Now, this iptables filtering mechanism is organized into three different kinds of structures:

3.1 tables

3.2 chains

3.3 targets

Let us check in briefly.


3.1 Tables

Tables allow you to process packets in specific ways. The iptables have four types of built-in tables. As a filter table, NAT table, Mangle table, and raw table.


3.1.1 Filter Table

Used to set policies for the type of traffic allowed into, through, and out of the system. If you don’t define your own table, then iptables operates on chains within this table by default. Its built-in chains are as follows:

  • INPUT CHAIN: indicates incoming traffic packets coming from the network to the local server.
  • FORWARD CHAIN: For packets forwarded by the local server, packets go to a router moving from one device to another device.
  • OUTPUT CHAIN: Outgoing packets from the firewall go from the local server to another network.

3.1.2 NAT table

NAT table used with connection tracking to redirect connections for network address translation. It has the following built-in chains.

  • PREROUTING CHAIN: As the name suggests, it immediately alters packets before routing.
  • POSTROUTING CHAIN: Post routing will be performed at the time of leaving the system. The alteration takes place after the process ends.
  • OUTPUT: NAT used for the locally generated packets.

3.1.3 Mangle table

Mangle table is used for specialized packet alteration, such as stripping off IP options. It has the following built-in chains:

  • PREROUTING CHAIN
  • OUTPUT CHAIN
  • FORWARD CHAIN
  • INPUT CHAIN
  • POSTROUTING CHAIN

3.1.4 Raw table

Raw table has the following built-in chains:

  • PREROUTING CHAIN
  • OUTPUT CHAIN

3.2 Chains

The chains that are attached to the tables allow us to inspect traffic at various points.

There are 3 main chains used in iptables.

  • INPUT: It indicates incoming traffic
  • FORWARD: going to a router, from one device to another
  • OUTPUT: For out-going traffic

You can filter traffic by adding rules to the chains.


3.3 Targets

Targets decide what to do with packets. It has three types of targets, as given below:

  • Accept: packets accepted.
  • Reject: packets rejected.
  • Drop: packets drop.

4. Basic iptables commands

First, let us list out all current rules of iptables:


sudo iptables -L

Here, you can see that all policies are allowed in chains, and we don't have any rule setup.

Chain INPUT (policy ACCEPT)

Chain FORWARD (policy ACCEPT)

Chain OUTPUT (policy ACCEPT)


Output:

[root@rockylinux-8 ~]# 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

Here,

Chain INPUT is used for incoming packets to the system, as we discussed earlier.

Chain OUTPUT means data(packets) going out from the system.

Chain FORWARD is used for routing the data.



Normally, you don't require a FORWARD policy for your home system. This can be rejected by executing this policy:

iptables -P FORWARD DROP


You can change the default policy as per your needs, the below commands set default policies to accept connections:

iptables -P INPUT DROP
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

The best practice is to DROP all INPUT packets by default, but at the same can be dangerous because you can lose established access to your server machine.


iptables -P INPUT DROP - drops any INPUT packet


# Allow established connections


iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPTiptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT


# Let’s allow <Your IP address> to connect SSH, replace '27.61.187.123' with your IP address


iptables -I INPUT -p tcp -s 27.61.187.123 --dport 22 -j ACCEPT

Or you can allow your ip to access any port of your server by


iptables -I INPUT -p tcp -s 27.61.187.123 -j ACCEPT

Next, Allow DNS connection for all


iptables -A INPUT  -p udp --sport 53 -m state --state ESTABLISHED  -j ACCEPTiptables -A INPUT  -p tcp --sport 53 -m state --state ESTABLISHED  -j ACCEPT


All other port connections are not allowed due to default policy DROP

If you want to allow some other ports to be publicly accessible you will need to add rules for them, let’s say we have another web service running on port 8080. The rule will look like


iptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 8080 -j ACCEPT

Let's assume we need to access our server from our office via ssh, then we need to add that IP into the iptables rules.


iptables -A INPUT -p tcp -s 223.226.210.133 --dport 22 -j ACCEPT

Here, we used -A which means it will append the rule at last.

Output:


[root@rockylinux-8 ~]# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 27.61.187.123 anywhere tcp dpt:ssh
ACCEPT tcp -- 202.131.100.12 anywhere tcp dpt:ssh
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)

In this way, you can easily secure the ssh connection of your server.



List iptables rules with Line number

For the clearer list with line numbers, we can use the following command:


iptables -nvL --line-numbers

Output:


[root@rockylinux-8 ~]# iptables -nvL --line-numbers
Chain INPUT (policy DROP 1913 packets, 146K bytes)
num pkts bytes target prot opt in out source destination
1 403 46490 ACCEPT tcp -- * * 27.61.187.123 0.0.0.0/0 tcp dpt:22
2 0 0 ACCEPT tcp -- * * 202.131.100.12 0.0.0.0/0 tcp dpt:22
Chain FORWARD (policy DROP 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 1737 packets, 178K bytes)
num pkts bytes target prot opt in out source destination

Allow Web Server

Next, We have a web server running on the system, and we want to allow HTTP and HTTPS connection for all, to do so execute the below command:


iptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 80 -j ACCEPTiptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 443 -j ACCEPT


Now, assume that you are getting many spam mails from a specific IP, and you want to block all the requests from that IP address.


iptables -A INPUT -s 104.248.87.24 -j DROP


You can also block the whole network IP address with a specific port, like shown in the below command:


iptables -A INPUT -s 104.248.0.0/24 -p tcp --dport 25 -j DROP


In the above command, we block TCP protocol and port 25 for the network range of 104.248.0.0/24.

But what if we want to allow 25 ports from IP 104.248.87.21. Well, in that case, we have to add these rules using the -I option.


iptables -I INPUT -s 104.248.87.21 -j ACCEPT

Here we need to add the above IP address at the top of the chain because sequence order is important in iptables.

Note: iptables rules work in a sequence order from top to bottom.


How to INSERT and DELETE exact line in the rules

Till now, we have a clear understanding of the above sequence order. Now we will learn how to add rules in specific line numbers without making mistakes through the entire iptables guide.

By using the following commands, you will be able to change the rules easily.


iptables -nL --line-numbers


Output:

[root@rockylinux-8 ~]# iptables -nL --line-numbers
Chain INPUT (policy DROP)
num target prot opt source destination
1 ACCEPT all -- 104.248.87.21 0.0.0.0/0
2 ACCEPT tcp -- 27.61.187.123 0.0.0.0/0 tcp dpt:22
3 ACCEPT tcp -- 202.131.100.12 0.0.0.0/0 tcp dpt:22
4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
6 DROP all -- 104.248.87.24 0.0.0.0/0
7 DROP tcp -- 104.248.0.0/24 0.0.0.0/0 tcp dpt:25
Chain FORWARD (policy DROP)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
[root@rockylinux-8 ~]#

In the above list, you will have to add a rule at line number 3 that accepts MySQL connection from your home IP.


iptables -I INPUT 3 -p tcp -s 27.61.187.123 --dport 3306 -j ACCEPT -m comment --comment "My home"iptables -nvL --line-numbers

Output:

[root@rockylinux-8 ~]# iptables -nvL --line-numbers
Chain INPUT (policy DROP 94 packets, 5927 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT all -- * * 104.248.87.21 0.0.0.0/0
2 100 7664 ACCEPT tcp -- * * 27.61.187.123 0.0.0.0/0 tcp dpt:22
3 0 0 ACCEPT tcp -- * * 27.61.187.123 0.0.0.0/0 tcp dpt:3306 /* My home */
4 0 0 ACCEPT tcp -- * * 202.131.100.12 0.0.0.0/0 tcp dpt:22
5 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
6 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
7 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
8 0 0 DROP tcp -- * * 104.248.0.0/24 0.0.0.0/0 tcp dpt:25
Chain FORWARD (policy DROP 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 194 packets, 23016 bytes)
num pkts bytes target prot opt in out source destination
[root@rockylinux-8 ~]#

Execute the below command If you want to delete a rule on line 4.


iptables -D INPUT 4

Output:


[root@rockylinux-8 ~]# iptables -nvL --line-numbers
Chain INPUT (policy DROP 157 packets, 9139 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT all -- * * 104.248.87.21 0.0.0.0/0
2133 10016 ACCEPT tcp -- * * 27.61.187.123 0.0.0.0/0 tcp dpt:22
3 0 0 ACCEPT tcp -- * * 27.61.187.123 0.0.0.0/0 tcp dpt:3306 /* My home */
4 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
5 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
6 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
7 0 0 DROP tcp -- * * 104.248.0.0/24 0.0.0.0/0 tcp dpt:25
Chain FORWARD (policy DROP 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 262 packets, 29016 bytes)
num pkts bytes target prot opt in out source destination
[root@rockylinux-8 ~]#


It is always good practice to set INPUT policy to DROP after making changes.


iptables -P INPUT DROP


Save iptables rules by running the following command:


service iptables save

Output:

[root@rockylinux-8 ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]

Flush iptables rules

Flush all existing rules by executing:


iptables -F


You can reset iptables rules and re-configure iptables policies by running the following command:


iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

Migrate iptables firewall rules

At this stage, you learn iptables basic commands and migration of iptables firewall rules to a new server by using the following steps:


1. List out existing the iptables rules


sudo iptables -S

Output:

[root@rockylinux-8 ~]# sudo iptables -S
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-A INPUT -s 104.248.87.21/32 -j ACCEPT
-A INPUT -s 27.61.187.123/32 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s 27.61.187.123/32 -p tcp -m tcp --dport 3306 -m comment --comment "My home" -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 104.248.0.0/24 -p tcp -m tcp --dport 25 -j DROP
[root@rockylinux-8 ~]#

2. Export iptables rules

Using iptables-save you can export it to the file. Using the following command, you can export rules and read that content.


cd ~sudo iptables-save > iptables-exportcat iptables-export


3. Copy File to the Remote Server

Now copy iptables-export file to remote desktop using scp.


scp iptables-export user@server_b_ip_address:/tmp


4. Import iptables rules and save

Go to the new server, install iptables and start service. Then run the following command:


sudo iptables-restore < /tmp/iptables-export


Last save iptables rules.


sudo service iptables save


This tutorial demonstrates how to set up an iptables firewall in Rocky Linux/CentOS 8 and the basics of iptables. You also had the opportunity to master a directed way of securing your system and migrating iptables rules from one server to another.