Iptables is essentially a software firewall for Linux distributions. This guide will provide a quick reference for common iptables commands. These commands include examples of allowing and blocking traffic for different services by port, network interface, and source IP address.
- The majority of the rules described here are based on the assumption that your default iptables policy is configured to drop incoming traffic and that you would like to allow incoming traffic on a selective basis.
- Be sure to use each section of the command that you need. Most of the sections are not dependent on each other, which means you can use the examples separately.
- Just copy and paste the example commands, replacing the highlighted values with your own values.
Keep in mind that the order of your rules is very important. All of the iptables commands use the -A flag to attach a new rule to the end of a chain. When you need to add it elsewhere in the chain, consider using the -I flag, with which you can indicate the position of the new rule (or, by not indicating a number for the rule, place it at the beginning of the chain).
While working with firewalls, make sure that you won’t get your instance locked by blocking SSH traffic (port 22 by default). If you lose your access because of your firewall settings, you must connect to it through the instance console. As soon as you are connected using the console, you will be able to change your firewall rules to allow SSH access (or allow all traffic). Additionally, if your saved firewall rules are allowing SSH access, you can restart the server.
Remember that you can verify your current set of iptables rules using sudo iptables -S and sudo iptables -L.
Saving Rules
Iptables rules are static, so they must be saved manually to ensure that they persist across reboots.
Using Ubuntu, one way to save iptables rules is by using the iptables-persistent package. It can be installed using apt:
sudo apt install iptables-persistent
You will be asked during the installation if you would like to save your current firewall rules.
To update your firewall rules and then save the changes, run the following command:
sudo netfilter-persistent save
List and Delete Rules
If you want to view the list and delete rules, refer to the Iptables Firewall Rules Listing and Deleting Guide.
Common and Widely Used Rules
In this section, you will find a series of iptables commands for creating rules that are commonly useful for most servers.
Accepting Loopback Connections
The loopback interface, also referred to as lo, is the interface used by a computer to forward network connections to itself. As an example, if you ping localhost or 127.0.0.1, your server will ping itself using loopback. Similarly, if you configure your application server to establish a connection to the database server with a localhost address, it will also be using the loopback interface. As a result, you have to make sure that your firewall will allow this connection.
To allow all traffic on the loopback interface, run the following commands:
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
Permitting Established and Related Incoming Connections
Since network traffic typically needs to be two-way – inbound and outbound – to properly function, it is common to set up a firewall rule allowing established and related incoming traffic in such a way that the server will permit loopback traffic for server-initiated outbound connections. Use the following command to allow this traffic:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Permitting Outbound Connections
You might want to permit outgoing traffic for all established connections, which are generally responses to legitimate inbound connections:
sudo iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
Allow Internal Network To Access an External Network
By assuming that eth0 is your external network and eth1 is your internal network, with this command, your internal network will be permitted to access the external network:
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
Removing Invalid Packets
Certain network traffic packets are flagged as invalid. It may sometimes be useful to log such packets, but more often than not, you would be better off dropping them. You can do this with the following command:
sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
Block an IP Address
If you want to block network connections coming from a certain IP address, such as 203.0.113.51, use this command:
sudo iptables -A INPUT -s 203.0.113.51 -j DROP
For this example, -s 203.0.113.51 – indicates the source IP address “203.0.113.51”. You can specify the source IP address in any firewall rule, which includes the Allow rule.
If you instead want to drop the connection, which will respond to the connection request with a “Connection Refused” error, you can replace “DROP” with “REJECT”:
sudo iptables -A INPUT -s 203.0.113.51 -j REJECT
Blocking Connections to an Interface
If you want to block a connection from a particular IP address, for example, 203.0.113.51, to a particular interface, for example, eth0, you can use this command:
iptables -A INPUT -i eth0 -s 203.0.113.51 -j DROP
SSH Service
When not using Instance Console to connect to the server, you will probably want to allow incoming SSH connections (port 22) for connecting to and managing your server. This section will explain how to configure the firewall for SSH.
Permitting All Incoming SSH Connections
If you want to allow all incoming SSH connections, run the following commands:
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT
You only need to use the second command that allows outgoing traffic from existing SSH connections when the default OUTPUT policy is not set to ACCEPT.
Permitting Incoming SSH Connections from a Particular IP Address or Subnet
If you want to permit incoming SSH connections from a particular IP address or subnet, indicate the origin. As an example, for allowing SSH connections to the entire /24203.0.113.0 subnet, run these commands:
sudo iptables -A INPUT -p tcp -s 203.0.113.0/24 --dport 22 -m conntrack --ctstate NEW,ESABLISHED -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT
You only need to use the second command, which will allow outgoing traffic from the established SSH connection when the OUTPUT policy is not set to ACCEPT.
Allow Outbound SSH
When your firewall’s OUTPUT policy is configured not to ACCEPT, and you would like to allow an outgoing SSH connection – that is, a server which initiates an SSH connection to another server – you can run the following commands:
sudo iptables -A INPUT -p tcp -s 203.0.113.0/24 --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT
You will only need to use the second command, permitting outgoing traffic from the established SSH connection, when the OUTPUT policy is set to something other than ACCEPT.
Permitting Inbound Rsync from Certain IP Address or Subnet
Rsync running on port 873 may be used to transfer files between servers.
Specify the source IP address and destination port to permit incoming Rsync connections from a particular IP address or subnet. If you want to allow /24203.0.113.0 subnet to sync with your server, for example, run these commands:
sudo iptables -A INPUT -p tcp -s 203.0.113.0/24 --dport 873 -m conntrack --ctstate NEW,ESABLISHED -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 873 -m conntrack --ctstate ESTABLISHED -j ACCEPT
You must use the second command that allows outgoing traffic on existing rsync connections only when the OUTPUT policy is not set to ACCEPT.
Web Server Service
Typically, web servers like Apache and Nginx listen to requests on ports 80 and 443 for HTTP and HTTPS connections. Assuming your default inbound traffic policy is set to “Drop” or “Deny,” you will need to create rules allowing your server to respond to these requests.
Allow All Inbound HTTP Traffic
To allow all incoming HTTP connections (port 80), you must run these commands:
sudo iptables -A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 80 -m conntrack --ctstate ESTABLISHED -j ACCEPT
You only need to run the second command, allowing outbound traffic on existing HTTP connections, when the OUTPUT policy is not set to ACCEPT.
Allow All Inbound HTTPS Requests
To permit all inbound HTTPS connections (port 443), run the following commands:
sudo iptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
You only need to run the second command that permits outbound traffic over established HTTPS connections when the OUTPUT policy is set to something other than ACCEPT.
Allow All Inbound HTTP and HTTPS Traffic
When you need to allow HTTP and HTTPS traffic, it is possible to use the Multiport module to create a rule that permits both ports. Therefore, to allow all inbound HTTP and HTTPS connections (port 443), run the following commands:
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
sudo iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
Use the second command, allowing outbound traffic on existing HTTP and HTTPS connections only when the OUTPUT policy is not set to ACCEPT.