Routing Packets with the Linux Kernel


As shown in Figures 2-2 and 2-3, all inbound and outbound network packets must pass through the kernel's routing rules. And, like the list of rules in an iptables chain, the list of routing rules is contained in an ordered list that is examined only until a packet matches one of the rules.

Like the rules in an iptables chain, each routing rule includes:

  • The criteria used to match packets

  • Instructions telling the kernel what to do with packets that match this criteria

The order of the routing rules is important because the kernel stops searching the routing table when a packet matches one of the routing rules. Because the last rule in the routing table will normally match any packet, it is called the default route (or default gateway).

When you assign an IP address to one of the network interface cards, the kernel automatically adds a routing rule for the interface. The kernel constructs the routing table entry so it will match all packets containing a destination address that falls within the range of IP addresses allowed on the network or subnet that the interface is connected to.

In a typical configuration, routing table entries are constructed that will match packets based on the packet's destination IP address. This type of packet is typically matched for:

  • A particular destination network

  • A particular destination host

  • Any destination or host

Note 

In the following sections, the add argument to the route command adds a routing rule. To delete or remove a routing rule after it has been added, use the same command but change the add argument to del.

Matching Packets for a Particular Destination Network

If we had to type in the command to add a routing table entry for a NIC connected to the 209.100.100.0 network, the command would look like this (we do not, because the kernel will do this for us automatically):

 #/sbin/route add --net 209.100.100.0 netmask 255.255.0.0 dev eth0 

This command adds a routing table entry to match all packets destined for the 209.100.100.0 network and sends them out the eth0 interface.

If we also had a NIC called eth1 connected to the 172.24.150.0 network, we would use the following command as well:

 #/sbin/route add --net 172.24.150.0. netmask 255.255.255.0 dev eth1 

With these two routing rules in place, the kernel can send and receive packets to any host connected to either of these two networks. If this machine needs to also forward packets that originate on one of these networks to the other network (the machine is acting like a router), you must also enable the kernel's packet forwarding feature with the following command:

 #/bin/echo 1 > /proc/sys/net/ipv4/ip_forward 

As we will see in Part III of this book, this kernel capability is also a key technology that enables a Linux machine to become a cluster load balancer.

Matching Packets for a Particular Destination Host

Now let's assume we have a Linux host called Linux-Host-1 with two NICs connected to two different networks. We want to be able to send packets to Linux-Host-2, which is not physically connected to either of these two networks (see Figure 2-4). If we can only have one default gateway, how will the kernel know which NIC and which router to use?

If we only need to be able to send packets to one host on the 192.168.150.0 network, we could enter a routing command on Linux-Host-1 that will match all packets destined for this one host:

 #/sbin/route add -host 192.168.150.33 gw 172.24.150.1 

This command will force all packets destined for 192.168.150.33 to the internal gateway at IP address 172.24.150.1. Assuming that the gateway is configured properly, it will know how to forward the packets it receives from Linux-Host-1 to Linux-Host-2 (and vice versa).

If, instead, we wanted to match all packets destined for the 192.168.150.0 network, and not just the packets destined for Linux-Host-2, we would enter a routing command like this:

 #/sbin/route add --net 192.168.150.0 netmask 255.255.255.0 gw 172.24.150.1 

Note 

In both of these examples, the kernel knows which physical NIC to use thanks to the rules described in the previous section that match packets for a particular destination network. (The 172.24.150.1 address will match the routing rule added for the 172.24.150.0 network that sends packets out the eth1 interface.)

image from book
Figure 2-4: Linux firewall and router example network

Matching Packets for any Destination or Host

As described previously, the last rule in the routing table, the default route, is normally used to match all packets regardless of their destination address and force them to a router or internal gateway device. The command to create this type of routing rule looks like this:

 #/sbin/route add --default gw 172.24.150.1 

This routing rule causes the kernel to send packets that do not match any of the previous routing rules to the internal gateway at IP address 172.24.150.1.

If Linux-Host-1 needs to send packets to the Internet through the router (209.100.100.1), and it also needs to send packets to any host connected to the 192.168.150.0 network, use the following commands:

 #/sbin/ifconfig eth0 209.100.100.3 netmask 255.255.255.0 #/sbin/ifconfig eth1 172.24.150.3 netmask 255.255.255.0 #/sbin/route add -net 192.168.150.0 netmask 255.255.255.0 gw 172.24.150.1 #/sbin/route add default gw 209.100.100.1 

The first two commands assign the IP addresses and network masks to the eth0 and eth1 interfaces and cause the kernel to automatically add routing table entries for the 209.100.100.0 and 172.24.150.0 networks.

The third command causes the kernel to send packets for the 192.168.150.0 network out the eth1 network interface to the 172.24.150.1 gateway device. Finally, the last command matches all other packets, and in this example, sends them to the Internet router.

To View Your Routing Rules

To view your list of routing rules, use any of the following three commands:

 #netstat -rn #route -n #ip route list 

The output of the first two commands (which may be slightly more readable than the list produced by the ip command) looks like this:

 Kernel IP routing table Destination     Gateway        Genmask         Flags  MSS  Window  irtt  Iface 209.100.100.0   0.0.0.0        255.255.255.0   U      0    0       0     eth0 192.168.150.0   172.24.150.1   255.255.255.0   UG     0    0       0     eth1 172.24.150.0    0.0.0.0        255.255.255.0   U      0    0       0     eth1 127.0.0.0       0.0.0.0        255.0.0.0       U      0    0       0     lo 0.0.0.0         209.100.100.1  0.0.0.0         UG     0    0       0     eth0 

Notice that the destination address for the final routing rule is 0.0.0.0, which means that any destination address will match this rule. (You'll find more information for this report on the netstat and route man pages.)

Making Your Routing Rules Permanent

Like the Netfilter iptables rules, the routing rules do not survive a system reboot. To make your routing rules permanent, place them into a script (and add them to the boot process with chkconfig or ntsysv, as described in Chapter 1) or use the method provided by your distribution.

iptables and Routing Resource Script

As with iptables, the standard Red Hat method of saving the routing rules is not the best one to use when you need your rules to failover from one server to another.[9] In a cluster configuration, we want to enable and disable packet handling methods just like any other service. Let's therefore expand our definition of a service to include capabilities offered inside the kernel. (Chapter 3 describes how to configure capabilities within the Linux kernel and recompile it.)

To failover kernel capabilities such as the iptables and routing rules, we need to use a script that can start and stop them on demand. This can be done for the kernel's packet-handling service, as we'll call it, with a script like this:

 #!/bin/bash # # Packet Handling Service # # chkconfig 2345 55 45 # description: Starts or stops iptables rules and routing case "$1" in start)     # Flush (or erase) the current iptables rules     /sbin/iptables -F     /sbin/iptables --table nat -flush     /sbin/iptables --table nat --delete-chain     # Enable the loopback device for all types of packets     # (Normally for packets created by local daemons for delivery     # to local daemons)     /sbin/iptables -A INPUT -i lo -p all -j ACCEPT     /sbin/iptables -A OUTPUT -o lo -p all -j ACCEPT     /sbin/iptables -A FORWARD -o lo -p all -j ACCEPT     # Set the default policies     /sbin/iptables -P INPUT DROP     /sbin/iptables -P FORWARD DROP     /sbin/iptables -P OUTPUT ACCEPT     # NAT     /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE     # Allow inbound packets from our private network     /sbin/iptables -A INPUT -i eth1 -j ACCEPT     /sbin/iptables -A FORWARD -i eth1 -j ACCEPT     # Allow packets back in from conversations we initiated     # from the private network.     /sbin/iptables -A FORWARD -i eth0 --match state --state ESTABLISHED,RELATED -j ACCEPT     /sbin/iptables -A INPUT --match state --state ESTABLISHED,RELATED -j ACCEPT     # Allow Sendmail and POP (from anywhere, but really what we     # are allowing here is inbound connections on the eth0 interface).     # (Sendmail and POP are running locally on this machine).     /sbin/iptables -A INPUT --protocol tcp --destination-port 25 -j ACCEPT     /sbin/iptables -A INPUT --protocol tcp --destination-port 110 -j ACCEPT     # Routing Rules --     # Route packets destined for the 192.168.150.0 network using the internal     # gateway machine 172.24.150.1     /sbin/route add -net 192.168.150.0 netmask 255.255.255.0 gw 172.24.150.1     # By default, if we don't know where a packet should be sent we     # assume it should be sent to the Internet router.     /sbin/route add default gw 209.100.100.1     # Now that everything is in place we allow packet forwarding.     echo 1 > /proc/sys/net/ipv4/ip_forward   ;; stop)     # Flush (or erase) the current iptables rules     /sbin/iptables -F     # Set the default policies back to ACCEPT     # (This is not a secure configuration.)     /sbin/iptables -P INPUT ACCEPT     /sbin/iptables -P FORWARD ACCEPT     /sbin/iptables -P OUTPUT ACCEPT     # Remove our routing rules.     /sbin/route del -net 192.168.150.0 netmask 255.255.255.0 gw 172.24.150.1     /sbin/route del default gw 209.100.100.1     # Disable packet forwarding     echo 0 > /proc/sys/net/ipv4/ip_forward ;; status)     enabled=`/bin/cat /proc/sys/net/ipv4/ip_forward`     if [ "$enabled" -eq 1 ]; then         echo "Running"     else         echo "Down"     fi ;; *)         echo "Requires start, stop or status" ;; esac 

This script demonstrates another powerful iptables capability: the ability to do network address translation or NAT to masquerade internal hosts. In this example, all hosts sending requests out to the Internet through Linux-Host-1 will have their IP addresses (the return or source address in the packet header) converted to the source IP address of the Linux-Host-1 machine. This is a common and effective way to prevent crackers from attacking internal hosts—the internal hosts use an IP address that cannot be routed on the Internet[10] and the NAT machine, using one public IP address, appears to send all requests to the Internet. (This rule is placed in the POSTROUTING Netfilter chain, or hook, so it can apply the masquerade for outbound packets going out eth1 and then de-masquerade the packets from Internet hosts as their replies are returned back through eth1. See the NF_IP_POSTROUTING hook in Figure 2-1 and imagine what the drawing would look like if it were depicting packets going in the other direction—from eth1 to eth0.)

The iptables' ability to perform network address translation is another key technology that enables a cluster load balancer to forward packets to cluster nodes and reply to client computers as if all of the cluster nodes were one server (see Chapter 12).

This script also introduces a simple way to determine whether the packet handling service is active, or running, by checking to see whether the kernel's flag to enable packet forwarding is turned on (this flag is stored in the kernel special file /proc/sys/net/ipv4/ip_forward).

To use this script, you can place it in the /etc/init.d directory[11] and enter the command:

 #/etc/init.d/routing start 

Note 

The command service routing start would work on a Red Hat system.

And to check to see whether the system has routing or packet handling enabled, you would enter the command:

 #/etc/init.d/routing status 

Note 

In Part II of this book, we will see why the word Running was used to indicate packet handling is enabled.[12]

The ip Command

Advanced routing rules can be built using the ip command. Advanced routing rules allow you to do things like match packets based on their source IP address, match packets based on a number (or mark) inserted into the packet header by the iptables utility, or even specify what source IP address to use when sending packets out a particular interface. (We'll cover packet marking with iptables in Chapter 14. If you find that you are reaching limitations with the route utility, read about the ip utility in the "Advanced Routing HOWTO."[13])

Note 

To build the cluster described in this book, you do not need to use the ip command.

[9]Red Hat uses the network init script to enable routing rules. The routing rules cannot be disabled or stopped without bringing down all network communication when using the standard Red Hat init script.

[10]RFC 1918 IP address ranges will be discussed in more detail in Chapter 12.

[11]This script will also need to have execute permissions (which can be enabled with the command: #chmod 755 /etc/init.d/routing).

[12]So the Heartbeat program can manage this resource. Heartbeat expects one of the following: Running, running, or OK to indicate the service for the resource is running.

[13]See http://lartc.org.



The Linux Enterprise Cluster. Build a Highly Available Cluster with Commodity Hardware and Free Software
Linux Enterprise Cluster: Build a Highly Available Cluster with Commodity Hardware and Free Software
ISBN: 1593270364
EAN: 2147483647
Year: 2003
Pages: 219
Authors: Karl Kopper

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net