How To Create Infinite Windows Cloud Desktops for Your Nonprofit with BoXenLinux®

Running Windows allows you to easily access proprietary closed source vertical market software. Using  an Azure Nvidia Tesla virtual machine lets you run graphic intensive programs in the cloud. For instance 2D and 3D CAD Drafting, Video, and 3D educational tools. Even 3D games! O_O Coupled with BoXenLinux, and a decent Internet connection you can dramatically reduce hardware, software, maintenance, and energy costs. While still providing many clients Windows Desktop Experiences. To find out more about BoXenLinux visit the github project page here:

As you can see from the matrix below there are MANY ways of providing desktops to your users.

However, I think this way has many advantages for a Nonprofit. I would recommend it generally, although of course other topographies are more useful in specific situations.

Benefits for a Nonprofit

  • Green computing – Thin clients use less power than traditional workstations.
  • Reduced maintenance costs – Thin client deployment means you’re only maintaining a couple servers, instead of multiple traditional workstations. Using Azure cloud means you don’t have to maintain server hardware.
  • 100% free horizontal software – Completely free Open Source horizontal market software.
  • Discounted vertical market software – Purchase heavily discounted MS remote desktop licenses at Techsoup. Along with anything else you might need. e.g. Quickbooks, MS Office, and any other vertical market software.
  • $3500 Azure Credit, Free Office 360 – Free cloud servers, Office.
    Apply for Microsoft Nonprofit here:…
  • Free Voice,Gsuite,etc.. – Free cloud Telephony, calendaring, file management, and email with custom domain.
    Apply for Google Nonprofit here:…
  • Free hardware; Nevada County among others will donate their old computers, and peripherals to any eligible local nonprofit. Perfect for blazingly fast thin clients. Bring your tax exempt paperwork to the warehouse on the last Friday of the month. Or, try Purchasing hardware from your local government entity here:… After that try eBay:…
  • No taxes – If you use Comcast as your internet provider, make sure to file tax exemption paperwork with them to waive the applicable taxes. Email tax exempt certificate to: SMB_WestOfflineSupport@c… . Include service address & account #.
  • 50% off internet – If you are school, or other eligible nonprofit in California sign up here for 50% off your internet bill.…



Follow along. At the end of this guide you should be able to plug in any number of old computers without hard drives into your local network. Then have them boot blazingly fast Windows based modern software. Wireless, and remote VPN clients are also supported.

In this setup all thin clients will be sharing a single Windows 2016 Datacenter instance. However, you can provide any number of environments using this method, including huge VDI deployments. My favorite is using LTSP Ubuntu fat client desktops with RemoteApps for seamless cloud integration of necessary windows based proprietary software.

I am using Ubuntu 18.04 Bionic Beaver for the LTSP server, because LTSP does not currently work with Ubuntu 18.10 Cosmic Cuttlefish.* In my case the entire setup was virtualized in the Azure cloud using KVM Virtual Machine Manager for virtual thin clients.

It might look like this:

[Azure Standard D4s v3[[PXE thin client – KVM guest] –> [Ubuntu 18.04] LTSP Server]] –>[Azure Standard NV6 [Windows 2016]]

In real life the more likely scenario would be to install Ubuntu on a bare metal server onsite. Then, install Ubuntu 18.04 inside a KVM vm. Plug a thin client into your network, and configure it for PXE boot in BIOS. It would look a little like this:

[PXE thin client] –> [[Ubuntu 18.10] [Ubuntu 18.04 KVM guest LTSP server]] –> [Firewall] –> [Internet] –> [Azure Standard NV6 [Windows 2016]]

In this guide I will be first showing you how to set up the virtualized system, and then go into some changes you’ll need to make in the field.


  • An internet connection. 3MB/s or more recommended.
  • A computer with keyboard and display capable of running at least SSH. To issue the commands from.
  • A computer capable of running Ubuntu with at least one network card. Or a virtual machine capable of nested virtualization like the Azure Standard D4s v3. For the LTSP server.
  • A virtual or real windows machine locally or in the cloud. You’ll need Remote desktop licenses if you want to use microphone forwarding. If using Azure, not every region has the NVIDIA Tesla servers (NV6) for hardware graphics rendering. USA South Central is what I used. This is used for the desktop environment.


  • – Gateway.
  • – eth0 – Local interface on Ubuntu server – Connected to the Internet.
  • – virbr0 – Virtual bridge on Ubuntu server for testing virtual thin clients.
  • – Windows 2016 datacenter RDP server with NV6 Nvidia Tesla hardware.

Create your Azure Virtual Machines

After signing up and being accepted to Microsoft Nonprofit, verify your $3500 credit here: www.microsoftazuresponso…

Create your virtual machines here:
Note: DO NO USE accelerated networking on the Ubuntu Server.

Screenshot from 2018-11-14 18-49-20

LTSP Server

  • Image type: Ubuntu 18.04
  • Size: Azure Standard D4s v3

Desktop Server

  • Image type: Windows 2016 Datacenter
  • Size: Azure Standard NV6
Azure comes with a premade Ubuntu 18.04 image, but if you are doing this in the field you would need to install Ubuntu on your server:

Install Ubuntu 18.04.1 Desktop (Minimal)

If you decide to have a local Windows server instead or in addition to the Azure vm, you’ll need to install Windows locally.

Install Windows 2016 Datacenter

  • Download ISO from Microsoft Volume Licensing Center
  • Install

Configure Windows 2016 Datacenter

Configure remote desktop for microphone redirection:

  • Install Remote Desktop Session Host
  • You’re either still inside the grace period OR have the Remote Desktop Licensing role installed and a valid CAL
  • Make sure the remote desktop group policy allows audio recording

Configure graphics acceleration:…

Configure the Ubuntu and install LTSP Server

You can find a bash script automating all the below commands here:…

To manually install BoXenLinux we will be configuring LTPS using the Chrootless Proxy mode for in the field. It is the easiest of the 4 ways to install LTSP. However, for the Azure cloud we’ll need to install using a chroot.

Set a static IP for your wired network interface in the field

Microsoft azure VM comes with the static IP set on your default interface. However, in the field you’ll need to set a static IP address.…

Optional: Install OpenSSH server
If using the Azure install as the LTSP server, you’ll want to overwrite the existing sshd_config so that you can using password login if you used a key when creating the VM.

sudo apt install ssh

Install LTSP and epoptes (epoptes lets you remote desktop in and help anyone using a thin client), Instructions from…:

sudo add-apt-repository --yes #The Greek Schools repository
sudo apt install --yes --install-recommends ltsp-server-standalone ltsp-client epoptes

Configure dnsmasq

Note: You may want to edit the /etc/dnmasq.d/ ltsp-server-dnsmasq.conf and add “dhcp-option=3,” to set a different gateway, but probably not.

sudo ltsp-config dnsmasq --enable-dns
sudo service dnsmasq restart

Add yourself the epoptes group

sudo gpasswd -a ${SUDO_USER:-$USER} epoptes

Was told to remove these packages

sudo apt purge --yes --auto-remove mate-hud snapd
Optional: Chroot Install

Build a chroot client for alternate arch, dekstop enviroment or package base

Grab freerdp’s key 

cd /etc/ltsp 
sudo wget
  • Option 1 – with command
sudo ltsp-build-client --purge-chroot --mount-package-cache --mirror '' \
 --apt-keys '/etc/ltsp/ADD6BF6D97CE5D8D.asc, /etc/apt/trusted.gpg.d/ts_sch_gr_ubuntu_ppa.gpg' \
 --extra-mirror ' bionic main, freerdp-nightly main' \
 --late-packages epoptes-client freerdp-nightly --prompt-rootpass --fatclient\
  • OR, Option 2 – using my ltsp-build-client.conf
sudo wget
sudo ltsp-build-client --config ltsp-build-client.conf

You may want to install a new kernel like this one if the azure kernel doesn’t work with all of KVM’s input drivers:

sudo apt-get install linux-image-lowlatency

Then you have to edit the update-kernels.conf file, so that LTSP chooses that one to boot the client.

Create some symlinks so freerdp-nightly is more easy t my lazy scripting

sudo ltsp-chroot
ln -s /opt/freerdp-nightly/bin/xfreerdp /usr/bin/xfreerdp-nightly
ln -s /usr/share/ltsp/screen.d/xfreerdp /usr/share/ltsp/screen.d/xfreerdp-nightly

Create GUI login screen for xfreerdp-nightly (Not updated!)

cd /opt/ltsp/amd64/usr/share/ltsp/screen.d/

sudo wget

sudo wget

sudo chmod +x rdpgui xfreerdp-prompt
sudo ltsp-update-image

Note: You may get this error on Microsoft Azure VM!… hmmmm…. This script seems to fix it:

# tadaen sylvermane | jason gibson
# configure locales for ubuntu bionic ltsp chroot creation

for var in LC_ALL= LANG= ; do
        export "$var"en_US.UTF-8
ltsp-build-client --chroot "$1"
Local Chrootless Install
This is the recommended, and simplest install

Install FreeRDP-nightly and client zenity GUI

sudo sh -c 'echo "deb$(lsb_release -cs)/ freerdp-nightly main" >> /etc/apt/sources.list.d/freerdp-nightly.list' 
wget -O - | sudo apt-key add - 
sudo apt update 
sudo apt install --yes freerdp-nightly
sudo ln -s /opt/freerdp-nightly/bin/xfreerdp /usr/bin/xfreerdp-nightly
cd /usr/share/ltsp/screen.d/
sudo ln -s xfreerdp xfreerdp-nightly
sudo wget 
sudo wget 
sudo wget
sudo mkdir boxen  
cd boxen
sudo wget 
cd ..
sudo ln -s launch welcome
sudo ln -s /sbin/shutdown shutdown
sudo chmod +x rdpgui xfreerdp-prompt launch boxen/welcome

Create LTSP client NBD image using the chrootless method of the servers root /

You need to run this any time you make changes to your filesystem you want to be updated in your LTSP client.

sudo ltsp-update-image --cleanup /

Grab the lts.conf for our thin clients

cd /var/lib/tftpboot/ltsp/amd64/
sudo wget

Edit lts.conf to suit your needs

nano -w lts.conf

Test with KVM virtual pxe thin client

If you are already using KVM to install Ubuntu in a VM then you don’t need to install it again. However, if you are using a real bare metal server then you’ll need to run the install command.

sudo apt install virt-manager
Libvirtd will run dnsmasq on virbr0 by default. We need to kill that instance and restart the global dnsmasq with our LTSP configs. You will need to killall and restart dnsmasq every time you reboot.

###dnsmasq hack for testing
sudo mv /etc/dnsmasq.d/libvirt-daemon /root/
sudo sh -c 'echo "dhcp-range=,,8h" >> /etc/dnsmasq.d/ltsp-server-dnsmasq.conf
#These steps will need to performed again if you reboot
sudo killall dnsmasq
sudo service dnsmasq restart
#Create the PXE test KVM client
sudo virt-install \
  --name pxe \
  --memory 4096 \
  --vcpus 2 \
  --disk none \
  --pxe \
  --os-variant ubuntu17.10 \
  --wait 0

Connect locally using very nice spice

virt-viewer --connect qemu:///system pxe

Connect remotely using spice

virt-viewer --connect qemu+ssh://[email protected]/system pxe

Screenshot from 2018-11-11 23-58-02

Screenshot from 2018-11-14 21-30-44 Screenshot from 2018-11-14 21-33-48 Screenshot from 2018-11-14 21-34-11 Screenshot from 2018-11-14 21-41-25 Tada!!!

See also

lts.conf manpage ltsp-build-client manpage ltsp-update-image manpage ltsp-config manpage ltsp-chroot manpage……………

* Ubuntu 18.10 I previously tried this with Ubuntu 18.10 Cosmic Cuttlefish, and ran into some issues. Mainly the maintainer of LTSP for Ubuntu does not fix anything that is not a LTS release.

Optional Install ltsp-manager

sudo add-apt-repository --yes ppa:franz-die/ltsp-manager; apt update

sudo apt install ltsp-manager

Optional: Install X2Go remote desktop software

sudo add-apt-repository ppa:x2go/stable
sudo apt-get update
sudo apt-get install x2goserver x2goserver-xsessions x2gomatebindings

Optional: Install Ubiquity to install Ubuntu on PXE booted clients or servers

sudo apt-get install ubiquity ubiquity-frontend-gtk

Running it is a manner of running from the client

ubiquity gtk_ui

Optional: Add iPXE to grub menu

apt install grub-ipxe

Optional: Set up Firewall with IP Masquerading 

Probably won’t need to do this.

First, packet forwarding needs to be enabled in ufw. Two configuration files will need to be adjusted, in /etc/default/ufw change the DEFAULT_FORWARD_POLICY to “ACCEPT”:

sudo nano -w /etc/default/ufw #change DEFAULT_FORWARD_POLICY="ACCEPT"

Then edit /etc/ufw/sysctl.conf,

sudo nano -w /etc/ufw/sysctl.conf

and uncomment:


Now add rules to the /etc/ufw/before.rules file. The default rules only configure the filter table, and to enable masquerading the nat table will need to be configured. Add the following to the top of the file just after the header comments:

sudo nano /etc/ufw/before.rules
# nat Table rules

# Forward traffic from eth1 through eth0.

# don’t delete the ‘COMMIT’ line or these nat table rules won’t be processed

Allow SSH

sudo ufw allow 22
sudo ufw allow from 
sudo ufw enable

Optional: Install apt-cacher

apt-cacher will cache packages so you don’t waste your time downloading them again again.

sudo apt install apt-cacher
sudo nano /etc/apt-cacher/apt-cacher.conf #Uncomment allowed_hosts= *
sudo ufw allow 3142/tcp
sudo sh -c 'echo "Acquire::http::Proxy \"\"";' > /etc/apt/apt.conf.d/01proxy
sudo /usr/share/apt-cacher/ -l /var/cache/apt/archives
sudo service apt-cacher restart

Optional: Test with QEMU

Set up virtual bridge for client networking

On the azure VM I was able to use the default virtual bridge virbr0. Just commented out the dnsmasq.d/ file libvirt that prevented dnsmasq from serving IPs on that network. However, testing on a real server I needed to make my own bridge. These commands should not be issued if working on your server remotely. Only a local bare metal install should issue these commands.

sudo ip tuntap add dev virttap mode tap user $USER
sudo brctl addbr virtbr
sudo brctl addif virtbr eth0 # your LAN interface
sudo brctl addif virtbr virttap
sudo ip link set virtbr up
sudo ip link set eth0 up
sudo ip link set virttap up
dhclient virtbr

You may need to restart dnsmasq again

sudo service dnsmasq restart

Run QEMU to test your LTSP setup

qemu-img create -f vmdk testpxe.vmdk 10
/usr/bin/qemu-system-x86_64 -m 1024 -hda testpxe.vmdk \
                              -boot n \
                              -option-rom /usr/share/qemu/pxe-rtl8139.rom \
                              -net nic \
                              -net tap,ifname=virttap,script=no,downscript=no


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.