a Linux Kiosk system

One Trick Pony : WWW

This is part of an experiment to use Linux as a kiosk system. 'Kiosk System' can mean a couple of things, but here we assume that it's a computer that runs just one application - a web browser - and does not allow the user to do anything else but use that browser. That way, the computer can be left unattended, e.g. in public places (public libraries, ... )

One of the appoaches often taken to accomplish this, is to install Windows, then lock it down and present the user with a limited menu-like user interface - often with specilised software (e.g. WinU). But that feels a bit like wasting resources and money : you'd have to buy a Windows License for a computer that will hardly be used (just a browser ...), and on top of that you pay for additional software to make it run nothing but that one browser. So we looked at it from a different angle : is this something Linux could do, without all the overkill ?

What do we need ?

To run just a web browser we don't need a full-blown desktop : a minimal x-windows system will do : all we need is 1 window in which the browser can run. This approach is also used in this "minimal GUI" setup for a Linux server where we provide a web browser to take advantage of the graphical front-ends to configure the system. Building on that approach, we will set up a base Linux system (install nothing but the operating system - e.g. Debian 3) and add some x-window components so that we can run a web browser (firefox).

Assuming this computer will be unattended, we don't want users to go and play with it, and we definitly don't want users to crack it or try to get escalate their privilegues or install their own software so that the machine becomes a zombie or what not - so we deny them all access to the system. For this, we use 'Bastille'. Bastille is a program that takes you trough the motions of locking down the system. (see Bastille home)

Finally, we want everything to work more or less automaticvally, so we'll take advantage of runlevels and startup scripts.

Installing the software and basic configuration

the base setup

We install nothing but a base system, then add the packages we need / want. The os used here is Debian 3.0, network installation. We add bastille, firefox, and some components from the x-windows system : just enough to create windows and provide a GUI logon for the user. We also add ssh for remote administration by root and vim to edit text files.

apt-get install x-window-system fvwm vim ssh 

System requirements : any pc capable of running (text mode) linux + xwindows. Hard disk space : ... mb (system + software) + swap + room for browser cache /temporary files. Meaning : any old pc will do.

create a user account

We create 1 user (www) with password www. This account will be used to use the PC as a web client.

	useradd -m -s /bin/false -p `mkpasswd www SD` www

the windows setup

Setting up X-windows means you will have to provide some input (monitor, keyboard, mouse, ...). To modify the configuration : dpkg-reconfigure xserver-xfree86 , or edit the configuration file (/etc/X11/X86config-4).

The configuration of the windows environment is found in the user's home directory (~/.xinitrc), and if that is missing, the system default is used :/usr/X11R6/lib/X11/xinit/xinitrc (re. XFree86 HOWTO). (On Debian) all this xinitrc does is call /etc/X11/Xsession, which in turn refers to files in /etc/X11/Xsession.d and ~/.Xsession. In /etc/X11/Xsession.d we find a script 99xfree86-common_start with an exec $STARTUP statemenent. Assuming that this is where we can put the programs we want to run in X, we replace exec $STARTUP with 'exec firefox'. This way, Firefox will start as soon as the xserver is started, and closing Firefox will stop the xwindows session as well.

To do :
find a way to force height and width on Firefox. We want it fullscreen. "firefox -height 600 -width 800" should work ? Workaround : run firefox once, configure preferences and windows - it will use those settings the next time

the runlevels

You may now find that your system now offers a graphical login and starts Firefox rightaway which is what we wanted anyway, except that root prefers a command prompt to set up the system firther. So we change the default runlevel to 3 (in /etc/inittab) and disable the X startup scripts in rc2.d (runlevel 2). Now, the system will boot to runlevel 3 (with GUI login for user www and Firefox started immediately) - root can boot init 2 for a command prompt and no worries.

the bonus

While you have now have a GUI, why not include a screensaver ? 'The Matrix' is a nice one.

the Bastille

Bastille is a program that will walk you through a large number of configuration settings to make your system more secure. Some have to do with networking, e.g. it sets up a firewall which - in the case of a web kiosk - should only allow outgoing http, and accept only replies to outgoing traffic. Another set of settings secures the system as such, by means of 'chroot', modyfing some file system permissions, and tightening the use of SUID. One feature is extremely useful for an unattended PC : setting a (root) password to runlevel 1 ('single user mode', 'root mode', 'recovery mode'; 'maintenance mode'). In single user mode, one could reset the root password and consequently log on as root - clearly a threath for an unattended computer : just pull the plug or hit the power button and you bypass all security, even with ctrl+alt+del disabled and shutdown/reboot only available to the root user.

Another point is the disabling of printers and /or give the ability to manage print jobs to root only. You'll have to figure this out depending on what this PC will be used for and whether the www user needs printing or not. In this locked down Ubunto/Gnome desktop kiosk system are some details about appropriate settings.


The web front-end of a major company's application site, running on a cluster of Citrix Metaframe servers
and presented on a "firefox only" linux system.

Things to do ...

Still needs some work :
to do : make sure that firefox is limited (e.g. don't allow browsing the filesystem ?). Establish 'ideal' firefox configuration and set it (preferences, history, cookies, ...). Privacy of consecutive users ? Import a predefined Firefox profile ? Firefox lockdown.

Roll-up : automate this

automate it : put all of the above in a script.


	echo starting KIOSK setup 
	sleep 3

	# reconfigure the base system if needed
	# /usr/sbin/base-config
	#download and install software
	apt-get update
	apt-get install aptitude vim ssh
	apt-get install x-window-system twm
	aptitude install --with-recommends bastille
	aptitude install --with-recommends mozilla-firefox
	#apt-get clean

	#reconfigure the x-server in case you missed something (keyboard layout, ...)
	#dpkg-reconfigure xserver-xfree86

	#create a user:password www:www
	useradd -m -s /bin/false -p `mkpasswd www SD` www
	tail -n1 /etc/passwd					#just checking
	tail -n1 /etc/shadow
	sleep 2				

	#manage runlevels and xwindows environment
	#+ quick&dirty : replace 99xfree86-common_start completely
	echo exec firefox > /etc/X11/Xsession.d/99xfree86-common_start

	#+ no GUI in runlevel 2
	mv /etc/rc2.d/S99xdm /etc/rc2.d/s99xdm
	mv /etc/rc2.d/S20xfs /etc/rc2.d/s20xfs
	mv /etc/rc2.d/S20xprint /etc/rc2.d/s20xprint`
	ln -s /etc/init.d/xdm /etc/rc2.d/K01xdm

	#run bastille to lock down the system
	#+ interactive run, save a copy of config in /root for future use in unattended mode
	echo starting bastille in interactive mode 
	echo this will take some time and you'll have to answer a lot of questions
	sleep 4
	bastille -c 
	cp /etc/Bastille/config /root/bastille_config || echo failed to safe copy of bastille config file
	cp /var/log/Bastille/TODO /root/bastille_todo || echo failed to safe copy of bastille to do list
	less /var/log/Bastille/TODO

	#+ alternative : run bastille preconfigured ; requires conf file from previous interactive setup
		#need to copy config file to /etc/Bastille first - from where if this is a virgin system ? USB stick ? CD ?
		#bastille -b

	# changing default runlevel
	cp /etc/inittab /etc/inittab.rmwebterm
	sed -i -e 's/id:2:initdefault:/id:3:initdefault:/'  /etc/inittab

	exit 0

Check Out

Koen Noens
October 2005