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: https://github.com/jphein/boxen
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. https://www.techsoup.org/
- $3500 Azure Credit, Free Office 360 – Free cloud servers, Office.
Apply for Microsoft Nonprofit here: https://nonprofit.microsoft.com/register - Free Voice,Gsuite,etc.. – Free cloud Telephony, calendaring, file management, and email with custom domain.
Apply for Google Nonprofit here: https://www.google.com/nonprofits/ - 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: https://www.publicsurplus.com/sms/nevadacounty,ca/list/current?orgid=315996 After that try eBay: https://rover.ebay.com/rover/1/711-53200-19255-0/1?mpre=https%3A%2F%2Fwww.ebay.com%2Fb%2FPC-Desktops-All-In-One-Computers%2F179%2Fbn_661752&campid=5337848787&toolid=20008
- 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: [email protected] . 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. https://jphein.com/discounted-phone-and-internet-for-nonprofits-in-california/
Terms
- [wiki]Vertical market software[/wiki] – https://en.wikipedia.org/wiki/Vertical_market_software
- [wiki]Thin client[/wiki] – https://en.wikipedia.org/wiki/Thin_client
- [wiki]Linux Terminal Server Project[/wiki] (LTSP) – https://en.wikipedia.org/wiki/Linux_Terminal_Server_Project
- [wiki]Ubuntu[/wiki] – https://en.wikipedia.org/wiki/Ubuntu
- [wiki]Remote Desktop[/wiki]
Guide
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.
Requirements
- 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.
IPs
- 10.0.0.1 – Gateway.
- 10.0.0.5 – eth0 – Local interface on Ubuntu server – Connected to the Internet.
- 192.168.122.1 – virbr0 – Virtual bridge on Ubuntu server for testing virtual thin clients.
- 10.0.0.4 – 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: https://www.microsoftazuresponsorships.com/Balance
Create your virtual machines here: https://portal.azure.com
Note: DO NO USE accelerated networking on the Ubuntu Server.

LTSP Server
- Image type: Ubuntu 18.04
- Size: Azure Standard D4s v3
Desktop Server
- Image type: Windows 2016 Datacenter
- Size: Azure Standard NV6
[jbox]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)
- Ubuntu 18.04.1 Desktop.
- Download ISO here: https://www.ubuntu.com/download/desktop
- Install the desktop version, minimal install.
- Instructions here: https://jphein.com/how-to-install-ubuntu-18-04-18-10-to-an-usb-3-1-m-2-16gb-drive-using-kvm/
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
[/jbox]
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: https://lg.io/2016/10/12/cloudy-gamer-playing-overwatch-on-azures-new-monster-gpu-instances.html
Configure the Ubuntu and install LTSP Server
[jbox]You can find a bash script automating all the below commands here: https://raw.githubusercontent.com/jphein/boxen/master/boxenbrain [/jbox]
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.
[jbox color=green]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.
https://www.itzgeek.com/how-tos/linux/ubuntu-how-tos/netplan-how-to-configure-static-ip-address-in-ubuntu-18-04-using-netplan.html
https://netplan.io/examples
[/jbox]
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 http://wiki.ltsp.org/wiki/Installation/Ubuntu:
sudo add-apt-repository --yes ppa:ts.sch.gr #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,192.168.122.1” 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} epoptesWas told to remove these packages
sudo apt purge --yes --auto-remove mate-hud snapd
[jbox color=blue title=”Optional: Chroot Install”]
Build a chroot client for alternate arch, dekstop enviroment or package base
Grab freerdp’s key
cd /etc/ltsp sudo wget http://pub.freerdp.com/repositories/ADD6BF6D97CE5D8D.asc
- Option 1 – with command
sudo ltsp-build-client --purge-chroot --mount-package-cache --mirror 'http://azure.archive.ubuntu.com/ubuntu/' \ --apt-keys '/etc/ltsp/ADD6BF6D97CE5D8D.asc, /etc/apt/trusted.gpg.d/ts_sch_gr_ubuntu_ppa.gpg' \ --extra-mirror 'http://ppa.launchpad.net/ts.sch.gr/ppa/ubuntu bionic main, http://pub.freerdp.com/repositories/deb/bionic/ freerdp-nightly main' \ --late-packages epoptes-client freerdp-nightly --prompt-rootpass --fatclient\
- OR, Option 2 – using my ltsp-build-client.conf
sudo wget https://github.com/jphein/boxen/raw/master/etc/ltsp/ltsp-build-client.conf 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 exit
Create GUI login screen for xfreerdp-nightly (Not updated!)
cd /opt/ltsp/amd64/usr/share/ltsp/screen.d/ sudo wget https://raw.githubusercontent.com/jphein/boxen/master/rdpgui sudo wget https://raw.githubusercontent.com/jphein/boxen/master/xfreerdp-prompt sudo chmod +x rdpgui xfreerdp-prompt
sudo ltsp-update-image
Note: You may get this error on Microsoft Azure VM! https://bugs.launchpad.net/ubuntu/+source/ltsp/+bug/1802707 hmmmm…. This script seems to fix it:
#!/bin/bash
# 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
done
ltsp-build-client --chroot "$1"[/jbox]
[jbox color=green title=”Local Chrootless Install”]
This is the recommended, and simplest install
Install FreeRDP-nightly and client zenity GUI
sudo sh -c 'echo "deb http://pub.freerdp.com/repositories/deb/$(lsb_release -cs)/ freerdp-nightly main" >> /etc/apt/sources.list.d/freerdp-nightly.list' wget -O - http://pub.freerdp.com/repositories/ADD6BF6D97CE5D8D.asc | 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 https://raw.githubusercontent.com/jphein/boxen/master/usr/share/ltsp/screen.d/rdpgui sudo wget https://raw.githubusercontent.com/jphein/boxen/master/usr/share/ltsp/screen.d/xfreerdp-prompt sudo wget https://raw.githubusercontent.com/jphein/boxen/master/usr/share/ltsp/screen.d/launch sudo mkdir boxen cd boxen sudo wget https://raw.githubusercontent.com/jphein/boxen/master/usr/share/ltsp/screen.d/boxen/welcome 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 /
[/jbox]
Grab the lts.conf for our thin clients
cd /var/lib/tftpboot/ltsp/amd64/ sudo wget https://raw.githubusercontent.com/jphein/boxen/master/var/lib/tftpboot/amd64/lts.conf
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
[jbox]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=192.168.122.20,192.168.122.250,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
[/jbox]
#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
Tada!!!
See also
lts.conf manpage ltsp-build-client manpage ltsp-update-image manpage ltsp-config manpage ltsp-chroot manpage http://wiki.ltsp.org/wiki/Installation/Ubuntu https://help.ubuntu.com/community/HowToSetupLTSPDevelEnvironment https://github.com/wyllianbs/xfreerdp-gui https://unix.stackexchange.com/questions/119880/make-freerdp-prompt-user-for-username-and-password/187370 http://www.saminiir.com/debugging-pxe-boot/
* 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
[jbox]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:
net/ipv4/ip_forward=1 net/ipv6/conf/default/forwarding=1
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 *nat :POSTROUTING ACCEPT [0:0]
# Forward traffic from eth1 through eth0.
-A POSTROUTING -s 192.168.122.0/24 -o eth0 -j MASQUERADE
# don’t delete the ‘COMMIT’ line or these nat table rules won’t be processed
COMMIT
Allow SSH
sudo ufw allow 22
sudo ufw allow from 192.168.122.0/24 sudo ufw enable
[jbox]
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 \"http://10.0.0.5:3142\"";' > /etc/apt/apt.conf.d/01proxy
sudo /usr/share/apt-cacher/apt-cacher-import.pl -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
cd 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


