Setup a Test Networking Lab With VirtualBox

Overview

I wanted to create a test lab for networking for testing things out without having to hack my real LAN about. I decided on using VirtualBox as it is freely available and works with Linux and also Windows guests. The virtual network in the lab needed to have a simulated router or even two, and be completely separate, and hidden from my actual LAN. From the point of view of the test lab my real LAN will be just another part of the internet.

Inside the virtual net I want a router, or possibly two, which will take the place of my ADSL modem/router. Each router will have two NIC’s, one inside the lab subnet the other NIC will be external to the VM subnet i.e the internet or in this case my local LAN.

I then want a bunch of machines inside the lab on their own VBox subnet to simulate the workstations, desktops and servers in an office environment or what every I’m learning about and testing.

I want to be able to access the internet and also my real LAN,as if it was the internet. i.e. I can use a firewall on the router to block incoming connections and use port forwarding to reach servers inside the lab network as required. I can also test out web servers, mail servers, remote access and VPN’s.

For the fully qualified names within the lab you could use example.lab if you are using example.local as your local domain.

Network Topology for the lab

VM_subnet

VirtualBox & Ubuntu Configuration

We need to create at least two virtual machines, a router and a desktop. These machines can be installed in your usual subnet. Once that has finished you can bend the network around to put them into the lab environment. Once you have them completed you can clone, or link clone them to simulate more machines as required.

The Lab Router

The lab router will require two network cards to be configured. I setup the first, eth0, as Bridged and the second, eth1, as Internal Network with a name of lab1 within VirtualBox.

Virtualbox settings for eth0

router-eth0

Virtualbox settings for eth1

router-eth1

The router will be a minimal install of Ubuntu 12.04 LTS Server. For a very basic install you do not need anything added when asked during the server install. Although, I tend to add openssh-server so I can access the new machine via a terminal and therefore copy paste while I’m setting it up. It also allows for a larger terminal rather than the default 80×23 🙂

Network settings lab-router

Lets start with a little script to turn off all rules for iptables. Then whenif we make a mistake or a typo we have an easy way to turn off the firewall 🙂

sudo nano /root/fw.stop
#!/bin/bash

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

Change the permissions so only root can execute it or in fact see the file.

sudo chmod 700 /root/fw.stop

Now any time you want to remove all the rules you have added to iptable simply execute the script.

sudo /root/fw.stop

Since the lab machines will need to talk to the outside world, and the internet, we will need to turn on port forwarding and then add a rule to the external interface, eth0, so that packets get SNATed to the outside.

sudo iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.0.4

With this rule connections from the lab will reach the internet and should work. 🙂 The rule will not survive a reboot though. To load the rule we can add a pre-up rule to the interfaces file.

sudo su -c 'iptables-save > /etc/iptables.rules'

It should look something like this:

# Generated by iptables-save v1.4.12 on Sun Mar 16 09:46:48 2014
*nat
:PREROUTING ACCEPT [151:24791]
:INPUT ACCEPT [77:16255]
:OUTPUT ACCEPT [22:1585]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o eth0 -j SNAT --to-source 192.168.0.4
COMMIT
# Completed on Sun Mar 16 09:46:48 2014
# Generated by iptables-save v1.4.12 on Sun Mar 16 09:46:48 2014
*filter
:INPUT ACCEPT [335:44854]
:FORWARD ACCEPT [1689:1480009]
:OUTPUT ACCEPT [164:20863]
COMMIT
# Completed on Sun Mar 16 09:46:48 2014

The above should be done whenever you want to update the rules loaded at boot time. That is, try out the new rules from the command line. When you are happy with them save them to the /etc/iptables.rules file.

Now we need to configure iptables/sysctrl to allow port forwarding
To turn on port forwarding we have some choices, to do it until the new reboot use the following.

sudo echo "1" > /proc/sys/net/ipv4/ip_forward

You can use sysctl to perform the same function but this will not survive through a reboot.

sudo sysctl net.ipv4.ip_forward=1

Or you can edit the conf file as shown below.

sudo nano /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

Now to setup the network interfaces for the lab router and add the pre-up line to load the iptables rules. The address is any IP address on your real LAN that is outside of the lab.

sudo nano /etc/network/interface

The gateway will most probably be your real LAN gateway as are the DNS addresses setup on this interface.

# The loopback network interface
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
   address 192.168.0.4
   netmask 255.255.255.0
   gateway 192.168.0.1
   dns-nameservers 192.168.0.9
   pre-up iptables-restore < /etc/iptables.rules

auto eth1
iface eth1 inet static
   address 10.1.200.1
   netmask 255.255.255.0

You will want to install some form of DNS and DHCP server on to the lab router. See my post for setting up dnsmasq. HOWTO Setup Dnsmasq as a DNS and DHCP server/. You can easily turn on and off the DHCP for Dnsmasq by commenting out the dhcp-range options in the configuration file and restarting the daemon.

Simple Port Forwarding from the lab-router

Our lab-router would not be of much use if it did not forward some ports such as 80 (HTTP), 443 (HTTPS) or maybe even 22 (ssh). We can achieve this with some reasonably simple rules for iptables. To start with we need to make sure IP forwarding is enabled. Turn on port forwarding, this should already be done if you followed all the steps.

In this example we have a web server with a static IP address of 10.1.200.20 and we want all connections on port 80, HTTP, which the router receives to be forwarded to our pretend web server in the lab on IP 10.1.200.20 on port 80.

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.1.200.20:80

To make sure the rules survive a reboot save them to the same file we created above and then they will be loaded when eth0 is brought up.

sudo su -c 'iptables-save > /etc/iptables.rules'

You can add additional rules for say, 25, 443 or 22 and they will all be forwarded to the new lab host.

Bandwidth Monitoring tool

I like to install this little command line tool to see the two NIC's working away on the router.

sudo apt-get install bwm-ng

Then just run it with bwm-ng on the command line. You will work it out. 🙂

The Desktop Machine

This machine is used to simulate a workstation or desktop computer inside the lab. It will not communicate directly with the local LAN only other lab machines and the lab router. This can be installing outside of the lab environment and then the network changed as follows:

VirtualBox settings for eth0

desktop-eth0

This machine only needs one NIC and it is on the Virtualbox Internal Nertwork with a name of lab1. Lets give it a static address to start off with.

lab-desktops

sudo nano /etc/network/interfaces
# The loopback network interface
auto lo
iface lo inet loopback

# If you have setup a DHCP server inside the lab,
# comment the below settings and uncomment this block.
auto eth0
iface eth0 inet dhcp
   hostname lab-desktop1

#auto eth0
#iface eth0 inet static
#   address 10.1.200.10
#   network 10.1.200.0
#   broadcast 10.1.200.255
#   gateway 10.1.200.1
#   netmask 255.255.255.0
#   dns-nameservers 10.1.200.1

Do not forget to change the network card to Internal Networking, and when you start this machine up again you should be able to dig or ping sites like bbc.co.uk or cnn.com and machines on your own local LAN remember to use the fully qualified names for your LAN, those outside of the lab.

Real host machine

If you want a quick and dirty way to add access to your lab network. On the lab router's NIC which is connected to your LAN, or as the the lab sees it "the internet" add the following. Remember 192.168.0.4 is the IP address on eth0 for the lab router.

sudo route add -net 10.1.200.0/24 gw 192.168.0.4

Note: this will NOT survive a reboot. You need to save the rule to a file and add it to the NIC config in the interfaces file, in the same way we did in Network settings lab-router by adding a line such as "pre-up iptables-restore < /etc/iptables2.rules"

sudo su -c 'iptables-save > /etc/iptables2.rules'

After restarting the desktop machine, you should be able to dig or ping sites like bbc.co.uk or cnn.com and machines on your own local LAN remember to use the fully qualified names for your LAN, those outside of the lab.

That is it!

Useful Links

Netfilter, Using iptables
Netfilter, Source NAT
Ubuntu iptables Howto

Scripts to Set Basic Firewall Configuration

This first one I use in the lab router when playing around with desktops and servers. It also turns on the DHCP server for dnsmasq.

#!/bin/bash

# Cancel all rules on iptables, start from a known state
/root/fw.stop

echo "Enable rules to block stuff"

# Allow replies to established connections
# ========================================
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Sort out NATing for lab machines
# ================================
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.0.4


# Try and stop DoS attacks
# ========================
#    -m limit: This uses the limit iptables extension
#    --limit 25/minute: This limits only maximum of 25 connection per minute. Change this
#                      value based on your specific requirement
#    --limit-burst 100: This value indicates that the limit/minute will be enforced only
#                      after the total number of connection have reached the limit-burst level.
iptables -A INPUT -i eth0 -p tcp -m multiport --dports 25,110,143,587,993,995 -m state --state NEW -m limit --limit 4/minute --limit-burst 5 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -m multiport --dports 80,443,8080 -m state --state NEW -m limit --limit 25/minute --limit-burst 50 -j ACCEPT

# Block connections from known spammers
# =====================================
# Block one IP address or range as CIDR
# or even a range
# iptables -A INPUT -s 11.22.33.44 -j REJECT
# iptables -I INPUT -m iprange --src-range 1.2.3.4-1.2.255.255 -j REJECT


# Allow a bunch of ports & services through
# =========================================
# web
iptables -A INPUT -i eth0 -p tcp -m multiport --dports 80,443 -j ACCEPT
# mail
iptables -A INPUT -i eth0 -p tcp -m multiport --dports 25,110,143,587,993,995 -j ACCEPT
# ssh from external & interal LANs
iptables -A INPUT -i eth0 -p tcp --dport ssh -j ACCEPT


# Port forwarding
# ===============
# Route port 2222 to port 22 on the lab-router
iptables -t nat -A PREROUTING -p tcp --dport 2222 -i eth0 -j DNAT --to 192.168.0.4:22
# forward ssh conections through to another machine
iptables -t nat -A PREROUTING -p tcp --dport 22 -i eth0 -j DNAT --to 10.1.200.10:22

# These go to another machine, looks like a mail and web server
iptables -t nat -A PREROUTING -p tcp --dport  80 -i eth0 -j DNAT --to 10.1.200.10:80
iptables -t nat -A PREROUTING -p tcp --dport 443 -i eth0 -j DNAT --to 10.1.200.10:443
iptables -t nat -A PREROUTING -p tcp --dport  25 -i eth0 -j DNAT --to 10.1.200.10:25
iptables -t nat -A PREROUTING -p tcp --dport 110 -i eth0 -j DNAT --to 10.1.200.10:110
iptables -t nat -A PREROUTING -p tcp --dport 143 -i eth0 -j DNAT --to 10.1.200.10:143
iptables -t nat -A PREROUTING -p tcp --dport 587 -i eth0 -j DNAT --to 10.1.200.10:587
iptables -t nat -A PREROUTING -p tcp --dport 993 -i eth0 -j DNAT --to 10.1.200.10:993
iptables -t nat -A PREROUTING -p tcp --dport 995 -i eth0 -j DNAT --to 10.1.200.10:995

# You could even do the above like this, assuming they all go to the same host
# it is less typing and easier to debug
for p in 80 443 25 110 143 587 993 995
do
   iptables -t nat -A PREROUTING -p tcp --dport $p -i eth0 -j DNAT --to 10.1.200.10:$p
done

# REJECT all remaining packets
# ============================
# This rule must be LAST, it blocks all remaining new INPUTs on eth0
iptables -A INPUT -i eth0 -j REJECT

# OR set the default action for INPUT to be DROP. This has the
# same effect but I found it causes a 3 second delay when accepting 
# connections. This rule can go anywhere, first, middle or last.
#iptables -P INPUT DROP

# ==========================
# Sort out dnsmasq, turn on dhcp
# ==========================
echo "Turn on the DHCP server in dnsmasq"
sed -e 's/^#\(dhcp-range=10.1.200.150.*\)/\1/' -i /etc/dnsmasq.conf
service dnsmasq restart

5 thoughts on “Setup a Test Networking Lab With VirtualBox

  1. Juan Navarro

    Actually, while doing a minimal install of this setup, the Router machine doesn’t provide DNS service, so the “lab-desktop” machine has to use any other DNS server (ie. the LAN router, if no other DNS server is operating in the network) as the nameserver:
    dns-nameservers 192.168.1.1 (which is the IP of my LAN router)
    instead of
    dns-nameservers 10.1.200.1

    Reply
    1. Richard Post author

      Which is precisely why about half way through I say “You will want to install some form of DNS and DHCP server on to the lab router. See my post for setting up dnsmasq. “ and provide a link on how to do that. 🙂

      Reply
  2. Kito Joseph

    Hello, thanks for this tutorial. It was exactly what I needed to setup up my environment for studying and testing purposes. I hope that you will have other similar articles in the future.

    Reply
    1. Richard Post author

      I’m not entirely sure what you mean here. The point of the test network is for you to test out networking ideas without changing your real LAN. The fact that you are using virtual machines means you can try things out and start again if it does not work out.

      If you want to limit your mailserver to only allow access from some machines, you could use a firewall or even add some checking in the HELO/EHLO checks if you use Postfix.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *