Tunnels, Routes and Rules: They're Easier with iproute2
Using the next-generation network tools in Linux can make your network management life a lot easier. Here's a guide to some useful tasks you can accomplish with the versatile ip.
Last week's riveting installment covered the whys and wherefores of using iproute rather than the old standbys in the net-tools package ifconfig, route, arp, and the rest of the gang, and how to use the ip command to read routing tables, ARP tables, assign additional IPs to network interface devices, and view network interface information. Today we shall effortlessly build static routes, tunnels, and implement policy rules.
Setting a default static route is so easy you'll invite your mom and dad to watch. This sets a default route from a workstation to the local Internet gateway:
# ip route add default via 192.168.1.1
Deleting a default route is just as easy:
# ip route del default
Deleting a route is a more routine task than some of you hardbitten old network admins may realize. DSL users have long been accustomed to having a dialup modem as a backup when (not if) the DSL went down. The default route leftover from the DSL interface must be deleted to get a connection with the modem. If you don't, the modem will connect, but no bits will flow over the wire, so the user is left sitting there sad, mystified, and possibly cursing.
On workstations there is usually a default route that is either assigned statically in /etc/network/interfaces on Debian, /etc/sysconfig/network-scripts/ifcfg-ethX on Red Hat and Fedora, or via DHCP.
You may change an existing route, instead of deleting it then adding a new one:
# ip route chg default via 192.168.1.2
Setting up NAT (network address translation) (define) is done this way -- map an internal address to an external public IP:
# ip route add nat 192.168.1.15 via 220.127.116.11
iproute2 does not have the flexibility of iptables for configuring NAT -- it only permits one-to-one address mapping. But if your needs are very simple, it's a nice alternative to iptables.
Simple load-balancing across multiple interfaces is done like this, with the nexthop argument marking this as a multipath route:
#ip route add default scope global nexthop via 192.168.1.1 dev eth0
nexthop via 192.168.1.1 dev eth1
nexthop via 192.168.1.1 dev eth2
You may add the weight parameter if you want to give preference to one path, like this:
#ip route add default scope global nexthop via 192.168.1.1 dev eth0 weight 1
nexthop via 192.168.1.1 dev eth1 weight 2
Because of caching, this may or may not actually have any noticeable effect. The fun bit is if you have the luxury of multiple Internet service providers, this gives automatic failover if one of them goes down. If you do get multiple providers for fault tolerance be sure they connect to different backbones; if they both rely on UUNet, for example, and UUNet horks up a big hairball, you don't gain anything.
Another way to do this is to alternate the path that each successive packet takes:
# ip route add equalize default
nexthop via 192.168.1.1 dev eth0
nexthop via 192.168.1.2 dev eth0
What if the two links carry traffic at different speeds? Suppose the first one is twice as fast as the second. This is where using the weight parameter makes sense; set the first link to send twice as many packets as the second:
# ip route add equalize default
nexthop via 192.168.1.1 dev eth0 weight 2
nexthop via 192.168.1.2 dev eth0 weight 1
Cheap, Easy WAN With GRE Tunnels
Setting up GRE (Generic Routing Encapsulation) tunnels is easy with iproute2. GRE is really slick for connecting remote offices over the Internet, a cheap, easy way to build a WAN (wide-area network) without hassling with expensive types of connectivity or BGP (border gateway protocol) and other horrid, complex routing methods. What's really nice about GRE is you can connect several LANs that use the same private addressing class, like 192.168.1.0/24.
You can run VPN (virtual private network) protocols over GRE without having to rebuild all of your routers/gateways, so it's a nice way to test and transition to new protocols. GRE is so flexible you can stuff just about any packets over it. It even supports its own form of encryption. This shows how to build one end of a GRE tunnel:
# ip tunnel add tunnel1 mode gre remote 18.104.22.168 local 22.214.171.124
# ip link set tunnel1 up
# ip addr add 192.168.1.1 dev tunnel1
# ip route add 192.168.1.0/24 dev tunnel1
tunnel1 is the name of your tunnel. You may name it anything, so using a descriptive name like "portland_sales" or "queen_marys_domain" is helpful. mode gre defines the tunnel type. (iproute2 supports ipip, gre, and sit, or IPv6-over-IPv4, tunnels.) remote is given the address of the remote network gateway, and local of course is the local gateway. The second line activates the new tunnel, or "device" as iproute likes to call it.
Next the address 192.168.1.1 is assigned to the tunnel. This can be any address you like, so you can design an addressing scheme any way you like to suit your needs. Finally add the route, and you're almost done. To complete the tunnel run the same commands from the other end, substituting the correct IP addresses.