Description

Experiment with and implement a server (openSUSE Kubic, SUSE CaaSP) with connected thin clients (Raspberry Pi) that executes GUI applications from docker containers running on the server.

1. First experiment succeeded

Executing Firefox installed on a MicroOS host with X11 from a client (Leap 42.3)

jupiter system - experiment 1

Required packages on MicroOS to run Firefox (packages not installed on the default MicroOS installation)

  • xauth
  • iso-codes
  • libcanberra-gtk3-module
  • cantarell-fonts
  • dejavu-fonts
  • fontconfig
  • fonts-config
  • google-opensans-fonts
  • libfont-specimen0
  • libfontenc1
  • mkfontdir
  • mkfontscale
  • yast2-fonts

You can install those packages on MicroOS with the following commands

transactional-update pkg install xauth iso-codes libcanberra-gtk3-module cantarell-fonts dejavu-fonts fontconfig fonts-config google-opensans-fonts libfont-specimen0 libfontenc1 mkfontdir mkfontscale yast2-fonts

And then

reboot

to use the new snapshot

Further details

On a MicroOS installation, the file /etc/ssh/sshd_config already have the setting X11Forwarding yes. Which is needed for X11 forwarding.

2. Second experiment succeeded

Executing Firefox on a docker container on a MicroOS host with X11 from a client (Leap 42.3)

jupiter system - experiment 1

To be able to run firefox, a lot of extra work has to be done to dockerize it. So I opted for an easier application, gedit, since the important part is the X forwarding to a docker container.

2.1 Preparing the docker image opensuse/tumbleweed:gedit (to run gedit, not firefox)

#!BuildTag: jupiter-system/gedit:1.0.2-3.20.2-3.24
FROM opensuse:42.3
LABEL MAINTAINER="sergiolindo.empresa@gmail.com"
LABEL VERSION="1.0.2"
LABEL DESCRIPTION="gedit to be executed on a MicroOS server with X forwarding from a remote X-client"
LABEL GITHUB="https://github.com/SergioAtSUSE/jupiter-system"

RUN usermod --append --groups nogroup nobody

RUN zypper --gpg-auto-import-keys ref
# OBS applicances requirements
RUN zypper --non-interactive install --force-resolution libsystemd0
RUN zypper --non-interactive install --force-resolution libudev1
# X forwarding auth requirement
RUN zypper --non-interactive install --force-resolution xauth

# App and dependencies
RUN zypper --non-interactive install --force-resolution gedit=3.20.2-3.24
RUN zypper --non-interactive install --force-resolution iso-codes
RUN zypper --non-interactive install --force-resolution libcanberra-gtk3-module
RUN zypper --non-interactive install --force-resolution cantarell-fonts

# For recently open files feature
VOLUME [ "/home/nobody/.local/share" ]
# For saving documents
RUN mkdir "/permanent-data"
RUN chown nobody:nogroup "/permanent-data"
RUN chmod ug+rwxs "/permanent-data"
VOLUME [ "/permanent-data" ]

USER nobody:nogroup
WORKDIR /permanent-data
ENTRYPOINT [ "/usr/bin/gedit" ]

xauth is needed to let the docker container authenticate to the X server.

iso-codes, gtk3-modules and cantarell-fonts are dependencies needed to run gedit, that usually are already on a normal installed system.

The volume /home/nobody/.local/share is needed for the recently open files feature to work properly.

The volume /permanent-data is the dedicated volume to save files that remains even if the container is removed.

Find more info about this dockerfile on section 3.2.

2.2 Preparing the docker container

2.2.1 First connect through ssh

sergio@leap42.3:~$ ssh -X sergio@microos

2.2.2 X11UseLocalhost no

The less dangerous, but still not secure, approach to allow docker containers to access the forwarded X port is using the value FamilyWild(65535 or 0xFFFF) on the cookie-based credential for xauth inside the container.

For that to work, it is necessary to allow X forwarding to X-clients from non-localhost hostnames in /etc/ssh/sshd_config:

X11UseLocalhost no

remember to restart the sshd service

sergio@microos:~$ sudo systemctl restart sshd.service

You need now to close the ssh session and connect again with -X. To check that the non-localhost forwarding is working, check the display used

sergio@microos:~$ exit
sergio@leap42.3:~$ ssh -O exit microos # if you use ControlPersist or ControlMaster
sergio@leap42.3:~$ ssh -X sergio@microos
sergio@microos:~$ echo $DISPLAY
microos:10.0

If instead the hostname of the machine (in this case microos) localhost is shown, make sure you did all the previous steps from this section (section 2.2).

2.2.3 xauth credential FamilyWild

The less dangerous, but still not secure, approach to allow docker containers to access the forwarded X port is using the value FamilyWild(65535 or 0xFFFF) on the cookie-based credential for xauth inside the container.

To create the credentials execute

sergio@microos:~$ touch .docker.xauth
sergio@microos:~$ xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f .docker.xauth nmerge -

Notice the '-' at the end, to tell the xauth command that it should take the input from STDIN (also from the piped command) and not from the yet empty .docker.xauth file.

This will write a cookie-based credential into the file .docker.xauth. This file is on the MicroOS host. The credential will have the FamilyWild value and the existing cookie for the forwarded X display.

xauth -f .docker.xauth nmerge - will set the right permissions 600. This is important, any user with access to that file can read the cookie and so access the forwarded display (because we allowed to forward X to non-localhosts X-clients).

Since this file is not used as the Xauthority on the MicroOS host, there is no danger of X-clients outside localhost trying to access that display, unless they get the cookie.

Finally start the docker container

sergio@microos:~$ sudo docker container run --rm --name ${USER}_gedit -e DISPLAY=$DISPLAY -e XAUTHORITY=/home/sergio/.Xauthority -v ~/.docker.xauth:/home/sergio/.Xauthority --user ${UID}:nogroup jupiter-system/gedit:1.0.2-3.20.2-3.24

The container needs to have the same DISPLAY set as the ssh server (microos host), which is the forwarded one.

It also needs the XAUTHORITY set with the credential file (even if we use the standard path, the environment variable is not automatically set on docker containers by default)

The credential file is bind-mounted as the XAUTHORITY file. For security, the container is not run as the default user root, but as a regular user on the MicroOS host (sergio(1000)). The user needs to have read access to the credential file, and it is more secure to use the local user on the MicroOS host than giving rights to the nobody user inside the container or even permissions to groups or others.

WARNING: Since the Xauthority file inside the container uses the value FamilyWild, any X-client that can access the container have access to the forwarded X. The security of the docker container has to be carefully reviewed.

3 Building the docker image with OBS

3.1 Getting the build context from github

In order to get the build context from github, the obs-service-download_url is needed. This is how the _service file looks like

<services>
<service name="download_url">
  <param name="protocol">https</param>
  <param name="host">raw.githubusercontent.com</param>
  <param name="path">/software-for-life/jupiter-system/v1.0.2-3.20.2-3.24/docker-build-contexts/gedit.jupiter/Dockerfile</param>
  <param name="filename">Dockerfile</param>
</service>
</services>

3.2 Dockerfile requirements in OBS

3.2.1 Image tag

The dockerfile needs to specify the image tag as the first line (see dockerfile on section 2.1)

#!BuildTag: jupiter-system/gedit:1.0.0-3.20.2-3.24

The version format I used is: [dockerfile-version]-[obs-package-version]-[obs-package-release-version]

3.2.2 Isolated build environment

OBS has a restriction for the base image. You can use any image from registry.opensuse.org (actually is taking the images available locally, it doesn't use any registry). And since it runs in an offline environment, you are not able to access files from outside. There is an exception, the virtual machine running the build is using Leap 42.3 as guest. Using the base image opensuse:42.3, you can access to the repositories to install packages from zypper.

3.2.3 systemd vs. systemd-mini

OBS would try to get systemd-mini variant packages by default, but this does not work for appliances. In order to force OBS to pick systemd varian packages, it is necessary to explicitly install libsystemd0 and libudev1.

3.2.4 osc build for docker image

At the moment, July 12th 2018, osc is not able to build an image that relies on a dockerfile fetched by an OBS service. It will expect and take the Dockerfile at the root directory of the OBS package.

After checking in the changes, OBS is able to build the Dockerfile fetched by the service.

3.2.5 zypper install package-x.y.z

To specify a version of a package, it is necesary to use the zypper operator =.

Looking for mad skills in:

docker x11 ssh raspberrypi kubic microos

This project is part of:

Hack Week 17

Activity

  • over 1 year ago: SLindoMansilla added keyword "microos" to Jupiter system
  • over 1 year ago: SLindoMansilla added keyword "kubic" to Jupiter system
  • over 1 year ago: SLindoMansilla added keyword "raspberrypi" to Jupiter system
  • over 1 year ago: SLindoMansilla added keyword "ssh" to Jupiter system
  • over 1 year ago: SLindoMansilla added keyword "x11" to Jupiter system
  • Show History

    Comments

    • okurz
      over 1 year ago by okurz | Reply

      Interesting idea. Where does the name "Jupiter system" come from? Your own invention or linked to any existing projects which have something to do with this?

    • SLindoMansilla
      over 1 year ago by SLindoMansilla | Reply

      It is my own invention. I always search for names ideas on internet to be sure that my project will not be confused by an existing one. I didn't find anything related with that name in google, so here I go.

    Similar Projects

    Convert the Docker Compose setup of OBS to Kubernetes Resources by dmarcoux

    Throughout this project, I will learn about Kub...


    Make "salt-toaster" available to be used outside SUSE by PSuarezHernandez

    The salt-toaster (https://github.com/openSUSE...


    House Daily Mutations Announcement System by jaimegomes

    The Goal is...

    to connect all the source...