Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

4/23/2019 Two default routes

Linux System Administration


Home Tech Linux Links Consulting

Notes Two default routes


This system
Linux has very advanced routing, filtering and traffic
shaping options. Here is how to configure a system 1. Installation
with two default routes. 2. The ip command
3. (Hot) Potato routing
4. Configuring two
default routes
1. Installation 5. Example
configuration
To activate Linux advanced routing on a Debian
GNU/Linux system, install the iproute package:

~# apt-get install iproute

This will create the /etc/iproute2/ directory. It also installs some new
executables, including ip.

IPv6 test 2. The ip command

From a command line on any Linux system, you can see the existing routing table
by simply typing route at the prompt (or /sbin/route if /sbin is not in your
path). Your routing table will be similar to this:

Kernel IP routing table


Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.0 * 255.255.255.0 U 0 0 0 eth1
default my.host.com 0.0.0.0 UG 0 0 0 eth1

Advanced routing commands are issued as arguments to the ip command. To see


the routing table with iproute2, you can use the long version ip route show
table main or the shortcut version ip route like this:

192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.20


default via 192.168.1.10 dev eth1

3. (Hot) Potato routing


Typically, a host connected to a network, such as the Internet, will have one default
route and one Internet (WAN) interface. However, if a second connection to the
www.rjsystems.nl/en/2100-adv-routing.php 1/7
4/23/2019 Two default routes

Internet is added and both are accessed, you can end up with a situation referred to
as (hot) potato routing, or deflection routing.

Normally, when a packet, such as an ICMP ping, arrives at the primary interface, it
is examined by the host, after which a reply packet is generated, the routing table is
consulted and the packet it sent back via the default route. On the other hand, if a
ping packet arrives at the secondary WAN interface, the same thing happens: it is
examined by the host, a reply packet is generated, the routing table is consulted and
the packet it sent back via the default route. In other words: a packet is received on
one interface and the reply is sent back via the other.

In theory such packets can be routed, but are dropped by ISPs. That's because these
packets have a source address that is not part of the network that they are being
routed from -- they look like they've been forged. Indeed, such forged packet
headers are often used in DOS attacks.

However, if you have more than one connection to the Internet and you want to use
them all despite the fact that you have only one default route, what can you do? The
answer is advanced routing.

4. Configuring two default routes

With advanced routing, you can have as many routing tables as you want. In the
example below, we add just one for an extra DSL line from an ISP called
"cheapskate."

First add a name for the new routing table to the /etc/iproute2/rt_tables
file. This can be appended to it with the command echo 2 cheapskate >>
/etc/iproute2/rt_tables. The result looks like this:

#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
2 cheapskate

Above I mentioned that the command ip route is actually a shortcut for the
longer command ip route show table main. Since there is no shortcut to list
the new routing table, you have no choice but to use the long form: ip route
show table cheapskate. Entering this command now will reveal that this new
table is still empty.

All that is necessary is to add the new default route to the cheapskate table -- the
old main table will continue to handle the rest. The reason for this will soon

www.rjsystems.nl/en/2100-adv-routing.php 2/7
4/23/2019 Two default routes

become clear. Here is the existing main table:

~# ip route show table main


192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10
192.168.2.0/24 dev eth1 proto kernel scope link src 192.168.2.10
default via 192.168.1.1 dev eth0
~# _

As follows, add the new default route to table cheapskate and then display it:

~# ip route add default via 192.168.2.1 dev eth1 table cheapskate


~# ip route show table cheapskate
default via 192.168.2.1 dev eth1
~# _

As you can see, the entire table consists of a single line. However, it is not yet
being used. To implement it, the command, ip rule is required. Routing tables
determine packet destinations, but now we need the kernel to use different routing
tables depending on their source addresses. The existing set of ip rules is very
simple:

~# ip rule
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
~# _

At this point you need to add a new rule:

~# ip rule add from 192.168.2.10 lookup cheapskate prio 1000

This command adds a rule for when a packet has a from pattern of 192.168.2.10 in
which case the routing table cheapskate should be used with a priority level of
1000. In this example the pattern only needs to match one address, but you can set
patterns in a Linux router to match different sets of addresses.

~# ip rule
0: from all lookup local
1000: from 192.168.2.10 lookup cheapskate
32766: from all lookup main
32767: from all lookup default
~# _

The kernel searches the list of ip rules starting with the lowest priority number,
processing each routing table until the packet has been routed successfully.

The default ruleset always has a local table with a match pattern of all. The local
table (priority 0) handles traffic that is supposed to stay on the localhost, as well as
broadcast traffic.

After the local rule comes our new rule with a priority of 1000. This priority
number is arbitrary, but makes it easy to add other rules before and after it later on.

www.rjsystems.nl/en/2100-adv-routing.php 3/7
4/23/2019 Two default routes

Our new rule comes before the main table, which is the one that is modified by the
old route command. The last rule is for the default table. I'm not certain what it's
for, as I've always found it to be empty, and seeing as there is a default route in the
table main, no traffic ever gets to the table default.

** Warning **

When working with more than one routing table, never forget to add the table part
of the command. If you do forget, rule changes in the wrong table (main) can seem
awfully mysterious. When learning the ropes and working remotely, you will
probably lock yourself out a few times this way: the changes happen very quickly,
so it may be wise to use a console instead.

Another important point to remember is that routes are cached. In other words, if
you update a routing table and nothing seems to happen, it's because the table is
still in memory. The solution is simply to flush the cache with ip route flush
table cache. In this manner it is possible to first make a number of changes and
then flush the cache so that all of the changes will be implemented simultaneously.
This is actually convenient when working on an active router.

5. Example configuration

When a secondary WAN interface became available at a client site, I wanted to


allow their remote users to use this connection as an alternative in case their
primary Internet connection ever went down. With Linux, we now know that this is
possible.

First, some background information. The client's router had the following
interfaces:

- eth0 Primary Internet connection (Versatel).


inet addr: 87.215.195.178
Bcast: 87.215.195.183
Mask: 255.255.255.248

- eth0:0 Private net behind the Versatel ADSL modem/router.


inet addr: 192.168.1.1
Bcast: 192.168.1.255
Mask: 255.255.255.0

- eth0:1 Private net behind the Zonnet ADSL modem/router.


inet addr: 10.0.0.100
Bcast: 10.255.255.255
Mask: 255.0.0.0

- eth1 Private net -- main internal network segment.


inet addr: 192.168.13.1
Bcast: 192.168.13.255
Mask: 255.255.255.0

- eth2 Private net -- wireless internal network segment.


inet addr: 192.168.14.1
Bcast: 192.168.14.255
Mask: 255.255.255.0

www.rjsystems.nl/en/2100-adv-routing.php 4/7
4/23/2019 Two default routes
- lo Loopback interface.
inet addr: 127.0.0.1
Mask: 255.0.0.0

- ppp0 Secondary Internet connection (Zonnet).


inet addr: 62.58.236.234
P-t-P: 195.190.250.17
Mask: 255.255.255.255

The main routing table displayed with route -n:

Kernel IP routing table


Destination Gateway Genmask Flags Metric Ref Use Iface
195.190.250.17 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
87.215.195.176 0.0.0.0 255.255.255.248 U 0 0 0 eth0
62.58.50.0 62.58.236.234 255.255.255.128 UG 0 0 0 ppp0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.14.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2
192.168.13.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
62.58.232.0 62.58.236.234 255.255.248.0 UG 0 0 0 ppp0
10.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 eth0
0.0.0.0 87.215.195.177 0.0.0.0 UG 0 0 0 eth0

The route for 62.58.232.0/21 via ppp0 may be unnecessary, but I figured it would
be 'cheaper' because the IP address for ppp0 is part of the same network. The route
to 62.58.50.0/25 via the ppp0, on the other hand, is a network segment that includes
an SMTP relay that is not be available via any other route.

The list of interfaces displayed with ip link list:

1: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue


link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:00:24:c1:10:5c brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:00:24:c1:10:5d brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:00:24:c1:10:5e brd ff:ff:ff:ff:ff:ff
5: sit0: <NOARP> mtu 1480 qdisc noop
link/sit 0.0.0.0 brd 0.0.0.0
6: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP> mtu 1500 qdisc pfifo_fast
qlen 3 link/ppp

NB: sit0 is an IPv6-IPv4 tunnel.

The main routing table displayed with ip route show table main:

195.190.250.17 dev ppp0 proto kernel scope link src 62.58.236.234


87.215.195.176/29 dev eth0 proto kernel scope link src 87.215.195.178
62.58.50.0/25 via 62.58.236.234 dev ppp0 scope link
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1
192.168.14.0/24 dev eth2 proto kernel scope link src 192.168.14.1
192.168.13.0/24 dev eth1 proto kernel scope link src 192.168.13.1
62.58.232.0/21 via 62.58.236.234 dev ppp0 scope link
10.0.0.0/8 dev eth0 proto kernel scope link src 10.0.0.100
default via 87.215.195.177 dev eth0

The idea was to create a second routing table for the second Internet connection
(ppp0) with its own default route. This can be done in only three steps. First, after
www.rjsystems.nl/en/2100-adv-routing.php 5/7
4/23/2019 Two default routes

installing the necessary software (see above), I created a second routing table (after
the existing main routing table) called 'zonnet':

~# echo 2 zonnet >> /etc/iproute2/rt_tables

Second, I added a default route to the zonnet routing table using the ppp0 interface
and its IP address:

~# ip route add default via 62.58.236.234 dev ppp0 table zonnet

Third, I added a new rule to the kernel that tell it to use the new routing table when
packets (connections) originate from the second interface:

~# ip rule add from 62.58.236.234 lookup zonnet prio 1000

Thus, the new zonnet routing table looks like this (just one line):

~# ip route show table zonnet


default via 62.58.236.234 dev ppp0
~# _

And the routing rule looks like this:

~# ip rule
0: from all lookup local
1000: from 62.58.236.234 lookup zonnet
32766: from all lookup main
32767: from all lookup default
~# _

So far, the result of all this is that all requests destined for the firewall coming in
from eth0 are sent back out eth0 (the main default gateway; 87.215.195.177), while
requests destined for the firewall coming in from ppp0 are sent back out ppp0 (the
secondary default gateway; 62.58.236.234). However, if the server responds to any
requests that are forwarded to it, those responses will still be routed out the main
default gateway regardless.

The first step towards a solution was to define a second network, 192.168.15.0/24,
on the UTP segment that the server is attached to. Luckily, Windows server 2003
allows you to bind additional IP addresses to its interfaces. In this case, only the
server and the firewall (via eth1) have addresses on this network.

- eth1:0 Private net -- additional internal network segment.


inet addr: 192.168.15.1
Bcast: 192.168.13.255
Mask: 255.255.255.0

On this network, the server is defined as 192.168.15.2 and the firewall is


configured to forward all requests for it that arrive via ppp0 on to this address.
Naturally, the responses come out this way too.

www.rjsystems.nl/en/2100-adv-routing.php 6/7
4/23/2019 Two default routes

Second, since all of the packets moving from 192.168/.15.0/24 into the firewall are
responses to requests that arrive via the secondary Internet connection (and should
be sent back that way) anyway, I could use this one routing rule:

~# ip rule add from 192.168.15.0/24 lookup secnet prio 990

The routing rule now looks like this:

~# ip rule
0: from all lookup local
990: from 192.168.15.0/24 lookup zonnet
1000: from 62.58.236.234 lookup zonnet
32766: from all lookup main
32767: from all lookup default
~# _

Now if a request is sent in via ppp0 and forwarded on to the server (via
192.168.15.0/24), its response will also be sent back via ppp0.

Last modified: 2017-08-02, 17:29

©2003-2017 RJ Systems. Permission is granted to copy, distribute and/or modify the


content of this page under the terms of the OpenContent License, version 1.0.

www.rjsystems.nl/en/2100-adv-routing.php 7/7

You might also like