Thin Clients with LTSP on Ubuntu Server 16.04 [Comprehensive Guide]

Esta guía está disponible en español

Picture this: You’re a Systems Administrator and your employer wants to spend the least amount of money on hardware when adding a new division to the company. You’ve been tasked, with making this happen. If he finds out he spent more than he has to, you’re fired. You’ve heard about this LTSP thing, but never really got into it. Now would be a better time than ever.

LTSP, the Linux Terminal Server Project, is an open-source server that, when configured correctly, can save businesses a lot of money by requiring minimal amounts of hardware for many machine instances, it also makes keeping security, software and OS instances up to date with minimal effort. First, a little background.

A computer, when starting/turning on/booting/etc, loads the kernel, which loads the rest of the operating system afterwards, all from the internal hard drive located inside the physical machine you’re using. Imagine a machine where there is no hard disk, no SSD, no M.2, no NVMe, no storage at all inside it. THIS. IS. SPART– ..thin client.

First off, we need to define the specs of the hardware we’ll be using. The CPU isn’t so important as the CPU resources will be based off of the thin client’s hardware, however the RAM will be important as all applications will be running on the local server when started from the thin client. My general rule of thumb for this would be to start will 1GB of RAM and add 300MB of RAM per thin client (machine)that will be concurrently accessing the LTSP server. This amount may change depending on the types of software you assign to the users.

Secondly, we need to consider the applications that we’ll be installing as per the request of whomever is in charge. In my case, it was requested that at the minimum a web browser, LibreOffice and gcc be provided for the thin clients.

Lastly, we need to consider how many users that we’ll have on the system. This will be needed to calculate how much storage space we’ll mount on the home directory. I would generally recommend 5 gigabytes per user that will be accessing the server. Beyond this recommendation, adjustments should be made for anyone accessing the machine that could especially need more space, although I can’t imagine why one would need more space when using a thin client.

Now that that’s settled, let’s get started on the setup and configuration.

The first step of set up, of course, would be to install the operating system. For this case, I’m required to use Ubuntu 16.04 LTS Xenial Xerus. Follow the installation found here. If this basic guide isn’t enough for you, please turn back now. This is guide is intended for Systems Administrators and the like.

Note: If you need remote access to this LTSP server, don’t forget to install the OpenSSH package. 

Once Ubuntu Server is installed, boot up and login, and configure your network interfaces. As we’ll be running a DHCP server on this machine, you’ll want to have at least two: one to face the internet and one to face the LTSP network. We’ll be using NAT later on to pass traffic back and forth to the internet from the LTSP network.


Once the interfaces are configured update your package list with sudo apt-get update and upgrade the packages with sudo apt-get upgrade. This way you have the latest up-to-date security packages, keeping things secure. If you want to learn about how to secure your server beyond simply updating packages, check out this handy guide.

Once that’s finished, go ahead and install the LTSP and NFSD packages.

sudo apt-get install ltsp-server-standalone nfs-kernel-server

next we’re going to do the initialization of the image the thin client downloads on boot by running sudo ltsp-build-client. This might take a little while depending on your internet connection, so while this is setting up the image, let’s configure the DHCP server that’s going to deliver the image to the thin clients connecting into the LTSP server. hit alt+f2 and log into the second tty on your server. We’ll be looking for /etc/ltsp/dhcpd.conf. Open that up in your favourite text editor, I’ll be using nano simply because I’m used to that, and we’ll be making a bunch of edits here and there.

For this DHCP server, I’ll be using the network with a netmask of (classic class B private network configuration) but you’ll be, of course, making your own decisions on your own network setup (for example using a 192.168.x.x/24 configuration). Taking the screenshot below, I’ll go through the configuration I’ve got here.

On line 7, we’ve got the clause that declares this DHCP server as the authoritative one for the network.

With line 9, we’ve set dhcpd to listen on the network. Line 10 tells us that the IPs being handed out to any clients of the server will be within the and range. We can assign this range because the broadcast, listed on line 13, is actually since we’ve chosen a subnet mask for it, like on line 17. On line 11, we’ve chosen the domain name for the subnet to be, for you it could certainly be anything you like.

Note: When choosing a subdomain, it would be wise to use an unresolvable top level for your domain (such as .lan or .ltsp).

Since I’ve chosen the static IP of the LTSP server to be and we’ll be using this server for NAT for thin clients, the next server on line 15, and the routers on line 14. Lastly, for the purposes of NAT, set the domain-name-servers option on line 12 to the address corresponding to the desired internet connected DNS server (for example Google’s or your home router’s IP address).

Now save the configuration file and open up /etc/dhcp/dhcpd.conf and add include "/etc/ltsp/dhcpd.conf"; to the absolute end of the file. Save it, then we move on to configuration of the NFS exports.

Open /etc/exports/ and add /opt/ltsp *(ro,no_root_squash,async,no_subtree_check) to the end of the file, save it.

Since the dhcp server is not starting on boot yet, we’ll enable that and then start it:

sudo systemctl enable isc-dhcp-server && sudo systemctl start isc-dhcp-server

Note: When looking for the process, it will be listed as dhcpd rather than isc-dhcp-server.

Once this has been started without errors (it happens to me all the time, missed a 5 here or a semicolon there, check /var/log/syslog/) we’ll move on to installing some software.

As I previously mentioned, I was instructed to install LibreOffice, gcc and some web browser. I was also instructed to have a lightweight desktop environment and I’ve chosen LXDE. LXDE installs with a web browser (deluge) so that will be taken care of already.

First we need to change the root directory into the LTSP client’s root directory so we’ll run:

sudo chroot /opt/ltsp/amd64

Since we’ve changed the root, our DNS requests will be sent to whatever DNS was set on the Ubuntu server when you installed and built the client image. We’ll have to change that in /etc/resolv.conf/ from inside the chroot and I’ve simply put mine as and

Before we install the packages, we’ll want to run mount -t proc proc /proc which will prevent the java installation errors that are demonstrated in the below screenshot.

Install the packages:

sudo apt-get install libreoffice gcc lxde

This may take a while. You’ll get an error at the end of the installation saying a few packages weren’t able to be installed.

This is because some of them require an actually running machine to install. We’ll finish this later through the client.

For now, we have users to add. Exit the chroot and add the users on the server itself. Any users with root access (eg: the administrator’s account) should be added with the following command:

useradd -g users -G sudo -m -s /bin/bash <username>

Firstly we have the command. After that, the -g flag says which group the user should be initialized into. In this case it’s the users group. The -G sudo flag and argument tells useradd to also add this user to the sudo group. -m says to create the home directory if there is none that already exists. -s /bin/bash tells useradd to use the bash shell. Of course, the last parameter is the name of the user.

Any regular users can be added with the command below:

useradd -g users -m -s /bin/bash <username>

Note: Don’t forget to add passwords for all the users.

Once the users are all added, the software installed and the configuration files modified and saved, go ahead and run sudo ltsp-update-image to rebuild the image with the changes we’ve made. This may take a while.

Now most of the client changes have been performed and built into the client image, we’ll set up the NAT between the LTSP network and the internet.

On the LTSP server, uncomment net.ipv4.ip_forward=1 in /etc/sysctl.confby removing the hash or pound sign from the beginning of the line.

To make this setting active immediately, run sudo sysctl -w net.ipv4.ip_forward=1. Otherwise, simply reboot.

Next we need to set up the iptables rule that will enable the NAT to take place. Since our LTSP network address/mask is, our command for this will be the following:

sudo iptables --table nat --append POSTROUTING --jump MASQUERADE --source

Note: This command is not universal, change the address/mask combination to fit your configuration.

Save the configuration by entering sudo bash -c 'iptables-save > /etc/ltsp/nat.

To make this configuration load on boot, we’ll want to add an iptables-restore entry into the interfaces configuration file to the LTSP connected interface, like so:

Finally, create the file /var/lib/tftpboot/ltsp/amd64/lts.conf and put the following:

LDM_SESSION = /usr/bin/lxsession

Save the file, exit, and we’re done!

You can enable PXE boot on your thin client through the BIOS or hit F12 on most machines and as long as your thin client is properly connected on the LTSP network you’ve set up, you should be able to boot from the LTSP server at this point.

Note: If you’ve installed another desktop environment, look for the binary that will start your respective session choice in /usr/bin.

Some closing statements:

  • Whenever performing updates on the client image’s software packages, be sure to update the image with ltsp-update-image afterwards as well.
  • One isn’t required to rebuild the image when adding new users.
  • Thin clients in this configuration do not need an internal storage drive and 512MB of RAM should suffice for most cases.
  • This is most certainly not the only possible configuration one can achieve. Visit for more information on possible configurations. Canonical also has some good information here and here although some of the information on Canonical’s site might be outdated and marked as applying to older versions, a lot of the information will suffice for today’s version of LTSP.
  • If you want to use a RaspberryPi 3 as a thin client, please read this tutorial from the Pi’s website. It is unlikely to reliably get PXE booting working on any previous models of the RaspberryPi.
  • This was a project assigned to me by my *nix class instructor. Any of the software choices were made by said instructor.
  • You don’t need to set up NAT through the LTSP server if you can directly connect the thin client machines to the main router through a switch. In that case, you would set option routers to the IP of the interface connected to the aforementioned switch.

Thanks for reading! If you have any success stories that came from your experience following this comprehensive guide, feel free to leave a comment below sharing said experience!

Also, if you’re looking for some sort of thin client solution for your own set up, consider the NComputing L-Series Thin Client L300, that has a four egg rating on Newegg(aff) as a potential option.

6 Comments Posted

    • This is one of the three reserved private IP spaces as specified in RFC 1918.

      ^ The above are the three reserved spaces

  1. i noticed this:
    On the LTSP server, uncomment net.ipv4.ip_forward=1 in /etc/sysctl.conf

    are ye using 2 servers cause i didnt read that in the tutorial till i came at this specific line

    • The reason I wrote “On the LTSP server” is because in a prior paragraph, we performed a “chroot” which is when you change the location to be defined as the “root” or “/” of the filesystem. Changing the location allows you to perform tasks on a system that lies within the current system (such as a linux install being mounted in a directory during a live CD).

      To “uncomment” is to remove the hash or pound sign “#” from the beginning of the line. When a line is “commented out”, a program that accesses the file will skip over that line. When we uncomment it, the line will no longer be skipped.

      I hope that helps 🙂

2 Trackbacks & Pingbacks

  1. Links 14/5/2017: Linux 4.12 RC1 and KDE Frameworks 5.34.0 | Techrights
  2. Thin clients via LTSP (Xenial) | 0ddn1x: tricks with *nix

Leave a Reply

Your email address will not be published.


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