Setting up an Ubuntu Router
I wanted to experiment with sniffing data on the network. Of course, my own network. This was not a creepy sniffing of my neighbours’ network. I was keen in converting my Ubuntu VM into a router VM. Then I can redirect all traffic from ‘client’ VM via the ‘router’ VM on which the sniffer is running. So, my requirements are simple, I need a VM with dual network adapter, one of which will be for the WAN side and other will be on the LAN side (exactly like a home router). What is required to convert a VM into router is a different topic and it will not be covered in this blog post.
Configure the Dual Network Adapter
The most important part of this is to understand that only one of the adapter is visible to your DHCP server and other is not. Why is this important? Because, only one of the adapter will get an IP from the DHCP and other will have to manually set. This DHCP-enabled adapter will be the WAN side adapter and the manual IP adapter will be the LAN side adapter. So, how do you configure dual interfaces on Ubuntu?
In Ubuntu, the networking system is configured via the ‘/etc/network/interfaces‘ file. Originally, there would have been only one interface as shown below:
$> ifconfig eth0 Link encap:Ethernet HWaddr 08:00:27:d9:7a:ca inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fed9:7aca/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:600 errors:0 dropped:0 overruns:0 frame:0 TX packets:852 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:273084 (273.0 KB) TX bytes:141395 (141.3 KB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:479 errors:0 dropped:0 overruns:0 frame:0 TX packets:479 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:147404 (147.4 KB) TX bytes:147404 (147.4 KB)
Now, let us configure the networking system to understand the 2nd interface, which we shall name as ‘eth1.’
So edit ‘/etc/network/interfaces‘ as show below:
# The loopback network interface auto lo iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet dhcp auto eth1 iface eth1 inet static address 192.168.50.1 network 192.168.50.0 netmask 255.255.255.0 broadcast 192.168.50.255
What this means is that:
- eth0 is DHCP-enabled and gets the IP from the DHCP server.
- eth1 has static IP of 192.168.50.1
Restart the network (via ‘sudo /etc/init.d/networking restart’):
Now, both the interfaces are up as shown below:
$> ifconfig eth0 Link encap:Ethernet HWaddr 08:00:27:d9:7a:ca inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fed9:7aca/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:600 errors:0 dropped:0 overruns:0 frame:0 TX packets:852 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:273084 (273.0 KB) TX bytes:141395 (141.3 KB) eth1 Link encap:Ethernet HWaddr 08:00:27:85:3a:24 inet addr:192.168.50.1 Bcast:192.168.50.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fe85:3a24/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:3043 errors:0 dropped:0 overruns:0 frame:0 TX packets:34454004 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:372333 (372.3 KB) TX bytes:3193181649 (3.1 GB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:479 errors:0 dropped:0 overruns:0 frame:0 TX packets:479 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:147404 (147.4 KB) TX bytes:147404 (147.4 KB)
Now we have 2 interfaces:
- ‘eth0’ (DHCP-enabled) pointing to the WAN side
- ‘eth1’ (static IP) pointing to the LAN side
Configure NAT routing
Use the following script, which I had borrowed from somewhere (forgot!) and slightly modified to my taste (available on github):
#!/bin/sh # #--------------------------------- constants fn_check_dependencies() { local __cmd=${1} local __path=$(which ${__cmd}) if [ $? -ne 0 ]; then echo "****************** !! \${__cmd}\' IS NOT AVAILABLE !! ******************" echo exit 1 fi echo ${__path} } # #--------------------------------- constants AWK=$(fn_check_dependencies awk) ECHO=$(fn_check_dependencies echo) DEPMOD=$(fn_check_dependencies depmod) GREP=$(fn_check_dependencies grep) IP=$(fn_check_dependencies ip) IPTABLES=$(fn_check_dependencies iptables) MODPROBE=$(fn_check_dependencies modprobe) NETSTAT=$(fn_check_dependencies netstat) # #--------------------------------- functions fn_get_wan_iface() { ${ECHO} $(${IP} route show | ${GREP} default | ${AWK} '{print $5}') } fn_get_lan_iface() { local _wan_ip=$(fn_get_wan_iface) ${ECHO} $(${NETSTAT} -i | ${GREP} -ve lo -ve Iface -ve Kernel -ve ${_wan_ip} | ${AWK} '{print $1}') } fn_load_mod() { local __mod_name=${1} ${ECHO} " |->; ${__mod_name}" ${MODPROBE} ${__mod_name} if [ $? -ne 0 ]; then ${ECHO} "****************** !! FAILED TO LOAD ${__mod_name} !! ******************" ${ECHO} exit 1 fi } fn_load_modules() { ${ECHO} " - Loading kernel modules: " ${DEPMOD} -a fn_load_mod ip_tables fn_load_mod nf_conntrack fn_load_mod nf_conntrack_ftp fn_load_mod nf_conntrack_irc fn_load_mod iptable_nat fn_load_mod nf_nat_ftp ${ECHO} } fn_enable_ipv4_forwarding() { ${ECHO} " - Enabling forwarding.." ${ECHO} "1" > /proc/sys/net/ipv4/ip_forward } fn_enable_ipv4_dynamic_addr() { ${ECHO} " - Enabling DynamicAddr.." ${ECHO} "1" > /proc/sys/net/ipv4/ip_dynaddr } fn_clear_previous_fw_rules() { ${ECHO} " - Clearing existing firewall rules" ${IPTABLES} -t nat -D POSTROUTING -o "$WANIF" -j MASQUERADE ${IPTABLES} -t filter -D FORWARD -i "$WANIF" -o "$LANIF" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT ${IPTABLES} -t filter -D FORWARD -i "$LANIF" -o "$WANIF" -j ACCEPT ${IPTABLES} -t filter -D FORWARD -j LOG } fn_create_fw_rules() { ${ECHO} " - Enabling firewall rules" ${IPTABLES} -t nat -A POSTROUTING -o "$WANIF" -j MASQUERADE ${IPTABLES} -t filter -A FORWARD -i "$WANIF" -o "$LANIF" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT ${IPTABLES} -t filter -A FORWARD -i "$LANIF" -o "$WANIF" -j ACCEPT ${IPTABLES} -t filter -A FORWARD -j LOG } # #--------------------------------- Main ${ECHO} ${ECHO} "======================= Enabling NAT =======================" ${ECHO} WANIF=$(fn_get_wan_iface) LANIF=$(fn_get_lan_iface) ${ECHO} "WAN Interface: $WANIF" ${ECHO} "LAN Interface: $LANIF" ${ECHO} if [ -z ${WANIF} ]; then ${ECHO} "****************** !! WAN interface not found !! ******************" ${ECHO} exit 1 fi if [ -z ${LANIF} ]; then ${ECHO} "****************** !! LAN interface not found !! ******************" ${ECHO} exit 1 fi if [ ${WAN} = ${LANIF} ]; then ${ECHO} "****************** !! Only one interface found !! ******************" ${ECHO} exit 1 fi ${ECHO} "Setting up network:" fn_load_modules fn_enable_ipv4_forwarding fn_enable_ipv4_dynamic_addr fn_clear_previous_fw_rules fn_create_fw_rules ${ECHO} ${ECHO} "======================= Done =======================" ${ECHO}
The above script does the following:
- Ensures the required kernel modules are loaded.
- Enable IP forwarding
- Enable masquerading on the WAN side interface
- All connections via LAN interface should be transferred to WAN interface
- Finally, all ‘established’ or ‘related’ connections via WAN should be transferred to LAN.
Done. Now when a device connects to this Ubuntu box via ‘eth1’ it connect to the internet. In other words, this ubuntu box serves as a router for other connected devices.
Leave a Reply