通过 SSH 连接时无法访问 LXC 中的设备节点

Device node in LXC is not accessible when connected via SSH

当我通过 SSH 连接时,无法读取或写入传递到 LXC 容器的物理硬件设备。

我的物理硬件设备的设备节点是这样的:

myuser@myhost:~$ ls -la /dev/usb/hiddev0
crw-rw-rw- 1 root root 180, 0 Jul 30 10:27 /dev/usb/hiddev0

这是我创建和启动容器的方式:

myuser@myhost:~$ sudo lxc-create -q -t debian -n mylxc -- -r stretch
myuser@myhost:~$ sudo lxc-start -n mylxc

然后我将设备节点添加到LXC:

myuser@myhost:~$ sudo lxc-device -n mylxc add /dev/usb/hiddev0

之后设备在 LXC 中可用,我可以在连接到 LXC 后读取它:

myuser@myhost:~$ sudo lxc-attach -n mylxc
root@mylxc:/# ls -la /dev/usb/hiddev0
crw-r--r-- 1 root root 180, 0 Aug 27 11:26 /dev/usb/hiddev0
root@mylxc:/# cat /dev/usb/hiddev0
����������^C
root@mylxc:/#

然后我在没有密码的情况下通过 SSH 启用 root 访问:

myuser@myhost:~$ sudo lxc-attach -n mylxc
root@mylxc:/# sed -i 's/#\?PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config
root@mylxc:/# sed -i 's/#\?PermitEmptyPasswords.*/PermitEmptyPasswords yes/g' /etc/ssh/sshd_config
root@mylxc:/# sed -i 's/#\?UsePAM.*/UsePAM no/g' /etc/ssh/sshd_config
root@mylxc:/# passwd -d root
passwd: password expiry information changed.
root@mylxc:/# /etc/init.d/ssh restart
Restarting ssh (via systemctl): ssh.service.
root@mylxc:/# exit

当我现在通过SSH连接时,设备节点在那里,但我无法访问它:

myuser@myhost:~$ ssh root@<lxc-ip-address>
root@mylxc:~# ls -la /dev/usb/hiddev0
crw-r--r-- 1 root root 180, 0 Aug 27 11:26 /dev/usb/hiddev0
root@mylxc:~# cat /dev/usb/hiddev0
cat: /dev/usb/hiddev0: Operation not permitted

在这两种情况下(lxc-attachssh)我都是 root 用户(通过 whoami 验证),所以这不是问题。

为什么我在通过 SSH 连接时不允许访问设备?


编辑

同时发现在一个脚本中直接依次调用所有的LXC初始化命令,错误消失,即:

sudo lxc-create -q -t debian -n mylxc -- -r stretch
sudo lxc-start -n mylxc
sudo lxc-device -n mylxc add /dev/usb/hiddev0
...

然后如上所述进行所有SSH配置。然后可以通过 SSH 正确访问该设备。

一旦在 lxc-startlxc-device 之间经过一段时间,就会出现错误,例如:

sudo lxc-create -q -t debian -n mylxc -- -r stretch
sudo lxc-start -n mylxc
sleep 1
sudo lxc-device -n mylxc add /dev/usb/hiddev0
...

为什么时间在这里相关?在 LXC 中的第一秒内发生了什么使设备变得不可访问?

lxc-users 邮件列表的帮助下,我发现 the restriction is intended。必须在 LXC 的配置中使用设备的 major/minor 编号明确允许访问设备:

lxc.cgroup.devices.allow = c 180:* rwm

使用 lxc-attach 的无限制访问似乎是我的一些错误。如果未明确允许,设备永远不应在 LXC 中访问。