Please enable JavaScript to view the comments powered by Disqus. SONKUN-DEV.net
Remote VirtualBox on dedicated servers
Wednesday, 24 October 2018

Dedicated servers are headless machines (computers with no monitor attached) meant to run non-graphical software such as servers. Why would you need to install Windows with remote graphical access ? Well, one of the reason is continuous integration. It's an important part of the software development cycle and when you don't want a paid service, you'd have to run your runners/slaves/workers/nodes (whatever they're called these days) on a 24/7 machine. But this article isn't about continuous integration, it's about setting up, remotely and with a terminal, a virtual machine and its maintenance practices.

In this article, I'll explain how to create a VM, create a secure remote graphical access using the RDP protocol, install guest additions, take snapshots for administrative purpose and have it started at boot time. At the end, you'll even be able to start and shut it down using the following standard command.

sudo systemctl start|stop vm

Note that if during the procedure you run into "vboxdrv kernel module is not loaded" issue, you'll need to switch to the default kernel. See previous article to fix it. Also, the following was tested on ArchLinux but it should not be much different for the other distributions.

Isolating the service with a system user and a partition

I like to isolate each service running on my dedicated server. In this case, this is about creating a system user and, eventually, limiting it to a given partition. Actually I also like naming services after Pokémon, therefore I'll use the name Pikachu.

Start with creating a regular system user pikachu with a standard home directory if you don't care about partition. This will create /home/pikachu and this is where we'll be installing the virtual machine.

sudo useradd -m -s /bin/bash pikachu

But if you have the luxury to create a dedicated partition, you will want to create the system user and set his home directory later on. Assuming the partition is at /mnt/pikachu, you need the following.

sudo useradd -s /bin/bash pikachu
sudo chown pikachu:pikachu /mnt/pikachu
sudo usermod --home /mnt/pikachu pikachu

The catch here is that the home directory must be owned by the pikachu user. However, it must be created first.

No password was created for this system user, instead we'll use root privilege (no need to create a password that we won't remember).

sudo su - pikachu

This log us in as the pikachu user and automatically change the current working directory to its home directory. The rest of the procedure is exclusively done under this user.

Creating and configuring the VM

For the next step, you obviously need VirtualBox installed. Use the underlying package manager to install it.

sudo pacman -S virtualbox

Create the virtual machine Pikachu with the following command. Note that the --ostype is important as it configures the machine with settings known to work for the given operating system.

vboxmanage createvm --name "Pikachu" --ostype Windows10_64 --register --basefolder pikachu

Now that we have given the virtual machine a name, we have to use it in every subsequent commands. If the virtual machine was successfully created, a message like that should appear.

Virtual machine 'Pikachu' is created and registered.
UUID: e9eacc2a-162a-4eb1-bfbd-6d49df306a60
Settings file: '/mnt/pikachu/.config/VirtualBox/pikachu/Pikachu/Pikachu.vbox'

After that you should configure the virtual machine with the CPU count, the RAM and VRAM size. You'll want change the values according to how you want to share the resource of your dedicated server across the different services.

vboxmanage modifyvm "Pikachu" --cpus 2
vboxmanage modifyvm "Pikachu" --memory 2048
vboxmanage modifyvm "Pikachu" --vram 128

We'll need to create a virtual hard disk and attach the Windows ISO file to the virtual "CD reader". Use the following set of self-explanatory command-lines to do that job. Adjust the size of the hard disk (expressed in Mb) and the path to the ISO file if necessary.

vboxmanage createhd --filename pikachu.vdi --size 100000
vboxmanage storagectl "Pikachu" --name "IDE Controller" --add ide
vboxmanage storageattach "Pikachu" --storagectl "IDE Controller" --port 0 --device 0 --type hdd --medium pikachu.vdi
vboxmanage storageattach "Pikachu" --storagectl "IDE Controller" --port 1 --device 0 --type dvddrive --medium Win10_1709_EnglishInternational_x64.iso

We're pretty much set up to start the virtual machine but we need one more thing... a remote graphical access to it.

Securing a remote graphical access

Unfortunately, we'll still have to install Windows the old fashion way and for that... we need a graphical access. We're using the RDP protocol so a client like Remmina on Linux does the trick.

First off, let's open the port for the connection. If you have a firewall set up like UFW, you'll want to type this.

sudo ufw allow 5012

We can configure the virtual machine to start a graphical server on port 5012 with the following.

vboxmanage setproperty vrdeauthlibrary "VBoxAuthSimple"
vboxmanage modifyvm "Pikachu" --vrde on
vboxmanage modifyvm "Pikachu" --vrdeport 5012
vboxmanage modifyvm "Pikachu" --vrdeauthtype external

This has set up the machine to use the username/password authentication mechanism, therefore, few more lines are needed to finish the configuration. I usually generate passwords with the pwgen -s command. For this article, I'll use Sf5gi5nO.

vboxmanage internalcommands passwordhash "Sf5gi5nO"
vboxmanage setextradata "Pikachu" "VBoxAuthSimple/users/sonkun" 15c889ee10763046eb56756da971e606b162bed7f3d5edfd7eaf868b47eb0fad

The first line generate the hash version of the password. Collect the output and reuse it in the second command which will actually set up the machine instance. Note that the occurrence sonkun refer to the username, change it accordingly.

Having the VM start at boot time

To start the virtual machine we'd actually have to type vboxmanage startvm "Pikachu" --type headless but it'd more convenient to just use the standard service manager systemd. Plus we also need to start it at boot time.

We do it by creating a system service configuration file in /etc/systemd/system that we name pikachu.service, then put the following content in it.

[Unit]
Description=Pikachu VM
After=network.target

[Service]
User=pikachu
Type=forking
ExecStart=/usr/bin/vboxmanage startvm "Pikachu" --type headless
ExecStop=/usr/bin/vboxmanage controlvm "Pikachu" poweroff

[Install]
WantedBy=multi-user.target

After it's done, two more commands are needed. The first one is to make systemd aware of our new script, and the second is to start the service at boot time.

sudo systemctl daemon-reload
sudo systemctl enable pikachu

Now you can start the virtual machine with sudo systemctl start pikachu and shut it down with sudo systemctl stop pikachu. From now on, you should be fine on your own but let me assist you during the installation of Windows to teach you a couple of awesome tricks.

Initial installation of Windows

I'll go through the Windows installation step with you to talk about snapshots which come in extreme handiness when it comes to administrating and updating a VM.

At this point, you should have started the VM and installed Windows on it. Now there are couple more things to do. First is removing the initial Windows ISO file, and putting the guests addition ISO file in the VM's CD reader.

While the guests additions ISO file can be downloaded from the official website of VirtualBox, on ArchLinux, there's a package that does just that.

sudo pacman -S virtualbox-guest-iso

The guest additions ISO file is then located here: /usr/lib/virtualbox/additions/VBoxGuestAdditions.iso.

Shut down the VM, either directly on Windows using the Power off button or from the command-line sudo systemctl stop pikachu, then proceed with removing the initial Windows ISO file and replace it with the guest additions ISO file.

vboxmanage storageattach "Pikachu" --storagectl "IDE Controller" --port 1 --device 0 --type dvddrive --medium /usr/lib/virtualbox/additions/VBoxGuestAdditions.iso

Start the VM again, and do install the guest additions as it now appears in the File Explorer, then proceed with shutting down the VM again and this time, definitely remove any medium from the CD reader.

vboxmanage storageattach "Pikachu" --storagectl "IDE Controller" --port 1 --device 0 --type dvddrive --medium none

This has probably been a tiring step and you probably don't want to do it (ever) again. I didn't even mention that one needs to update the Windows system and using an old ISO might result in waiting a couple of hours until Windows is fully up-to-date. At this point, a snapshot can be taken. Preferably, shut down, properly" the VM before running that command.

vboxmanage snapshot "Pikachu" take windows-installed

This will save the current states of the machine and later, if anything goes wrong on it, you can just go back to where it was... the time after all the tedious things we just did. In this case, I named the snapshot "windows-installed" and it can be restored with the following command.

vboxmanage snapshot "Pikachu" restore windows-installed

In fact, you can have different variations of your Windows machine using snapshots and easily switch from one to another. Let's say you need different version of Microsoft compilers for your software, you can install one version of Visual Studio in one snapshot named "visual-studio" and MinGW in another one called "mingw". Check out the snapshot documentation for more information but this should save you hours of maintenance when done intelligently.

Conclusion

This was a follow-up of the previous article about fixing a common problem that occurs when running VirtualBox on dedicated servers (https://www.sonkun-dev.net/article/fix-vboxdrv-kernel-module-is-not-loaded). Now we took it to the next step and actually created and configured a VM machine quite neatly.

Hope it helped some people out there, and drop a message in the comments section below if you have a question. For the next article I might talk about installing Teeworlds servers.