Creating a custom Ubuntu Linux thin client distribution

14 07 2013


I’ve been the de-facto IT guy for my dad’s small business since I was a teenager. His 15 Windows XP desktops and 2 Server 2003 servers — which were, of course, state of the art when we set them up — have gotten a bit long in the tooth. We decided for various reasons to replace that infrastructure with a thin-client setup based on Server 2012’s Remote Desktop Services.

Now, thin clients tend to cost a few hundred bucks a pop. Meanwhile, we have a fleet of old Dell desktops, most of which are perfectly functional, at least physically (their years-old XP installations are another story). I thought that surely there must be a way to repurpose these machines as thin clients. I didn’t want to keep Windows on these machines — having to stay current on Windows updates and antivirus definitions and worrying about what people were doing to them wasn’t appealing. Microsoft has this thing called Thin PC, but it requires Software Assurance licensing, which we don’t have.

So I decided to look for a Linux-based solution. The closest thing I could find to what I wanted was ThinStation, which is a teeny-tiny Linux distribution that can used as a thin client on really old hardware. But the documentation seemed not-so-great, the ISO download links weren’t working at the time I tried them, and I didn’t want to have to deal with finding the specific drivers I’d need for the different kinds of hardware we have, if they were available at all.

The approach I ended up choosing was to build a custom Ubuntu distribution based on Ubuntu Mini Remix, a very lightweight LiveCD edition of Ubuntu. It combines Ubuntu’s very good hardware support and Debian-based toolset with an extremely slimmed down base installation, allowing you to install and customize it however you like.

My objective was to create a custom LiveCD that, when booted, would login in automatically, start a bare-bones graphical interface, and launch a Remote Desktop session using the FreeRDP client. I also wanted it to be installable onto the hard drive of the system to improve boot time and so that the CD would not be required. I found the process of doing this to be not terribly well documented and I definitely hit some problems along the way. So I thought I would document for posterity the process I followed to create my simple thin client distribution.

Prep Work

To get started, you’ll need a copy of Ubuntu installed on a local computer to work with. I installed the Ubuntu 12.04 desktop edition in a Parallels-based VM on my Mac with all defaults, and that worked just fine.

Next, download an ISO CD image of Ubuntu Mini Remix onto your Ubuntu machine. As of this writing, the current version is 12.10, which you can download with wget:


Now it’s time to choose an Ubuntu LiveCD customization tool. All of these tools do basically the same thing: they take your LiveCD ISO, extract it to some location on your system, and using chroot to set that location as a temporary root directory, allow you to run commands, edit files, etc. within the context of the filesystem contained on the ISO. When you’re done, it rolls up the finished product back into a new ISO. I tried uck and a few other customization tools, but ultimately had the best luck with Customizer. It’s certainly not perfect, but it mostly works. Customizer is maintained in a git repository, so to retrieve it, you’ll need to install git:

sudo apt-get install git

With git installed, you can clone the Customizer repository to /opt/Customizer, which is where it expects to live on your machine:

sudo git clone /opt/Customizer

Next, install GAMBAS 2, a development environment used by Customizer; and SquashFS Tools, which Customizer uses to extract the LiveCD’s compressed filesystem:

sudo apt-get install gambas2 squashfs-tools

Setting Up Customizer

Now we’re ready to customize the ISO. Launch Customizer with the following command line. (Note: it wasn’t immediately apparent that sudo was necessary, but things won’t work without it.)

sudo /opt/Customizer/GUI.gambas

Next, we tell Customizer which ISO we’ll be customizing. Click the Select ISO button and browse to the Mini Remix ISO we downloaded earlier.


Once you hit Open, Customizer extracts the ISO and the “squashed” filesystem to the directories /home/ISO and /home/FileSystem. (Note: This is obviously a weird place to put files. Customizer does theoretically let you specify another location from the Settings dialog box, but that didn’t work for me. The ISO would be extracted, but the whole interface would remain grayed out.)

Now, the interface should light up and let us start working on our distribution:


Distribution Configuration

Now, let’s customize the name and version of our configuration. (Note that by default, these changes will appear in some places but not others.) While we’re at it, we’ll change the default username and hostname.


Configuring Apt Sources

The Mini Remix ISO ships with the ‘universe’ and ‘multiverse’ apt repositories disabled, and we’ll need those enabled to install some of our software. Click the “Edit Sources” button — it’s misspelled, but that’s OK 🙂 — and uncomment all the lines that begin with “deb” or “deb-src”. Save the file and close it.


Install GUI Environment with Openbox

Next, we’ll install X, the Linux GUI environment, along with a window manager for our thin client to run. I went with the bare-bones Openbox. Customizer will actually do this for us if we go to the Extras dropdown and select Install GUI. A text-based menu appears. We select 6 to install Openbox.


Custom Configuration With Terminal

Now, we want to make some changes to our distribution that Customizer doesn’t know how to do. Fortunately, Customizer provides a a Terminal function. When you click the Terminal button, Customizer opens up a special Terminal window chroot’d to its working directory. This will allow us to install packages and edit configuration files within the confines of the distribution we’re building, not on our local computer. So let’s click the Terminal button, which gives a window that looks like this:


Create Custom User Account

This threw me for a loop. Even though we gave Customizer a custom username for our LiveCD, that doesn’t actually create the user account. Ain’t that a hoot? So let’s create it now, and we’ll give it a blank password:

useradd -m dumbuntu
usermod dumbuntu -p U6aMy0wojraho

Auto Logon

Now, we want the Openbox environment to launch at boot, automatically logged in with our generic “dumbuntu” username. To do this, we’ll install and configure SLiM, a login manager. First, we install it:

apt-get install slim

Then, we’ll open the configuration file /etc/slim.conf in a text editor like nano and add the following lines:

auto_login yes
default_user dumbuntu

Install FreeRDP and Write Launch Script

The whole point of this thin client distribution is to connect to Remote Desktop Services using FreeRDP, so let’s install that now:

apt-get install freerdp-x11

Now, we’ll create a script to launch the FreeRDP client with our desired parameters. We’ll run it in an infinite loop so that if the user closes the client or if it crashes for some reason, it’ll just start again. Since the dumbuntu user will be running, we’ll put the script in that user’s home directory and set the ownership of the script accordingly.

cat<<EOF > /home/dumbuntu/
while true; do
  xfreerdp -x 0x80 -f -T 'Remote Desktop Session' --no-nla --plugin rdpsnd --data alsa -- server-hostname-goes-here
  sleep 2
chmod 755 /home/dumbuntu/
chown dumbuntu:dumbuntu /home/dumbuntu/

Install ALSA for Sound

To make sound work, we need to install the alsa-base package. This will provide access to the amixer utility, which can be used to unmute and set the audio volume.

apt-get install alsa-base

Configure Post-Login Commands

After auto-login, we want to configure audio volume in Ubuntu to 100% (users can change it within the remote desktop session if they like). We also want to launch our FreeRDP script automatically. We can configure OpenBox to do this by editing the file /etc/xdg/openbox/autostart and adding the following lines:

amixer set Master 100%
amixer set Master unmute

Only One Virtual Desktop (and Edit Key Bindings)

By default, Openbox configures 4 virtual desktops. I don’t want my users to accidentally move the FreeRDP window to another desktop and get confused. To change this, you can edit /etc/xdg/openbox/rc.xml and look for a line that says <desktops>. Below that, there’s a line beginning with <number>. Change the 4 on that line to 1.

This file also controls the key bindings that Openbox associates to various window management tasks. I wasn’t too concerned about this, since FreeRDP takes over most of these key bindings when it’s open anyway. If you wanted to, you could certainly delete or comment out some of the <keybind> items in the <keyboard> section.

Configure Openbox Menu

The only menu our streamlined graphical environment will have is the Openbox desktop context menu, accessible by right-clicking on the desktop. This menu can be customized by editing /etc/xdg/openbox/menu.xml. I decided to configure a single menu option to run my FreeRDP Launch script — just in case the user accidentally kills the instance that runs automatically — and a submenu with a few administrative tools. Here’s what it looks like.

<?xml version="1.0" encoding="UTF-8"?>

<openbox_menu xmlns=""

<menu id="root-menu" label="Dumbuntu">
 <item label="Remote Desktop">
 <action name="Execute"><execute>/home/dumbuntu/</execute></action>
<menu id="utils-menu" label="Utilities">
 <item label="XTerm">
 <action name="Execute"><execute>xterm</execute></action>
 <item label="Local Install">
 <action name="Execute"><execute>ubiquity --automatic</execute></action>
 <item label="Restart">
 <action name="Execute"><execute>sudo reboot</execute></action>
 <item label="Shut Down">
 <action name="Execute"><execute>sudo halt</execute></action>


Install the Installer

As discussed earlier in this article, Ubuntu Mini Remix is a LiveCD distribution. This means that you can boot off the CD directly into the operating system. What we’ve built so far, therefore, is a customized LiveCD distribution. That’s cool, but I’d like to be able to actually install this distribution on a PC’s hard drive. To do that, we need to install the Ubuntu installer, Ubiquity. We’ll configure it in the next step.

apt-get install ubiquity

Done With Customizer Terminal

We’re done customizing our new distribution’s filesystem. Type exit to close the Terminal. Don’t just close the window! Customizer doesn’t like that. Keep the main Customizer window open — we’ll come back to it.

Configure the Installer

To configure the installer, we actually need to do some work in a regular Terminal, not in the Customizer Terminal. The reason is that all the work we’ve done so far has been focused on customizing our distribution’s filesystem. The work we need to do on the installer will live outside the filesystem on the CD itself.

Create the Preseed File

Ideally, we don’t want the installation process to require a bunch of clicks – I like things to be automated according to set a predetermined choices. Fortunately, Ubiquity supports what’s called a preseed file, which contains instructions that will be fed to the installer. Create a file called /home/ISO/preseed/dumbuntu-preseed.cfg. There are lots more options you can customize, but these values worked for me.

d-i debian-installer/locale string en_US

d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/layoutcode string us

d-i netcfg/choose_interface select auto
d-i netcfg/get_hostname string tmsbuntu
d-i netcfg/get_domain string tmsbuntu
d-i netcfg/wireless_wep string

d-i mirror/country string manual
d-i mirror/http/hostname string
d-i mirror/http/directory string /ubuntu
d-i mirror/http/proxy string

d-i clock-setup/utc boolean true
d-i time/zone string US/Eastern
d-i clock-setup/ntp boolean true

d-i partman-auto/method string lvm
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-md/device_remove_md boolean true
d-i partman-lvm/confirm boolean true
d-i partman-auto/choose_recipe select atomic
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i partman-md/confirm boolean true
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true

d-i passwd/user-fullname string TMS User
d-i passwd/username string tmsbuntu
d-i passwd/user-password-crypted password U6aMy0wojraho
d-i user-setup/allow-password-weak boolean true
d-i user-setup/encrypt-home boolean false

tasksel tasksel/first multiselect ubuntu-desktop

d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true
d-i finish-install/reboot_in_progress note

xserver-xorg xserver-xorg/autodetect_monitor boolean true
xserver-xorg xserver-xorg/config/monitor/selection-method \
 select medium
xserver-xorg xserver-xorg/config/monitor/mode-list \
 select 1024x768 @ 60 Hz

Customize the Boot Menu

The question comes to mind: how will folks actually install our distribution? If you’ve ever installed the Ubuntu LiveCD, you know that when you boot off the CD, you get a prompt to either boot into the LiveCD environment or into the installer. Our distribution will offer the same choice. But there’s one problem: it doesn’t work. With the Mini Remix distribution, the installer choice appears in the boot menu, but if you choose it, nothing happens — it just boots into the LiveCD environment anyway. Bummer.

Unfortunately, I don’t have an answer to this one, but I can offer a workaround: once you boot into Openbox, you can manually launch the Ubiquity installer in automatic mode — the command, oddly enough, is ubiquity –automatic — which will kick off the installation of our distribution using our preseed file. Remember when we configured the Openbox menu earlier? You may have noticed that I sneaked into the menu an option called Local Install to do just that.

For Ubiquity to pick up our preseed file, we need to edit our CD’s boot menu file, which can be found in /home/ISO/isolinux/txt.cfg, to specify the preseed filename. I took the opportunity to clean out some extraneous options also:

default live
label live
  menu label ^Try or install Dumbuntu
  kernel /casper/vmlinuz
  append  file=/cdrom/preseed/dumbuntu-preseed.cfg boot=casper initrd=/casper/initrd.lz quiet splash --
label hd
  menu label ^Boot from hard drive
  localboot 0x80

Build, Test, Rinse, Repeat

Phew! It’s finally time to build the ISO for our distribution. Back in Customizer, click Build ISO. This takes a fairly long time, so go make a pizza or something. Once it’s done, the ISO will be in the /home directory. you can use Customizer’s built-in QEMU virtualization feature to boot the ISO, or you can create a VM in your virtualization software of choice, boot it up with the ISO, and see what happens.

If you need to tweak things, you can always go back to Customizer, make more changes, and build the ISO again. As long as you don’t click the Clean button or tamper with the /home/ISO and /home/FileSystem folders, all your customizations should remain waiting for you to come back and continue working. Even if you do wipe out your customizations in those folders, you can always open up your customized distribution’s ISO file in Customizer and go from there.

Once you’re happy with your distribution, you’re ready to redistribute your ISO or burn it to CD and start using it. Have fun!


Getting started

25 11 2011

I recently wrapped up a side gig running the server infrastructure for a popular technology news site. I’m going to get this blog started by posting some useful tidbits I happened upon during that project.