dev-guides

SSHing into your VirtualBox Instance

Out of the box, local virtual machines make great, isolated testing platforms for software systems, but working just through the serial console emulator window can make development pretty cumbersome. The GUI can be clunky, sluggish, and unfamiliar, and can seem pretty excessive if all we really need out of our virtual machine is a terminal window.

This guide will walk you through how to set up your VirtualBox Linux VM as a local server that you can login to using ssh (Secure SHell).

You may alternatively set up a host-only network, on which your VM is a device with its own IP address; see the host-only network guide for instructions on how to set this up. Using a host-only network can be a little nifty because your IP address may change, but is useful for networking multiple VMs together for tasks like load-testing web servers on one VM from another.

Note that this guide will also refer to your virtual machine (VM) as a guest machine, and your computer (running VirtualBox) as its host machine.

Setup OpenSSH

Arch

Before you can SSH into your guest machine, you must run sshd (SSH daemon) in your VM to listen for incoming login requests. You’ll need to perform these steps as the root user, so either su to root, or use sudo.

First, let’s install the OpenSSH package, which contains sshd. On ArchLinux, we can use pacman:

[guest]# pacman -S openssh

Now we need to enable sshd as a service (a long-running background process). On ArchLinux, we manage services using systemctl. We set it to launch on boot:

[guest]# systemctl enable sshd.socket

We can also start the service in our current instance without needing to reboot:

[guest]# systemctl start sshd.socket

If you’d like, you may configure sshd by editing /etc/ssh/sshd_config, though the default settings are sufficient for the purposes of this class. Note that by default, sshd listens for incoming login requests on port 22. You may consult the sshd_config man pages if you’d like to learn more:

[guest]$ man sshd_config

Debian

You need to first update the apt package repository cache by running the following command:

# apt update

Note: On Debian, SSH server comes as ‘openssh-server’ package. In order to install OpenSSH:

# apt install openssh-server

Press ‘y’ and then press to continue.

The default behavior of OpenSSH server in Debian is that it will start automatically as soon as it is installed. To check whether OpenSSH server is running:

# systemctl status ssh

In case OpenSSH server is not running, you can run the following command to start OpenSSH server:

# systemctl start ssh

Setup VirtualBox Port Forwarding

Open your VirtualBox Manager. Select your VM, open the “Settings” menu, and go to the “Network” tab. You should see that for at least one of your adapters, “Enable Network Adapter” is checked, and the “Attached to:” field is set to “NAT”.

Open up the “Advanced” section, and select “Port Forwarding”.

You should see a dialogue window appear with a table of port forwarding rules. Add a new rule using the button with a “+” sign on the right, and fill in the following:

VirtualBox VM Manager Port Forwarding

This will forward all TCP connections to port 4118 on your host machine to port 22 on your guest machine.

Hit “OK” to save your port forwarding rule, and then hit “OK” on your Settings window to save your settings.

SSH Into Your Local VM

Now you should be able to ssh into your local VM! If you’re working in a terminal on your host machine, you may login to your guest machine using:

[host]$ ssh -p <host-port> <username>@localhost

For example, if we set up our VM with username debbie, forwarding requests from port 4118, we would use:

[host]$ ssh -p 4118 debbie@localhost

You may need to type in your password here in order to authenticate yourself. Now we don’t have to wait for your VM’s GUI to render, and interact with it via a text-only command line terminal interface.

SSH Configuration

Logging into your VM with that long command may seem a bit cumbersome, but there’s a few things we can do with SSH for our convenience.

First, let’s create our config file if we haven’t already:

[host]$ mkdir -p ~/.ssh
[host]$ touch ~/.ssh/config

Open ~/.ssh/config with your favorite text editor, and add the following:

Host osvm
    Hostname localhost
    User debbie
    Port 4118
    ForwardAgent yes    # optional
    AddKeysToAgent yes  # optional

Make sure to update the appropriate fields if you have a username other than debbie, or chose a port other than 4118. Optionally, if you prefer some alias other than osvm, feel free to pick something else for the Host field at the very top. Note that ForwardAgent yes and AddKeysToAgent yes are optional, though they will come in handy in the following section.

Now you can login with just (assuming you chose osvm as your alias):

[host]$ ssh osvm

Setting Up SSH Keys

You’ll want to set up your SSH keys so that you can authenticate securely without having to type in your password.

First, if you haven’t already, generate an RSA key pair on your host machine and add it to your ssh-agent following this excellent guide by GitHub. And while you’re at it, add your key to your GitHub account. This will help you authenticate with GitHub, so that you don’t have to type in your password for repos that you clone with SSH.

Now that you have your key, you can set up your VM to authenticate the same way. Assuming that you had configured SSH to use osvm as your alias, and that you named your RSA key pair id_rsa (the default), run the following command:

[host]$ ssh-copy-id osvm

This copies the public RSA key on your host machine to the ~/.ssh/authorized_keys file on your guest machine, which sshd will use to authenticate the SSH client on your host machine. For more details, see this Digital Ocean guide.

Note that in the previous section on SSH Configuration, we set up the ForwardAgent yes and AddKeysToAgent yes options. This should forward your host’s SSH credentials to your VM when you login, so that you can authenticate with GitHub there too without copying in your keys. Alternatively, you may simply generate a new SSH key on your guest machine, which you can add to your GitHub separately.

You can test your GitHub connection with the following command:

[guest]$ ssh -T git@github.com

If you see a greeting with your username, you’re all set! Happy coding!

Windows Guide for a Better Terminal

Windows has been notorious for having a poor terminal. Neither the CMD nor PowerShell are very good. In OS, however, you should have a good terminal on your host to enable you to SSH into your VM. Fortunately, Windows now has Windows Subsystem for Linux (WSL) to help with that.

This guide will walk you through how to set up your WSL to give you a better terminal. I will also go through some important changes to give you the best experience.

Setup WSL

We first need to enable WSL. To do that, search for Turn Windows features on or off This should bring up a dialog box. Scroll to the end and tick the checkbox for Windows Subsystem for Linux and restart your computer.

Install a Distributuion

Now that you have enabled WSL, visit the Microsoft Store and search for linux and download one of the available distros. While you’re at it, I recommend you download the Windows Terminal (Preview) (WTP for short) app (you will need to have Windows 10 version 18362.0 or higher).

To complete the installation of your distro, launch a new instance of it. The first time, it will take a few minutes to complete, and then it will ask to enter a username and password.

Setting Up Windows Terminal (Preview)

At this point, you’ll want to set up your WTP to work for you. Here are some of the important and good settings to change.

To modify the default settings, you will edit profile.json. To open the file press Ctrl + , in WTP. This will launch the default text editor you have set for JSON files. Here is what yours should look like when you first open profile.json.

// To view the default settings, hold "alt" while clicking on the "Settings" button.
// For documentation on these settings, see: https://aka.ms/terminal-documentation

{
    "$schema": "https://aka.ms/terminal-profiles-schema",

    "defaultProfile": "{abc}",

    "profiles":
    [
        {
            // Make changes here to the powershell.exe profile
            "guid": "{abc}",
            "name": "Windows PowerShell",
            "commandline": "powershell.exe",
            "hidden": false
        },
        {
            // Make changes here to the cmd.exe profile
            "guid": "{def}",
            "name": "cmd",
            "commandline": "cmd.exe",
            "hidden": false
        },
        {
            "guid": "{ijk}",
            "hidden": false,
            "name": "Ubuntu",
            "source": "Windows.Terminal.Wsl"
        },
        {
            "guid": "{xyz}",
            "hidden": false,
            "name": "Azure Cloud Shell",
            "source": "Windows.Terminal.Azure"
        }
    ],

    // Add custom color schemes to this array
    "schemes": [],

    // Add any keybinding overrides to this array.
    // To unbind a default keybinding, set the command to "unbound"
    "keybindings": []
}

First, you will want to set the defaultProfile property to the GUID of the distro you are running. This will ensure WTP opens with linux.

Next, in the profiles section you may want to add some custom properties in your linux distro object. For starters, by default WTP will open in your Windows User Directory. To force WTP to open in your linux user directory, append the following line to the JSON object corresponding to your distro.

"startingDirectory": "\\\\wsl$\\\\home\\",

Of course, replace and with the correct values for your machine.

You may also want to give your terminal some padding. The code that does that is simply called:

"padding" : "5, 0, 0, 10",

The order the padding will be applied is from left, top, right, bottom. In this case, I gave my terminal 5 units padding from the left and 10 from the bottom.

If you plan to use a custom .bashrc file that uses the Powerline font, you should change your default fontFace to one of Powerline Fonts like this.

"fontFace" : "DejaVu Sans Mono for Powerline",

NOTE: make sure you don’t have a comma for the last item in your JSON object.

Useful Keyboard Shortcuts

WTP has the ability to split screen horizontally and/or vertically. To activate a vertical split use the keyboard shortcut shift + alt + + and shift + alt + - for a horizontal split.

You can also locate files in your Windows drives with cd /mnt/c/Users/{user}/ for instance, I added

alias win='/mnt/c/Users/Dave/'
alias cwin='cd /mnt/c/Users/Dave/Documents'

to my .bashrc so that I can copy files and change to work in Windows.

Using Visual Studio Code (Optional)

If you’re a fan of Visual Studio Code (VS Code), you can work on your VM directly from a VS Code window on your host machine, allowing you to take advantage of all of VSCode’s features (such as quickly opening any file without navigating directories using Ctrl + P, which becomes really useful when dealing with Linux kernel source code) in a local-quality development experience.

Note: Keybindings differ in macOS. If running macOS, replace Ctrl with Cmd.

After setting up a running SSH server as above, all you have to do is install the VS Code SSH Extension. From now on, you can SSH into your VM by simply opening your Command Palette (Ctrl + Shift + P) and looking for Remote-SSH: Connect to Host.

Useful VS Code Features:

  1. After opening a remote folder, use Ctrl + P to quickly open any file in your workspace.

  2. Use Ctrl + J to open a terminal to run commands on your VM.

  3. The Welcome Tab whenever you open a new VS Code window has a “Recent” section that allows you to quickly open the file you were working on in previous sessions. This becomes extremely useful when you have to restart your VM after installing your kernel.

See the documentation for more features and tricks.