Setting Up VirtualBox On Windows

I recently purchased a Microsoft Surface Pro 6. It's a nice little device that I will use to replace my dead Nexus 9 tablet and my mostly-dead Asus linux laptop. Having a Microsoft Store near us is nice as I can get immediate assistance for problems.

I have very little experience using Windows as I have either used Android tablets or linux laptops for a very long time. I knew I wanted some sort of real linux available on the Surface, it was just a matter of how.

Before I go further I would add that you can build quite a nice environment on top of Windows alone if you like. I installed Chocolaty and use it to manage most of the utilities I install instead of individual downloads. I was able to get Perl5 and Rakudo installed, as well as emacs and Go. Still, I am most comfortable in linux (Debian in particular), so I wanted the real deal.

I thought I might be able to just make due with Docker, but Windows 10 Home has a weird and disappointing limitation about how services like the Docker daemon are run. There was a hacky setup to run the daemon but that felt weird. I also installed WSL, but this still feels like a slightly gimped experience since it doesn't run on top of a linux kernel.

I knew VirtualBox existed but since I have very little experience using Windows, by extension I knew little of VirtualBox. I was at least aware that running VirtualBox would finally help me achieve my original goal - booting and running linux.

Running VirtualBox "as is" to get going is just fine. The point of this post is to explain how I got around a frustrating issue - ssh'ing into the VirtualBox host from a local shell like WSL. I'm not entirely sure why this has been such a challenge, but since it seemed to be needlessly frustrating, I thought I would document my process here. Hopefully I haven't overlooked any details - I am assuming that all you need are just high-level pointers. I am also assuming you already have ssh installed in Windows via WSL etc.

Open the VirtualBox console for the VM you have installed. Get the IP address using "ip addr" or however you like. Now turn off the VM and open the Settings menu for it. Under "Network" you will find an "Advanced" link. Click on the "Port Forwarding" button. Create a new new rule with Protocol as TCP, the Host IP as 127.0.1.1, the Host Port as 2222, the Guest IP will be the IP of the VM you noted earlier, and the Guest Port should be 22 (or whatever port you like to run sshd on in your VM). Of course you should be sure that sshd will be running on the VM.

Now on the VM you need to do some iptables magic to let Windows ssh to your VM. Install iptables-persistent. After that, add rules like:

iptables -A INPUT -p tcp -m tcp --dport 22 -m conntrack
      --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 22 -m conntrack
    --ctstate ESTABLISHED -j ACCEPT

Save these:

      iptables-save > /etc/iptables.up.rules
    

We want this done every time the VM starts. There are a lot of ways to do this but I prefer to create a systemd service that mimics what used to happen in /etc/rc.local. Create a script /etc/rc.local:

      #!/bin/sh -e
      /sbin/iptables-restore < /etc/iptables.up.rules
      exit 0                         
    

Make a systemd "rc.local" service /etc/systemd/system/rc-local.service:

      [Unit]
      Description=/etc/rc.local
      ConditionPathExists=/etc/rc.local
      StartLimitIntervalSec=0
      After=network.target

      [Service]
      Type=forking
      ExecStart=/etc/rc.local start
      User=root
      StandardOutput=tty

      [Install]
      WantedBy=multi-user.target
    

You can start that with "systemctl start rc-local", and enable it with "systemctl enable rc-local".

Now you can ssh directly to 127.0.1.1 port 2222, and the connection will be forwarded to the VM.

As one last step, you can add a line to c:\Windows\System32\Drivers\etc\hosts:

      127.0.1.1 myvm # or whatever you call your VM.
    

last update 2019-03-03