Using External Editor With VirtualBox

Want to edit files on Ubuntu running on your Mac through VirtualBox?

I fiddled so much getting this right, that I felt I short write this down with all the mistakes I made.

VirtualBox is software which allows you to run another operating system in a virtual environment. E.g. I am on a Mac and need to test software on Linux.

What you do in this dialog is to add a virtual machine. I am calling this machine foobar to be able to easily find it later. Use a more sensible name.

Here is the first possible confusion: Selecting Ubuntu (64-bit) does not actually install Ubuntu. Rather it creates a virtual machine capable of running Ubuntu. You still need to actually download a particular Ubuntu version to install.

You can download an Ubuntu iso image from the official download page. It will have names like ubuntu-20.04.2.0-desktop-amd64.iso. Normally this is burned straight to a DVD. However you just startup your VM machine by selecting it in the left list and hitting the green run button.

When starting up it will ask you to select the iso image containing the operating system you want to install on this virtual machine.

Next, you will go through the Ubuntu installer just like on any other physical machine.

Enable SSH into VirtualBox Operating System

To be able to use an editor on e.g. your Mac, which edits files on Ubuntu running inside VirtualBox, you need to enable SSH into the virtual computers.

Let us get terminology in place. In this case macOS is the host operating system, and Ubuntu is the guest operating system.

To be able to SSH into your Ubuntu box, it needs to actually have an SSH server running which accepts SSH connections. This may already be in place. But in case it isn’t, you need to install the SSH server software:

$ sudo apt-get install openssh-server

Enable the service with:

$ sudo systemctl enable --now ssh

Check the status:

$ sudo systemctl status ssh

Out of the box you can SSH from the guest OS (Ubuntu) into the host OS (macOS), by SSHing to 10.0.2.2 like this:

$ ssh erik@10.0.2.2

Here erik should be replaced with a username on your host OS. Although for this to work on macOS, you need to enable remote login on your Mac, in the sharing preferences:

Anyway, this is not the important or tricky part. What is more tricky is enabling SSH from the host (macOS) to the guest (Ubuntu). To do this, right click on your virtual machine in VirtualBox and select settings....

If you do this while your Ubuntu is running however you will be frustrated to find that you are unable to click on the Adapter 2 tab. There is the important part:

Make sure you shut down your virtual machine before changing settings. On a real physical machine you cannot add and remove network cards while it is running. You cannot do that on a virtual one either. Now you can configure the second Network adapter to allow host connections:

Except most likely you will not be able to do this out-of-the-box. That is because vboxnet0 most certainly will not exist. You need to add it by selecting the menu File → Host Network Manager.... That will give you the following dialog where you can add the vboxnet adapter.

Now you can configure your Adapter 2 properly.

To be be able to open files on the guest OS (Ubuntu) on your host (macOS), you need to install the rmate tool on the guest OS. This makes sure edits to files in the VirtualBox environment gets channeled to an editor running on your Mac or Windows machine.

$ sudo apt-get install ruby $ sudo gem install rmate

Here is the part I really screwed up. You got to configure the SSH connection, so that opening a file on the guest OS causes that file to be opened on the host (macOS). That means editing the ~/.ssh/config file on your host OS, not on the guest OS (Ubuntu). That was my initial screwup. So do this on the host (macOS):

$ cd
$ mkdir -p .ssh
$ touch .ssh/config
$ vim .ssh/config # or whatever favorite editor you use

Now you add the following to your config file. The stuff in brackets has to be supplied by you.

Host <guest hostname>
HostName <guest IP address>
User <username on guest>
RemoteForward <port> localhost:<port>

Here is an example of what my ~/.ssh/config looks like:

Host vbox
HostName 192.168.56.101
User erik
RemoteForward 52698 localhost:52698

The vbox hostname is just something I choose myself. It allows me to SSH into my VirtualHost machine by writing:

$ ssh vbox

What about the IP address 192.168.56.101? This is IP address of the network card connecting the guest to the host. To obtain this, you need to run e.g. ifconfig on your guest OS (Ubuntu), like this:

$ ifconfig
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255
inet6 fe80::ef23:b485:fa1e:3569 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:b3:d8:2d txqueuelen 1000 (Ethernet)
RX packets 9560 bytes 12670148 (12.6 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3367 bytes 291449 (291.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.56.101 netmask 255.255.255.0 broadcast 192.168.56.255
inet6 fe80::bf5:450f:22ef:ac07 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:55:ec:c7 txqueuelen 1000 (Ethernet)
RX packets 1978 bytes 397695 (397.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 665 bytes 92488 (92.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 505 bytes 45431 (45.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 505 bytes 45431 (45.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

You got to look at the network interface named enp0s8, In this example you will see the following line:

inet 192.168.56.101  netmask 255.255.255.0

This is what informs me that the IP address I should use is 192.168.56.101. You will likely get a different number.

I use port number 52698, but where does that come from. It is actually a default for rmate. If you run the TextMate editor, you can actually see this port number in the preferences panel:

Now you may not use TextMate, but since TextMate inspired a lot of modern text editors such as Sublime, VSCode and many others, you will find that they use some of the same conventions and defaults.

Geek dad, living in Oslo, Norway with passion for UX, Julia programming, science, teaching, reading and writing.