Provide outside access to host-only VMs
I have a few VMs on my work laptop that provide services that are accessible using TCP ports, for example one that hosts an ElasticSearch/Kibana combination that I want to connect to on ports 22, 80, 443 and 9200. I want these VMs to work even when I am not connected to any outside network, so they are hanging off VirtualBox's host-only network. They have static IPv4 addresses on the host-only network, outside of the DHCP pool of course, so I can reach them consistently. Their names are in the
hosts
files on the work laptop. (“Files” (plural) because I use the Linux subsystem quite often, and that uses its own
hosts
file instead of that of the host Windows system.)
However, if I am at home, I want to access these virtual machines, at least some selected TCP ports on them, from other computers, not just from the computer they run on. So I need to somehow build a TCP proxy to get to them. In principle, Windows has such a thing built-in, namely the
netsh
program. If I were happy to just pick a few random port numbers and remember that when I want to get to machine
x
on port
y
I need to remember to use port
xyz
on my work laptop, I would be all set using
netsh
.
Needless to say, I don't want that. I want to be able to reach the machines exactly the same, no matter if I am working on my work laptop or any other machine in the house.
So I allocated a few IPv4 addresses in my normal home network and assigned the names of the VMs to them – the same names they have in the
hosts
files. So when I use the name of one of the VMs on my work laptop, it resolves to the IP address on the host-only network, but when I use the same name on another machine, it resolves to an address in my home network.
Now I need to connect the dots. I need to add the allocated IPv4 addresses to the work laptop's Ethernet interface and have a TCP proxy listen on them. But here the problems begin: in order to do that, I would have to switch the laptop's Ethernet port to static IPv4 configuration, but I don't want to do that, because I will surely forget I did if I ever try to connect to a wired network anywhere else. Windows however is unable to mix IPv4 DHCP and static addresses on the same interface.
To get around this problem, I created yet another VM with – you guessed it – Ubuntu Server as the operating system. It can be quite small; one processor and 1024 megabytes of RAM is enough. (This is for 22.04 "jammy".) This VM is connected to both the home network through bridged networking and the host-only network through another network interface. It has static IPv4 addresses on both. At this point, it is important to edit
/etc/ssh/sshd_config
and configure SSHD to only listen on the main addresses on both interfaces, not the alias addresses, or you can't tunnel port 22 on the alias addresses.
The last step is the TCP proxy. I use
rinetd
which is in the
universe
package repository. So add that to
/etc/apt/sources.list
if it isn't in there already, install
rinetd
, enable it with
systemctl
, configure your tunnels in
/etc/rinetd.conf
, add the alias addresses in
00-installer-config.yaml
, disable
cloud-init
by creating an empty file named
/etc/cloud/cloud-init.disabled
, reboot.
Whenever I want to use my VMs at home, I just have to start the tiny proxy VM as well.