The original requirement was for a collection of 4 touchscreen information stands in a NHS hospital (providing information such as maps/”You are Here”, patient information etc.). It was absolutely critical that the system could not be hacked and that content was limited. The kiosks were to serve information from a local web server but some of the content being provided was from pages on the Internet. To that end, a further requirement was locking access to sites, only sites and content in a safe “whitelist” were to be served, making it necessary to block attempts to retrieve any other Internet content.
Approach
A custom distribution of the Linux Operating System was built called KiOS (abbreviation for Kiosk Operating System). KiOS is a custom distribution of Linux (based on SuSE / built using SuSE Studio) intended for usage in the Kiosk environment. There are 2 variants, one for the clients and one for the server. Rolling back in time, the solution “rough cut” was as follows:
- Content via web browser. Browser must not have any controls (file menu, address bar, right click etc.), downloads or similar.
- The Kiosk must not allow access to the underlying operating system and the browser must not be closed.
- The Kiosk will connect to the network via DHCP.
- The Server will always assign the same IP address to the same MAC (allowing for “you are here” to function).
- The Server runs a whitelist of allowed sites, requests to any other content are denied.
- The Server acts as a web proxy to cater for the “Internet Down” scenario.
The KiOS Operating System (for clients)
The base distribution began as follows:
- KiOS was built using SuSE Studio ( http://www.susestudio.com ).
- A base template “JeOS” (Just enough Operating System) was used.
- X11 was added as a package. Note that NO WINDOW MANAGER was used. This gives an advantage in that no window manager keyboard shortcuts are available/no update manager alerts are given etc.
- The Flash player was also added (optional and not necessarily desired in every scenario).
- The firewall was setup to block ALL incoming requests. NO PORTS are open.
- The OS was set to load at run level 3 (normal non-graphical console).
The KiOS disk image is written to a USB pendrive. The system is set to boot off USB. No hard disk is required. This also benefits in that the “worst case scenario” typically requires just a reboot. If that fails, the pendrive can be removed and inspected or simply re-flashed. The pendrive in the real kiosk is locked away behind a secure panel.
The first time the OS boots it performs setup (network, graphics etc.). We then run a script to secure the GRUB boot menu and make the “default” option boot immediately:
if [ -f /etc/init.d/suse_studio_firstboot ] then # Lets protect our lovely grub... echo "Running KiOS first boot script..." cat /boot/grub/menu.lst | grep -v timeout > /boot/grub/menu.tmp cat /home/kiosk/menu.lst /boot/grub/menu.tmp > /boot/grub/menu.new mv /boot/grub/menu.lst /boot/grub/menu.old mv /boot/grub/menu.new /boot/grub/menu.lst fi
In short, remove the standard timeout of 10 seconds. Then paste the contents of a second file at the start of the menu. The second file contains the following:
timeout 0 hiddenmenu password --md5 <hash>
Effectively hiding the menu by default, causing immediate boot to the default option, and (worst case) if someone does intercept the menu a password is required to edit any options.
Also, on first boot, a number of files are overlaid into the operating system:
/home/kiosk/.bashrc contains a simple “exec startx”. EXEC replaces the shell. Thus, if X dies, the kiosk user is logged out. /home/kiosk/.xinitrc starts Opera in Kiosk mode with a number of options. Namely – full screen, no keyboard shortcuts, no menu, no toolbar, no address bar, no saving, no printing, no downloading, no right click/context menu, a reset flag (if the kiosk is left unattended, return to the home page after a given interval), no “mailto” links, no history, clear the cache on exit, no ctrl-alt-del etc. /home/kiosk/opera.tar.gz is restored to /home/kiosk/ creationg a directory called .opera with one file – opera6.ini – containing other Opera preferences to lock down the web browser ( for more information see http://www.opera.com/support/mastering/kiosk/ ). This also has a knock on effect in that it tricks Opera into believing this is not the first execution – the EULA does not appear as one would normally expect. A new version of inittab is copied over to /etc/ that forces run level 3, turns off all TTYS (ctrl-alt-F1 etc.), and automatically logs in the kiosk user. This combination now means that if Opera is killed, X dies, user is logged out and re-logged in automatically (i.e., the browser simply reappears!). Ditto if Ctrl-Alt-Backspace is hit twice (this was left in as a tidy way of restarting Opera if it crashes). A replacement xinitrc.common is copied to /etc/X11/xinit/ – the only difference being the suppression of an error message (by default, on login, a dialog appears complaining that no window manager has been found).The user can still Ctrl-Alt-F1 (etc.) but the terminals are all dead aside from the one running Opera. Anything killing Opera results in a logout/login/startx/start opera. In the real world – the keyboard on the kiosk has no Ctrl or F keys – but, it is still better to cater for every eventuality (keyboard!).
KiOS without a Server
If KiOS is to be used in an environment without a server Opera can be configured to handle the whitelist/blacklist:
- Exit Opera
- Define a filter file in opera:config
- Create a filter file if it does not exist already
- Make an [exclude] section listing the URLs to block
- Make an [include] section listing the URLs to allow
- Restart Opera
Example limiting access to just one site:
[prefs] prioritize excludelist=0
[include] http://???.opera.com/*
[exclude] *
Dealing with the USB stick and what happens if SuSE remove the Studio service?
The raw disk image is written to the USB stick with the following command:
sudo dd if=/home/garyr/Desktop/KioS/KiOS.i686-1.1.11.raw of=/dev/sdb bs=4k
If the USB will not boot:
umount /dev/sdb1 fdisk /dev/sdb \tp «--- print partition table \ta «--- activate partition (bootable) \t1 «--- partition 1 is bootable \tw «--- write changes to partition table
The disk image can be modified without using Studio as follows:
mount -oloop,offset=32256 discimage.raw /mnt/
Key File Contents
.bashrc:
clear exec startx
.xinitrc:
opera -kioskmode -nowin -resetonexit -nosplash -nosave -noprint -nomenu -nomaillinks -nomail -nokeys -nocontextmenu -kioskresetstation -nodownload
inittab (selected entries only):
id:3:initdefault: ... 1:2345:respawn:/sbin/mingetty --noclear --autologin kiosk tty1 ... #2:2345:respawn:/sbin/mingetty tty2 #3:2345:respawn:/sbin/mingetty tty3 #4:2345:respawn:/sbin/mingetty tty4 #5:2345:respawn:/sbin/mingetty tty5 #6:2345:respawn:/sbin/mingetty tty6
xinitrc.common (basically delete a block):
# # Error, no Window Manager found. Normally the exit # raises the fallback trap of the sourcing script. # ...error dialogue removed leaving just: exit 1
menu.lst and first boot:
See earlier
opera6.ini (selected entries only, proxy settings also go in here):
[User Prefs] Language File=/usr/share/opera/locale/en-GB/british.lng Preferences Version=2 Has Restored MIME Flag=1 Trust Server Types=0 Check For New Opera=0 DevTools Splitter Position=500 History View Style=0 Open Page Next To Current=0 Last Used Auto Window Timeout=60 Enable Wand=0 Show Startup Dialog=0 Startup Type=2 Home URL=http://www.google.com Ignore Target=1 Target Destination=3 Ignore Unrequested Popups=0 Keyboard Configuration=/usr/share/opera/ini/standard_keyboard.ini Enable Gesture=0 Mouse Configuration=/usr/share/opera/ini/standard_mouse.ini Window Cycle Type=0 Use Thumbnails in Window Cycle=0 Use Thumbnails in Tab Tooltips=1 Activate Tab On Close=0 ...snip... Visited Pages=0 Accept Cookies Session Only=1 Enable Cookies=3 Toolbar Configuration=/home/kiosk/.opera/toolbar/standard_toolbar_1.ini AddressBar Alignment=0
[State] Accept License=1 Reading Plugins=0 Run=0
[Disk Cache] Size=20000 Enabled=1 Empty On Exit=1 Images Expiry=18000 Other Expiry=18000 Docs Modification=1 Figs Modification=2 Other Modification=2
[Special] Go Home Time Out=60
Closing Notes for the Client
- The host PC should be set to boot from USB!
- The host PC should have a BIOS password to prevent changing of the boot order.
- It may ultimately be worth disabling Ctrl-Alt all together.
- Still need to investigate SysRq ( http://en.wikipedia.org/wiki/Magic_SysRq_key ) though on first inspection the only combination that works is Alt-SysRq-o to power down.
- Navigation Issues. There is no home button, back/forward etc. In the initial application of KiOS this is not an issue as the web page being used will handle it. In other scenarios, a navigational IFRAME could be used or limited toolbar buttons re-enabled.
- Customer did not want a screen saver kicking in, the screen stays on with “touch here to start”. This was fixed by adding “xset -dpms” and “xset s off” to the xinitrc before the Opera call.
- Touch screen drivers. The package x11-input-evtouch was added to the build in SuSE Studio.
The KiOS Server Configuration
Broadly speaking, the steps involved were:
- Setup the router (firewall, make it keep IPs per MAC address etc.).
- Setup server OS including web server.
- Write the kiosk client image to USB sticks.
- Edit the USB client sticks setting the Homepage and the proxy settings:
[Proxy] Use HTTP=1 Use HTTPS=1 Use FTP=1 Use GOPHER=1 Use WAIS=1 Use Automatic Proxy Configuration=0 HTTP server=192.168.1.3:3128 HTTPS server=192.168.1.3:3128 FTP server=192.168.1.3:3128 Gopher server=192.168.1.3:3128 WAIS server=192.168.1.3:3128 Automatic Proxy Configuration URL= Enable HTTP 1.1 for proxy=0 Use Proxy On Local Names Check=0 No Proxy Servers= No Proxy Servers Check=0
- We then setup Squid (the web proxy software) to run on its default port (3128).
- Configure the white list/ACL using Squid so only sites stated are allowed:
http://en.kioskea.net/faq/sujet-804-ubuntu-installing-an-http-proxy-server-squid http://beginlinux.com/server_training/121-proxy-server/1051-squid-acls
- You can do that in your squid.conf using an acl such as:
acl whitelist dstdomain "/etc/squid/whitelist" http_access deny !whitelist ...and a whitelist that looks like... .slashdot.org .linuxquestions.org
- Another option would be to use an acl with “dst (ip-address/netmask)” instead of “dstdomain (.linuxquestions.org)”. Modify to your needs,
there are tons of other options described in the squid.conf comments. - Custom 404/redirect to HOME for sites not accessible.
- Firewall Server OS except for port 80 (web) and 22 (ssh for remote admin – will require port forwarding in router – no other outside ports should be accessible).
- Confirm all of this via both internal and external NMAP scans.
- Deploy the content to the server. Tweak as necessary. Server should be only MAC with Internet access. Everything else via proxy.
- Check IP assignment in router, force it to stay the same always, and update the “where am I” configuration accordingly
- Check squid logs to make sure clients are indeed going via proxy.