Skip to content

Instantly share code, notes, and snippets.

@crundberg
Last active April 27, 2024 16:51
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save crundberg/a77b22de856e92a7e14c81f40e7a74bd to your computer and use it in GitHub Desktop.
Save crundberg/a77b22de856e92a7e14c81f40e7a74bd to your computer and use it in GitHub Desktop.
Setup deCONZ on unprivileged Proxmox container

Setup deCONZ on unprivileged Proxmox container

Preparation on host

First find your Conbee with lsusb and note the ID. The vendor is 1cf1 and the product is 0030.

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 1cf1:0030 Dresden Elektronik ZigBee gateway [ConBee II]
Bus 001 Device 003: ID 8087:0aaa Intel Corp. Bluetooth 9460/9560 Jefferson Peak (JfP)
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Run ls -la /dev/ttyACM0 and note cgroup, in my case it was 166

crw-rw-r-- 1 root root 166, 0 Jan  3 21:45 /dev/ttyACM0

To handle the permission for the device I created a new directory where I created a device file with correct permissions. Change 166 in mknod to the cgroup you noted in previous step. mkdir -p /lxc/120/devices
cd /lxc/120/devices/
mknod -m 660 ttyACM0 c 166 0
chown 100000:100020 ttyACM0
ls -al /lxc/120/devices/ttyACM0

Run nano /etc/pve/lxc/120.conf and add the last two rows for cgroup and mount. Change 166 in cgroup to the cgroup you noted before.

arch: amd64
cores: 1
features: nesting=1
hostname: zigbee.test.com
memory: 512
net0: name=eth0,bridge=vmbr0,firewall=1,gw=192.168.10.1,hwaddr=52:CE:FD:D2:03:0F,ip=192.168.10.120/24,type=veth
ostype: ubuntu
rootfs: local:120/vm-120-disk-0.raw,size=8G
swap: 512
unprivileged: 1
lxc.cgroup2.devices.allow: c 166:* rwm
lxc.mount.entry: /lxc/120/devices/ttyACM0 dev/ttyACM0 none bind,optional,create=file

nano /etc/udev/rules.d/50-myusb.rules

SUBSYSTEM=="tty", ATTRS{idVendor}=="1cf1", ATTRS{idProduct}=="0030", MODE="0666", SYMLINK+="conbee"

udevadm control --reload-rules && service udev restart && udevadm trigger
ls -l /dev/ttyACM*

Install deCONZ in container

apt install gnupg2
wget -O - http://phoscon.de/apt/deconz.pub.key | apt-key add -
sh -c "echo 'deb [arch=amd64] http://phoscon.de/apt/deconz $(lsb_release -cs) main' > /etc/apt/sources.list.d/deconz.list"
apt update
apt install deconz

GCFFlasher_internal -l

GCFFlasher V3_17 (c) dresden elektronik ingenieurtechnik gmbh
Path             | Vendor | Product | Serial     | Type
-----------------+--------+---------+------------+-------
                 |        |         |            | 

mkdir -p /run/udev/data/ echo "E:ID_VENDOR_ID=1cf1 E:ID_MODEL_ID=0030" > /run/udev/data/c166\:0

GCFFlasher_internal -l

GCFFlasher V3_17 (c) dresden elektronik ingenieurtechnik gmbh
Path             | Vendor | Product | Serial     | Type
-----------------+--------+---------+------------+-------
/dev/ttyACM0     | 0x1CF1 | 0x0030  |            | ConBee II

/sbin/setcap cap_net_bind_service+ep /usr/bin/deCONZ

getcap /usr/bin/deCONZ

/usr/bin/deCONZ = cap_net_bind_service+ep

useradd deconz-user mkdir /home/deconz-user chown -R deconz-user:deconz-user /home/deconz-user usermod -a -G dialout deconz-user

systemctl enable deconz

Created symlink /etc/systemd/system/multi-user.target.wants/deconz.service -> /lib/systemd/system/deconz.service.

nano /lib/systemd/system/deconz.service

[Unit]
Description=deCONZ: ZigBee gateway -- REST API
Wants=deconz-init.service deconz-update.service
StartLimitIntervalSec=60

[Service]
User=deconz-user
PermissionsStartOnly=true
ExecStartPre=/bin/mkdir -p /run/udev/data
ExecStartPre=/sbin/setcap cap_net_bind_service+ep /usr/bin/deCONZ
ExecStartPre=/bin/bash -c "/bin/echo -e 'E:ID_VENDOR_ID=1cf1\nE:ID_MODEL_ID=0030' > /run/udev/data/c166:0"
ExecStart=/usr/bin/deCONZ -platform minimal --http-port=80
Restart=on-failure
#AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME

[Install]
WantedBy=multi-user.target

shutdown -r now

References

https://doc.turris.cz/doc/en/public/deconz_lxc_howto\ https://www.xmodulo.com/change-usb-device-permission-linux.html\ https://monach.us/automation/connecting-zwave-stick-under-lxc/\ https://blog.benoitblanchon.fr/lxc-unprivileged-container/\ https://gist.github.com/Yub0/518097e1a9d179dba19a787b462f7dd2\

@torwag
Copy link

torwag commented Oct 1, 2022

Hi,
I don't get how you connect your newly created block device to the hardware. In my understanding, your udev-rule should point to the created block device, but it simply points to a symlink called conbee. After that, you check that /dev/ttyUSB0 is valid. So how does all this connect?

@rsporsche
Copy link

I just added this:

SUBSYSTEM=="tty", ATTRS{idVendor}=="1cf1", ATTRS{idProduct}=="0030", MODE="0666", SYMLINK+="conbee"

to nano /etc/udev/rules.d/50-myusb.rules

Then this:

lxc.cgroup2.devices.allow: c 166:* rwm
lxc.mount.entry: /dev/conbee dev/ttyACM0 none bind,optional,create=file

to the container conf file

and that's all I had to do on the host. Your udev rule changes the permissions to allow anyone to read/write the device so you don't need to do anything else.

@Vincent-Stragier
Copy link

Hi @crundberg,

Thank you, it really helped me to configure my Proxmox container. My goal was different (interfacing an Arduino Uno board).

What I think is crucial to configure the pass-through for the device is first to know the correct device file to map, then to set the right permission and to correctly map it to the container. On my side, it was not needed to add udev rules.

@ispiropoulos
Copy link

I just added this:

SUBSYSTEM=="tty", ATTRS{idVendor}=="1cf1", ATTRS{idProduct}=="0030", MODE="0666", SYMLINK+="conbee"

to nano /etc/udev/rules.d/50-myusb.rules

Then this:

lxc.cgroup2.devices.allow: c 166:* rwm lxc.mount.entry: /dev/conbee dev/ttyACM0 none bind,optional,create=file

to the container conf file

and that's all I had to do on the host. Your udev rule changes the permissions to allow anyone to read/write the device so you don't need to do anything else.

Hi @rsporsche

Do you mean that that's all that's needed to be done, or are these step an addition to what the original guide on this gist suggests?

@rsporsche
Copy link

@ispiropoulos
To be honest I'm using zigbee2mqtt on docker in an LXC container on proxmox and I may have lost sight of the fact that this page is dealing with deCONZ when I posted.
It was very helpful in guiding me to a solution for my setup but I can't say for certain whether doing what I did instead of what's described under 'Preparation on host' would work for deCONZ in LXC.
I also have the issue that zigbee2mqtt loses communication with the adapter if I restart the docker container so I have to reboot the entire pve node which is a pain.

@ispiropoulos
Copy link

@ispiropoulos
To be honest I'm using zigbee2mqtt on docker in an LXC container on proxmox and I may have lost sight of the fact that this page is dealing with deCONZ when I posted.
It was very helpful in guiding me to a solution for my setup but I can't say for certain whether doing what I did instead of what's described under 'Preparation on host' would work for deCONZ in LXC.
I also have the issue that zigbee2mqtt loses communication with the adapter if I restart the docker container so I have to reboot the entire pve node which is a pain.

Aaaah maybe then, in this context, a VM with USB passthrough would be a fitter choice. Thanks @rsporsche

@jaark
Copy link

jaark commented Apr 17, 2023

A small (pedantic) point that was confusing me in your description...
The '166' in your instructions is not a cgroup number. A cgroup (control group) is a mechanism used to enable process isolation between containers. The 166, 0 numbers you are seeing have nothing to do with cgroups, but are the major and minor device node numbers and the 'c' indicates that the device is a character based device (one byte at a time) as opposed to a block (b) device such as a disk device. These numbers indicate what device driver is used to interface with the device and can be looked up in /proc/devices if you are curious.

@Fijo
Copy link

Fijo commented Oct 9, 2023

I just added this:

SUBSYSTEM=="tty", ATTRS{idVendor}=="1cf1", ATTRS{idProduct}=="0030", MODE="0666", SYMLINK+="conbee"

to nano /etc/udev/rules.d/50-myusb.rules

Then this:

lxc.cgroup2.devices.allow: c 166:* rwm lxc.mount.entry: /dev/conbee dev/ttyACM0 none bind,optional,create=file

to the container conf file

and that's all I had to do on the host. Your udev rule changes the permissions to allow anyone to read/write the device so you don't need to do anything else.

I'm assuming /dev/conbee was that symlink created from the udev rule above.
For me that didn't work and docker was complaining when I was trying to bind-mount that device into a container.

init: error creating device nodes: mount /dev/ttyACM0:/var/lib/docker/overlay2/249d145bc5038dc0a591c0caba9150d0aec0238974714c16c21766abc56d6999/merged/dev/ttyACM0 (via /proc/self/fd/6), flags: 0x1000: no such file or directory: unknown

The solution was to not use the symlink and change
lxc.mount.entry: /dev/conbee dev/ttyACM0 none bind,optional,create=file
into
lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file
instead.

I was also able to redude
SUBSYSTEM=="tty", ATTRS{idVendor}=="1cf1", ATTRS{idProduct}=="0030", MODE="0666", SYMLINK+="conbee"
to
SUBSYSTEM=="tty", ATTRS{idVendor}=="1cf1", ATTRS{idProduct}=="0030", MODE="0666"

This ended up working for me on a Proxmox 8 running an unprivileged debian 12 LXC container with Docker Version 24.0.6.

@andrzej-r
Copy link

I'm trying to get my Sonoff Zigbee Dongle-P working with Zigbee2MQTT on docker on an unprivileged LXC container in Proxmox 8.1.

I've managed to forward /dev/ttyUSB0 device to the LXC container, set permissions and map the device to docker. The container starts normally but when I try to control the device (toggle a light off) I get:

Publish 'set' 'state' to 'Lights' failed: 'Error: Command 0xdc8e95fffe3581f6/1 genOnOff.off({}, {"sendWhen":"immediate","timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":false,"direction":0,"srcEndpoint":null,"reservedBits":0,"manufacturerCode":null,"transactionSequenceNumber":null,"writeUndiv":false}) failed (Data request failed with error: 'MAC channel access failure' (225))'

Hardware and the device file:

root@pve1:~# lsusb
Bus 001 Device 004: ID 10c4:ea60 Silicon Labs CP210x UART Bridge
root@pve1:~# ll /dev/serial/by-id/usb-Silicon_Labs_Sonoff_Zigbee_3.0_USB_Dongle_Plus_0001-if00-port0 
lrwxrwxrwx 1 root root 13 Dec 10 04:41 /dev/serial/by-id/usb-Silicon_Labs_Sonoff_Zigbee_3.0_USB_Dongle_Plus_0001-if00-port0 -> ../../ttyUSB0
root@pve1:~# ll /dev/ttyUSB0
crw-rw-rw- 1 100000 100000 188, 0 Dec 10 05:00 /dev/ttyUSB0

Device forwarded with:

lxc.cgroup2.devices.allow: c 188:* rwm
lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file

Any ideas?

@exodatame
Copy link

This was great help setting up Conbee II. But even including what Ive picked up on device permissions in LXC since, have not much success with a Conbee III. Has anyone successfully setup Conbee III in an unprivileged Proxmox container?

@andrzej-r
Copy link

I've installed docker and zigbee2mqtt directly on Proxmox. Works great. When testing I noticed some of the problems I have previously attributed to permissions were caused by my sonoff adapter being too close to the metal chassis.

@bastian-mer
Copy link

This was great help setting up Conbee II. But even including what Ive picked up on device permissions in LXC since, have not much success with a Conbee III. Has anyone successfully setup Conbee III in an unprivileged Proxmox container?

I encounter the same problem. I was able to setup a ConBee II using this guide but I failed when trying to adept it to a conbee III

@bastian-mer
Copy link

The Conbee III identifies as
0403:6015 Future Technology Devices International, Ltd Bridge(I2C/SPI/UART/FIFO)
and debian creates an /dev/ttyUSB0
I tried to adept the guide to this parameters but fail when it comes to GCFflash_internal -l inside the lxc container.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment