Routing Between Different Networks Using Route Commands and Iptables in a Virtualized Network
In this tutorial, I will show you how to use route and iptables commands to route packet between two networks e.g from Class A and Class C, and vice versa. You need to machines but in this tutorial I use Linx KVM virtualization. In this way, both my machines are in a virtualized networks. For those of you who are not familiar with virtualization and have the luxury of having two machines, you may want to refer to my earlier tutorials. This tutorial also does not show you how to setup KVM virtualization.
To route IP packets between two different networks, and in my case between class A and class C, here is a summary of the tasks that are needed:
- On the class A network, configure IP address, subnet mask of the class A host. Leave the gateway IP at this stage. The ifconfig command is to achieve this.
- Add the other network (Class C) and include the gateway (the gateway is the IP address of the class A host). Use the route add command.
- On the class C network, configure IP address, subnet mask of the class C host. Leave the gateway IP at this stage. The ifconfig command is to achieve this.
- Add the other network (Class A) and include the gateway (the gateway is the IP address of the class C host). Use the route add command.
- You can use the ip route show and the route -n command each time you configure the network interfaces.
- You should be able to ping the hosts on the different networks.
On the class A network,
Configure IP address, subnet mask of the class A host. Leave the gateway IP at this stage.
# ifconfig eth0 10.0.0.10 netmask 255.0.0.0
You can verify if this is set by typing:
# ifconfig eth0
Add the other network (Class C) with the subnet mask, and include the gateway (the gateway is the IP address of the class A host).
# route add -net 192.168.1.0/24 gw 10.0.0.10
You can verify if this is set by typing:
linux-m286:~ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.2.0 10.0.0.10 255.255.255.0 UG 0 0 0 eth0
10.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
On the class C network,
Configure IP address, subnet mask of the class C host. Leave the gateway IP at this stage.
# ifconfig eth0 192.168.1.111 netmask 255.255.255.0
You can verify if this is set by typing:
# ifconfig eth0
Add the other network (Class A) with the subnet mask, and include the gateway (the gateway is the IP address of the class C host).
# route add -net 10.0.0.0/8 gw 192.168.1.111
You can verify if this is set by typing:
root@linuxbeatswindows:~/.config/openbox# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 br0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 br0
10.0.0.0 192.168.2.111 255.0.0.0 UG 0 0 0 br0
root@linuxbeatswindows:~/.config/openbox#
Try to ping the class A host from the class C host and vice versa. You should be able to ping the hosts from the two different networks.
Now let’s say you have an Internet connection that is connected to the 192.168.1.0 network. HowI do you configure the network so that hosts in the class A network are able to access the Internet? This will be discussed in the next section.
Sharing Internet Connection between Class A and Class C Networks
Before proceeding with this tutorial, your hosts on either networks, class A and C must be able to ping to each other. It is also assume that your Internet gateway is in the class C network i.e. 192.168.1.0/24 (In some cases, the 192.168.2.0/24 network, depends on the modem router’s IP address).
In my case, my modem router gateway IP is set at 192.168.1.1. (At work it is set at 192.168.2.1. It does not matter. You only have to make the changes accordingly).
For internet sharing, you will also need to have 2 network interface cards (NICs); one connected to the Internet and the other connected to the LAN.
So once you have made the two hosts from different networks able to ping each other, you will need to do the following:
- On the class C network (192.168.1.0/24), do ip forwarding.
- On the class C network, run iptables command to allow traffic from the class C network (192.168.1.0/24) and class A network (10.0.0.0/8). It is recommended to flush previous iptables.
- On the class A network, add a default gateway that points to the gateway of the Internet. This is the IP address of the modem router that connects to the Internet.
Now let’s get into the details how we are going to achieve the tasks mentioned above.
- On the class C network (192.168.1.0/24), do ip forwarding.
# echo 1 > /proc/sys/net/ipv4/ip_forward
- On the class C network, run iptables command to allow traffic from the class C network (192.168.1.0/24) and class A network (10.0.0.0/8). It is recommended to flush previous iptables.
Before we define the iptables which allow the networks to the Internet, it is recommended that you flush the iptables. To flush iptables, you can type a series of iptables command. I have included them in a script.
# more chkroute_flush
#!/bin/sh
echo “Stopping firewall and allowing everyone…”
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
After you have flush the iptables, you can now include iptables which allow traffice from the networks to access the Internet. I have put them in a script. Just ignore the name of the script.
# more chkroute_others_int_home
#!/bin/bash
#you may need to change the interface name
iptables -t nat -A POSTROUTING -o br0 -j MASQUERADE
iptables -A FORWARD -s 10.0.0.0/8 -j ACCEPT
iptables -A FORWARD -d 10.0.0.0/8 -j ACCEPT
iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT
iptables -A FORWARD -d 192.168.1.0/24 -j ACCEPT
- On the class A network, add a default gateway that points to the gateway of the Internet. This is the IP address of the modem router that connects to the Internet.
On the class A network, type:
#route add default gw 192.168.1.1
Then to verify the routing table, type:
linux-m286:~ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.2.0 10.0.0.10 255.255.255.0 UG 0 0 0 eth0
10.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
linux-m286:~ #
From the routing table shown above, any IP (0.0.0.0) that is not found in the 192 or 10 network is sent to the IP 192.168.1.1. This is how the machine on the class A network is able to access the Internet. Lauch the web browser to test or run the nslookup command.
linux-m286:~ # nslookup
> yahoo.com
Server: 192.168.2.1
Address: 192.168.2.1#53
Non-authoritative answer:
Name: yahoo.com
Address: 98.139.180.149
Name: yahoo.com
Address: 209.191.122.70
Name: yahoo.com
Address: 67.195.160.76
Name: yahoo.com
Address: 72.30.2.43
Name: yahoo.com
Address: 98.137.149.56
> exit
linux-m286:~ #
Life experince
In my case I use bridging network, br0 for virtualization. If you cannot access the Internet, you could bring down the eth0 of the host machine (not the guest)
#ifconfig eth0
#dhclient -r eth0
Annex A
So here is how my Ubuntu host network configuration looks like.
The /etc/network/interface
# more /etc/network/interfaces
auto lo
iface lo inet loopback
#if using virtualization,need to comment wireless
#and need to run ifconfig br0 down
#auto wlan0
#iface wlan0 inet dhcp
#I added this for kvm virtualization,the need for bridge interface
auto eth0
iface eth0 inet manual
auto br0
iface br0 inet static
#chg this line for work or home network
address 192.168.2.111
#address 192.168.1.111
network 192.168.0.0
netmask 255.255.255.0
#chg this line for work or home broadcast
broadcast 192.168.2.255
#broadcast 192.168.1.255
#chg this line for work or home gateway
gateway 192.168.2.1
#gateway 192.168.1.1
bridge_ports eth0
bridge_fd 9
bridge_hello 2
bridge_maxage 12
bridge_stp off
It’s important to mentioned that, to explore virtualization you need to use wired connection rather than wireless. So you need to connect your notebook or server to modem router using Ethernet cable. After that boot up your machine.
Upon booting, the ip route show reveals the following output:
# ip route show
192.168.2.0/24 dev br0 proto kernel scope link src 192.168.2.111
192.168.2.0/24 dev eth0 proto kernel scope link src 192.168.2.106
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1
169.254.0.0/16 dev br0 scope link metric 1000
default via 192.168.2.1 dev eth0
default via 192.168.2.1 dev br0 metric 100
From the preceding output, we see that there is one Ethernet interface, eth0, one bridge interface, br0. Thus in fact there is only one physical Ethernet interface i.e eth0. The bridge interace br0 is created in a virtualized environment.
To access Internet, however, we need br0 and not eth0. Thus we need to bring down eth0 by typing the following commands:
# ifconfig eth0 down
# dhclient -r eth0
Don’t worry, you will still be able to connect to your other guests using the bridge interface br0.
So after bringing down eth0, the ip route show command will reveal the following output:
# ip route show
192.168.2.0/24 dev br0 proto kernel scope link src 192.168.2.111
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1
169.254.0.0/16 dev br0 scope link metric 1000
default via 192.168.2.1 dev br0 metric 100
Now before we boot up our guests, make sure we can access the Internet via the host machine.
You can fire up your Internet Web browser or run the nslookup command:
root@linuxbeatswindows:~# nslookup
> yahoo.com
Server: 192.168.2.1
Address: 192.168.2.1#53
Non-authoritative answer:
Name: yahoo.com
Address: 72.30.2.43
Name: yahoo.com
Address: 98.137.149.56
Name: yahoo.com
Address: 98.139.180.149
Name: yahoo.com
Address: 209.191.122.70
Name: yahoo.com
Address: 67.195.160.76
>exit
Once the Internet connection works, the next thing is to launch the guests machines. In my case I will boot up two guests; OpenSUSE server and CentOS server.
Once they bootup, record down their network configuration.
CentOS
[root@centos53 ~]# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 52:54:00:9F:AB:0F
inet addr:192.168.2.118 Bcast:192.168.2.255 Mask:255.255.255.0
[root@centos53 ~]# more /etc/sysconfig/network-scripts/ifcfg-eth0
# Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+
DEVICE=eth0
BOOTPROTO=dhcp
HWADDR=52:54:00:9F:AB:0F
ONBOOT=yes
DHCP_HOSTNAME=centos53
[root@centos53 ~]# more /etc/resolv.conf
; generated by /sbin/dhclient-script
nameserver 192.168.2.1
[root@centos53 ~]# ip route show
192.168.2.0/24 dev eth0 proto kernel scope link src 192.168.2.118
169.254.0.0/16 dev eth0 scope link
default via 192.168.2.1 dev eth0
For my CentOS server I will change its IP address to 172.16.0.3 with a subnet mask /16
[root@centos53 ~]# ifconfig eth0 172.16.0.3 netmask 255.255.0.0
Confirmed that the IP address has changed
ip route show
Now we will route the 172 network to the 192 network of the host machine. We do this using route commands.
Route add command
Take note that the gateway IP is the inteface IP itself
Route -n command
You will not be able to ping 192.168.2.1. This is because we need to set route commands on the 192 network.
On the 192 network, The Ubuntu host
# route add -net 172.16.0.0/16 gw 192.168.2.111 br0
Take note that the interface used here is br0 and not eth0
The Kernel IP Routing Table looks like this:
root@linuxbeatswindows:~# route -n
root@linuxbeatswindows:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 br0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
172.16.0.0 192.168.2.111 255.255.0.0 UG 0 0 0 br0
169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 br0
0.0.0.0 192.168.2.1 0.0.0.0 UG 100 0 0 br0
root@linuxbeatswindows:~#
root@linuxbeatswindows:~# ip route show
192.168.2.0/24 dev br0 proto kernel scope link src 192.168.2.111
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1
172.16.0.0/16 via 192.168.2.111 dev br0 scope link
169.254.0.0/16 dev br0 scope link metric 1000
default via 192.168.2.1 dev br0 metric 100
From the 192 network (Ubuntu host) try pinging the 172 network (CentOS guest).
root@linuxbeatswindows:~# ping 172.16.0.3
PING 172.16.0.3 (172.16.0.3) 56(84) bytes of data.
64 bytes from 172.16.0.3: icmp_req=1 ttl=64 time=5.37 ms
64 bytes from 172.16.0.3: icmp_req=2 ttl=64 time=0.438 ms
So the 172 network can connect to 192 network and vice versa
ping command
The 192 network can connect to the Internet. For the 172 network to connect to the Internet, we need to run iptables commands and enable IP forwarding on the Ubuntu host.
Enble IP Forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
Client
Before adding default gateway on Network Class A
linux-m286:~ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.2.0 10.0.0.10 255.255.255.0 UG 0 0 0 eth0
10.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
linux-m286:~ #
after adding default gateway on Network Class A
linux-m286:~ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.2.0 10.0.0.10 255.255.255.0 UG 0 0 0 eth0
10.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
0.0.0.0 192.168.2.1 0.0.0.0 UG 0 0 0 eth0
linux-m286:~ #
The last line in bold shows that if the destination is for other IP, then the packet is routed via the gateway 192.168.2.1, which is the gateway of the modem router connected to the Internet. This allows the machines on the Class A to access the Internet.