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
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
Virtualbox settings for 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.
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
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.
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!
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 126.96.36.199 -j REJECT # iptables -I INPUT -m iprange --src-range 188.8.131.52-184.108.40.206 -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