Creating a kiosk with Linux

One of the presentations I did this week was about kiosks — how to configure them for various platforms. Since I’ve spent a fair amount of time working with Linux over the past couple of years, that was one of the platforms that I covered. Here’s an overview of what I did to create a single app kiosk on Linux. That could be a digital sign (e.g. menu board at a fast food restaurant or a flight status display at an airport) or an interactive kiosk (e.g. directions in the mall, more information in a museum). Basically, you need a way to boot up and display a web page. So how do you do that?

First, you need to start with a Linux installation. I picked Rocky Linux 9.1, as a free starting point that has a browser, Firefox, preinstalled. But you can choose other distributions as well. While the instructions here work fine with Rocky Linux, you might need to make minor tweaks to them for other distributions.

At a high level, these are the necessary tasks:

  • Create a kiosk user without a password.
  • Configure the Linux desktop manager (GDM in this case) to automatically log on the user.
  • Configure the user to run a restricted “gnome-kiosk-script-session” profile that runs a shell script to launch an appropriate app, e.g. Firefox with some command line options.

Those tasks can be done via a shell script like so:

useradd -m kiosk
passwd -d kiosk

yum -y install gnome-kiosk-script-session

cat > /etc/gdm/custom.conf << EOF
# GDM configuration storage

# Uncomment the line below to force the login screen to use Xorg




# Uncomment the line below to turn on debugging

mkdir -p /home/kiosk/.local/bin /home/kiosk/.config
cat > /home/kiosk/.local/bin/gnome-kiosk-script << EOF
firefox -kiosk
sleep 1.0
exec "$0" "$@"

chmod +x /home/kiosk/.local/bin/gnome-kiosk-script

cat > /var/lib/AccountsService/users/kiosk << EOF

When I run that script, I can see the steps being processed:

Once the script finishes (takes a few seconds), the OS can be rebooted:

After the reboot, this is what you get:

Working great. As I mentioned in the session, the kiosk configuration works very well, and sometimes too well — when I tested the script and rebooted, I could no longer get to the script to copy it off the OS volume. To work around that, I had to reconfigure the device to PXE boot, boot into a Linux image, mount the disk volume, and then copy the script off to my server.

But wait, there’s more

That shows a somewhat manual way of setting this up: installing the original OS by hand, then running a shell script to configure that OS. Since Tanium Provision supports capturing and deploying an image of a Linux system, I can either capture an already-configured kiosk install, or for more flexibility, I can capture a more generic image and then customize it using Cloud-Init (which works great even outside of the cloud, e.g. on a physical kiosk PC).

When creating an OS bundle with a Linux image in Tanium Provision, you can specify the cloud-init configuration file that you want to use. This is a YAML file, and we provide a very basic example:

password: password
- [ bash, /_t/ ]

That configures the root password, and then runs a script to install the Tanium client (since you want the OS to be properly managed). So how would we extend that to configure the kiosk? With a few more lines added:

password: %AdminPassword%
- [ bash, /_t/ ]
- [ bash, chmod +x /_t/ ]
- [ bash, /_t/ ]
  delay: now
  mode: reboot

This does the same steps as before, with new steps that mark the script as executable (it gets extracted from a zip file, and depending on where you captured that zip file, it might not have preserved that attribute), execute the script, and then automatically reboot. The end result (sped up to 8x speed, otherwise it would be 4 minutes instead of 30 seconds):

All done. But you can see one other thing in this screen capture: We boot into an even-smaller Linux boot image via PXE, and it runs completely from RAM. At just over 400MB, it contains the OS, network drivers (wired and wireless), and a WebKit (Safari) image. Using something like that, the device doesn’t even need a disk — everything can be kept in RAM. Maybe a future blog post can show how to create that…

Categories: Linux

Tagged as: ,