In an earlier post I went through how to create an LXD container that has graphics access through X11 forwarding. This is a simple method but if your goal for using containers is to sandbox applications and decrease the attack surface from malicious parties, X11 forwarding isn’t really a good idea. X11 is infamous for it’s lack of security.
X11 security
Essentially any application on an X server has access to all other applications on the same server which makes it really easy to log key strokes and doing a lot of other fishy stuff. The combination of allowing access over the network could be devastating. It’s a bit unjust to blame all this on the X11 protocol designers, since the protocol wasn’t developed for the environment that it’s operating in these days but nevertheless, it’s a fact that needs to be addressed. X11 has some security extensions that mitigate problems a bit but it seems hard to get the control you need for truly sandboxed applications. So, a way to address this is to use separate X servers to make sure that apps do not interact in unwanted ways. One can use VNC, Xephyr etc for this. I have chosen to use Xpra, since it can make “remote” applications blend in like native ones, still using a separate X server.
Container setup
Create a fresh container, and do basic container setup. We will run xterm for demonstration purposes but any X application will work of course.
$ lxc launch images:ubuntu/trusty/amd64 xpra $ lxc exec xpra /bin/bash root@xpra:~# apt-get install xterm openssh-server root@xpra:~# adduser xpra root@xpra:~# exit
Get Xpra
This will setup Xpra on Ubuntu Trusty. Unfortunately the Xpra package on Trusty is really old and buggy so manual installation is needed. Get the latest xpra package and python-reencode dependency from https://xpra.org/dists/trusty/main/ and install. If you are on a newer Ubuntu, the distro supplied packages may work fine.
Xpra needs to be installed both on the host and in the container so for both parties do:
# cd /tmp # wget https://xpra.org/dists/trusty/main/binary-amd64/python-rencode_1.0.3-1_amd64.deb # dpkg -i python-rencode_1.0.3-1_amd64.deb # apt-get install python-gtkglext1 python-opengl python-lzo python-appindicator libswscale2 libwebp5 libx264-142 libxkbfile1 x11-xserver-utils xvfb python-numpy python-imaging # wget https://xpra.org/dists/trusty/main/binary-amd64/xpra_0.15.10-1_amd64.deb # dpkg -i xpra_0.15.10-1_amd64.deb # cd -
Run xterm
Find the ip address of the container:
$ lxc list | grep xpra | xpra | RUNNING | 10.0.3.75 (eth0) | | PERSISTENT | 0 |
Invoke xpra on the host, launching a remote app via ssh.
$ xpra start ssh:xpra@10.0.3.75:100 --start-child=xterm --exit-with-children --exit-with-client=yes
There are a lot of options when it comes to invoke xpra and start up the app. It’s possible to use a TCP socket instead of ssh for instance and you can choose to keep the application alive, attaching to it for recurring startups etc. Launching an app like this is just as simple as it gets when the packages are installed.
For creating an application script and desktop binding see Creating an LXD container for graphics applications.