Setting up a Linux environment on Windows using VirtualBox and PuTTY
As a Windows user who frequently develops on Linux I often find it convenient to have a local Linux environment to do work in. Projects like Foreign Linux, MinGW and Windows Subsystem for Linux get a close approximation but nothing beats having a real virtual Linux machine on your computer. In this post I will show you how to set up a Linux VM that you can connect to using PuTTY.
The end result will be the ability to open a linux shell in seconds. No need to worry about “Syscall not implemented” errors or tools that aren’t compatible on Windows. With modern linux optimizations on virutal machines performance is almost as good as native and very low idle overhead (see performance at the end).
Who is this for?
Anyone who can copy commands into linux. Whether your an absolute beginner or just don’t want to scour the internet for the right steps, this tutorial is set up to let you just copy commands into linux.
Setting up the machine
Create a machine in Virtualbox using the guided setup. You should give the VM at least 256MB memory, but preferably at least 2GB. Keep in mind Virtualbox will not allocate memory Linux isn’t using. Your hard drive should be at least 3GB, but the default of 8GB is preferable. Again, keep in mind a Dynamically Sized VDI will not use space on your real hard drive until it is touched by Linux. Make sure the OS is set to Linux and Arch Linux 64-bit.
When you first boot, Virtualbox should prompt you to select an installation medium. Select the Arch ISO you downloaded earlier. Otherwise, open the machine settings and attach the ISO to the empty optical drive under the IDE controller in storage. If the text on the VM is too small scale up the display under the video tab.
Once arch is booted select the installation option.
The Arch Linux install
Arch Linux will be the OS of choice given it’s lightweight and customizable. We don’t want to be weighed down by a graphical interface, for example. If your having trouble with the installation, consult the official installation guide.
Arch Linux gets a bad rap for not being beginner-friendly, but once installed its as simple as any other distribution. Furthermore, Arch is known for its huge number of resources, like Arch Wiki and helpful community. In other words, if your just a beginner, don’t fret.
Check your internet and setup package sources
The installation ISO does not contain everything needed to install arch on the disk, so an internet connection is needed to download packages.
# ping google.com
If you don’t have internet check your machine settings under the network tab and make sure your host internet works. Don’t continue until you have internet.
Package sources are available in the
/etc/pacman.d/mirrorlist file. When
downloading, pacman will go through this file in order until it finds a mirror
that works, so move sources closer to your location to the top.
# vim /etc/pacman.d/mirrorlist
In my case, this means moving the first few sources labelled United States towards to the top. This file will be copied to your system to be used after the installation.
# timedatectl set-ntp true
Accurate time is necessary for encrypted network connections. The time may already be accurate without this.
Partition and format disk
First, find the name of the hard drive your trying to format.
# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 3G 0 disk sr0 11:0 0 756M 0 rom /run/archiso/bootmnt loop0 7:0 0 328M 1 loop /run/archiso/sfs/airootfs
The virtual drive will be the one that hasn’t already been mounted and matches
the size of the one we created earlier. In this case
The simplest way to format the disk will be a single partition booted using BIOS. This can be done using parted.
# parted /dev/sda GNU Parted 3.2 Using /dev/sda Welcome to GNU Parted! Type 'help' to view a list of commands.
First, format the drive as msdos. Then create the partition and make it bootable.
(parted) mklabel msdos (parted) mkpart primary ext4 1MiB 100% (parted) set 1 boot on (parted) quit
After exiting parted, check that the partition has been created.
# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 3G 0 disk -sda1 8:1 0 3G 0 part ...
We will format the new partition,
/dev/sda1, as ext4.
# mkfs.ext4 /dev/sda1
And mount the filesystem.
# mount /dev/sda1 /mnt
pacstrap command has the job of installing arch to the drive. In
this case, I install
base-devel because I plan to use this for development.
This includes tools like
gcc. I will assume you have these
installed for the rest of the tutorial, but they are also trivial to install
only when needed. The
base package is required. I also install
vim at this
nano is included in
# pacstrap /mnt base base-devel vim
Set your fstab file to automatically mount the drive.
# genfstab -U /mnt >> /mnt/etc/fstab
Now we’re ready to start doing work on our drive. Chroot into the system.
# arch-chroot /mnt
Install the grub bootloader.
# pacman -S grub # grub-install /dev/sda # grub-mkconfig -o /boot/grub/grub.cfg
By default grub will pause for 5 seconds before booting. This can be changed by
GRUB_TIMEOUT variable in
/etc/default/grub then running
I’m going to breeze through most of this since the Arch Wiki does a good job explaining it. Essentially, we need to setup the timezone, locals, hostname and the root user.
# ln -s /usr/share/zoneinfo/America/New_York /etc/localtime # hwclock --systohc --utc # echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen # locale-gen # echo "LANG=en_US.UTF-8" >> /etc/locale.conf # echo linux-dev > /etc/hostname
Obviously if you live in a different time zone or need a different locale find the one you need and use that instead.
Change the root password.
Exit chroot and shutdown.
# exit # exit chroot # shutdown -h now
In the VM settings under Storage, remove the installation ISO from the disk drive. When you restart you should be able to boot into the drive we installed Arch to.
Setup arch to work with PuTTY
After testing that the VM is able to boot and login, shut down again.
Our VM needs two connections: one to the internet, and the other to our host. Open the Network tab of the settings and enable the second adapter.
The first adapter should be “NAT” and will be set up automatically. This gives the VM access to the internet, but doesn’t give any way for our host to reach it. This is solved by the second adapter which should be set to “Host-only Adapter”. The Virtualbox Host-Only Adapter should appear in Windows task manager under Performance.
Boot and login to your VM.
Enable and start dhcpcd. This will automatically configure the network.
# systemctl enable dhcpcd # systemctl start dhcpcd
ip addr repeatedly until your assigned an IP.
# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 ... link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 UP ... link/ether 08:00:27:7f:dc:35 brd ff:ff:ff:ff:ff:ff inet 192.168.56.102/24 brd 192.168.56.255 scope global enp0s3 valid_lft forever preferred_lft forever inet6 fe80::63aa:9ffe:d962:cd46/64 scope link valid_lft forever preferred_lft forever 3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 UP ... link/ether 08:00:27:50:e3:04 brd ff:ff:ff:ff:ff:ff inet 10.0.3.15/24 brd 10.0.3.255 scope global enp0s8 valid_lft forever preferred_lft forever inet6 fe80::aca5:92ee:42f8:95cf/64 scope link valid_lft forever preferred_lft forever
In Virtualbox, look under File->Preferences->Nat Network to find the subnet of
the selected NAT and match it to the correct IP. The other network (ignore
the loopback adaptor) is the host-only adaptor. In this case,
you are not assigned an IP for the NAT make sure “Supports DHCP” is checked.
To setup PuTTY correctly, it’s important the host-only adaptor always uses the same IPv4 address. This can be configured in dhcpcd.
# echo "interface enp0s3" >> /etc/dhcpcd.conf # echo "static ip_address=192.168.56.101" >> /etc/dhcpcd.conf
After, you must restart dhcpcd.
# systemctl restart dhcpcd
Install virtualbox guest additions
This isn’t strictly necessary but will give better performance and make shared folders easier.
# pacman -S virtualbox-guest-utils-nox
virtualbox-guest-modules-arch when prompted. If you choose the dkms
option make sure you also install the proper kernel headers.
Load the vbox modules.
# modprobe -a vboxguest vboxsf vboxvideo
After a reboot you should be able to use paravirtual features such as the paravirtual network driver, which may improve performance. You may need to reconfigure the network.
Create a new user
It’s considered bad practice on Linux to do work as the root user. This new
user will be the one you should work from. If root is required, you can
su. Note the vboxsf group is necessary for shared folders.
# useradd -m -G vboxsf -s /bin/bash eric # passwd eric
Add the user to the
/etc/sudoers file, so we no longer need to login as
In this case I would add the following line under the User Specifications section, although it could technically go anywhere in the file.
eric ALL=(ALL) ALL
Logging in with PuTTY
Install, enable and start
# pacman -S openssh # systemctl enable sshd.socket # systemctl start sshd.socket
You should now be able to login and continue working from PuTTY. After you login with IP from earlier, check that sudo works.
$ sudo echo success
Entering your username and password every time is inconvenient, so we will setup public key login.
On Windows, run the PuTTY Key Generator and generate a new SSH-2 RSA key. Save this key somewhere on your computer, such as in the directory your VM is stored in.
In PuTTY, copy the text area with the public key starting with ssh-rsa. Open
~/.ssh/authorized_keys in nano and paste (right click) the key in. You may
have to create this file. Remove any newlines within your key.
$ mkdir ~/.ssh $ nano ~/.ssh/authorized_keys
Since you are just creating the authorized_keys file set the permissions to readonly for other users.
$ chmod 700 ~/.ssh $ chmod 600 ~/.ssh/authorized_keys
In order to use public key authentication we need to enable it in openssh.
/etc/ssh/sshd_config and uncomment/add the following two lines.
RSAAuthentication yes PubkeyAuthentication yes
Restart the OpenSSH service.
$ sudo systemctl restart sshd.socket
On PuTTY, when connecting to the VM, select the private key file you saved earlier under Connection->SSH->Auth. You can use Saved Sessions to connect automatically to the right server.
I wrote this article in a PuTTY terminal attached to a local VM, with another VM open to test and take screenshots, on a Microsoft Surface with an i5-6300U and experienced few performance issues. In fact, Spotify and Chrome individually use more CPU and RAM than Virtualbox. Doing more intensive tasks like compiling gives comparable, though longer, results to doing them on Windows.
A fresh install of Arch takes about 1.5GB, but will grow as you add tools.
tmux, ZSH and themes
As functional as PuTTY+Linux is, the current setup is a bit drab. This short section will outline how to enable tmux with full mouse support, along with zsh and the agnoster theme. I purposely chose this theme because it looks cool and requires a special font that isn’t obvious how to setup.
Both tmux and zsh can be installed using pacman.
# pacman -S tmux zsh
Enabling tmux mouse support requires one line in
$ echo "set -g mouse" > ~/.tmux.conf
Test it out by running
tmux, opening 2 panes using
ctrl-b % and dragging
the dividing line up and down using your mouse. Additionally you can drag
to select text in tmux and copy/paste using tmux’s built-in keyboard (to select
text, copy or paste to/from the Windows keyboard use shift-right/left-click).
The agnoster theme requires oh-my-zsh to be installed.
$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
Following the setup, set your
the theme is fully functional, PuTTY must first be setup with the correct fonts.
DejaVu Sans Mono for Powerline.ttf from the Powerline font
repository. Open and click “Install”
at the top of the Windows Font Viewer. Select this font in PuTTY under
Window->Appearance->Font Settings. Update your settings under Saved
My personal setup includes zsh and tmux with full mouse support and shared
folders to allow easy data transfer. I wrote this in neovim with jekyll
automatically building my changed using
jekyll serve --host=0.0.0.0.
The more customized your setup is, the more fun it is to use.