SDB:KIWI Cookbook Kiosk System
All of KIWI edit
Creating a Web-Kiosk image
In this example we combine various topics discussed previously to create an image that is a bit more functional. While the example does not yield a fully functional web-kiosk (some additional customization and hardening would be required), the image created is very close to a deployable system.
Create a Web-Kiosk image
Prep Time:
- 45 min
Cook Time:
- 20 min
Ingredients:
- a running openSUSE 11.1 or 11.2 system
- an openSUSE 11.1 or 11.2 repository
- installed recent release of the KIWI toolset (at least version 3.93)
- installed kiwi-doc package
- about 1 GB free disk space
The example uses the suse-min-gnome example located in /usr/share/doc/packages/kiwi/examples/suse-11.x/suse-min-gnome as a starting point. From there we will make some significant modifications to achieve our goal.
Creating the KIWI configuration tree
As mentioned above we will use the suse-min-gnome example discussed in Live_USB-Stick Recipe as our baseline. Therefore the initial creation of the configuration tree is a simple copy.
Modifying config.sh
First we will modify the config.sh file to suit our needs. Edit /tmp/web-kiosk/config.sh in your favorite editor and make the following modifications:
- In the "services section" of the file add
- suseInsertService sshd
- In the SUSEConfig section add
- baseUpdateSysConfig /etc/sysconfig/displaymanager DISPLAYMANAGER_AUTOLOGIN kioskuser
- baseDisableCtrlAltDel
We need to start the ssh service to allow us to remotely access the system once it is up an running as there will be no access to a terminal from the running image. We are also configuring the user kioskuser for auto login and the call to the baseDisableCtrlAltDel function disables the Ctrl-Alt-Delete key sequence, i.e. we are disabling a forced reboot from the keyboard.
With these changes the new config.sh file should look as follows:
#!/bin/bash #================ # FILE : config.sh #---------------- # PROJECT : OpenSuSE KIWI Image System # COPYRIGHT : (c) 2006 SUSE LINUX Products GmbH. All rights reserved # : # AUTHOR : Marcus Schaefer <ms@suse.de> # : # BELONGS TO : Operating System images # : # DESCRIPTION : configuration script for SUSE based # : operating systems # : # : # STATUS : BETA #---------------- #====================================== # Functions... #-------------------------------------- test -f /.kconfig && . /.kconfig test -f /.profile && . /.profile #====================================== # Greeting... #-------------------------------------- echo "Configure image: [$kiwi_iname]..." #====================================== # Activate services #-------------------------------------- suseActivateDefaultServices suseInsertService boot.device-mapper suseInsertService sshd #====================================== # SuSEconfig #-------------------------------------- baseUpdateSysConfig /etc/sysconfig/displaymanager DISPLAYMANAGER_AUTOLOGIN kioskuser baseUpdateSysConfig /etc/sysconfig/displaymanager DISPLAYMANAGER gdm baseUpdateSysConfig /etc/sysconfig/windowmanager DEFAULT_WM gnome baseDisableCtrlAltDel baseSetRunlevel 5 suseConfig #====================================== # Umount kernel filesystems #-------------------------------------- baseCleanMount exit 0
Modifying config.xml
Now we will modify the config.xml file to make the appropriate changes for our web-kiosk. Edit /tmp/web-kiosk/config.xml and apply the following changes:
- Change the name attribute of the image
- <image schemaversion="3.8" name="suse-11.2-web-kiosk-demo">
- Change the value of the specification element
- <specification>openSUSE 11.2 Web kiosk appliance</specification>
- Remove the iso image type
- <type boot="isoboot/suse-11.2" flags="unified">iso</type>
- Add an OEM image type with the USB format
- <type filesystem="ext3" boot="oemboot/suse-11.2" format="usb">oem</type>
- Change the user tux to be the kioskuser
- <user pwd="$1$wYJUgpM5$RXMMeASDc035eX.NbYWFl0" home="/home/kioskuser" name="kioskuser"/>
- Remove the lines pulling in gnome-applets, Perl, and Python
- <package name="gnome-applets"/>
- <package name="perl"/>
- <package name="python"/>
Making a wild guess that the web-kiosk hardware will not have an optical drive for installation we create a self installing image on USB stick by adding the OEM type with format USB.
An oem image is a virtual disk image representing all partitions and bootloader information as it exists on a real disk. This image can then be dumped to physical storage using the dd command. By specifying the format attribute we instruct kiwi to create this OEM image in a way that is suitable for a USB stick that may then be used to install the disk image. The result is a USB stick that will install our kiosk image on the target machine when used as a boot device. In this process all data on the target installation device is lost. For more information about the OEM image type see the KIWI Image System Cookbook in /usr/share/doc/packages/kiwi/kiwi.pdf, installed with the kiwi-doc package or the online version found here.
The configuration also describes the VMware image type which we will use for testing purposes.
With changes applied your configuration file should looks as follows:
<?xml version="1.0" encoding="utf-8"?> <image schemaversion="3.8" name="suse-11.2-web-kiosk-demo"> <description type="system"> <author>Robert Schweikert</author> <contact>rschweikert at novell dot com</contact> <specification>openSUSE 11.2 Web kiosk appliance</specification> </description> <preferences> <type primary="true" filesystem="ext3" boot="vmxboot/suse-11.2" format="vmdk">vmx</type> <type filesystem="ext3" boot="oemboot/suse-11.2" format="usb">oem</type> <version>1.0.1</version> <packagemanager>zypper</packagemanager> <rpm-check-signatures>false</rpm-check-signatures> <rpm-force>true</rpm-force> <locale>en_US</locale> <keytable>us.map.gz</keytable> </preferences> <users group="users"> <user pwd="$1$wYJUgpM5$RXMMeASDc035eX.NbYWFl0" home="/home/kioskuser" name="kioskuser"/> </users> <users group="root"> <user pwd="$1$wYJUgpM5$RXMMeASDc035eX.NbYWFl0" home="/root" name="root"/> </users> <repository type="yast2"> <source path="opensuse://11.2/repo/oss/"/> </repository> <packages type="image" patternType="plusRecommended" patternPackageType="plusRecommended"> <package name="bootsplash"/> <package name="bootsplash-branding-openSUSE" bootinclude="true" bootdelete="true"/> <package name="firefox"/> <package name="gdm"/> <package name="gfxboot-branding-openSUSE" bootinclude="true" bootdelete="true"/> <package name="ifplugd"/> <package name="iputils"/> <package name="kernel-default"/> <package name="preload"/> <package name="vim"/> <package name="xorg-x11-server"/> <opensusePattern name="base"/> </packages> <packages type="vmware"> </packages> <vmwareconfig memory="1024"> <vmwaredisk controller="ide" id="0"/> </vmwareconfig> <packages type="bootstrap"> <package name="filesystem"/> <package name="glibc-locale"/> </packages> </image>
config.xml for Kiwi 4.1 or greater
<?xml version="1.0" encoding="utf-8"?> <image schemaversion="4.1" name="suse-11.2-web-kiosk-demo"> <description type="system"> <author>Robert Schweikert</author> <contact>rschweikert at novell dot com</contact> <specification>openSUSE 11.2 Web kiosk appliance</specification> </description> <preferences> <type image="vmx" primary="true" filesystem="ext3" boot="vmxboot/suse-11.2" format="vmdk"> <vmwareconfig memory="1024"> <vmwaredisk controller="ide" id="0"/> </vmwareconfig> </type> <type image="oem" filesystem="ext3" boot="oemboot/suse-11.2" format="usb"/> <version>1.0.1</version> <packagemanager>zypper</packagemanager> <rpm-check-signatures>false</rpm-check-signatures> <rpm-force>true</rpm-force> <locale>en_US</locale> <keytable>us.map.gz</keytable> </preferences> <users group="users"> <user pwd="$1$wYJUgpM5$RXMMeASDc035eX.NbYWFl0" home="/home/kioskuser" name="kioskuser"/> </users> <users group="root"> <user pwd="$1$wYJUgpM5$RXMMeASDc035eX.NbYWFl0" home="/root" name="root"/> </users> <repository type="yast2"> <source path="opensuse://11.2/repo/oss/"/> </repository> <packages type="image" patternType="plusRecommended" patternPackageType="plusRecommended"> <package name="bootsplash"/> <package name="bootsplash-branding-openSUSE" bootinclude="true" bootdelete="true"/> <package name="firefox"/> <package name="gdm"/> <package name="gfxboot-branding-openSUSE" bootinclude="true" bootdelete="true"/> <package name="ifplugd"/> <package name="iputils"/> <package name="kernel-default"/> <package name="preload"/> <package name="sax2"/> <package name="vim"/> <package name="xorg-x11-server"/> <opensusePattern name="base"/> </packages> <packages type="vmware"> </packages> <packages type="bootstrap"> <package name="filesystem"/> <package name="glibc-locale"/> </packages> </image>
Creating the overlay files
With the configuration file and the configuration script all set up it is time to create the overlay files for our web kiosk.
We will need to further lock down the system. We want to disable keyboard shortcuts, so far we have only disabled Ctrl-Alt-Delete, and we need to start Firefox automatically on startup.
Disable X-Server restart
Disabling a keyboard forced X-Server restart, i.e. the Ctrl-Alt-Backspace key combination, is accomplished via the xorg.conf file in /etc/X11. As previously noted there are differences between the distribution versions. With openSUSE 11.2 and later distributions the X-Server uses auto-configuration, while earlier distributions have a static configuration via a complete xorg.conf file.
X-Server auto-configuration settings (openSUSE 11.2 and later)
With X-server auto-configuration the /etc/X11/xorg.conf file is still parsed, however the neat trick as that the file does not have to be complete. This means we only create the section we need in the file and leave the rest to the auto-configuration mechanism.
Create the file /tmp/web-kiosk/root/etc/X11/xorg.conf with the following content:
Section "ServerFlags" Option "DontZap" "yes" Option "DontVTSwitch" "yes" EndSection
With this we disable the virtual consoles and the Ctrl-Alt-Backspace key sequence.
X-server static configuration (openSUSE 11.1 and earlier)
First lets get rid of any default configuration that might exist. Edit /tmp/web-kiosk/config.sh and add rm -f /etc/X11/xorg.conf after the call to suseConfig. Below is the snipped of the file showing the new line.
baseDisableCtrlAltDel baseSetRunlevel 5 suseConfig # Remove the default xorg.conf file rm -f /etc/X11/xorg.conf
Not to worry, we will configure the X-server the system initially boots. This step is next. Edit /tmp/web-kiosk/root/etc/init.d/boot.local. If you copied the suse-min-gnome example from 11.1 this file already exists. Into this file we will insert some sed magic to get the desired effect. The following shows the file with the added sed command.
#! /bin/sh # # Copyright (c) 2009 Novell Inc. # # Author: Robert Schweikert <rschweikert@novell.com> # # Create the X-server configuration file if it does not yet exist if [ ! -f /etc/X11/xorg.conf ]; then /usr/sbin/sax2 -c 0 -a -i &>/dev/null /usr/bin/sed -i 's/Section "ServerFlags"/Section \ "ServerFlags"\n Option "DontZap" "yes"\n \ Option "DontVTSwitch" "yes"/' /etc/X11/xorg.conf
GNOME settings
Back to uniformity between the 11.x based distributions, hurray. GNOME behavior is configured via a configuration tree. For user customizations this configuration tree lives in $HOME/.gconf. System wide configuration lives in /etc/gconf/<some-directory>. The changes we are interested in are such that they cannot be changed by anyone or through the user interface. Thus our configuration changes end up in gconf.xml.mandatory. For more on GNOME configuration see Locking down GNOME in SUSE 11 based distributions. In /tmp/web-kiosk/root/etc/gconf/gconf.xml.mandatory we want to create the following tree:
./apps ./apps/%gconf.xml ./apps/metacity ./apps/metacity/%gconf.xml ./apps/metacity/general ./apps/metacity/general/%gconf.xml ./apps/metacity/global_keybindings ./apps/metacity/global_keybindings/%gconf.xml ./apps/metacity/keybinding_commands ./apps/metacity/keybinding_commands/%gconf.xml ./apps/nautilus ./apps/nautilus/%gconf.xml ./apps/nautilus/preferences ./apps/nautilus/preferences/%gconf.xml ./desktop ./desktop/%gconf.xml ./desktop/gnome ./desktop/gnome/%gconf.xml ./desktop/gnome/lockdown ./desktop/gnome/lockdown/%gconf.xml ./desktop/gnome/session ./desktop/gnome/session/%gconf.xml ./desktop/gnome/session/required_components ./desktop/gnome/session/required_components/%gconf.xml
The following commands will get us going:
Next we need to create the %gconf.xml files that are not empty.
Edit apps/metacity/global_keybindings/%gconf.xml
In this file we disable some of the global keybindings (as the location suggests). Add the following content to the file. The names indicate what keybinding is being disabled.
<?xml version="1.0"?> <gconf> <entry name="cycle_panels" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> <entry name="cycle_panels_backwards" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> <entry name="panel_main_menu" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> <entry name="panel_run_dialog" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> <entry name="run_command_screenshot" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> <entry name="run_command_window_screenshot" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> <entry name="switch_group" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> <entry name="switch_panels" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> <entry name="switch_to_workspace_down" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> <entry name="switch_to_workspace_left" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> <entry name="switch_to_workspace_right" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> <entry name="switch_to_workspace_up" mtime="1263563592" type="string"> <stringvalue>disabled</stringvalue> </entry> </gconf>
Edit apps/metacity/keybinding_commands/%gconf.xml
In this file the commands to be executed on a given keybinding are set. Since we want to lock the system down we clear all the commands. Create the following content in the file:
<?xml version="1.0"?> <gconf> <entry name="command_screenshot" mtime="1263563592" type="string"> <stringvalue></stringvalue> </entry> <entry name="command_window_screenshot" mtime="1263563592" type="string"> <stringvalue></stringvalue> </entry> </gconf>
Edit apps/nautilus/preferences/%gconf.xml
In this configuration we control the behavior of nautilus, nautilus is more than just the file browser in GNOME, it also controls part of the desktop.
<?xml version="1.0"?> <gconf> <entry name="show_desktop" mtime="1263563592" type="bool" value="false" /> </gconf>
With this setting we disable the nautilus features that mingle with the desktop display.
Edit desktop/gnome/lockdown/%gconf.xml
Now we will set some GNOME global options.
<?xml version="1.0"?> <gconf> <entry name="disable_command_line" mtime="1263563592" type="bool" value="true" /> <entry name="disable_printing" mtime="1263563592" type="int" value="0" /> <entry name="disable_print_setup" mtime="1263563592" type="bool" value="false" /> <entry name="disable_user_switching" mtime="1263563592" type="bool" value="false" /> </gconf>
Edit desktop/gnome/session/required_components/%gconf.xml
With this file we can control the GNOME components started when the GNOME desktop starts. In our case we will disable the panel.
<gconf> <entry name="panel" mtime="1263563592" type="string"> <stringvalue></stringvalue> </entry> </gconf>
Finishing touches
With the system locked down we now want to get Firefox started when the system boots, remember the kioskuser is already setup for autologin based on our changes in config.sh.
Lets first create the setup to autostart Firefox. We need the autostart directory and a .desktop file.
Create the file firefox.desktop with your favorite editor with the following content.
[Desktop Entry] Type=Application Name=Firefox Exec=firefox file:///home/kioskuser/kioskdemoHome.html Icon= Comment=
Also create the home page file /tmp/web-kiosk/root/home/kioskuser/kioskdemoHome.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>KIWI Kiosk Demo</title> </head> <h1>KIWI Kiosk Demo</h1> This is a placeholder page to demo the Kiosk set up. Adding your own page here with a link to the Internet will provide the Internet Kisok setup functionality. <p> For this demo the Firefox <a href="https://addons.mozilla.org/en-US/firefox/addon/1659">Kiosk Mode plugin</a> has been installed. </body> </html>
Last but not least we need to deal with Firefox. There are various ways to lockdown Firefox. One relatively simple way is to use the Kiosk Mode plugin. The question of course is how do we get the plugin into the kioskuser home directory?
The simple and straight forward way if to create a new user on your running system, login as the user, start Firefox and install the plugin. Then log back in as yourself and copy the .mozilla directory from the new user on your system into /tmp/web-kiosk/root/home/kioskuser. You can apply this trick to a user in virtual machine if you would rather not mess with your running system. In any event the idea is the same.
That's it. Time to build and test out web-kiosk image.
This will create the VMware image that is configured as the default. To create the self installing USB stick image add the --type oem command line option to the create command as follows:
Once you have the USB image use dd to dump it onto a stick.
- plugin the stick
- determine the dev of the stick using fdisk -l
- It should be fairly obvious which device node the stick ended up with
- dd if=/tmp/web-kiosk_img/suse-11.2-web-kiosk-demo.x86_64-1.0.1.raw.install.raw of=/dev/<stick-node> bs=32k
The USB stick can then be used to boot any system and install the web-kiosk image.