This chapter will introduce you to a common security mechanism used in networks: firewalls. A firewall is a device (usually implemented in software) that controls what traffic can enter and leave a network. If an organisation wants to protect their network, then a firewall between their internal network and all external networks (“the rest of the Internet”) will be configured to inspect the traffic entering/leaving the network, and only allow the traffic that meets the organisations policies. This chapter will show you how to setup your own simple firewall, using the command iptables. The focus is primarily on packet filtering capabilities of firewalls, as they are the building blocks of all firewalls. There is no coverage of transport or application level firewalls.
This chapter assumes you have knowledge of:
Basic Linux command line skills, as covered in Chapter 4, are assumed. You will need to be able to:
While some of the practical tasks in this chapter can be completed on a single Linux computer, to test the firewall it is beneficial to have multiple computers. You are recommended to use virtnet (Chapter 3), as it allows for quick deployment of the computers in a topology that allows running a firewall on one computer, and testing that firewall with a separate client and server computer.
The recommended virtnet topology is:
All of the practical tasks in this chapter can be completed on a single Linux computer. Most of the demonstrations use a single Linux computer, specifically node1 in virtnet (Chapter 3). Although virtnet is not required, if you do use it, as only a single computer is necessary, topology 1 is appropriate (or in fact any topology—just use a single node).
Firewalls are network devices that control what packets enter and leave a computer network. Typically a company (and more recently, a home user) will use a firewall to stop people outside the company network (that is, everyone on the external Internet) from accessing computers and resources inside the company network. For example, consider a firewall protecting the internal networking of a univeristy. The firewall can be used to:
The firewall can also be used to control what computers inside the network access. For example:
The firewall is usually a specialised router that acts as a gateway between the local network and the outside networks. That is, all traffic goes through the firewall. Figure 13.1 illustrates the view of a router, R, running a firewall, where one interface is connected to the outside and the second interface is connected to the inside network.
In the practical tasks in this chapter we will use a Linux computer to act as a simple firewall.
A gateway router (that is, the router between the inside and outside networks) normally receives an IP packet, looks at the destination IP address, looks up its routing table to determine where to sends the packet, and sends (or forwards) the packet.
A firewall is hardware or software running on the gateway router that provides additional functionality:
The rules used by firewalls are the most important aspect. They can be very simple (e.g. “drop all packets destined to the local network”) or very complex (e.g. 1000’s of rules).
Packet-filtering firewalls usually create the rules using the following information:
Using the above conditions, a reasonably good firewall can be built that can filter packets based on where the packets are coming from, where they are going to, and what applications are being used (remember, if a destination port number is 80, we can assume that a web browsing application is being used—if a university wanted to stop all web browsing, then they could drop all packets destined to port 80).
More complex firewalls (application-level firewalls) can be created by not only looking at the TCP/IP packet information, but also looking at the content of the messages. For example:
Most applications operate in a client/server mode, where a client inside a network accesses a server outside the network. Most computers inside the network DO NOT run servers accessible to the outside network. For example, there is no need for a university student’s PC to run a web server accessible to someone outside the university.
Therefore, it is common for firewalls to be setup that will:
Although the above cases can become quite complex in practice, very basic rules can be used to implement a simplified firewall that performs this functionality.
iptables is a program on Linux that can be used to create a firewall. It allows the user to create a set of rules. Then when packets are received by the computer, the rules are processed. The packet is only sent if accepted by the rules.
With iptables the firewall is configured with tables of filters. The most common table is simply called filter, but there are others such as mangle (for modifying packet contents) and nat (for performing Network Address Translation (NAT)). Each table contains chains, as described in Section 13.3.1, and chains contains rules, as described in Section 13.3.2.
iptables defines classes of rules called chains). Rules from each chain are applied based on where the packet is from/going to, as illustrated in Figure 13.2.
On host-based firewalls, the main chains are INPUT and OUTPUT, since the packets are either destined to that host (INPUT) or sent from that host (OUTPUT).
For network-based firewalls on routers, the main chain is FORWARD, since the packets are forwarded by the router from one network to another. The router/firewall is not usually the original source or final destination of packets.
The PREROUTING and POSTROUTING chains are used for NAT or sending packets with fake source addresses (Section 17.2).
Rules in iptables consist of:
A packet is checked against rules in a chain, from first rule to the last rule. If the packet does not match the rule, then the next rule is processed. If a packet does match a rule, then the action as specified by the target is taken. If no rules match, then a default action is taken. The default action is referred to as the table policy.
The iptables command is used to add, delete and list rules in a chain. We will use a set of examples to show the syntax for common operations. See the man page for more details.
The following sections will give examples of general firewall rules, and then implementation of those rules with iptables. Note that other firewall software/hardware may use a different syntax and terminology, but the concepts will be the same. Also, this section does not use virtnet, but rather refers to a general (fake) network. Therefore you cannot test these comments; rather use them to learn the syntax and ideas of iptables.
We will use the example network in Figure 13.3, which shows a small internet. Hosts (e.g. PCs, laptops, servers) are drawn as squares. Routers that connect subnets together are drawn as circles. The ovals are the subnets. The IP address of a device (host, router interface) can be determined using the subnet address and the value inside the device.
We will first assume the firewall is running on the host, specifically 1.1.1.12 in Figure 13.4. This firewall is protecting only that host. An example of this is that the host is a server.
The following sections will give a security aim or policy, and then show how to implement that as a set of rules first, followed by the syntax for creating those rules with iptables.
Ping is an application used for testing network connectivity and response times (see Section 9.5). It uses ICMP as the transport protocol, inside IP packets.
The aim is to prevent ping from working on computer 1.1.1.12. To achieve this at the protocol level, we will drop all ICMP packets in and out of this computer. The design is:
The implementation with iptables is achieved with:
fwadmin@1.1.1.12:~$ sudo iptables -A INPUT -p icmp -j DROP
fwadmin@1.1.1.12:~$ iptables -A OUTPUT -p icmp -j DROP
The way to read the first iptables command is: “Append a rule to the INPUT chain. The rule matches packets that use transport protocol icmp. When a packet matches then jump to the action DROP.”
Video: iptables Syntax Example including Blocking Ping and TCP (21 min; Mar 2016)
Use the -L option to list the current set of rules. You can also use -n to show the rules using numeric addresses (rather than hostnames).
fwadmin@1.1.1.12:~$ iptables -L -n
Chain INPUT (policy DROP)
target prot opt source destination
DROP icmp -- 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DROP icmp -- 0.0.0.0/0 0.0.0.0/0
To list the rules in a particular chain, specify the chain name (in all uppercase) as the command parameter.
fwadmin@1.1.1.12:~$ iptables -L -n INPUT
Chain INPUT (policy DROP)
target prot opt source destination
DROP icmp -- 0.0.0.0/0 0.0.0.0/0
Use the -F option to flush or delete all rules:
fwadmin@1.1.1.12:~$ sudo iptables -F
fwadmin@1.1.1.12:~$ iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Check the man page for other options, such as deleting individual rules.
Now we will consider a different example with the firewall running on router Ra, and protecting the subnet 1.1.1.0. That is, from the firewalls perspective, subnet 1.1.1.0 is internal, and all other subnets are external.
When a firewall is on a router (as opposed to host) then it normally has rules for packets that are forwarded through it, and hence we deal with the FORWARD chain.
The security policy is to prevent all external hosts from accessing the SSH server on internal host 1.1.1.11. Note that SSH application protocol uses TCP as a transport protocol, and a SSH server uses port 22.
Since SSH is a request/response application from client to server, to stop it working you only need to DROP the initial request to the server. If the initial request is never received by server, then there will never be a follow up response. This is used for many Internet applications: to block them, just block access to the server.
The firewall design is:
The implementation with iptables is achieved with:
fwadmin@Ra:~$ sudo iptables -A FORWARD -p tcp --dport 22 -d 1.1.1.11 -j DROP
The way to read the rule is: “Append a rule to apply to all FORWARDed packets. The packets must use transport protocol tcp and must be going to destination port 22. They must also be going to destination IP 1.1.1.11. If packets match these conditions then jump to the DROP action.
The security policy is to prevent the internal host 1.1.1.12 from accessing any web servers in the subnet 3.3.3.0/24.
The firewall design is:
The implementation with iptables is achieved with:
fwadmin@Ra:~$ sudo iptables -A FORWARD -p tcp --dport 80 -s 1.1.1.12
-d 3.3.3.0/24 -j DROP
This is imilar to the SSH example, but web servers use port 80 and the packets must come from source IP 1.1.1.12. In practice the rules can get complicated quite quickly. Web servers use port 80 and port 443 (for HTTPS) so rules for both will be needed.
Up until now, if a packet did not match any of the rules, then action taken on that packet is to accept it. That is, the default firewall policy is accept. Alternative is to set the default policy to drop. What default policy should be used? A brief comparison of the two follows.
The permissive approach is to accept by default.
The restrictive approach is to drop by default.
While you may choose, generally the restrictive approach is recommended.
To change the policy with iptables use the -P option:
fwadmin@Ra:~$ sudo iptables -P DROP
In this example we are using the default policy of drop. The security policy is to allow all external hosts to access the internal web server on 1.1.1.11 (considering only port 80).
The design is:
Unfortunately since clients obtain random/dynamic ports, we cannot set the browser/client port in the firewall rule. So we must allow communications from any port to port 80 on the server. This creates potential security holes, as malicious software on 1.1.1.11 can send packets out using the source port 80 (it is easy for malicious software to choose any source port). SPI will solve this problem in Section 13.5.
The implementation with iptables is achieved with:
fwadmin@Ra:~$ sudo iptables -P DROP
fwadmin@Ra:~$ sudo iptables -A FORWARD -p tcp --dport 80 -d 1.1.1.11 -j DROP
fwadmin@Ra:~$ sudo iptables -A FORWARD -p tcp --sport 80 -s 1.1.1.11 -j DROP
The above implementation could be improved by specifying the direction of packets. One way to do this is identifying the input interface or output interface using the -i and -o conditions, respectively. See the man page for details.
A traditional packet filtering firewall makes decisions based on individual packets. Each arriving packet is compared against a table of rules and the decision for that packet is made. When making a decision for one packet, the outcome of previous packets is not considered. Thus, the firewall is stateless. However many Internet applications are stateful, especially connection-oriented applications. A connection is established between client and server, and a group of packets belong to that connection. To create firewall rules that implement security policy, it is often easier to define rules for connections (and all packets belong to the connection), rather than individual packets. To do so, the firewall needs to store information about the connection, in particular past packets. That is, the firewall must be stateful. Stateful Packet Inspection (SPI) is an extension of traditional (stateless) packet filtering firewalls that allow rules and decisions to be made for connections. The benefits of SPI include:
The storage of connection/state information in an SPI table incurs extra overhead on firewalls, but with today’s computers that overhead is negligible. Hence SPI is a feature on almost all firewalls today.
When SPI is available, the steps for packet processing at the firewall are:
In summary, there are now two tables: the normal firewall rules and the SPI table that keeps track of the ACCEPTed connections.
To turn on SPI feature in iptables:
fwadmin@Ra:~$ sudo iptables -P FORWARD DROP
fwadmin@Ra:~$ sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
First we set the Policy for FORWARDed packets to DROP. Then we Append a rule for FORWARDed packets. The rule uses the module for stateful packet inspection. All packets that belong to an ESTABLISHED connection or are RELATED to a current connection are ACCEPTed.
If an initial TCP Syncrhonise (SYN) packet is accepted, then the SYN/ACK and ACK are RELATED and automatically accepted. Once a TCP connection is established via the 3-way handshake, all data packets, ACK packets and FINish packets are automatically accepted.
Now let’s implement the security policy that will allow all external hosts to access web server on 1.1.1.11. The design is:
The implementation is:
fwadmin@Ra:~$ sudo iptables -A FORWARD -p tcp --dport 80 -d 1.1.1.11 -j ACCEPT
The benefit of SPI is that we only need to write a single rule that will cover packets in both directions. The firewall rule accepts the first packet coming in to the server, and SPI automatically accepts all subsequent packets. This greatly simplifies the firewall rules the admin needs to create (less chance of errors, more secure).