VirtualBox 4.1 on a Headless Debian Server

Installing VirtualBox on a headless Debian server and setting up a Ubuntu 12.04 guest operating system. 

Software

Software used in this article:

  1. Debian Wheezy
  2. VirtualBox 4.1.18

Installation

Install kernel headers:

# apt-get update && apt-get install linux-headers-`uname -r`

Install VirtualBox:

# apt-get install virtualbox

Three packages should be installed by default, virtualbox, virtualbox-dkms and virtualbox-qt. If you need VirtualBox guest additions, install them:

# apt-get install virtualbox-guest-additions virtualbox-guest-additions-iso

Check if VirtualBox kernel modules are loaded:

# lsmod | egrep 'Module|vbox'
Module         Size Used by
vboxpci       18742 0 
vboxnetadp    25431 0 
vboxnetflt    23260 0 
vboxdrv      165027 3 vboxnetflt,vboxnetadp,vboxpci

In case these are no loaded, do it:

# modprobe vboxdrv 
# modprobe vboxnetflt
# modprobe vboxnetadp
# modprobe vboxpci

Install VirtualBox Extensions

Download VirtualBox extension pack (v4.1.18) which contains a VRDE module needed for VBoxHeadless:

# wget http://download.virtualbox.org/virtualbox/4.1.18/Oracle_VM_VirtualBox_Extension_Pack-4.1.18.vbox-extpack

Install extension pack:

# VBoxManage extpack install ./Oracle_VM_VirtualBox_Extension_Pack-4.1.18.vbox-extpack
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Successfully installed "Oracle VM VirtualBox Extension Pack".

Verify installation:

# VBoxManage list extpacks
Extension Packs: 1
Pack no. 0:   Oracle VM VirtualBox Extension Pack
Version:      4.1.18
Revision:     78361
Description:  USB 2.0 Host Controller, VirtualBox RDP, PXE ROM with E1000 support.
VRDE Module:  VBoxVRDP
Usable:       true 
Why unusable:

If you ever need to remove the extension pack, you can do it this way:

# VBoxManage extpack uninstall "Oracle VM VirtualBox Extension Pack"

Configuration

We’ll be using a separate 30GB /dev/sdb1 disk to store VirtualBox images:

# df -h|egrep "Size|vb"
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1        30G  172M   28G   1% /vb

We will use a regular “sandy” user to run VirtualBox. Add sandy to vboxusers group:

# usermod -aG vboxusers sandy

Verify:

# grep vbox /etc/group
vboxusers:x:110:sandy

Change ownership of the VirtualBox directory to sandy:

# chown -R sandy /vb/

Switch to regular sandy user:

# su -l sandy

Create VirtualBox Ubuntu Image

All the configuration below can be done by using the vbox-script.sh:

#!/bin/bash
# written by Tomas (www.lisenet.com)
# 12/04/2014 (dd/mm/yy)
# copyleft free software
# below are the variables to pass to VBoxManage, modify appropriately
VM="Ubuntu1204";
ISO="/path/to/iso/file.iso";
VBROOT="/vb";
OSTYPE="Ubuntu";
DISKSIZE=10240; #in MB
RAM=512; #in MB
CPU=1;
CPUCAP=100;
PAE="off";
HWVIRT="off";
NESTPAGING="off";
VRAM=8;
USB="off";

echo "Creating the "$VM" VM."
cd ~;
VBoxManage createhd --filename "$VBROOT"/"$VM"/"$VM".vdi --size "$DISKSIZE";
VBoxManage createvm --register --name "$VM" --basefolder "$VBROOT" --ostype "$OSTYPE";
VBoxManage storagectl "$VM" --name "SATA Controller" --add sata  --controller IntelAHCI;
VBoxManage storageattach "$VM" --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium "$VBROOT"/"$VM"/"$VM".vdi;
VBoxManage storagectl "$VM" --name "IDE Controller" --add ide;
VBoxManage storageattach "$VM" --storagectl "IDE Controller" --port 0 --device 0 --type dvddrive --medium "$ISO";
VBoxManage modifyvm "$VM" --memory "$RAM";
VBoxManage modifyvm "$VM" --boot1 dvd --boot2 disk --boot3 none --boot4 none;
VBoxManage modifyvm "$VM" --chipset piix3;
VBoxManage modifyvm "$VM" --ioapic off;
VBoxManage modifyvm "$VM" --mouse ps2;
VBoxManage modifyvm "$VM" --cpus "$CPU" --cpuexecutioncap "$CPUCAP" --pae "$PAE";
VBoxManage modifyvm "$VM" --hwvirtex off --nestedpaging off;
VBoxManage modifyvm "$VM" --nic1 bridged --bridgeadapter1 eth0;
VBoxManage modifyvm "$VM" --vram "$VRAM";
VBoxManage modifyvm "$VM" --monitorcount 1;
VBoxManage modifyvm "$VM" --accelerate2dvideo off --accelerate3d off;
VBoxManage modifyvm "$VM" --audio none;
VBoxManage modifyvm "$VM" --snapshotfolder "$VBROOT"/"$VM"/Snapshots;
VBoxManage modifyvm "$VM" --clipboard bidirectional;
VBoxManage modifyvm "$VM" --usb "$USB";
echo "Run 'vboxmanage list -l vms | less' to check configuration."
exit 0

Set the name of the virtual machine to use:

$ VM=Ubuntu1204

Download Ubuntu server’s image file:

$ cd ~
$ wget http://releases.ubuntu.com/12.04/ubuntu-12.04.5-server-i386.iso

Create 10GBs virtual hard drive /vb/Ubuntu1204/Ubuntu1204.vdi:

$ VBoxManage createhd --filename /vb/$VM/$VM.vdi --size 10240
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Disk image created. UUID: e9071338-8ec2-4517-bfc8-24e7c24753d0

Find the operation system type for Ubuntu image to use:

$ VBoxManage list ostypes | grep -i ubuntu
ID:          Ubuntu
Description: Ubuntu
ID:          Ubuntu_64
Description: Ubuntu (64 bit)

We use a 32-bit Ubuntu image, therefore “Ubuntu” is just fine. Create and register the virtual machine:

$ VBoxManage createvm --register --name $VM --basefolder /vb --ostype Ubuntu
Virtual machine 'Ubuntu1204' is created and registered.
UUID: bf4911f5-f1d1-46d6-ab89-d7e0d2cc7407
Settings file: '/vb/Ubuntu1204/Ubuntu1204.vbox'

Configure Storage

Add SATA controller:

$ VBoxManage storagectl $VM --name "SATA Controller" --add sata  --controller IntelAHCI

Attach virtual hard drive to SATA port:

$ VBoxManage storageattach $VM --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium /vb/$VM/$VM.vdi

Add IDE controller:

$ VBoxManage storagectl $VM --name "IDE Controller" --add ide

Attach Ubuntu DVD image file to IDE port:

$ VBoxManage storageattach $VM --storagectl "IDE Controller" --port 0 --device 0 --type dvddrive --medium ~/ubuntu-12.04.4-server-i386.iso

Configure System Motherboard

Give 512MB of RAM:

$ VBoxManage modifyvm $VM --memory 512

Set up boot priorty, DVD-ROM first, hard drive second:

$ VBoxManage modifyvm $VM --boot1 dvd --boot2 disk --boot3 none --boot4 none

Leave chipset as piix3 unless you have a reason to change to ich9:

$ VBoxManage modifyvm $VM --chipset piix3

Disabling I/O APIC because our guest OS is 32-bit and we’ll use a single virtual CPU for the virtual machine:

$ VBoxManage modifyvm $VM --ioapic off

Change to usbtablet if absolute poiting device is needed.

$ VBoxManage modifyvm $VM --mouse ps2

Configure System Processor

Give a single virtual CPU with 100% execution cap. Also enabling physical address extension since our CPU supports it.

$ VBoxManage modifyvm $VM --cpus 1 --cpuexecutioncap 100 --pae on

Configure System Acceleration

Disabling hwvirtex as our CPU does not support Intel VT-x hardware virtualisation:

$ VBoxManage modifyvm $VM --hwvirtex off --nestedpaging off

Configure Network Adapter

Add a bridged eth0 (that’s our adapter) network card:

$ VBoxManage modifyvm $VM --nic1 bridged --bridgeadapter1 eth0

Configure Display and Audio

Set the amount of video memory provided to the virtual machine:

$ VBoxManage modifyvm $VM --vram 8
$ VBoxManage modifyvm $VM --monitorcount 1

No need for video acceleration as we’re not going to use a GUI on the guest machine:

$ VBoxManage modifyvm $VM --accelerate2dvideo off --accelerate3d off

Disable audio as it’s also not needed:

$ VBoxManage modifyvm $VM --audio none

Configure General Advanced Features and USB

Set /vb/Ubuntu1204/Snapshots path to snapshots folder:

$ VBoxManage modifyvm $VM --snapshotfolder /vb/$VM/Snapshots

Enable bidirectional clipboard sharing:

$ VBoxManage modifyvm $VM --clipboard bidirectional

Disable USB support:

$ VBoxManage modifyvm $VM --usb off

Review Guest Virtual Machine Configuration

Configuration can be checked this way:

$ vboxmanage list -l vms | less

Install Virtual Machine

On our headless Linux server, start the VM and bind VirtualBox remote desktop extension server to TCP 8888 port:

$ VBoxHeadless --startvm $VM -e "TCP/Ports=8888" &
Oracle VM VirtualBox Headless Interface 4.1.18_Debian
(C) 2008-2014 Oracle Corporation
All rights reserved.

VRDE server is listening on port 8888.

Note that since the headless server has no other means of output, the VRDP server will always be enabled, regardless of whether we had enabled the VRDP server in the VM’s settings.

We can check if VRDP is listening on TCP port 8888 with netstat. Make sure the port is open on a firewall to be able to connect.

# netstat -ntlp | grep -i vbox
tcp   0  0 0.0.0.0:8888    0.0.0.0:*      LISTEN   24318/VBoxHeadless

To proceed with Ubuntu installation, simply connect with rdesktop (or xfreerdp) from another GUI capable machine and follow on-screen instructions:

$ rdesktop <virtualbox_server_ip>:8888

When installation is finished, the Ubuntu VM can be started with no VRDP server as we’re going to use SSH:

$ VBoxHeadless --startvm $VM --vrde off &

Get the Private IP of the Virtual Machine (for SSH)

You can find out the private IP of the VM by issuing the following command:

$ VBoxManage guestproperty enumerate $VM | grep IP
Name: /VirtualBox/GuestInfo/Net/0/V4/IP, value: 10.1.2.3, timestamp: 1234, flags:

Or:

$ VBoxManage guestproperty get $VM "/VirtualBox/GuestInfo/Net/0/V4/IP"
Value: 10.1.2.3

Create Snapshots

When done installing the guest OS, create a snapshot so you can always revert back changes if needed:

$ VBoxManage snapshot $VM take fresh-install
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

Restoration from a snapshot is as simple as:

$ VBoxManage snapshot $VM restore fresh-install
Restoring snapshot d437e014-0bcf-4d4b-9314-4ff050162627
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

10 thoughts on “VirtualBox 4.1 on a Headless Debian Server

  1. Thanks so much for this excellent and detailed tutorial.

    Could you add one additoinal step at the end (or comment) – how do I use ssh to connect to the VM from a different machine on the same LAN? I don’t know how to do that without using rdesktop as you’ve shown.

    In other words, I dont’ understand your last step:
    “When installation is finished, the Ubuntu VM can be started with no VRDP server as we’re going to use SSH:
    $ VBoxHeadless –startvm $VM –vrde off &”

    That starts the VM from a shell on the host (that I’ve ssh’d into), but then how to connect to it?

    • Hi Keith. I assume that you have installed the SSH server on your VM. If so, you can SSH by using the credentials you provided during the server installation.

      What you may not know is the private (LAN) IP of you VM, there are quite a few ways of finding it out. One of them is to run the following:

      $ VBoxManage guestproperty enumerate $VM | grep IP

      Another way would be to check your router’s DHCP leases (again, I assume that you use DHCP in this case, otherwise you’d know the static IP you set up).

      You can power on the VM with VRDP and check the private IP via ifconfig or ip addr.

      You can also find out the private IP (assuming that you use a “bridged” mode) with arp-scan. Something like that should do the trick:

      # arp-scan -l | grep 08:00:27
  2. Thanks so much Tomas! You have a really good teaching style. Every sentence you write teaches me something.

    I had made (at least) two mistakes- first, (as you reminded me) I forgot that a minimal Debian netinstall does _not_ by default install ssh (or sudo!) … so I needed to install those.

    More important, I had accidently put the VM into an “aborted” state. Using vboxmanage from the command line I could not figure out how to restart the VM. According to the man page, the options for controlvm are: pause, resume, reset, poweroff, or savestate. None of those options worked for the VM in aborted state.

    In my case, I do have a minimal x windows setup on the host, and I was able to physically go to it and use the virutalbox gui to “start” the VM again. But that, of course, would not typically be a solution for a really headless remote server.

    What’s the correct vboxmanage command from the CLI that I should have used to recover from the aborted state?

    • I normally use an X11 forwarding to restart an aborted VirtualBox VM. If you find a better way of doing that, feel free to share.

    • Oh, OK, I thought perhaps I was using the wrong command. I could have just killed the process after connecting to the host, I suppose, since it is just a test server. I haven’t learned enough about using vnc or x11, yet.
      Thanks for your help!

Leave a Reply

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