Linux Networking: Using Ipchains

By: William Wong
Monday, July 24, 2000 08:05:03 AM EST
URL: http://www.linuxplanet.com/linuxplanet/tutorials/2100/1/

Multiple Machines, A Single Connection

Linux can route network traffic from one network segment to another. Routing is normally done on a PC with two or more network adapters. This article presents a configuration using a pair of Ethernet adapters. More specifically, the article examines how a Linux computer can link a local network to the Internet through an Ethernet-attached device like a cable modem or a DSL modem. The article examines the basic concepts pertaining to routing, network address translation (NAT), firewalls, and a program called ipchains.

Individual sections address each concept. The last section combines the basics into a sample configuration for linking a local network to the Internet.

Routing 101
Routing can be done using a number of network protocols but the IP protocol is the one that is addressed in this article. IP is also the protocol used on the Internet. The previous articles address configuration of the IP protocol for network adapters on a Linux computer.

Linux can implement very complex routing using multiple network adapters, but most configurations utilize a pair of network adapters. These can be any combination from a pair of Ethernet adapters to an Ethernet adapter and a modem. This article will concentrate on the former, while the next article will address the latter.

The routing software, or simply router, listens at a network adapter for messages, also called packets, addressed to it in the same way as the Apache web server, httpd, listens for Web-page requests. Many services can use a single network adapter without a conflict. Other computers on the network direct messages to the router. The other computers are setup to do this by setting the IP address of the router in the computer's default router or gateway setting.

The router takes incoming messages and checks the destination IP address to determine where to forward the message. It uses routing tables to make this determination. The message may wind up being sent to another network segment or it may be forwarded yet again to another computer acting as a router. This router-to-router handoff is essentially how the Internet works. A router-to-router handoff is called a hop. Messages going in the reverse direction are handled in the same fashion.

The router assumes the network adapter handles the low level transmission of messages. For modem links, like those covered in the next article, often utilize the Point-to-Point Protocol (PPP). Some DSL and cable modems utilize PPP over Ethernet (PPPoE). For this support, check in the next article. This article assumes that DSL and cable modems are connected to an Ethernet adapter.

The Linux route program is used to configure and display the routing tables. The routing support is built into Linux. The basic syntax and semantics for the route program are covered later.

Network Address Translation 101

The basic router support simply moves messages from one network subnet to another without translation. This works well in most instances but there is one case where network address translation (NAT) is worthwhile. This is where an Internet Service Provider (ISP) supplies a single IP address to a customer. A single IP address is sufficient when a single computer is attached to the Internet but NAT is required if the single IP address must support a network.

NAT takes advantage of the fact that messages do not contain just source and destination IP addresses but rather IP and port address pairs for source and destination routing. The NAT router has a table to handle translation. When a NAT-enabled router receives a message from the local network it takes a look at the source IP address and port number and checks the table to see if this is the first message from this source. If it is, then a new entry is added to the table with the source IP address and port number. A new alias port number is allocated from a pool of unused port addresses. This number is added to the table entry.

The NAT router then changes the source IP address to the IP address of the outgoing network interface. It also changes the source port number to the alias port number from the table entry. The translated message is then sent through the outgoing network interface.

Messages coming into the outgoing network interface follow the reverse process. The destination IP address matches the one for the outgoing network interface for the NAT router. The destination port number is used to look up the matching IP and port number. The destination IP address is changed as is the port number in the message using the values from the table. The message is then sent to the local network and the local computer.

Neither the source nor the destination computer know about the masquerade due to the address translation. The process would be completely transparent if it were not for the fact that some protocols contain port and IP addresses in the message in addition to the source and destination addresses. Luckily, this is another area where masquerading can take place. It just takes a bit more work including recognition of higher level protocols and the ability to translate these additional addresses.

The Linux NAT support is integrated with firewall support that uses a configuration program called ipchains. This handles protocols that require basic source and destination translation. The ip_masq is actually a series of programs that handle different protocols. Only those protocols to be supported need be used. Protocols like FTP and IRC require masquerading programs. More on these in the next two sections.

IPCHAINS 101

The ipchains program was written by Paul Russell and it is included in most Linux distributions. (It can also be found at http://netfilter.filewatcher.org/ipchains/.) There is an IPCHAINS-HowTo available at this site, and the online documentation is extensive. This section provides a general overview of the syntax and semantics of ipchains.

The ipchains program is very powerful, and surprisingly simple once you get the basics down. The general format is:

ipchains <command> <chain> [<options>]

The complete syntax for ipchains is a little more complex, but this is sufficient for our needs. The online help enumerates the complete syntax including a useful command like:

ipchains -L

that lists the currently loaded ipchains configuration.

Linux keeps a set of tables for ipchains that it uses when routing packets to non-local destinations as well as routing incoming packets destined for other computers. The ipchains program changes these tables. Typically this is done when the system boots or as part of a script associated with a particular network adapter, such as a modem adapter discussed in the next article.

The three commands that we look at are -F, -P, and -A. The -F command flushes a chain so it starts fresh. The -P command sets up the default handling, while the -A command adds conditions or rules to a chain.

As yet we have not defined what a chain is. With ipchains, three chains are predefined: input, output, and forward. The following two commands are normally used to set up a chain:

ipchains -F input
ipchains -P input REJECT

This causes any rules for the input chain to be discarded and sets up the default condition so incoming packets are rejected. It is easier to discuss how chains work using an example, so we'll assume that the following command is next:

ipchains -A input -i eth0 -s 10.1.0.0/16 -d 0.0.0.0/0 -j ACCEPT

This is used to accept packets that meet the criteria specified in this command. In particular, the -i option is followed by the interface name, eth0. The -s and -d options are followed by source and destination values. If a packet is received on eth0 and it is from the specified source and going to the specified destination then it will be accepted by the router.

The source and destination values are IP address and mask bit pairs. In this case, the source will match any IP address of the form 10.1.x.x. The destination matches anything. Therefore, the rule accepts any packet with an address like 10.1.54.103 going anywhere. If a source or destination criteria is not specified then 0.0.0.0/0 is used.

The output chain controls what packets can be sent. A packet may be accepted by the input chain but rejected by the output chain. Likewise, the forward chain controls what packets will be routed.

In general, the input chain controls incoming packet filtering. The packet is either destined for the router or for another computer. In the latter case, the packet is processed by the forward chain. Packets that make it through this chain will then be processed by the output chain.

Additional -A, or add, commands can be used with the same chain name. The rules can also be used to reject packets as well. For example:

ipchains -A input -i eth0 -s 10.2.0.0/16 -d 0.0.0.0/0 -j REJECT

will reject packets with a source address like 10.2.x.x to any destination. This is actually redundant for the current set of rules since anything that does not match the first example rule for 10.1.x.x will be rejected. Including a rule like:

ipchains -A input -i eth0 -s 10.2.0.0/16 -d 10.1.0.0/16 -j ACCEPT

will accept a packet if it is from a source address like 10.2.x.x and destined for an IP address of the form 10.1.x.x. Note that rules are order dependent in a first-come-first-used basis so this rule should be added before the rule that rejects a more general condition.

We have used the -j option in a simplistic fashion to designate whether a packet will be accepted or rejected. This option is actually called a jump and can be used to link to user-defined chains, as well as using ACCEPT and REJECT. User-defined chains are manipulated in the same fashion as the standard chains. Only the names have been changed. User-defined chains are typically used to manage more complicated routing configurations. The bottom line is that the rules are followed until the packet is ACCEPTed or REJECTed.

Other argument values for the -j option when used with the forward chain. These include DENY and MASQ. DENY is similar to REJECT in that it terminates checking of the chain. MASQ indicates that a packet should be masqueraded using the built-in NAT support. In this case, the accepted packet will be modified so its IP address and port address are changed as described with NAT earlier. The reverse translation for response packets is done automatically. Selective use of MASQ allows a Linux router to forward some packets NAT-fashion and others with no translation. This is handy for small companies that have been assigned more than one IP address and use them for PCs on the local network.

For simple router support when an ISP provides a single IP address, MASQ is typically used. User-defined chains are usually unnecessary.

The ipchains program can also delete a rule using the -D command. A rule must match exactly with a command's argument to be deleted.

The ipchains commands are normally included in a script that runs when Linux boots or when a particular network adapter is started. The following section addresses masquerading of special protocols.

One last item for ipchains is to enable forwarding using the following command:

echo "1" > /proc/sys/net/ipv4/ip_forward

This creates a single byte file containing the number "1". Note: Linux distributions based on Red Hat Linux can normally specify this feature by adding the following to /etc/sysconfig/network:

FORWARD_IPV4=true

IP_MASQ 101

The ip_masq files are actually drivers loaded using the modprobe program. The file names start with ip_masq_. The files are normally found in the /lib/modules/version/ipv4 directory where the version subdirectory is the version number of kernel as in /lib/modules/2.2.15-2.5.0/ipv4.

The typical collection of masquerading modules includes:

     ip_masq_autofw.o
     ip_masq_cuseeme.o
     ip_masq_ftp.o
     ip_masq_irc.o
     ip_masq_mfw.o
     ip_masq_portfw.o
     ip_masq_quake.o
     ip_masq_raudio.o
     ip_masq_user.o
     ip_masq_vdolive.o

FTP, IRC, and Quake may be familiar, but protocols like CuSeeME streaming video may not be. Protocols installed but not used simply use up RAM. Most users will want FTP and IRC support.

These modules are used only if the masquerade support is set up using ipchains. The typical command line for loading these modules is:

/sbin/modprobe ip_masq_ftp

Note that the .o is not needed. A module does not need to be loaded if the associated application is not used. Loading a module that will not be used simply uses more memory, but does not impact ipchains.

Setting Up The Router

The sample hardware configuration considered in this article is a computer with two network adapters. These interfaces are assumed to be eth0 and eth1. Likewise, it is assumed that the IP address given by an ISP for the Internet connection is fixed. Dynamic IP addresses will be considered in the next article.

There are a number of variables defined in the following script. In particular, the external network interface variable, extif, is set to the second Ethernet adapter, eth1. The internal network interface variable, intif, is set to eth0. The fixed IP address for the router on the external network is in the variable extip while the internal network address and mask are saved in intnet.

The following script file is assumed to be saved as /etc/rc.d/rc.firewall. It must be set up as an executable file and it should be run when the system boots. This can be done by running the script from /etc/rc.d/rc.local. Keeping the firewall file separate from rc.local allows it to be run after the computer has been booted. This is usually required when a dynamic IP address is obtained from an ISP as considered in the next article. Here's the script file:

#!/bin/sh
# A simple example of ipchains saved as /etc/rc.d/rc.firewall
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin

# Load required ip_masq modules (FTP included here)
/sbin/depmod -a
/sbin/modprobe ip_masq_ftp

# Enable IP forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward

# Assign external IP variables
extip="64.66.99.123"
extif="eth1"

# Assign internal IP variables
intif="eth0"
intnet="192.168.1.0/24"

# Initialize MASQ timeout and standard chains
ipchains -M -S 7200 10 60
ipchains -F input
ipchains -P input REJECT
ipchains -F output
ipchains -P output REJECT
ipchains -F forward
ipchains -P forward DENY

# Setup input policy
# local interface, local machines, going anywhere is valid
ipchains -A input -i $intif -s $intnet -d 0.0.0.0/0 -j ACCEPT

# reject IP spoofing where external computer claims to be a local
ipchains -A input -i $extif -s $intnet -d 0.0.0.0/0 -l -j REJECT

# allow external access via external interface
ipchains -A input -i $extif -s 0.0.0.0/0 -d $extip/32 -j ACCEPT

# loopback interface is valid
ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT

# Setup output policy
# all outgoing traffic is allowed
ipchains -A output -i $intif -s 0.0.0.0/0 -d $intnet -j ACCEPT

# prevent traffic for local network from using external interface
ipchains -A output -i $extif -s 0.0.0.0/0 -d $intnet -l -j REJECT

# prevent traffic from local network from using external interface
ipchains -A output -i $extif -s $intnet -d 0.0.0.0/0 -l -j REJECT

# anything else can go out
ipchains -A output -i $extif -s $extip/32 -d 0.0.0.0/0 -j ACCEPT

# loopback interface is valid
ipchains -A output -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT


# Setup forwarding policy
# Masquerade local net traffic to anywhere
ipchains -A forward -i $extif -s $intnet -d 0.0.0.0/0 -j MASQ

The lo interface is a local loopback found on all computers. The masquerade support is strictly for local computers communicating with the Internet through the router. Access from the Internet is restricted to the router. If there is a Web server running on the router then this may be accessible from the Internet. Check out the next section for details.

Caveats

Configuring Linux as a router with NAT support is not difficult but it can be confusing. What makes the job difficult is making sure the connection to the Internet is secure. The ipchains configuration is the first step. Additional steps are required if the router is running other services such as DNS, the Apache Web server, or an FTP server.

The /etc/inet.conf file is typically used to designate how IP-based services will be started if a request comes from another computer. The telnet and FTP services can be handled using inet.conf. This article will not go into any detail oninet.conf, but online help is available.

In addition, certain services will be started when Linux boots. The Apache Web server and the DNS server, BIND, are normally started this way. By default, these services, and the ones started via inet.conf, will work with any network adapter on the computer but it is possible to configure applications to work with specific adapters. For example, the Apache Web server keeps its configuration files in /etc/httpd/conf. The httpd.conf and access.conf files control what computers and what adapters can be used with the web server. If a statement like Listen 123.45.67.89:80 is in the configuration files then the Web server will ignore other adapters, such as an Ethernet adapter connected to the Internet, and only use port 80 on the adapter associated with the IP address 123.45.67.89. The linuxconf program can be used to set up this configuration instead of dealing with the configuration files directly.

Another possible option is to set up the DNS server so it can service the local network and transparently forward Internet requests to an ISP's DNS server. This makes configuration of local workstations easier but it requires an understanding of BIND.

Copyright Jupitermedia Corp. All Rights Reserved.