Brief Introduction to Netfilter / iptables

[TOC]

What is netfilter / iptables

In general

  • Netfilter refers to the whole project, otherwise the official website would not be called www.netfilter.org. 
  • In this project, netfilter, in particular, is the framework in the kernel. The iptables is the user-space configuration tool.
  • Iptables is a command-line interface to the packet filtering functionality in netfilter. It makes use of policy chains to allow or block traffic. When a connection tries to establish itself on your system, iptables looks for a specific rule in its list to match. If it doesn’t find one, it resorts to the default action.

The Components Of Iptables

The packet filtering mechanism provided by iptables is organized into three different kinds of structures: tables, chains and targets. Specifically, a table is where sets of rules locate and they have chains that attached to them. Chains in iptables enables traffic inspections on various points, such as the when packets arrive on a network interface or before handing them over to a process. In chains, rules are defined to match certain packets, like TCP packets transporting to port 22(ssh), and to associate packets to targets.  A target is the final decision made on packets. It can be ‘ACCEPT’, ‘REJECT’ or ‘DROP’.

How Does Iptables Work

When a packet arrives (or leaves, depending on the chain), iptables matches it against rules in these chains one-by-one. When it finds a match, it jumps onto the target and performs the action associated with it. If it doesn’t find a match with any of the rules, it simply does what the default policy of the chain tells it to. The default policy is also a target. By default, all chains have a default policy of allowing packets.

Basic Concepts

Tables

If you take a closer look at the Netfilter modules directory, you’ll find modules with a variety of features that only provide some filtering capabilities, and if you want to use Netfilter, It also needs to be given the “rules” to execute. Once the rules are set, Netfilter knows which packets are passing, which packets are blocked, and which packets are being replaced for processing. 

According to the function division, Netfilter is divided into five functions: filter, nat, mangle, raw and security, from which five tables are derived. the main functions are as follows: 

  • raw is used only for configuring packets so that they are exempt from connection tracking.
  • filter is the default table, and is where all the actions typically associated with a firewall take place.
  • nat is used for network address translation, e.g. port forwarding).
  • mangle is used for specialized packet alterations.
  • security is used for Mandatory Access Control networking rules (e.g. SELinux – see this article for more details).

Note: In most common use cases you will only use two of these: filter and nat. The other tables are aimed at complex configurations involving multiple routers and routing decisions and are in any case beyond the scope of this guide.

Chains

Tables consist of chains, which are lists of rules which are followed in order. Different Tables contain different chains, which is as follow.

Tables↓/Chains→ PREROUTING INPUT FORWARD OUTPUT POSTROUTING
raw      
mangle
nat (DNAT)      
filter    
security    
nat (SNAT)      

Rules

The rule is stored on a specific chain for a particular table, and each rule contains the following two parts of information:

Matching.  Matching is how to match a packet with many matching conditions, such as protocol type, source / destination IP, source / destination port, in/out interface, data in the header, connection status, and so on. These conditions can be arbitrarily combined to achieve matching in complex cases. For more information, please refer to Iptables matches.

Targets.  Targets is what to do when a matching packet is found. the common ones are the following: 

DROP: discards packets directly and no longer performs subsequent processing. 

RETURN: jumps out of the current chain, the subsequent rule in the chain is no longer executed. 

QUEUE: puts packets in user-space queues for processing by user-space programs. 

ACCEPT: allows the packet to pass and continues to execute the subsequent rule. 

Or jump to another user-defined chain to continue execution. 

Of course, iptables contains a lot of targets, but not every table supports all targets,  The target supported by rule is determined by the table and chain in which it is located, as well as the extensions turned on, and the targets supported by each table is referred to Iptables targets and jumps.

Traversing Chains

A network packet received on any interface traverses the traffic control chains of tables in the order shown in the flow chart (If a packat has been DROPed, it will leave the traffic.). When a packet passes through each chain on the path, each rule in the chain matches sequentially.

tables traverse

Usage

Command Format

Iptables should be run as root or with sudo:

# iptables [-t table] command [chain] [rulenum] [matchings] [-j target]

table: specifies table names, such as filter table, raw table, mangle table, nat table. By default it is filter table.

command: operations on a chain, such as -A for an append rule, -I for an insert rule and -D to delete a rule. 

chain: chain names, such as INPUT chain, OUTPUT chain, FORWARD chain, PREROUTING chain, POSTOUTING chain. 

rulenum: the number of the rule you would like to operate.

matchings: limitations of the rule, such as -p protocol to specify a certain packet type, -s/d to specify source/destination address, etc.

target: How action is going to be performed, i.e. processing method, such as, ACCEPT (through), DROP (discard) or REJECT (discard and respond to an Destination Unreachable ICMP packet on the sender), when the conditions in the mentioned rule match.

Examples on Different Chains

PREROUTING&POSTROUTING

What is prerouting and postrouting?

Prerouting takes place before all the routing table processes. That is, when the packet is arrived at your gateway, before that packet is processed, it gets done with the prerouting rule.

Postrouting takes place when the packet goes out from your system. that is, after all the processing and when the packet is about to leave the system, the postrouting rule will be executed.

What Prerouting & Postrouting can do in tables?
Prerouting:

DNAT:

  • Destination NAT is when you alter the destination address of the first packet: i.e. you are changing where the connection is going to. Destination NAT is always done before routing, when the packet first comes off the wire. Port forwarding, load sharing, and transparent proxying are all forms of DNAT.

MANGLE

  • The mangle PREROUTING chain used to set netfilter, routing and SEC marks, both on a per packet basis and on a per connection basis.
    Postrouting:

    SNAT:

  • Source NAT is when you alter the source address of the first packet: i.e. you are changing where the connection is coming from. Source NAT is always done post-routing, just before the packet goes out onto the wire. Masquerading is a specialized form of SNAT.

MANGLE

  • The POSTROUTING chain in the mangle table is mainly used when we want to do mangling on packets before they leave our host, but after the actual routing decisions. This chain will be hit by both packets just traversing the firewall, as well as packets created by the firewall itself.
Examples:

Prerouting:

  • DNAT
    • redirect any traffic that just reached the server on port 80 to the port 8080
      • iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 80 -j REDIRECT –to-port 8080
    • set a rule for routing incoming HTTP requests to a dedicated HTTP server at 10.0.4.2 (outside of the 192.168.1.0/24 range of the LAN), NAT calls a PREROUTING table to forward the packets to their proper destination
      • iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 80 -j DNAT \ –to-destination 10.0.4.2:80
    • all packets arriving on the router with a destination of 10.10.20.99 will depart from the router with a destination of 10.10.14.2.
      • iptables -t nat -A PREROUTING -p tcp -d 10.10.20.99 –dport 80 -j DNAT –to-destination 10.10.14.2
    • full network address translation, as performed with iproute2 can be simulated with both netfilter SNAT and DNAT, with the potential benefit (and attendent resource consumption) of connection tracking
      • iptables -t nat -A PREROUTING -d 205.254.211.17 -j DNAT –to-destination 192.168.100.17
      • iptables -t nat -A POSTROUTING -s 192.168.100.17 -j SNAT –to-destination 205.254.211.17
  • MANGLE
    • The most common reason is to alter the Type of Service (TOS) field. This field is read by the Linux kernel and alters a packets priority. Maximum reliability (4 or 0x04)
      • iptables -t mangle -A PREROUTING -p tcp –dport 25 -j TOS –set-tos 0x04
      • iptables -t mangle -A PREROUTING -p tcp –sport 25 -j TOS –set-tos 0x04
    • Mark all packet coming from 192.168.2.0/25 with number 1
      • iptables -A PREROUTING -t mangle –match mark –mark 1 -j ACCEPT
    • Drop all packets which has been mark with number 1
      • iptables -A PREROUTING -t mangle -i eth1 -j MARK –set-mark 1

Postrouting:

  • SNAT
    • Change source addresses to 1.2.3.4
      • iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to 1.2.3.4
    • Change source addresses to 1.2.3.4, 1.2.3.5 or 1.2.3.6
      • iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to 1.2.3.4-1.2.3.6
    • Change source addresses to 1.2.3.4, ports 1-1023
      • iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT –to 1.2.3.4:1-1023
  • MANGLE
    • we can mark a packet with a number. This is done with the –set-mark facility.
      • iptables -t mangle -A POSTROUTING -p tcp –dport 80 -j MARK –set-mark 10
      • iptables -t mangle -A POSTROUTING -d 8.8.8.8 -j MARK –set-mark 20

FORWARD

This chain could be confused with the output chain, due to their functional similarity. Rules in the FORWARD chain would be applied on any data packets that are destined to other hosts. Normally, this chain is associated with tables in iptables including ‘filter’,’mangle’, and ‘security’.

Setting up rules in the FORWARD chain is often seen as an effective approach to boost cybersecurity. One of its most prevalent application is restricting access to confidential information(websites) or physical resources(ports). Here are some examples for FORWARD chain using iptables.

We firstly need to check temporary FORWARD tables. The default one is empty.

➜ sudo iptables -L FORWARD
Chain FORWARD (policy DROP)
target     prot opt source               destination   

We try to prevent users to access to youtube.com. We try to insert a new rule into FORWARD table and show what has changed.

➜ sudo iptables -I FORWARD -d www.youtube.com -j DROP
➜ sudo iptables -L FORWARD
Chain FORWARD (policy DROP)
target     prot opt source               destination
DROP       all  --  anywhere             lga15s48-in-f206.1e100.net 
DROP       all  --  anywhere             ord30s31-in-f14.1e100.net 
DROP       all  --  anywhere             ord38s19-in-f14.1e100.net 
DROP       all  --  anywhere             ord38s01-in-f14.1e100.net 
DROP       all  --  anywhere             ord37s03-in-f110.1e100.net 
DROP       all  --  anywhere             ord37s08-in-f14.1e100.net 
DROP       all  --  anywhere             ord38s08-in-f14.1e100.net 
DROP       all  --  anywhere             ord36s01-in-f14.1e100.net 
DROP       all  --  anywhere             ord30s21-in-f78.1e100.net 
DROP       all  --  anywhere             ord31s21-in-f14.1e100.net 
DROP       all  --  anywhere             ord38s04-in-f14.1e100.net 
DROP       all  --  anywhere             lga15s46-in-f46.1e100.net 
DROP       all  --  anywhere             ord37s18-in-f14.1e100.net 

One thing noteworhty is that the upper procedure is not the same as the one in OUTPUT chain, because this chain is always used in a LAN environment. If you ping youtube after running the command shown above, you can still get ICMP packets from the server. But if you run this script in an router/switch which is responsible to transfer all the requests from internal network to external one, all the requests sending to youtube.com must be filtered out when they pass through this FORWARD chain. Then, all the requests packets will be dropped.

INPUT

‘INPUT’ is a chain that exists in the default table ‘filter’. It is used to controls the behavior of any incoming connections. Rules in this chain apply to packets just before they are given to a local process. By default, INPUT chain accepts all connections, which allows any packets from network to reach local processes. That would leave the system vulnerable to attacks. So for cybersecurity purpose, it is alway desirable to employ rules in INPUT chain as the last lines of defence before malicious data goes to processes to block suspicious connections.

To beef up the cybersecurity, many strategies can be applied in the INPUT chain. The most straightforward approach would be setting up a blacklist to block known threats. The threats could be spammers or requests that made to suspicious ports, like computer scanning for unprotect ports. By explicitly adding known suspicious IPs to the list, iptables can drop any connections from them.

➜ iptables -A INPUT -s 192.168.0.119 -j DROP 
OR
➜ iptables -A INPUT -s 192.168.1.0/24 -j DROP

For a server on which a web application is running, we have to leave ports like 80,8080 or 443 visible to the public in order to receive requests from clients. However, by relaxing the constraint on these two ports, we also open the door to attacks. One of the most prevalent attack on a web server would be DoS which involves flooding requests to a server to disrupt its services. But iptables is equipped with the ability to prevent.

➜ iptables -A INPUT -p tcp -dport 80 -m limit --limit 2000/minute --limit-burst 4000 -j ACCEPT

Enabling ping reception is often considered as a potential risk. Since ICMP echo contains a data component, it can be exfiltrating data or being used as a control channel, or being used as a tunneling protocol. For that reason, to disable ping would be a recommended practice, especially for a server that is not publicly-visible.

➜ iptables -A INPUT -p icmp -j DROP -i eth0

Even ping is considered acceptable in some cases, it is advisable to only allow ICMP echo to pass.

➜ iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

Except for blacklist strategy, another common but practical approach would be whitelist. As opposed to blacklist, any ports and protocols that included in the list would be made visible/detectable to the public and the rest would be protected. To this purpose, we need to set the default target to ‘DROP’ for INPUT chain, then add specified ports back to the whitelist.

➜ iptables -P INPUT DROP
➜ iptables -A INPUT -i lo -j ACCEPT 
➜ iptables -A INPUT -p tcp -dport 22 -j ACCEPT 
➜ iptables -A INPUT -p tcp -dport 80,443 -j ACCEPT

In addition, a IPs whitelist could be introduced to make a port available only to the specified IPs.

➜ iptables -A INPUT -p tcp -dport 22 -s 192.168.1.0/24 -j ACCEPT

OUTPUT

The ‘output’ chain contains rules that would be applied on the data packets that produced by the local process.

Block Website with URL

When we aim to prevent users from accessing a certain website, the easiest way we can come up with is to add a rule to the OUTPUT chain.

Firstly, we can see there is no rule in the OUTPUT chain in the filter table.

➜ sudo iptables -L OUTPUT
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

In case you might have some rules already, we would better backup what already exists in the chain.

➜ sudo iptables-save > iptables.backup

Here we would like to block www.youtube.com with URL. To that purpose, we should adopt the following rule.-A here means to append. -d here means destination is www.youtube.com. -j means the target you would like to jump.

➜ sudo iptables -A OUTPUT -d www.youtube.com -j DROP

After running the upper command, we can see that we have a few new rules in the table. Any packets that are destined for the addresses list in the destination column would be dropped.

➜ sudo iptables -L OUTPUT                           
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       all  --  anywhere             ord37s08-in-f14.1e100.net 
DROP       all  --  anywhere             ord36s02-in-f14.1e100.net 
DROP       all  --  anywhere             ord37s19-in-f14.1e100.net 
DROP       all  --  anywhere             ord31s22-in-f14.1e100.net 
DROP       all  --  anywhere             ord36s04-in-f14.1e100.net 
DROP       all  --  anywhere             ord37s09-in-f14.1e100.net 
DROP       all  --  anywhere             lga15s49-in-f14.1e100.net 
DROP       all  --  anywhere             ord30s26-in-f14.1e100.net 
DROP       all  --  anywhere             lga15s47-in-f78.1e100.net 
DROP       all  --  anywhere             ord38s09-in-f14.1e100.net 
DROP       all  --  anywhere             ord38s04-in-f14.1e100.net 
DROP       all  --  anywhere             ord38s01-in-f14.1e100.net 
DROP       all  --  anywhere             ord30s25-in-f206.1e100.net 
DROP       all  --  anywhere             lga15s46-in-f46.1e100.net 
DROP       all  --  anywhere             ord37s07-in-f46.1e100.net 
DROP       all  --  anywhere             ord30s22-in-f14.1e100.net 
DROP       all  --  anywhere             ord36s01-in-f14.1e100.net 
DROP       all  --  anywhere             ord38s08-in-f14.1e100.net 
DROP       all  --  anywhere             ord31s21-in-f206.1e100.net 

Now we try to open www.youtube.com with the chrome brower and the attempt should fail. (This would recover after a while. The reason behind it might be that our DNS got some new destinations pointed to youtube but not in our table. Our dear Google has this feature to protest agaist potential threats.)

Then we try to ping www.youtube.com, which failed as well.

➜ ping www.youtube.com -c 4
PING youtube-ui.l.google.com (172.217.4.78) 56(84) bytes of data.
ping: sendmsg: operation not permitted
ping: sendmsg: operation not permitted
ping: sendmsg: operation not permitted
ping: sendmsg: operation not permitted

--- youtube-ui.l.google.com ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3074ms

At last, do not forget to recover the backup.

➜ sudo iptables-restore < iptables.backup 

The example is just to show how iptables works on OUTPUT. This way is not very effective apparently. In order to block a website, we need more other operations.

References

  1. https://netfilter.org/documentation/HOWTO/packet-filtering-HOWTO.html
  2. https://www.digitalocean.com/community/tutorials/a-deep-dive-into-iptables-and-netfilter-architecture
  3. https://wiki.archlinux.org/index.php/Iptables