Establishing a good firewall is an imperative step in securing an instance. The majority of Linux distributions include various firewall tools which we can use to set up our firewalls. Iptables is a standard firewall that is included by default in most Linux distributions. Using a set of rules, this firewall determines what to do by matching each packet passing through the network card.

We will discuss the iptables firewall in this guide.

How Does Iptables Work?

Before we start looking at the commands necessary to control iptables and build firewall rules, we will review some of the terms used in this firewall and see how iptables works.

The iptables firewall works by matching network traffic with a set of rules. Using the rules, it will determine what characteristics a packet must have for it to match the rule, and also what actions should be taken to match the packets to the rule.

Many options are available to specify which packets match a particular rule. You can take into account the packet’s protocol type, source or destination address or port, the interface used, its relation to previous packets, and more.

When the defined pattern matches, the action that is performed is called a target. A target could be a final decision on handling the packet, such as accepting or rejecting it. The packet can also be moved to another chain for processing or it can simply be logged.

Such rules are arranged in groups called chains. Each chain is a set of rules used to check a packet in sequence. In case the packet matches one of the rules, it will perform the appropriate action and it will not be checked with the rest of the rules in the chain.

If necessary, the user can create a chain. Three chains are defined by default:

  • INPUT: This chain will handle all packets sent to your instance.
  • OUTPUT: This chain includes rules for traffic that is generated by your server.
  • FORWARD: This chain is used to manage traffic to other servers that are not generated on your server. With this chain, you can configure your server to forward requests to other machines.

Note that each chain may contain zero or more rules and has a default policy. It is this policy that defines what happens should a packet pass through all the rules in the chain and fail to match any of them. If there is no match, you can reject or accept the packet.

You can also use iptables to keep track of connections using a module which is loaded by rules. In other words, you can create rules for what happens to a packet based on its relation to previous packets. This feature is called “State Tracking”, “Connection Tracking” or “State Machine” configuration.

Important Notes About Iptables

So now that we know how iptables routes packets coming through its interface (forwarding the packet to the appropriate chain, checking it against each rule until one matches, then applying the chain’s default policy if no match is found), we can explore some of the important things about defining rules.

First, we must ensure that we have rules to keep current connections active by applying the default policy of drop or block. This is particularly important if you are using SSH to connect to your server. Should you accidentally run a rule or policy that disrupts your current connection, it is always possible to connect to your instance via the console.

One more thing to keep in mind is the order of the rules in each chain. When a packet is expected to match a specific rule, it should not come across a more general rule that it will match.

This is why the rules at the start of a chain are supposed to have a higher specificity than those at the end. At first, you should match specific cases and thereafter provide more general rules for matching broader patterns. When a packet does not match any rule, it will hit the most general rule, which is the default policy.

What a chain’s default policy is will have a large impact on the types of rules that are added to the chain. For example, a chain having the default policy ACCEPT will contain rules that explicitly drop packets. However, a chain with a default value of DROP will contain exceptions for packets which should be explicitly accepted.