Passing serial port to unprivileged container

I make use of Proxmox and sometimes you need to use an external device within a LXC container. This article describes howto pass a serial port to the container, but the procedure is the same for any device.

As we are going to pass through the ttyS1 device, lets take a look at the type and major and minor id’s.

root@proxmox:/# ls -l /dev/ttyS1
crw-rw---- 1 root dialout 4, 65 Nov 23 /dev/ttyS1

In this case it is a character device (c), with major id 4 and minor id 65. It is owned by root and the dialout group.

To add this device to the container we need to edit the containers configuration. With proxmox you can find this configuration file in /etc/pve/lxc.

We need to add two lines to the configuration:

lxc.cgroup.devices.allow: c 4:* rw
lxc.mount.entry: /dev/ttyS1 dev/ttyS1 none bind,optional,create=file

Line 1 gives Read and Write access from within the container to all character devices with major id 4.
Line 2 mounts the device within the container itself so it shows up.

root@container:/# ls -l /dev/ttyS1
crw-rw---- 1 nobody nogroup 4, 65 Nov 23 /dev/ttyS1

We now have the device available, there’s only one problem. If we run a piece of software which wants to open the serial port it will be presented with an “access denied”. This is all due to the different userid within and outside the container. Because all users within the container will be mapped to different user ids none of them will reside within the dialout group (or be root for that matter). So access to the device will be restricted.

There are, of course, multiple solutions to this problem. The solution I found the easiest is to adjust the permissions at the proxmox host so that ttyS1 is readable and writable by everyone. For me this is secure enough in this case, as no-one will have access to the underlying Proxmox host.

To adjust the permissions on ttyS1 at the host we need to create an udev rule. Local rules need to go in /etc/udev/rules.d so that’s where we create a file called “99-serial-passthrough.rules”.

KERNEL=="ttyS1", SUBSYSTEMS=="tty", MODE="0666"

The file contains only 1 line. This will match our serial device (ttyS1) and adjust the permissions so it is readable and writable by everyone.

When we reload udev the device shows up with new permissions.

root@proxmox:/# ls -l /dev/ttyS1
crw-rw-rw- 1 root dialout 4, 65 Nov 23 /dev/ttyS1

Within the container the same thing happens

root@container:/# ls -l /dev/ttyS1
crw-rw-rw- 1 nobody nogroup 4, 65 Nov 23 /dev/ttyS1

Within the container we now should be able to use the serial port.