Using Ubuntu as a Terminal Server

(I posted a version of this guide on the Ubuntu Forums)

There’s a lot of information about LTSP (the Linux Terminal Server Project) out there, including quite a few guides, but nothing that really brought everything together well enough for me. In particular, they were bad at explaining the reasons for each step. So, here’s my version!

Note that you do not need a dedicated Ubuntu server for this guide. I ran a terminal server just fine using Ubuntu 14.04 or 12.04 running inside VirtualBox. If you do so, just make sure the virtual machine is running with the network adapter in bridged mode, so that it is a full participant in the LAN.

How Does LTSP Work?

When it does work it seems like magic, but it’s worth understanding what LTSP does, because it’s actually a rather simple (but beautiful!) combination of existing technologies and products.

The thin client runs applications on the server using X forwarding, in fact not much differently from Unix terminals in pre-PC days. You can easily try this technology without LTSP by using “ssh -X”, as long as you have X running on the client. What LTSP adds to this is the initial handshaking, the creation of the client/server session. You thus require specialized thin/fat clients that include support for logging into the LTSP server. After this handshake, LTSP actually plays no further role. So, all a client really needs is this LTSP session creator, and then X. (I’m simplifying this a bit: LTSP adds support for forwarding USB devices and sharing network drives, too, but that stuff is all done within the X forwarding framework.)

So how do you get that specialized LTSP session creator and X on the client? One way is to install it manually, assuming the client has some storage. That’s how BerryTerminal works: it’s a tiny operating system that includes only that bare minimum. When it boots up, it will look for the LTSP server and display the login screen (or login automatically if you have that configured on the server).

Network Boot

But obviously, many clients do not have storage. They can, however, automatically download their operating system over the network, using an technology called PXE. PXE has been included in practically every network card controller since the past decade. PXE, in turn, relies on two services: a DHCP server provides the client with its initial IP address, DNS, and PXE boot information. The client then uses TFTP to download the operating system image and boot it. So, in fact you will need three things to make this work: 1) a DHCP server; 2) a TFTP server; 3) a client operating system image. The whole dance of getting an IP address, downloading the image and booting it doesn’t take that long: within 30 seconds you should get a login screen, even for weak clients.

To complicate things, there is an important limitation: only a single DHCP server can exist on a LAN, and it’s very likely that you already have one running on your router. If that’s the case, you have two options: 1) you might be able to configure your router’s DHCP server to send clients PXE information about your terminal server, an advanced option that unfortunately does not exist in cheap office routers; 2) you can use a PXE feature called “proxy DHCP”, created exactly for this situation. It’s very easy to set up, and indeed that’s what this guide is for. (Note that some very old equipment does not have proxy DHCP support in its PXE, in which case you can’t use this method. But that’s very rare these days.)

(Actually, there is a third, more complicated option: you can create a special closed LAN just for your terminal server and clients. In this LAN, your terminal server will act as both the DHCP server and TFTP server. Remember: you don’t need a router in this LAN, because clients--assuming they are thin and not fat--run all their software on the server. But this means that your terminal server likely has two network cards, one sitting on this client LAN, and the other sitting on your broader network, likely with access to the Internet. This is what the “ltsp-server-standalone” package is for, and where most guides for LTSP begin. Here’s an excellent one if that’s your situation. So, to reiterate, this guide assumes that you already have a working DHCP server on your network.)

Let’s Do It!

Let’s install LTSP, a proxy DHCP server, and a TFTP server:

sudo apt-get install ltsp-server dnsmasq tftpd-hpa

(Though Dnsmasq can do both DHCP and TFTP, I’ve found it has a crucial bug when functioning as a TFTP server specifically with Ubuntu 14.04, so we’ll be using tftpd-hpa instead for that.)

Warning: do not install “ltsp-server-standalone” package as is suggested by other guides, because that assumes that you want your terminal server to be a full DHCP server.

Now we need a client operating system image. As stated earlier, for thin clients all we need the is the LTSP session creator and X. Of course, we also need a kernel (Linux), basic drivers for keyboard, mouse, video card, audio, etc. It’s still an operating system! Marvelously, LTSP on Ubuntu comes with a tool to automatically create such an image for you, based, of course, on Ubuntu. But it should be emphasized that this client operating system is nothing like the regular full-blown Ubuntu desktop distribution: it is stripped down and highly specialized to work purely as an LTSP client. Indeed, for thin clients its total size is less than 300 mb.

LTSP on Ubuntu gives you many options for customizing the client image, but the defaults should work just fine. (Customization would be necessary in case the default image doesn’t support your thin clients' hardware for some reason. In that case, you might need to install additional drivers on your image.)

This is going to take a while, so sit back and relax:

Ubuntu 14.04:

sudo ltsp-build-client

Ubuntu 12.04:

(We’ll assume in this guide that our thin clients are 32-bit x86 machines, which is most common. You can also build 64-bit x86 images, assuming you have clients that could support it, though there would be no serious advantage to it unless they are fat clients running heavy software. More commonly useful, perhaps, are images for ARM architecture clients. Simply replace the “i386” in this guide with the client architecture you are using, as long as it’s supported by Ubuntu.)

sudo ltsp-build-client --arch i386

The command will download all packages for this stripped-down Ubuntu-based client operating system and install them under: /opt/ltsp/i386/. It will then compress this into /opt/ltsp/images/i386.img, the actual image to be sent to the client.

(Note that this image will be based on your current Ubuntu version, at the current state of packages in its repositories. Since this is merely a thin client operating system, it shouldn’t really matter if the image is stays “old”, as long as it works. Remember, the software is actually running on your server, not the client. However, it is possible to upgrade this image to latest Ubuntu packages, something you might want to do once in a while, especially if security is important. This guide won’t cover that.)

Actually, we need to stop and explain one more aspect of the network booting process for LTSP on Ubuntu: it happens in two stages. In order to download, decompress and boot into the i386.img, we need a network operating system bootloader. This is provided by PXELINUX, a tiny Linux-based bootloader (really, a mini operating system) designed exactly for this use case. If you’re used to desktop Ubuntu, consider that PXELINUX is similar to GRUB, but designed around network boot. The “ltsp-build-client” created it for us under /var/lib/tftpboot/ltsp/i386/. It is less than 15 mb in size. So, the client gets this pxelinux directly over TFTP and runs it, and PXELINUX then downloads i386.img, decompresses it into a RAM drive, and boots.

The configuration file for our PXELINUX is under /var/lib/tftpboot/ltsp/i386/pxelinux.cfg/default. Unfortunately, in the version of LTSP included in Ubuntu 14.04 and 12.04, it is generated without support for proxy DHCP by default. To fix this, you must run:

Ubuntu 14.04:

sudo sed -i 's/ipappend 2/ipappend 3/g' /var/lib/tftpboot/ltsp/i386/pxelinux.cfg/default

Ubuntu 12.04:

(cat <<EOF
ipappend 3
) | sudo tee -a /var/lib/tftpboot/ltsp/i386/pxelinux.cfg/default

If you update your client image in the future (with “ltsp-update-image”) then you will need to run this command again.

(Documentation for the “ipappend” can be found here. The value “3” is the logical OR of “1” and “2”.)

OK! Now it’s time to configure Dnsmasq. Edit /etc/dnsmasq.d/ltsp.conf (the file isn’t there, you must create it) and put something like this:

# Dnsmasq running as a proxy DHCP and TFTP server
# See: http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html


# This might work instead of tftpd-hpa:


# DHCP proxy on this network

# Tell PXE clients not to use multicast discovery
# See section in http://tools.ietf.org/html/draft-henry-remote-boot-protocol-00

# Better support for old or broken DHCP clients

# Enable this for better debugging


# Note the file paths are relative to our "tftp-root" and that ".0" will be appended

pxe-prompt="Press F8 for boot menu", 3
pxe-service=x86PC, "Boot from network", /ltsp/i386/pxelinux
pxe-service=x86PC, "Boot from local hard disk"

You will need to change “dhcp-range” to the subnetwork of your LAN. Also change “i386” and “x86PC” to something else if you are using a different client architecture image. Now, restart dnsmasq:

sudo service dnsmasq restart

Note that on Ubuntu 14.04, there is currently a bug with tftpd-hpa, with this solution.

And ... you should be good to go. Start your clients with network boot: they should get an IP address from your router’s DHCP server, then get PXE information from your proxy DHCP server (Dnsmasq), then boot PXELINUX from your TFTP server (also Dnsmasq), then download and boot into the i386.img stipped-down-Ubuntu-based client operating system, and then display the login screen.


By default, LTSP on Ubuntu uses an ssh tunnel for secure X forwarding, but you can switch to “direct X” mode for better scalability and performance, at the expense of reduced security on the LAN. Edit /var/lib/tftpboot/ltsp/i386/lts.conf (the file will not exist, but it’s OK to create it) and put this:


Now we need to regenerate the image and not forget to fix the proxy DHCP issue:

Ubuntu 14.04:

sudo ltsp-update-image
sudo sed -i 's/ipappend 2/ipappend 3/g' /var/lib/tftpboot/ltsp/i386/pxelinux.cfg/default

Ubuntu 12.04:

sudo ltsp-update-image --arch=i386
(cat <<EOF
ipappend 3
) | sudo tee -a /var/lib/tftpboot/ltsp/i386/pxelinux.cfg/default

The next time clients boot, they will be using this new image.

Need Guest Users for a Public Lab?

I’ve created a separate guide for doing that.

Dec 31, 1969, 18:00 CST