Mark Bishop

Analytical Chemistry and

Signal Acquisition/Analysis

Setup a Remote, Unattended, VirtualBox Workstation and Manage it Remotely with SSH

This article presents a working strategy that has been tested on a variety of platforms. Sections of this article will be of value if you are only trying to accomplish part of the described objective.

Definitions: A virtual machine is called a guest. The native install from which you run the guest is called the host. Beware, in common network terminology, a computer into which a remote session can be established is also called a host. I will try to use the term VBox host when referring to the former and remote machine for the latter. Finally, a computer that has made a remote network connection to a network host is called a client.

Our community's nature lodge has a computer that is used by visitors and volunteers to view presentations, search the web, use web-mail, etc. The network also has an IP camera that is focused on the bird feeder and is available on the Internet. The camera is also accessed by a program on the computer that captures images when motion is detected. We periodically ssh into the computer to do updates and other chores.

This computer is exposed to the Internet and is used by random persons with unpredictable skills and caution levels. Visitors/staff don't want to develop new computer skills at the lodge and they usually ignore admonitions on sticky notes attached to the monitor. They will install tool bars, delete system files, navigate to fake anti-virus sites, etc. Managing a system like this can be a time consuming headache for a small, resource-limited organization. Volunteer computer managers often have to "fix" the machine on each visit... never really knowing what problems they may have missed.

A virtual machine is inherently restorable and can be comprehensively backed-up... operating system and all. We use fresh-daily clones from a stable virtual machine template. It is easy and reliable. We use Linux for our native OS and run Windows in a virtual machine (but you can use this approach if your VM is Linux or if your VBox host is Windows). In a startup script, a clone of a template virtual machine is made each morning. The previous day's clone is erased just before each new clone is made. Toolbars, off-color images, and rogue software are conveniently purged in an instant! Daily permanent storage for users is done with a thumb drive (a weak point if the drive is compromised). I keep the master template's virtual disk write-protected.

Virtual machine performance isn't quite as good as a native install but this compromise will be tolerable if you keep things simple... both on the VBox host and the guest.

Stepwise, here is the overall process:

Remember that every system can be compromised and an exposed virtual machine running on a locked-down VBox host is no exception. The best strategy for security is to be a well maintained, low-value target.

Install your favorite native OS . This could be Windows, Mint, Ubuntu, Lubuntu, etc. but be sure your choice can run VirtualBox. Another consideration is your operating system's memory and processor demands. Not-for-profit computers are often second hand and bog down with flashy operating systems (we prefer a bare-bones, Gnome 2, Linux VBox host). Configure the native OS as you see fit, being careful not to burden the system with overhead. Consider a minimal install: just enough to support VBox, openssh, and a firewall. The virtual machine's VBox host will be the most time consuming component to restore when thinks go wrong. Take precautions to protect your VBox host including updates, firewalls, backups, periodic tactical diagnostics, etc.

Install VirtualBox and the VBox extension Pack. Consider changing the VBox host key (File → Preferences → Input) to something other than Right Cntl (say f9). This will help users avoid stumbling upon the VBox host when using the virtual machine.

The Guest

Install your guest operating system. Completely update the machine and install guest additions. Our community application uses a Windows XP guest but everything in this article can be done with a Linux guest. Setup the guest exactly as you want it but limit the resources used by it appropriately. A fixed size disk rather than dynamic allocation should be considered. Make the disk as small as possible. Isolate the virtual machine from the VBox host (and your LAN) as much as possible. We delete the clone everyday, so we don't overdo it with anti virus/maleware packages and I turn off all of the automatic updating. On my particular guest, I set-up my IP camera software, Windows Remote Desktop, Open Office, and Cygwin/SSH.

If you want to present the guest to your users and do not wish to confuse them, then make the guest display full screen. Also, in the machine's settings, uncheck “Mini Toolbar – Show in Fullscreen/Seamless.”

VBox Machine Network Settings

Use a Vbox NAT controller with port forwarding to reach the guest. Disabling firewalls during configuration can save time during setup. Start them up again after everything is working, checking connectivity as you go.

Using NAT and Port Forwarding

If your guest does not have to reach LAN resources, then NAT with port forwarding is all you need. Using NAT forwarding allows you to isolate the guest from the VBox host's LAN. When you want to access a service port on the guest from the LAN (or the Internet), you reach it by requesting the service from the VBox host's IP address. For example, let's say that your guest provides a service on port 2241. We arbitrarily decide that we want to access it by way of port 2240 on the VBox host. When the VBox host receives a service request 2240, it will pass it along to the guest at port 2241. There are a few ways to set this up but I like the VBox GUI. Go to Settings → Network for your virtual machine and enable a NAT adapter. Click on “Advanced” on your adapter page then select “Port Forwarding.” Add a rule that looks like this:

image of Port Forwarding Rules

You can use any unused VBox host port you want but, if you have a Unix VBox host, make it greater than 1024! Be sure that the host's firewall allows connection to the source port (2240). Don't open the guest's port (2241) on the VBox host's firewall.

Using a bridged adapter

If you are accessing LAN IP addresses from the guest (an IP camera for example) you need to use a bridged adapter. When, additionally, there are ports on the guest that you do not want available to the LAN, add both a NAT adapter and a bridged adapter and firewall incoming connections to the bridged adapter.


Linux guest

If your guest is Linux and you have ufw, you can use the following (where, in my case, eth0 is the NIC for the VBox NAT) to firewall within the guest and allow VBox host access via NAT to port 2241:

~$ sudo ufw status
Status: inactive
~$ sudo ufw enable
Firewall is active and enabled on system startup
~$ sudo ufw default deny
Default incoming policy changed to 'deny' (be sure to update your rules accordingly)
~$ sudo ufw allow in on eth0 to any port 2241
~$ sudo ufw status verbose
Status: active
Logging: on (low) Default: deny (incoming), allow (outgoing)
New profiles: skip

To Action From
-- ------ ----
2241 on eth0 ALLOW IN Anywhere
2241 on eth0 ALLOW IN Anywhere (v6)

Windows Guest

The Windows firewall does not have a (simple) feature to restrict an explicit rule to a specific adaptor. The Windows firewall allows you to turn off the firewall on a specific NIC, so you could allow any port in from the VBox NAT. Alternatively, you can create a new rule allowing a port (say port 2241), then restrict the rule's scope to the Vbox NAT's IP range by assuming the NAT will always have the same subnet. For example, if the NAT NIC shows 10.0.2.XY with ipconfig, your rule's scope would be "custom list:" Specifying the allowed IP range in this way has a pitfall; the VBox NAT adaptor needs to assign the address range of consistently. You can force feed the VBox NAT range for a machine with VBoxManage modifyvm "VM name" --natnet1 "XXX.YYY/16". So far, we haven't bothered and we are happy.

Getting to your guest with ssh

Just what is this port we are opening in the above networking example? It could be any service (e.g. web server). In our organizations and our homes, we don't like to expose service ports to the greater world. The only port we expose is a secure shell port. We access all services on the guest (network host) through SSH and SSH tunnels.

The procedure for installing an SSH server is presented in Easy, secure remote connections When you follow the SSH tutorial, interpret the word host as network host. Also, be aware that our VBox system schematic has an additional, intermediate VBox host between the network and the guest:

image of system

Secondly, the SSH tutorial uses Port 3000 as an example SSH port that is exposed on the network host. Here instead, being consistent with the NAT forwarding example, we use Port 2241 as the SSH Port on the guest, but... our guest's firewall prevents direct connections to it. To widen the scope of the guest's SSH connectivity to the greater network we configure the router to forward port 2240 to the VBox host as port 2241. Also, we must open Port 2240 on the the vbox host's firewall.

Finally, when we connect to the SSH server from anywhere other than the guest itself, we reach it by addressing the vbox host at port 2240... the vbox host will automatically re-forward the request to the guest at port 2241 – provided NAT with port forwarding is properly configured.

Using tunnels

The real power of SSH is it enables us to use services on the network host that are firewall-protected from the network/Internet. Services like VNC remote desktops, ftp servers, etc. are not secure. Passwords can be sniffed or cracked. Traffic isn't necessarily encrypted. But tunneling these services through SSH provides an encrypted channel for the use of the services. Better still, when you use key-authenticated SSH to tunnel the services, you only pass your clear text password to the localhost.

Another important use of an SSH tunnel is using a tunneled port as a web browser proxy. Say you are on a potentially hostile network but your SSH server is not. Browser traffic is pretty transparent to eavesdroppers. Even SSL (https) traffic can be interpreted by bad guys if they can subvert your browser's certificate policies. If you have an SSH connection to a host on a safer network then, using a dynamic tunnel, you can browse the web and the local bad guy will only see a stream of nonsensical tcp packets. Another advantage for some is, you can browse the web as though you are located at the host's address. You reveal reverse DNS information to the sites you visit. If you are on the moon and some earth websites block (or discriminate against) moon people, then looking like you are from earth is advantageous.

See Using SSH tunnels to learn how to use these tunnels.

Autostart script

Once your guest is completely setup and its configuration has been adequately tested, you want to preserve it as a template. First, clean-up your temporary files, browser history, etc. Close the machine and remove all snapshots. From your file manager, make the virtual disk (vdi) ready-only. Next, we create a start-up script that deletes yesterday's clone (if one exists) and creates a new one. Here is a bash script (where “MasterLynx” is my template's Vbox name and “LynxClone” is my daily copy's name):

VBoxManage unregistervm /home/VBoxVMs/LynxClone/LynxClone.vbox -delete
vboxmanage clonevm /home/VBoxVMs/MasterLynx/MasterLynx.vbox --name LynxClone --basefolder /home/VBoxVMs --register
vboxmanage startvm /home/VBoxVMs/LynxClone/LynxClone.vbox
exit 0

Be sure to make it executable. You can translate this to a batch file if your host is Windows. You will probably want it to run when the computer is turned on. With Ubuntu 10.04 this is done by making a new start-up task at System → Preferences → Start-up Applications. In this case, the command is “ sh yourScriptFile.”

Starting up in the morning will be slow. I won't recommend it, but our current solution is to set the BIOS to start the computer at power restore then put the computer on a timer that cuts the power during off hours and turns back on before people come in for the day. It's a host-stressful procedure but the power fails around here every day or so anyway.


Updating your host can be done in person or by ssh. Updating your guest is easiest if you are at the machine. If you want to do guest updates (e.g. Windows updates) remotely, you will need to setup ssh for the host using the same procedure described above. Update the clone and make it your new master template. Don't forget to write protect the vdi.

Appendix A, installing Cygwin in Windows

From a Linux machine, download setup.exe and setup.exe.sig, then Checking Download Signatures
Move the setup.exe file to your Windows guest — logged in with an administrative user— and double click it. You will be presented with a choice mirror sites to download from. Pick one that is near you and, preferably one you recognize and trust.

During setup, you will be given a dialog window for choosing additional programs. Add openssh (net), rsync (net), and nano (editor). Type the names in the window search box to find them.

After the installation is done, navigate to C:/Cygwin and double click the Cygwin.bat file.

Next find the Cygwin desktop icon (or start menu item) and Run As Administrator. In the terminal that opens, run ssh-host-config. There will be a series of mostly yes or no questions that may vary depending on the Windows version and previous installation history. In general, the answers are "yes." One line will prompt; "Enter the value of CYGWIN for the daemon: []." I respond with: "ntsec tty." I used my Windows password when asked to enter one. Here is the output from a Windows 7 install:

$ ssh-host-config
*** Query: Overwrite existing /etc/ssh_config file? (yes/no) yes
*** Info: Creating default /etc/ssh_config file
*** Query: Overwrite existing /etc/sshd_config file? (yes/no) yes
*** Info: Creating default /etc/sshd_config file
*** Info: Privilege separation is set to yes by default since OpenSSH 3.3.
*** Info: However, this requires a non-privileged account called 'sshd'.
*** Info: For more info on privilege separation read /usr/share/doc/openssh/README.privsep.
*** Query: Should privilege separation be used? (yes/no) yes
*** Info: Note that creating a new user requires that the current account have
*** Info: Administrator privileges. Should this script attempt to create a
*** Query: new local account 'sshd'? (yes/no) yes
*** Info: Updating /etc/sshd_config file

*** Query: Do you want to install sshd as a service?
*** Query: (Say "no" if it is already installed as a service) (yes/no) yes
*** Query: Enter the value of CYGWIN for the daemon: [] ntsec tty
*** Info: On Windows Server 2003, Windows Vista, and above, the
*** Info: SYSTEM account cannot setuid to other users -- a capability
*** Info: sshd requires. You need to have or to create a privileged
*** Info: account. This script will help you do so.

*** Info: You appear to be running Windows XP 64bit, Windows 2003 Server,
*** Info: or later. On these systems, it's not possible to use the LocalSystem
*** Info: account for services that can change the user id without an
*** Info: explicit password (such as passwordless logins [e.g. public key
*** Info: authentication] via sshd).

*** Info: If you want to enable that functionality, it's required to create
*** Info: a new account with special privileges (unless a similar account
*** Info: already exists). This account is then used to run these special
*** Info: servers.

*** Info: Note that creating a new user requires that the current account
*** Info: have Administrator privileges itself.

*** Info: No privileged account could be found.

*** Info: This script plans to use 'cyg_server'.
*** Info: 'cyg_server' will only be used by registered services.
*** Query: Do you want to use a different name? (yes/no) no
*** Query: Create new privileged user account 'cyg_server'? (yes/no) yes
*** Info: Please enter a password for new user cyg_server. Please be sure
*** Info: that this password matches the password rules given on your system.
*** Info: Entering no password will exit the configuration.
*** Query: Please enter the password:
*** Query: Reenter:

*** Info: User 'cyg_server' has been created with password '************'.
*** Info: If you change the password, please remember also to change the
*** Info: password for the installed services which use (or will soon use)
*** Info: the 'cyg_server' account.

When changing your computer password, change the Cygwin service logon password too (My computer → Manage → Services → CYGWIN SSH Properties → margin-left: 2em; logon).

ID may be exposed