Help

Configuring the iptables Firewall

Iptables is a firewall for Linux operating systems that controls how network traffic passes through. When someone tries to connect to the server (or the server sends a request), iptables checks the chain of rules for that particular connection and applies the configured settings.

Iptables is installed by default in all modern Linux distributions.

Chain types

There are three types of iptables chains: INPUT, OUTPUT and FORWARD.

  • INPUT — this chain is used to handle incoming connections.
  • OUTPUT — used for outgoing connections.
  • FORWARD — used to handle transit traffic, for example on a router. If you are not configuring routing, you will not need rules of this type.

A chain is an ordered set of rules. Each rule includes a criterion (for example, the packet's source IP address) and an action to apply to a packet that matches this criterion (for example, "allow"). If no criterion is specified, the rule applies to all packets.

When deciding what to do with a packet, iptables goes through the corresponding chain from the top of the rule list, checking the rules one by one until it finds a match. If no match is found (the connection does not match any of the rules you created), the default rule is applied.

When configuring iptables rules, keep in mind that for many ports, a connection must be established and a response received for data to be transferred successfully. Also be careful not to accidentally lock yourself out: for example, a remote SSH connection to the server is also an incoming connection.

Connection actions

There are three types of actions that can be applied to connections:

Accept — allow the connection.

Drop — ignore (block) the connection without notifying the source that it was blocked. This is recommended for handling traffic on internet-facing ports, since attackers get minimal information when scanning ports.

Reject — reject the connection and notify the source of the request that it was blocked. By default, an "icmp-port-unreachable" response packet is sent, but you can also configure the message (for example, "icmp-host-unreachable", "icmp-net-prohibited", "icmp-host-prohibited" and others).

Configuring rules

In this article, the general format for configuring rules is as follows:

iptables action chain rule

We omit the table from this format because we are covering the main filter table, which iptables commands use by default. There is no need to specify this table explicitly.

Action in this context is the operation to perform on the rule (for example, add or delete it).

Examples of available iptables actions:

  • -A — append a rule to the chain;
  • -I — insert a rule into the chain at a specified position;
  • -D — delete a rule;
  • -F — delete all rules;
  • -L — list all rules in the current chain;
  • -P — set the default policy.

Additional options:

  • -p — specify the packet protocol;
  • -s — specify the packet's source IP address;
  • -j — specify how to handle the packet (allow, block, etc.).

Viewing existing rules

To list all rules, use the following command:

iptables -L

Or a command with more detailed output:

iptables -L -n -v

You can also view the rules for a specific chain, for example the INPUT chain:

iptables -L INPUT

Default rules

If none of the rules you created matches an incoming packet, the default rule is applied.

To view the default rules, run the following command:

iptables -L | grep policy

If you have not changed the default policy, all chains are initially set to allow.

Configuring the iptables Firewall

To set the default rule, use the -P option, for example:

iptables -P FORWARD DROP

Configuration examples

To add a rule to an existing chain, run the command:

iptables -A

If you need to place a rule somewhere other than the end of the list, you can use the following command format and specify the rule's position in the list:

iptables -I chain number rule

For example, the following rule will be the first in the INPUT chain:

iptables -I INPUT 1 --dport 80 -j ACCEPT

To block all incoming connections from a specific IP:

iptables -A INPUT -s 1.2.3.4 -j DROP

To block connections from a specific subnet:

iptables -A INPUT -s 1.2.3.4/24 -j DROP

You can specify either an IP address or a host as the source. For example, to deny all connections from test.domain.ru:

iptables -A INPUT -s test.domain.ru -j DROP

To deny connections from hosts other than test.domain.ru:

iptables -A INPUT ! -s test.domain.ru -j DROP

To allow access to port 25 (SMTP) for everyone:

iptables -A INPUT -m state --state NEW -p tcp --dport 25 -j ACCEPT

To block port 25 (SMTP) for everyone (just replace ACCEPT with DROP):

iptables -A INPUT -m state --state NEW -p tcp --dport 25 -j DROP

To open the Apache ports to everyone:

iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT 
iptables -A INPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT

To allow access to port 3306 (MySQL) for a specific IP:

iptables -A INPUT -s 1.2.3.4 -p tcp -m tcp --dport 3306 -j ACCEPT

To set up logging:

iptables -A INPUT -p tcp -m multiport --dports 22,53,8080,139,445 -j LOG --log-level INFO --log-prefix "New connection from 1.2.3.4/24:" 
iptables -A INPUT -s 1.2.3.4/24 -m multiport --dports 22,8080,139,445 -j ACCEPT

With this configuration, every new connection to the server from the 1.2.3.4/24 subnet will be recorded in the log.

To protect against common attacks, you can add the following settings:

To block all "invalid" packets:

iptables -A INPUT -m state --state INVALID -j DROP

To block null packets:

iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

To protect against SYN flood attacks:

iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP 
iptables -A OUTPUT -p tcp ! --syn -m state --state NEW -j DROP

To block fragmented packets and protect against ping floods:

iptables -A INPUT -p icmp --fragment -j LOG --log-prefix "ping flooding" 
iptables -A INPUT -p icmp --fragment -j DROP

To block ping:

iptables -A INPUT -p icmp --icmp-type echo-request -j DROP 
iptables -A INPUT -i eth0 -p icmp --icmp-type echo-request -j DROP

To allow ping from specific addresses:

iptables -A INPUT -s 1.2.3.4 -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -s 1.22.33.44 -p icmp --icmp-type echo-request -j ACCEPT

To limit the number of simultaneous connections (connlimit) to port 80 to 5:

iptables -A INPUT -p tcp -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -m connlimit --connlimit-above 5 --connlimit-mask 32 -j DROP

Saving changes

To make sure the rules you created stay in effect even after a system reboot, you need to save them.

On CentOS, use the following command:

/sbin/service iptables save

If you use Debian or Ubuntu, it is recommended to install the iptables-persistent package to save the rules. You can install it with the following command:

apt install iptables-persistent

During installation, you will be asked whether to save the current rules. Answer "Yes".

After changing the iptables rules, save them by running the command:

netfilter-persistent save

Deleting rules

To delete a specific rule, use the -D option, for example:

iptables -D INPUT -s 1.2.3.4 -j DROP

To delete all rules, run the following command:

iptables -F

To delete the rules for a specific chain, run the command:

iptables -F INPUT

Have more questions about Hosting?