Home Wiki > SDB:KIWI Cookbook Kiosk System
Sign up | Login

SDB:KIWI Cookbook Kiosk System

tagline: From openSUSE


Using the Minimum GNOME example as a base to make appropriate modifications in order to create an image that may be used as a web-kiosk.
Icon-checked.png This procedure was tested on at least Kiwi version 3.25 ( kiwi --version ) - older version did not support all shown features Version


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.

WEB_KIOSK


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.

cp -r /usr/share/doc/packages/kiwi/examples/suse-11.2/suse-min-gnome /tmp/web-kiosk

If you are working on openSUSE 11.1 use the openSUSE 11.1 suse-min-gnome example. The difference between working on openSUSE 11.1 and openSUSE 11.2 is in the configuration of the X-server. In openSUSE 11.2 the X-Server uses auto configuration and thus there is no boot.local overlay file in the root tree.

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:

  1. In the "services section" of the file add
    1. suseInsertService sshd
  2. In the SUSEConfig section add
    1. baseUpdateSysConfig /etc/sysconfig/displaymanager DISPLAYMANAGER_AUTOLOGIN kioskuser
    2. 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>

The config.xml file above will only work with versions of Kiwi less than 4.1. With Kiwi 4.1 incompatible changes were introduced and the config.xml file does no longer get upgraded automatically. Therefore, manual intervention is required.

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

Watch your line breaks, you might want to remove the escape (\) characters and put everything on one line. The line breaks were inserted to make the wiki look at bit prettier.

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:

mkdir -p /tmp/web-kiosk/root/etc/gconf/gconf.xml.mandatory
cd /tmp/web-kiosk/root/etc/gconf/gconf.xml.mandatory
mkdir -p apps/metacity/{general,global_keybindings,keybinding_commands}
mkdir -p apps/nautilus/preferences
mkdir -p desktop/gnome/{lockdown,session}
mkdir desktop/gnome/session/required_components
touch apps/%gconf.xml
touch apps/metacity/%gconf.xml
touch apps/nautilus/%gconf.xml
touch desktop/%gconf.xml
touch desktop/gnome/%gconf.xml
touch desktop/gnome/session/%gconf.xml

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.

mkdir -p /tmp/web-kiosk/root/home/kioskuser/.config/autostart
cd /tmp/web-kiosk/root/home/kioskuser/.config/autostart

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>

You can point Firefox at any URL, if you want your web kiosk to have Google search as the home page just add the URL in the .desktop file instead of the kioskdemoHome.html file location

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.

cd /tmp
kiwi --prepare ./web-kiosk --root /tmp/web-kiosk_unpacked
kiwi --create ./web-kiosk_unpacked -d /tmp/web-kiosk-img

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:

kiwi --create ./web-kiosk_unpacked -d /tmp/web-kiosk_img --type oem

Once you have the USB image use dd to dump it onto a stick.

  1. plugin the stick
  2. determine the dev of the stick using fdisk -l
    1. It should be fairly obvious which device node the stick ended up with
  3. 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.

Previously noted caveats about 64 bit images apply