[arch-general] sandboxing

Leonid Isaev leonid.isaev at jila.colorado.edu
Fri Feb 3 07:18:17 UTC 2017


On Thu, Feb 02, 2017 at 09:30:58PM +0100, Bennett Piater wrote:
> On 02/02/2017 07:28 PM, Leonid Isaev wrote:
> > I already described an approach when one always runs browsers, pdf readers,
> > etc, inside an lxc container, as an unprivileged user. That container resides
> > on a filesystem mounted with nosuid (so things like ping, su, sudo won't work),
> > and has a locked root account. On top of that, it connects to a xephyr session
> > running on the host, to avoid X11 sniffing attacks.
> > 
> > I have been using such setup on all my desktops for over a year now. The only
> > way to break out of such a container is a local kernel privilege escalation. Of
> > course, having *privileged* userns *might* help because inside container UID=0
> > will map to smth like UID=123456 on the host, but this doesn't seem worth doing
> > given all the ussues with userns.
> 
> This sounds cool. Do you happen to have written that up somewhere? :)
> 

Hmm, there is really nothing to write up, because it is very simple.

Anyway, first you install any linux distro into an lxc container. I chose arch
guest because in that case I have a good control over installed features, and I
chose lxc over docker or systemd-nspawn because it is the most mature project.
If you are conscious about the installation size (in GB), get rid of all
unnecessary packages (anything that deals with hardware, man-pages, man-db,
...) and completely purge the package cache (with pacman -Scc). Configure
networking in the container whatever is appropriate for you. I have a bridge on
the host where I plug veth interface pairs for containers and VMs, and use NAT
to hide thus created LAN behind the host. Make this container start on boot by
enabling the appropriate lxc at .service.

Second, configure ssh server inside container to accept X11 forwarding. Choose
whatever user policy, for instance, you can lock all user accounts, even root
(with passwd -l root, passwd -l <user_name>) and configure ssh keys. There is a
way to generate one-time keys, similar to how archiso generates pacman keyring
on boot -- I can explain separately if you are interested (so there is no
secret stored on the machine, not even hashed in /etc/shadow).

Install any additional software inside container, that you'll actually use,
e.g. epiphany ad evince. Also, install xorg-server-xephyr on the host. You can
connect to the container with smth like
---
host$ xephyr -resizeable -screen 1000x1000 :3 &
host$ export DISPLAY=:3 && ssh -Y <container_ip>
...
guest$ <desktop> &
---
where as a <desktop> I used fluxbox.

Now, you'll run a complete desktop inside Xephyr over ssh. You need a window
manager to manage multiple windows. Xephyr then protects your keystrokes from
being sniffed by the containerized X11 clients (but of course, you won't be
able to paste into apps inside container). If this is not a concern for you,
then simply do ssh -Y and forget about xephyr and DISPLAY variables.

Yes, starting graphic apps over ssh incurs a performance overhead. You can use
VNC or similar, but because all network connections are actually local this
overhead is not noticeable on modern hardware (but you can't use a graphical
browser on old machines anyway). Also, a container is simply a few processes on
the host (after cold start, only systemd, journald, logind, dbus and sshd), so
it doesn't waste too much memory.

Technicalities of all of the above are explained in archwiki (search for LXC,
qemu networking and xephyr).

Finally, I found it convenient to script the above login procedure by using ssh
tunnels in detached screen sessions with optinal sshf mounts for file exchange.
A very quick example script that you can start from .bash_login or your DE
session autostarter:
---
host$ cat local-c-setup.sh
#!/bin/bash

# systemD cleans /tmp
tmpdir="/run/user/$UID"

# Xephyr DISPLAY
xeph_d=":2"

# ssh tunnel
tuncmd="ssh -YNMS $tmpdir/ssh-%r@%h:%p"

# sshfs options and mountpoints
local_mnt_base="$HOME/obmennik"
sshfs_opt="-o noexec -o sshfs_sync -o workaround=rename"

# hosts and their sshfs shares
hosts=('rallidae' 'wolf')
rmt_dir=('/home/lisaev/obmennik' '/home/lisaev/obmennik')

# do X11 forwarding to Xephyr (at $xeph_d) only on wolf, and mount sshfs
i=0
while [ $i -lt 2 ]; do
	[[ $i -eq 1 ]] && export  DISPLAY=$xeph_d

	/usr/bin/screen -S ${hosts[i]} -d -m $tuncmd ${hosts[i]}
	/usr/bin/sshfs $sshfs_opt ${hosts[i]}:${rmt_dir[i]} \
		$local_mnt_base/${hosts[i]}

	let i=i+1
done
host$
host$ screen -ls
There are screens on:
      3863.wolf       (Detached)
      3860.rallidae   (Detached)
2 Sockets in /run/screens/S-leis8574.
---

Hope this helps,
-- 
Leonid Isaev


More information about the arch-general mailing list