Ubuntu Kiosk

This post is a work in progress. I’ll update it as I tweak the solution.

Last Wednesday I was helping a friend build a Kiosk. We tried to follow https://thepcspy.com/read/building-a-kiosk-computer-ubuntu-1404-chrome/ but it didn’t work. It turns out between using the wrong version of ubuntu (16.04 instead of 14.04) and doing it in a virtual machine, we were all messed up.

There has to be a better way.

There is a secret to debian/ubuntu packages. If you aren’t trying to get them included in debian/ubuntu, you can break most of the rules and get them to do whatever you want. I figured I should be able to use this and make creating a kiosk as easy as apt install kiosk

TL;DR: you can try this by running these two commands on a new ubuntu-server installation:

add-apt-repository ppa:evarlast/kiosk
apt install --no-install-recommends kioskme

The rest of the post describes how I did this.

First, I’m going to create a new PPA on launchpad just for this, so that a user can `add-apt-repository ppa:evarlast/kiosk`

I visit https://launchpad.net/~/+activate-ppa and fill in the fields with kiosk and click activate.

Next, I start a new deb. I may as well build it from source. There might be a better way, but I’ve gotten to know dh (debhelper) a bit, so I’m going to use it.

$ mkdir kioskme ; cd kioskme
$ cat > Makefile
<tab>echo noop
<tab>install -d 755 ${DESTDIR}/usr/bin
<tab>install -m 755 kioskme ${DESTDIR}/usr/bin/kioskme
$ cat > kioskme
xset -dpms
xset s off 
openbox-session & 
while true; do 
  rm -rf ~/.{config,cache}/chromium/ 
  chromium-browser --kiosk --no-first-run 'http://duckduckgo.com' 

Now debianize this script directory using dh_make:

dh_make -p kioskme_0.0.0 --createorig -s

Now customize the deb with a service, preinst for user creation and some dependencies:

$ cat > debian/service

ExecStart=/usr/bin/startx /etc/X11/Xsession /usr/bin/kioskme
$ cat > debian/preinst

set -e

. /usr/share/debconf/confmodule

case "$1" in
 if ! getent group kioskme >/dev/null; then
 addgroup --system kioskme >/dev/null
 if ! getent passwd kioskme >/dev/null; then
 adduser \
 --system \
 --disabled-login \
 --ingroup kioskme \
 --gecos kioskme \
 --shell /bin/false \
 kioskme >/dev/null
 mkdir -p /var/log/kioskme
 chown kioskme:kioskme /var/log/kioskme
 setfacl -m u:kioskme:rw /dev/tty0 /dev/tty7


 echo "preinst called with unknown argument \`$1'" >&2
 exit 1

# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.


exit 0

Alright, maybe that preinst is a bit big. I copy it around and fill it out like a template for services I put into debs.

Now edit the debian/control file to add dependencies, change the section to utils, fill in whatever else you want, set Depends to look like this:

Depends: ${shlibs:Depends}, ${misc:Depends}, Xorg, openbox, chromium-browser, pulseaudio

Now create the deb:

fakeroot debian/rules clean build binary

To test the deb, I copy it to a fresh ubuntu server install and dpkg -i to install it. I get a bunch of errors because dpkg -i doesn’t resolve dependencies, but I run apt install -f and the dependencies are installed.

Once I tested and tweaked and got things working, I updated the tarball `tar -Jcf ../kioskme_0.0.0-0.orig.tar.xz -C ..  –exclude=’debian’ kioskme` and I used dpkg-buildpackage -S to build a source package and then I used dput ppa:evarlast/kiosk ../kioskme_0.0.0-1_source.changes to upload to PPA.

Now, this still does not work in a VM. Ubuntu desktop installer must do some magic to make X work in a virtual machine with a driver which works with VMWare, VirtualBox, or Parallels.


Some LXD containers on a hidden net, others on your lan

Back in November I wrote about Converting eth0 to br0 and getting all your LXC or LXD onto your LAN

It works, but you might not want ALL of your LXD on your LAN.

You’ll still need your LAN interface to be a br0 instead of a device that isn’t a bridge. Go follow the Bridge your interface section of that post to convert your eth0 to br0.

I’ve fully converted to using LXD. I don’t even remember if LXC supports profiles. I think it does, so I think the same idea could be applied to LXC, but I’m only showing this for LXD.

First, copy the default profile:

lxc profile copy default lanbridge

Second, edit the new profile to use br0 instead of lxdbr0:

lxc profile device set lanbridge eth0 parent br0

Third and finally, start instances with that profile:

lxc launch ubuntu-xenial -p lanbridge

In my case, this instance is on my local lan AND on public ipv6 space (thanks Comcast).

heritable-gale    | RUNNING | (eth0) | 2601:400:8000:5ab3:216:3eff:fe73:d242 (eth0)