LTSP Kiosk
Introduction

Basic Setup
Server-side Changes
Client-side Changes
Adding New Clients

Additional Features
Locking FireFox
PDF Support
Background Image
Printing

Advanced Issues
Securing Connection
Client Firewall
Detect Kiosk Idle
Booting Clients Remotely

Tailored Tools

NFS over SSL

Client Setup

Kernel: NFS over TCP support

Make sure your client kernel is compiled with NFS over TCP support. If not, recompile the kernel with the option.

Add stunnel to initrd

This example uses stunnel for SSL. Thus, you have to add stunnel executable, relevant libraries, configuration file and certificate to initrd.

1) Compile stunnel or use an existing binary. This example uses stunnel 4.05. My configuration:

./configure --prefix=/usr --without-tcp-wrappers

2) Copy stunnel binary to initrd's /usr/bin, e.g.

palkki:ltsp_initrd_kit# cp /usr/src/stunnel/stunnel-4.05/src/stunnel root/usr/bin/

3) Copy relevant libraries to initrd

Firstly, check which library are needed:

palkki:ltsp_initrd_kit# ldd root/usr/bin/stunnel
libutil.so.1 => /lib/libutil.so.1 (0x4001d000)
libpthread.so.0 => /lib/libpthread.so.0 (0x40020000)
libnsl.so.1 => /lib/libnsl.so.1 (0x40035000)
libdl.so.2 => /lib/libdl.so.2 (0x40049000)
libssl.so.0.9.6 => /usr/lib/libssl.so.0.9.6 (0x4004c000)
libcrypto.so.0.9.6 => /usr/lib/libcrypto.so.0.9.6 (0x40079000)
libc.so.6 => /lib/libc.so.6 (0x40139000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

This tells you which libaries are needed by stunnel. Copy each of them to initrd tree, e.g.

palkki:ltsp_initrd_kit# cp /lib/libutil.so.1 root/lib/
... more libraries in /lib
palkki:ltsp_initrd_kit# mkdir root/usr/lib/
palkki:ltsp_initrd_kit# cp /usr/lib/libssl.so.0.9.6 root/usr/lib/
... more libraries in /usr/lib

4) Copy your certificate file to initrd's /etc

E.g.:

palkki:ltsp_initrd_kit# cp ~/HY-CA.pem root/etc/

5) Write a stunnel.conf skeleton to initrd's /etc/stunnel.conf. My configuration:

client=yes
CAfile=/etc/HY-CA.pem
verify=2
output=/dev/null
debug=0
pid=/tmp/stunnel.pid

  • Note that the linuxrc script adds the actual services (see the linuxrc hack below).
  • Note that my CAfile is HY-CA.pem, yours is probably different. Make sure that you use the certificate and its verification, since this is they key security issue here. Without the CAfile your stunnel can not be sure whether it connects to your authorised server (or a hostile one).

6) Create /dev/random and /dev/urandom devices to initrd. These devices are used by stunnel for enthropy purposes.

palkki:ltsp_initrd_kit# mknod root/dev/random c 1 8
palkki:ltsp_initrd_kit# mknod root/dev/urandom c 1 9

7) Hack linuxrc

The linuxrc has to

  • create the final stunnel configuration file
  • start the stunnel
  • do the NFS mount with added parameters

Edit the initrd's linuxrc and search the NFS mount:

echo "Mounting root filesystem: ${NFS_DIR} from: ${NFS_IP}"
mount -n -o nolock,ro ${NFS_IP}:${NFS_DIR} /mnt

Replace the mount line with the following snippet:

# NFS-SSL hack begins

# Activate lo device for 127.0.0.1 (used by stunnel)
ifconfig lo inet address 127.0.0.1 up

# Build /tmp/stunnel.conf based on /etc/stunnel.conf
echo "# This file was created by /linuxrc based on /etc/stunnel.conf" >/tmp/stunnel.conf 
cat /etc/stunnel.conf >>/tmp/stunnel.conf
echo "[portmapper]" >>/tmp/stunnel.conf
echo "accept = 127.0.0.1:111" >>/tmp/stunnel.conf
echo "connect = ${NFS_IP}:3111" >>/tmp/stunnel.conf
echo "[mountd]" >>/tmp/stunnel.conf 
echo "accept = 127.0.0.1:1025" >>/tmp/stunnel.conf
echo "connect = ${NFS_IP}:3025" >>/tmp/stunnel.conf
echo "[nfsd]" >>/tmp/stunnel.conf
echo "accept = 127.0.0.1:2049" >>/tmp/stunnel.conf
echo "connect = ${NFS_IP}:3049" >>/tmp/stunnel.conf

# Start stunnel
/usr/bin/stunnel /tmp/stunnel.conf
if [ $? -ne 0 ]; then
	echo
	echo "ERROR! Failed to execute stunnel"
	echo
	exit 1
fi

mount -n -o nolock,ro,tcp,port=2049,mountport=1025 127.0.0.1:${NFS_DIR} /mnt

# NFS-SSL hack ends

Now you're ready to run buildk script that builds the actual initrd file for you. Since the root directory is significantly larger after adding the stunnel binary and C library, you have the increase the initrd disk size from default 2500 to 5000:

Size of initrd filesystem [2500]: 5000

Make the kernel and initrd Available

Dont't forget to put your new kernel and initrd files available to your server. As explained in the Man-in-a-middle Page a proper way to do this is by SSL-secured http (https).

Server Setup

Kernel: NFS over TCP support

Make sure your client kernel is compiled with NFS over TCP support. If not, recompile the kernel with the option.

Fixed Ports for nfsd and mountd

Make sure that your nfsd and mountd listen to fixed port numbers. If the port numbers are changing, you have troubles pointing the ports to stunnel.

Check your /etc/init.d/nfs or whatever that starts the nfs services. Use following switches to set ports:

  • rpc.mountd: Set port using -p, e.g. -p 1025 (this port is used below) It is also suggested to pass parameters --nfs-version 3 and --no-nfs-version 2 to the daemon.
  • rpc.nfsd: Set port using -p, e.g. -p 2049 (this is the default port number and used below).

Protect the Ports Using stunnel

First of all, you need to have a SSL certificate signed by a CA to use stunnel. The basic idea of using stunnel in this setup is to make the clients verify the certificate and accept only servers whose certificates have been signed by certain CA. If no certificate verification is being done the setup provides no protection agains man-in-a-middle attacks.

  • Make a certificate request and get a signed certificate
  • Remove the pass phrase from your PEM key to avoid PEM passphase question while starting stunnel (see stunnel FAQ on certificates)
  • Combine the PEM and signed certificate for stunnel:
    cat newkey.pem.nopass newreq.signed >stunnel.pem
  • Start stunnel with proper switches, this example tunnels port 1025 (mountd) to 3025:
    /usr/sbin/stunnel -p /etc/stunnel/stunnel.pem -d 3025 -r 1025 -P /var/lock/stunnel.mountd
  • Do the same for nfsd:
    /usr/sbin/stunnel -p /etc/stunnel/stunnel.pem -d 3049 -r 2049 -P /var/lock/stunnel.nfsd
  • Repeat this once again for the portmapper:
    /usr/sbin/stunnel -p /etc/stunnel/stunnel.pem -d 3111 -r 111 -P /var/lock/stunnel.portmap

Please note that the stunnel examples are expecting stunnel 3.x version.

Edit /etc/exports

The LTSP installation has probably made some additions to your /etc/exports file. In my "Standard LTSP kiosk installation" each client had a line of its own in /etc/exports, e.g.:

/opt/ltsp/i386 \
	128.214.170.174(ro,no_root_squash,sync) \
	128.214.170.170(ro,no_root_squash,sync) \
	128.214.207.244(ro,no_root_squash,sync) \

Since the clients are not any more connecting the server directly but via the stunnel, the connections to the nfsd are now coming from the localhost, so add one line to the definition:

/opt/ltsp/i386 \
	127.0.0.1(ro,no_root_squash,sync,insecure) \
	128.214.170.174(ro,no_root_squash,sync) \
	128.214.170.170(ro,no_root_squash,sync) \
	128.214.207.244(ro,no_root_squash,sync) \

The insecure flag means that nfsd should allow connections from the ports that are above 1023.

Access Control

Since our clients are now communicating with mountd, nfsd and portmapper through SSL-secured ports (here 3025, 3049 and 3111), the no-secured ports (1025, 2049, 111, respectively) should be closed.

While the /etc/exports file has no longer effect what comes to allowing IP addresses to connect the server, the access restrictions should be carried out in the firewall level. In other words, the firewall should allow only specified IPs to contact SSL-secured mountd, nfsd and portmapper ports (here 3025, 3049 and 3111).

Updated: 27-MAY-2004