Introduction
iptables is a powerful tool that every system administrator should know and use. But as a web developer, it is sometimes difficult to take advantage of all the functionalities that this huge firewall offers.
The following is an example of a restrictive and useful iptables configuration, in which we will close all ports and open the necessary ones according to our personal needs.
The first thing to do is to specify what kind of rules we are going to add. This is done by marking the start and end:
*filter
# Here are our rules
COMMIT
Basic rules
We will use a restrictive policy where we will close all ports by default:
-P INPUT DROP
-P OUTPUT DROP
-P FORWARD DROP
If a connection already got permission to interact with our machine, we let it continue to have them:
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
We also allow loopback connections from our machine:
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
And finally we configure the logging system:
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
-A OUTPUT -j LOG --log-prefix "[Output Log] "
Common rules
The rules are fairly simple: specify the protocol, the port and include INPUT
if you want incoming connections and/or OUTPUT
if you want outgoing connections.
For example, if our server runs an HTTP service (Apache, Nginx, etc), we generally want port 80 (HTTP) and 443 (HTTPS) to be accessible from the outside:
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
And in turn, if we want to browse from our server to the outside (e.g. with lynx or another browser), we will need to create the same rule but this time changing INPUT
to OUTPUT
:
-A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
Simple, isn't it? Here is a list of common rules that we might be interested in adding.
SSH
In order to be able to connect via SSH and in turn allow our server to connect via SSH to other servers, we will need to create the INPUT
and OUTPUT
rules for port 22:
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 22 -j ACCEPT
DNS
If we want our server to be able to query domain names to other DNS servers, we will need to open port 53:
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
And if our server runs a DNS service (e.g. BIND), we will use INPUT
:
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
FTP
In the case of the FTP protocol, normally our server will run the FTP service on port 21. We will rarely need to connect from our server to the outside via FTP, so just INPUT
:
-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT
Rsync
It is very common to use rsync for backups. In addition, some Linux package managers also use rsync to download packages. For these cases we use the OUTPUT
rule for port 873:
-A OUTPUT -p tcp -m tcp --dport 873 -j ACCEPT
Git
The default port for Git is 9418. Since we do not run a Git server on our machine and only need to download software via GitHub, we will use the following:
-A OUTPUT -p tcp -m tcp --dport 9418 -j ACCEPT
Ping
If we want our server to be able to send and receive pings, these are the rules:
-A INPUT -p icmp -j ACCEPT
-A OUTPUT -p icmp -j ACCEPT
Summary
If you want to copy and paste the entire rules file, remember that it is available at articles/introduction-to-iptables/rules.
In the blog repository on GitHub you will find all the content associated with this and other articles.
To further limit the port opening and access from a specific IP (for example, to connect only from our desktop computer), just add the parameter -s 12.34.56.78
to the rule in question.
To load the rules in iptables just save these rules in a file and then run iptables-restore < file
.
Once we have loaded the rules in iptables, if we want to replace the rules with new ones or if we want to delete the current ones, we must execute a series of commands:
iptables -F
iptables -X
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
This will remove the existing rules and allow access to everything again.
If we just flush (iptables -F
), we will remove the rules but we will be offline, so this is not a good idea.
You can support me so that I can dedicate even more time to writing articles and have resources to create new projects. Thank you!