VirtualBox Notes

Backing up

Just make a copy of the .vbox and .vdi files.

Reducing disk space of dynamic disks.

This doesn’t work for encrypted disks.

On client virtual machine:

  • For Windows
    • Defragment disk, e.g defrag c:
    • Zero free space, e.g sdelete -z c: (sdelete is part of SysInternals)
  • For Linux
    • dd if=/dev/zero of=zeroes bs=1M until there is no space left
    • rm zeroes

Followed by on host computer:

  • VBoxManage.exe modifyhd /path/to/file.vdi --compact

Alternate technique

It may help to defragment and zero free space on existing disk first.

  • Create new VDI of smaller size.
  • Boot GParted or Clonezilla using ISO image, and clone existing disk to the new smaller sized disk (vdi).
  • Change VM settings and boot VM using smaller disk.

Sharing a folder RHEL or CentOS Linux VirtualBox VM

Update VirtualBox Guest Additions modules

Requires gcc and kernel headers installed. If not then run:

yum instal -y gcc kernel-devel-$(uname -r)

Devices > Insert Guest Additions CD image

mount /dev/cdrom /mnt
sh /mnt/
umount /mnt

Check module is installed with lsmod | grep vbox. You should see the vboxsfmodule.

Sharing a folder

To attach a folder for sharing:

  • Under Device > Shared Folders – Add your desired folder. Select “permanent” if you want this folder shared all the time.
  • Mount the drive with: mount -t vboxsf FOLDERNAME MOUNTPOINT
  • When finished, umount MOUNTPOINT

To make mount point persistent between reboots, add entry in /etc/rc.local (or /etc/fstab).

Moving Virtual Box VDI

Note This works with encrypted VDI disks.

Virtual machine must be shut down before proceeding.

Backup first!

Backup .vdi and .vbox files. Ths is very important! If you’re using encryption, these keys are inside the vbox file so make sure you back this up to somewhere safe. From now on we don’t touch the backups (unless something goes wrong), we’re referring to the actual working .vdi and .vbox files.


  1. Copy the vdi to the other location, e.g a different hard drive.
  2. In VirtualBox Manager, right click on the machine and remove from the machine list. Select “Remove only” (not “Delete all files”).
  3. Optional: Rename the original vbox file to something else. This is just a sanity check to make sure the machine won’t later find the old VDI.
  4. Open the .vbox file in a text editor. Look for a section that looks a bit like:
    <HardDisk uuid="XXX" location="Windows 8.1.vdi" format="VDI" type="Normal">
    <Property name="CRYPT/KeyId" value="Windows 8.1"/>
    <Property name="CRYPT/KeyStore" value="XXX"/>
  5. Edit the location= part to point to your new vdi location e.g location="E:\New Spot\Windows 8.1.vdi". Note that the location field will not have a drive or path if the vdi file is in the same directory as the vbox file. Save the modified vbox file.
  6. In VirtualBox Manager again, go to Machine > Add, and select your modified vbox file. Check the settings, and they should be the same as before but the drive will be in a different location.
  7. Start and test the machine. If you followed all the steps above exactly, it should be working.
  8. You can safely remove the old vdi file.


  • You can not have disks with the same UUID configured on your system. When you removed the machine from the list, it would have removed the disk from the Virtual Media Manager. If you skipped this remove and add machine part, this process won’t work.


Set up Let’s Encrypt with Nginx web server with webroot plugin

This will allow the Nginx web server to read /.well-known/acme-challenge/ from each domain. This path is used by the webroot plugin.

We’ll need to make a directory to service the challenge files from, we’ll call this /home/www/letsencrypt from now on, and we’ll need to make sure this is set up with appropriate permissions so Nginx can serve these files to the public.

In Nginx’s config, we can add the following to each server block configuration:

location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /home/www/letsencrypt;

Generally, adding this in /etc/nginx/global/global.conf and including this file (usually already done by a default install) in each .conf file in each of /etc/nginx/conf.d/ files is recommended.

Install certbot-auto

wget && chmod a+x certbot-auto && mv certbot-auto /usr/local/bin    

Add a certificate for a domain

certbot-auto certonly --webroot -w /home/www/letsencrypt -d

Renew all certs if near expiry

certbot-auto renew --webroot -w /home/www/letsencrypt

This can be added as a cron job.

00 2 * * * root /usr/local/bin/certbot-auto renew --webroot -w /home/www/letsencrypt 2> /dev/null

If you wish the automation to apply for a single domain only, use:

00 2 * * * root /usr/local/bin/certbot-auto renew --webroot -w /home/www/letsencrypt --cert-name NAME 2> /dev/null

Certificate names are usually the same as the domain name, however this may not always be the case. You can check your certificate names with:

certbot-auto certificates

To test configuration

certbot-auto renew --webroot -w /home/www/letsencrypt --dry-run

Configure nginx server blocks

In each domain’s server block add:

listen 443 ssl;

ssl_certificate      /etc/letsencrypt/live/;
ssl_certificate_key  /etc/letsencrypt/live/;
include ssl/ssl.conf;

In ssl.conf we have:

ssl_session_timeout       5m;
ssl_protocols             TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache         shared:SSL:10m;
ssl_dhparam               /etc/nginx/ssl/dhparams.pem;

The above SSL config is my personal preference, but you can adjust to your liking.

How to remove old Linux kernel images from /boot

For RedHat based OS

e.g RHEL or CentOS

Install yum-utils

yum -y install yum-utils

Check current running kernel version

rpm -q kernel

Remove old kernels, but leave the 2 latest ones.

package-cleanup --oldkernels --count=2

Edit /etc/yum.conf and set:


This will delete old kernels automatically but leave the latest two next time you perform a yum update

For Debian based OS

e.g Ubuntu

apt-get -f autoremove

If that doesn’t work, you may need to manually remove files from /boot using rm. Then run update-grub after.

You can always check what kernel is currently loaded by running uname -a

Generate some easy to remember passwords

Do not use this for sending sensitive data! For that please use a public key encryption scheme like PGP or GnuPG. This below is suitable for things such as online logins etc.

Obtain word list

Prepare a text file with dictionary words. Here we download some word lists from Scowl.

wget "" && \
tar -zxvf scowl-2016.01.19.tar.gz --wildcards --strip-components=2 scowl-2016.01.19/final/english-words.*

We grab the file english-words.10 and english-words.20 which contain a lot of popular words, filter it and remove the words we don’t want. There are other files here too which you can use as well, though they may contain less commonly used words which may be more difficult to remember.

To make a word list from english-words.10 and english-words.20 with 5 chars or more

cat english-words.10 english-words.20 | grep -v "'" | grep -e "....." | uniq | xz -9 -e > words.txt.xz

On Mac OSX, you’ll need to set LANG=C otherwise you’ll get a charset error with uniq.

Count the number of words in the list. For my current test, there is 9481 words.

xz -dc words.txt.xz | wc -l

Generate a 4 word password

Let’s random sort and create a password with 4 words. We’ll capitalise the first letter as well.

On Mac OSX, install coreutils and gnu-sed on Homebrew.


xz -dc words.txt.xz | sort -R | head -n 4 | sed 's/^\(.\)/\U\1/' | tr -d '\n'


xz -dc words.txt.xz | gsort -R | head -n 4 | gsed 's/^\(.\)/\U\1/' | tr -d '\n'

Make 10 random 4 word passwords

The above command repeated 10 times.


for i in {0..9}; do xz -dc words.txt.xz | sort -R | head -n 4 | sed 's/^\(.\)/\U\1/' | tr -d '\n'; echo ""; done

Generate 10 random 3 word passwords

Make 10 random 3 word passwords


for i in {0..9}; do xz -dc words.txt.xz | sort -R | head -n 3 | sed 's/^\(.\)/\U\1/' | tr -d '\n'; echo ""; done


for i in {0..9}; do xz -dc words.txt.xz | gsort -R | head -n 3 | gsed 's/^\(.\)/\U\1/' | tr -d '\n'; echo ""; done