Skip to content

Setting up a cyber lab

It is a good idea to be careful when deploying an unknown virtual machine created by someone else. We should not allow it access to the Internet or our local network. In this article I will describe the steps I take to achieve this.

Virtualisation

My virtualisation platform of choice is VirtualBox - it is simple to set up, easy to use, and open source. VirtualBox supports importing machines using the Open Virtualization Format (OVF). VirtualBox offers an 'Internal Network' which is completely isolated from the host network environment. We shall connect any unknown virtual machines to this internal network.

Now the problem is how we can connect to virtual machines in this isolated network, without opening up access to our local network and/or the Internet. We can solve this by setting up a virtual machine to act as a gateway. This gateway will have 2 NICs; one connected to the internal network and the other connected to our LAN through VirtualBox Bridged Adapter mode.

To control access to the Internet we will use some clever routing tricks and set up a VPN.

First follow the instructions available here to setup OpenVPN:

https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-debian-9

The guide is quite long and detailed, covering setting up OpenVPN service, TLS authentication, and client configuration. I used iptables rather than ufw for firewall configuration:

# apt-get install iptables-persistent

Answer yes when prompted to save current IPv4 and IPv6 configurations. Edit the file /etc/iptables/rules.v4, adding in the content below starting from "*nat" until the first instance of "COMMIT":

*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o enp0s3 -j MASQUERADE
COMMIT

# Generated by xtables-save v1.8.2 on Fri Dec 25 18:36:19 2020
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed on Fri Dec 25 18:36:19 2020

The masquerade command tells the firewall to replace the source address of outgoing packets from the 10.8.0.0/24 subnet with the server's own IP address, so that return packets will have a path back.

Check IP forwarding is enabled in the kernal (see step 6 in the linked article):

# /usr/sbin/sysctl -p

net.ipv4.ip_forward = 1

We should now have a working OpenVPN server, and connected clients will be able to access the Internet and LAN resources, while clients on the internal network will be completely isolated.

To connect a (linux) client:

# /usr/sbin/openvpn --config client1.ovpn &

To disconnect, end the openvpn process:

# pkill -SIGTERM openvpn

See the troubleshooting section in case the connected client cannot access the Internet.

Acessing the internal network from the VPN client

Now that VPN clients can and access one another, as well as the Internet, one thing remains. We want to be able to access clients connected to the Internal network, while at the same time prevent the same clients from accessing our network. We can do this in a similar way to how we allowed VPN clients on the 10.8.0.0/24 subnet external access - masquerading.

To achieve this goal, we need to think about address on the Internal network as if they are external addresses, and masquerade traffic leaving via the Internal network interface. Add a line in the nat section, under the similar from before to /etc/iptables/rules.v4

-A POSTROUTING -s 10.8.0.0/24 -o enp0s8 -j MASQUERADE

It is almost the same command, except the destination changes to the Internal network. The iptables should look something like this:

/usr/sbin/iptables -t nat -L -v -n

Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 1432 packets, 447K bytes)
 pkts bytes target     prot opt in     out     source               destination         
   83  6113 MASQUERADE  all  --  *      enp0s3  10.8.0.0/24          0.0.0.0/0           
    2   112 MASQUERADE  all  --  *      enp0s8  10.8.0.0/24          0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination        

The client machine will need to add an entry into it's routing table to direct traffic intended for the Internal network correctly. For example, on a windows box (assuming the VPN interface was assigned the IP 10.8.0.10):

route add 192.168.240.0 mask 255.255.255.0 10.8.0.10

This provides a path the subnet which would otherwise be unreachable, and that should be all you need.

Happy hacking!

Troubleshooting

VirtualBox Internal Network does not offer IPv4 address

I found the new internal network I created did not have a working DHCP server to assign IP addresses to clients. I needed to configure the DHCP server by running VBoxManage on the host:

$ VBoxManage list dhcpservers
$ VBoxManage dhcpserver add --netname hackernet --ip 192.168.240.100 --netmask 255.255.255.0 --lowerip 192.168.240.101 --upperip 192.168.240.254 --enable

I found I needed to restart the VirtualBox Manager GUI for the settings to take effect.

Bridged mode adapter does not acquire IPv4 address on startup

I could't find the reason bridged mode adapters were not acquring an IP address, as a workaround I ran ifup/down after boot:

# /usr/sbin/ifdown enp0s3
# /usr/sbin/ifup enp0s3

If you know of a solution, please let me know in the comments section.

OpenVPN client cannot access Internet - unable to redirect default gateway

This error can happen if a client machine did not have a default gateway already configured prior to connecting to the vpn server. OpenVPN does not know how to reroute external packets if there is no default route configured. This a likely to happen on a machine connected to the VirtualBox internal network.

A possible solution would be to configure the default route manually after connecting to the openvpn server:

$ ip route
10.8.0.1 via 10.8.0.5 dev tun0
10.8.0.5 dev tun0 proto kernel scope link src 10.8.0.6
192.168.240.0/24 dev enp0s3 proto kernel scope link src 192.168.240.102

Manually add route (replicate the line "via X dev tun0", replacing 10.8.0.1 with default)

# ip route add default via 10.8.0.5 dev tun0

Updated routing table:

$ ip route
default via 10.8.0.5 dev tun0
10.8.0.1 via 10.8.0.5 dev tun0
10.8.0.5 dev tun0 proto kernel scope link src 10.8.0.6
192.168.240.0/24 dev enp0s3 proto kernel scope link src 192.168.240.102

Another option could be to add a dummy default route (eg. to 127.0.0.1) prior to connecting the the vpn server. See https://unix.stackexchange.com/questions/308751/can-openvpn-create-the-default-route-if-it-doesnt-exist for more information.

Further reading

Comprehensive guide to VirtualBox networking configurations:

https://www.nakivo.com/blog/virtualbox-network-setting-guide/

Good guide to NAT with iptables:

https://www.karlrupp.net/en/computer/nat_tutorial

Superuser.com question - how to forward packets from one network interface to another:

https://superuser.com/questions/938805/how-forward-packets-from-network-interface-to-another

Trackbacks

No Trackbacks

Comments

Display comments as Linear | Threaded

No comments

Add Comment

Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Form options