Configuring a Firewall with iptables

Configuring a Firewall with iptables

The first iptables application described in this chapter is packet-filter firewall configuration. You can use these options on either a router or a non-router system (a workstation or server). When a router is so configured, it's often referred to as a firewall computer, but there are other types of firewall as well. Configuring a packet-filter firewall requires setting a default policy and then configuring exceptions to that policy based on port numbers , IP addresses, or other criteria.

What Is a Firewall?

Traditionally, a firewall is a computer that sits between two networks and controls access between those networks. This function is similar to that of a router, but there are several potential differences. For one thing, a router without firewall functions doesn't control access in the same sense as a firewall; a firewall can block computers on one network from accessing particular services on the other network. For instance, a firewall can block Telnet access from the Internet to a protected internal network. Also, some types of firewall don't forward data packets in the way that a router does; these proxy server firewalls run special proxy server software, which partially processes requests intended for other systems, recreates the requests as coming from itself, and forwards the reply to the original system. A proxy server firewall can help protect against fairly high-level threats, such as viruses embedded in Java or JavaScript.

This section is devoted to a different type of firewall: packet-filter firewalls. These operate on a lower level of the TCP/IP stack, and are restricted to examining various types of addressing information in individual packets, or at most to tracking a transaction to ensure it's not hijacked. Although packet-filter firewalls are often implemented as part of a router, they can also be set up on a workstation or server. When so configured, the firewall works to protect the computer on which it runs, but has no effect on other computers.

Most people think of firewalls as existing to protect a local network from the Internet, as shown in Figure 25.2. Indeed, this is one of the functions of a firewall, and a very important one. Firewalls can also serve to prevent local users from attacking other systems on the Internet, though. You might use a firewall to block all but approved local protocols, and perhaps even restrict certain protocols except from particular computers. For instance, you might allow only the mail server to connect to port 25 on outside computers. (ISPs sometimes use this configuration as an anti-spam measure.) Outgoing controls provide protection against both untrustworthy individuals who have access to your local network and viruses, worms, Trojan horses and the like installed on your local computers without your knowledge. This protection most directly helps other networks, but it's ultimately important to you as well, because blocking hostile actions from your own network can keep your network from being the target of investigations by your ISP or even legal action.

Figure 25.2. Packet filter firewalls can limit some types of access while allowing others.


In some cases, you might use a firewall's rules to redirect connection attempts, as described in the upcoming section, "Redirecting Ports with iptables ." This redirection causes a packet directed at one system to be sent to another. You can use this feature in conjunction with NAT to run servers on a protected network. You might also use it with external-connection restrictions to allow a connection to succeed in a way the client doesn't expect. For instance, instead of blocking outgoing SMTP connections from anything but your mail server, you might redirect such requests to your own mail server. In the case of SMTP, the result is normal mail delivery, provided the mail server is configured to relay local mail. This particular trick won't work with most other protocols, though.

Referring to Figure 25.1, a Linux packet-filter firewall operates by configuring the INPUT , FORWARD , and OUTPUT chains. Each of these chains has its role:

  • The INPUT chain protects local processes. You should configure INPUT chain rules for both router firewalls and the firewalls on individual workstations or servers.

  • The FORWARD chain intervenes in routing. You'd configure this chain if you want to turn a router into a packet-filter firewall.

  • The OUTPUT chain blocks undesired outgoing accesses . You can use this on a standalone firewall much as you might use FORWARD or INPUT chain rules, or on a workstation or server to restrict local users' ability to contact certain hosts or use certain protocols.

A router with firewall features is most likely to use INPUT and FORWARD rules, while a workstation or server is most likely to use INPUT and OUTPUT rules. In some cases, these rules may have nearly identical effects, particularly with respect to FORWARD and OUTPUT rules on a router. The OUTPUT chain affects both forwarded and locally generated traffic, though, whereas the FORWARD chain affects only routed traffic.

Setting a Firewall's Default Policy

The first step in firewall configuration is in setting the default policy. This is a statement of what the firewall is to do with packets that don't match other rules. You set the default policy with the -P option to iptables , thus:

  # iptables -P INPUT DROP   # iptables -P OUTPUT DROP   # iptables -P FORWARD DROP  

This example sets the default policy separately on each of the three standard chains in the filter table. The default policy may be any firewall target, as described earlier ( ACCEPT , DROP , QUEUE , RETURN , or another policy enabled through an appropriate kernel option). The most common default policies are ACCEPT , DROP , and REJECT . The first is the default, and tells Linux to pass on all packets. DROP tells the system to ignore all packets; it's as if they don't exist. REJECT is like DROP , but instead of ignoring the packet, Linux tells the calling system that it can't accept the packet; it's similar to the way Linux responds if there's no process using the port. The most secure firewall configurations use DROP or REJECT as the default policy, because this means that any packet type you don't explicitly permit in subsequent steps is blocked. If you use ACCEPT as the default policy, you must remember to explicitly disallow all the packet types you don't want to let pass. This can be a tedious process, and it's easy to overlook something. With a default policy of DROP or REJECT , by contrast, you only need to explicitly allow certain protocol types. Most computers and even networks only use a few protocols, so this is generally a more manageable task.

Creating Firewall Rules

You create firewall rules by using the --append option to iptables ( -A is a shorter synonym). You follow this command by one or more criteria specifications and a --jump option ( -j being a shorter synonym), which specifies a firewall target such as ACCEPT , DROP , or REJECT . In sum, the command looks something like this:

 #  iptables --append   CHAIN   selection-criteria   --jump   TARGET  

This can be shortened by using the shorthand option names :

 #  iptables  -  A   CHAIN   selection-criteria   -j   TARGET  

There are other options you can use in place of --append :

  • --delete or -D ” This option deletes the rule from the existing chain.

  • --insert or -I ” You can insert a rule in the middle of a chain with this option. You ordinarily follow this with a rule number. If you don't, iptables inserts the rule at the top of the chain, rather than the bottom as --append does.

  • --replace or -R ” This option replaces a rule. As with --insert , you specify a rule number to replace that rule.

  • --list or -L ” This option lists the rules in the chain.

There are several additional options beyond these; consult the iptables man page for details. The following sections describe various options for the selection-criteria you may pass to iptables . You can include multiple criteria in one command; for instance, you can restrict access based on port number and IP address.



The kernel reads rules in a chain in order, and acts on the first rule that matches a packet. Thus, if you want to set up a rule with exceptions (such as denying access to the Telnet port except for local computers), you should enter the exceptions first, then the more general rule. In some sense, the default policy is a rule that comes at the end of a chain, and matches anything that's not already been matched.

Opening and Closing Specific Ports

One way to filter packets is to use specific source or destination ports. For instance, you might want to configure a mail server to pass packets sent to its SMTP port (25). You can do this by using the --destination-port ( --dport ) option. This option also relies upon the --protocol ( -p ) option, which sets the protocol type ( tcp , udp , icmp , or all for all of them). The --source-port ( --sport ) option works in a similar way, but matches the port from which the packet originated. The final command might resemble the following:

 #  iptables -A INPUT -p tcp --dport 25 -j ACCEPT  #  iptables -A OUTPUT -p tcp --sport 25 -j ACCEPT  

These commands tell the kernel to accept packets directed at port 25 for its local INPUT and OUTPUT chains. The result is that, even if the default policy is set to block packets, the system will accept incoming mail and be able to send mail to others, assuming a mail server is configured appropriately. One key point is that, if you've set the default policy to DROP or REJECT , you must normally open both the input chain to the port for a particular server and the output chain from the same server's port. If you fail to do this, your server may be able to receive packets but not reply to them, or generate packets but not receive them. On a separate firewall computer, you might want to create --destination-port and --source-port rules on the FORWARD chain, to permit SMTP transfers to pass through the firewall. You can combine these with an IP address specification, as described in the next section, "Using Source and Destination IP Addresses," to allow SMTP transfers only to and from the mail server.

If you use a default DROP or REJECT policy, it's important to open ports to allow client programs to communicate with the outside world. There are a couple of ways you can do this:

  • Open access to server ports on outside computers. This works just like the preceding example, except that -A INPUT would be paired with --source-port , and -A OUTPUT would be paired with --destination-port . On a router configured as a firewall, you'd set both --source-port and --destination-port using -A FORWARD , possibly paired with IP address specifications for your network. You must explicitly enable access for every protocol your internal clients use.

  • You can open the entire unprivileged port range, 1024 “65535. Instead of specifying a single port number with --source-port and --destination- port , you specify a range by separating the values with a colon , as in --source-port 1024:65535 . For incoming connections, you may want to add the ! --syn option. The --syn option matches only connection initiation requests, and an exclamation mark ( ! ) reverses the sense of a connection, so ! --syn allows return packets but not connection requests.

Using Source and Destination IP Addresses

You can match packets to source and destination IP addresses or network blocks with the --source ( -s ) and --destination ( -d ) options. For instance, if you know that the network block is controlled by undesirables, you could include options like the following to block all access to and from that network block in a default ALLOW configuration:

 #  iptables -A INPUT -s -j DROP  #  iptables -A OUTPUT -d -j DROP  

These options are often used in conjunction with port-based connections to allow only specific computers to access certain ports, especially in a default DROP configuration. For instance, suppose you run a firewall computer that protects a network, but you want to allow external users on the network to access your internal network's SSH servers (on TCP port 22). You might do this with options like the following:

 #  iptables -A FORWARD -s -p tcp \   --destination-port 22 -j ALLOW  #  iptables -A FORWARD -d -p tcp \   --source-port 22 -j ALLOW  

Because this example modifies only the FORWARD chain, it does not give any user direct access to the firewall computer's own SSH server (if it's even running one). You might want to add entries to give your local computers access to this server. Suppose your local network uses the network addresses. The appropriate commands would resemble the following:

 #  iptables -A INPUT -s -p tcp \   --destination-port 22 -j ALLOW  #  iptables -A OUTPUT -d -p tcp \   --source-port 22 -j ALLOW  
Filtering by Interface

Another filtering option is to use the network interface, such as ppp0 or eth1 , as an identifier. This option is most useful on a router or other computer with multiple interfaces. It can help protect against address spoofing, in which a remote system tries to contact a router using a local address, in the hopes that the router has a more lenient configuration for local computers. For the INPUT and FORWARD chains, you specify the input interface name with the --in-interface ( -i ) option; for the FORWARD and OUTPUT chains, you specify the output interface with the --out-interface ( -o ) option. For instance, suppose your internal network uses the network address space and is on the router's eth1 , while your Internet connection is on eth0 . You might use a generic anti-spoofing rule like the following:

 #  iptables -A INPUT -s -i eth0 -j DROP  #  iptables -A FORWARD -s -i eth0 -j DROP  #  iptables -A FORWARD -s ! -i eth1 -j DROP  #  iptables -A OUTPUT -s ! -i eth1 -j DROP  

The first two commands protect against packets directed at the router and internal systems from external systems (on eth0 ) that claim to be internal systems. The last two commands prevent internal systems (on eth1 ) from claiming to have IP addresses outside of the local network.

Performing Stateful Inspection

The latest addition to the Linux packet filtering firewall capabilities is stateful packet inspection. The options that have been described earlier in this chapter all operate on individual packets. There's no way to tell if a packet is part of an existing data stream or is an interloper inserted into an existing data stream by a clever attacker. (The --syn option allows you to check if a packet claims to be opening a new connection, but it's possible to have a computer send out packets that claim to be part of an existing data stream. Such packets can be used to " hijack " an existing TCP connection.) With stateful packet inspection, the kernel can track connections by using packet sequence numbers, source IP addresses, and so on. If you tell it to do so, you can have the kernel reject packets that contain errors that might indicate the session has been hijacked.

Stateful packet inspection requires using the --state option, preceded by the -m state option to load the stateful inspection capabilities of the kernel. You can pass this option one or more of several parameters. If you pass more than one parameter, you must separate them with commas. You can use an exclamation mark ( ! ) prior to the --state option to reverse its meaning. The available parameters are:

  • INVALID ” The packet can't be matched to a known connection, and thus may be forged.

  • NEW ” The packet is trying to establish a new connection.

  • ESTABLISHED ” The packet is associated with an existing connection.

  • RELATED ” The packet is not part of an existing connection, but it's related, such as an ICMP error packet.



Specifying ! --state INVALID is the same as specifying --state NEW,ESTABLISHED,RELATED .

You might want to add stateful inspection to an existing rule. For instance, suppose you have a default DROP or REJECT policy on a server, but have a rule to permit connections to and from the server's HTTP port (80). You might add a stateful inspection rule to allow only new, established, or related packets to that port:

 #  iptables -A INPUT -m state -p tcp --dport 80 \   --state NEW,ESTABLISHED,RELATED -j ACCEPT  #  iptables -A OUTPUT -m state -p tcp --sport 80 \   --state ESTABLISHED,RELATED -j ACCEPT  

This rule permits only new, established, or related incoming connections, and only established or related outgoing connections. (New outgoing connections aren't required because the connection is always created by the client, not the server whose port these rules protect.) These rules prevent an interloper from taking over a client's existing Web server connection.



Stateful packet inspection became available in Linux with the 2.4. x kernel series and iptables ; earlier kernels and packet filtering tools don't support this feature. In fact, this is one of the primary reasons you might want to upgrade an older kernel or packet filter firewall script to use iptables .

Using Additional Parameters

The iptables tool supports many additional options that may be useful in packet filter firewalls. For instance, you can create entirely new chains with the --new-chain ( -N ) option, create a rule that applies only to the second and subsequent fragments of a fragmented packet with the --fragment ( -f ) parameter, or match specific TCP flags with the --tcp-flags option. For more information on such parameters, consult the iptables man page or a book on Linux packet filter firewalls. (Be sure to get a title that covers iptables ; some older titles cover only ipchains .)

Putting It All Together

It may be useful to see an entire iptables packet filter firewall script. Listing 25.1 presents such a script. This script is designed for a Web server computer that also supports local connections using SSH for configuring the system.



Most serious firewall scripts are much longer than Listing 25.1. This script includes just a few configuration options for the two servers the computer runs, plus a few other useful rules. For readability, Listing 25.1 calls iptables without a full path, which is a potential security risk should your path be modified. Listing 25.1 may serve as a core for a more complete script, but at the very best, you'll have to customize and expand it for your network.

Listing 25.1 A sample iptables firewall script
 #!/bin/sh iptables -F INPUT iptables -F OUTPUT iptables -F FORWARD iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP # Permit DNS traffic iptables -A INPUT -p udp --sport 53 -j ACCEPT iptables -A OUTPUT -p udp --dport 53 -j ACCEPT # Accept local-network return traffic for clients iptables -A INPUT -m state -p tcp --dport 1024:65535 \   --state ESTABLISHED,RELATED -s -j ACCEPT iptables -A OUTPUT -m state -p tcp --sport 1024:65535 \   ! --state INVALID -d -j ACCEPT # Accept all HTTP connections iptables -A INPUT -m state -p tcp --dport 80 \   ! --state INVALID -j ACCEPT iptables -A OUTPUT -m state -p tcp --sport 80 \   --state ESTABLISHED,RELATED -j ACCEPT # Accept local ( SSH traffic iptables -A INPUT -m state -p tcp --dport 22 \   ! --state INVALID -s -j ACCEPT iptables -A OUTPUT -m state -p tcp --sport 22 \   --state ESTABLISHED,RELATED -d -j ACCEPT # Accept all local traffic on the lo interface iptables -A INPUT -s -i lo -j ACCEPT iptables -A OUTPUT -d -o lo -j ACCEPT 

Some key features to consider about Listing 25.1 are the following:

  • Setup and default policy ” The first six iptables commands flush the existing filter set rules and set the default policy to DROP . This creates a fairly strict security setup, and subsequent commands loosen it for the desired protocols. Although the computer for which this script is intended isn't a router, this script sets the same strict default DROP policy on the FORWARD chain, just in case another interface appears (say, because of a PPP link).

  • DNS configuration ” In order to grant the computer access to a name server, the two lines following the Permit DNS traffic comment open the computer to connections to external DNS servers (UDP port 53). This setting is actually fairly lenient. Chances are you only need access to a couple of servers, so these commands could be expanded to include references to the DNS servers'IP addresses, or perhaps to the local network on which those servers reside.

  • Client return traffic ” The lines following the Accept local-network return traffic for clients comment open the server to return traffic destined for the unprivileged ports (1024 “65,535). The OUTPUT chain specification uses stateful inspection to reject invalid connections, and the INPUT chain specification uses stateful inspection to reject all but established and related traffic. Note in particular that the INPUT chain disallows new connections, so even if the computer runs a server on an unprivileged port, other computers won't be able to connect to it. Both the INPUT and OUTPUT chain entries limit access to the local network. For a stronger firewall, you would replace these rules with more specific rules that permit traffic from unprivileged local ports to the ports used by specific protocols you might want to use from this system.

  • Web server traffic ” The computer's Web server needs to accept connections from anywhere , so the rules for this connection don't include any IP address specifications. They do use stateful inspection, though, as an anti-hijacking provision.

  • SSH server traffic ” The SSH configuration option is much like that for the Web server, but it includes an IP address restriction to ensure that only local users connect to the SSH server.

  • Loopback traffic ” Linux computers use the loopback interface ( lo ), which is associated with the IP address, for some internal purposes. This firewall script therefore explicitly allows loopback access. This configuration doesn't use stateful inspections for this purpose, but does specify that only traffic from the lo interface will be accepted on the address.

Advanced Linux Networking
Advanced Linux Networking
ISBN: 0201774232
EAN: 2147483647
Year: 2002
Pages: 203

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: