I'm road testing the Harting MICA Complete IIoT Starter Kit. In this post, I review the mechanism to restrict or grant access to character devices such as USB and serial ports. I'm showing the principle on a Linux Debian Stretch Container. The principle is true for all containers. |
How Does the Device Assignment work?
In the MICA web application, there's an management page that allows to select the devices that are assigned to a particular container.
Each container has all available device available in the /dev directory. Even if they aren't selected for that container.
All devices that aren't selected are assigned to the Linux group root.
if you execute the command ls -l /dev , you'll see that all devices are there, whether they are selected in the management app or not.
Here's an example filtered on the BOSCH CISS USB device that comes with the MICA IIoT USB kit. Check the group assignment: root.
If you select that /dev/ttyACM0 device and assign it to your container (see the image in the post intro), and restart the MICA (not only your container!),
the ownership changes to the dialout group.
You can use this mechanism in the container. But that requires that you don't execute our programs as root (root has access to everything, whatever the group).
More on that in the next section.
Test the Setup with a non-root User
Let's try this out.
Steps:
- don't list the device in the management app.
- create a new user
- test if the new user can access the device (should fail)
- list the device in the management app and reboot the MICA
- test again (should fail)
- assign the new user to the dialout group
- log on and test again (should work)
You can test by executing cat /dev/ttyACM0 , but in this example I'll use a Java program I made for this roadtest (because that's how I tested it - I don't want to redo the exercise ).
I created a user jancumps
useradd -m jancumps passwd jancumps
Moved the java libraries to the new user's home directory using winSFTP, logged in as jancumps.
It's easyest if you move them as that user, so you don't have to change any ownership and rights.
Then execute my code (if you don't have the Java program, run cat /dev/ttyACM0).
It fails - as expected, because only root group can access the device.
$ ls -l /dev | grep ttyA crw-r----- 1 root root 166, 0 May 3 14:02 ttyACM0 $ java -cp ./CISSBoschUSB-1.0-SNAPSHOT.jar:./commons-cli-1.4.jar:jSerialComm-2.5.0.jar net.cumps.cissboschusb.CISSBoschApp -usb "/dev/ttyACM0" -baud 115200 May 03, 2019 2:07:38 PM net.cumps.cissboschusb.Cli parse INFO: Using cli argument -usb=/dev/ttyACM0 May 03, 2019 2:07:38 PM net.cumps.cissboschusb.Cli parse INFO: Using cli argument -baud=115200 May 03, 2019 2:07:39 PM net.cumps.cissboschusb.CISSNode connect SEVERE: Open port failed May 03, 2019 2:07:39 PM net.cumps.cissboschusb.CISSBoschApp main INFO: Disconnecting Exception in thread "main" java.lang.NullPointerException at net.cumps.cissboschusb.CISSNode.stream(CISSNode.java:56) at net.cumps.cissboschusb.Cli.parse(Cli.java:68) at net.cumps.cissboschusb.CISSBoschApp.main(CISSBoschApp.java:35) May 03, 2019 2:07:39 PM net.cumps.cissboschusb.CISSBoschApp$1 run INFO: Shutdown hook
I add /dev/ttyACM0 to the container, and reboot the whole MICA.
Log in as jancumps again and execute.
As expected, it fails, because user jancumps is not part of the dialout group:
$ ls -l /dev | grep ttyA crw-rw---- 1 root dialout 166, 0 May 3 14:05 ttyACM0 $ pwd /home/jancumps/java $ java -cp ./CISSBoschUSB-1.0-SNAPSHOT.jar:./commons-cli-1.4.jar:jSerialComm-2.5.0.jar net.cumps.cissboschusb.CISSBoschApp -usb "/dev/ttyACM0" -baud 115200 May 03, 2019 2:07:38 PM net.cumps.cissboschusb.Cli parse INFO: Using cli argument -usb=/dev/ttyACM0 May 03, 2019 2:07:38 PM net.cumps.cissboschusb.Cli parse INFO: Using cli argument -baud=115200 May 03, 2019 2:07:39 PM net.cumps.cissboschusb.CISSNode connect SEVERE: Open port failed May 03, 2019 2:07:39 PM net.cumps.cissboschusb.CISSBoschApp main INFO: Disconnecting Exception in thread "main" java.lang.NullPointerException at net.cumps.cissboschusb.CISSNode.stream(CISSNode.java:56) at net.cumps.cissboschusb.Cli.parse(Cli.java:68) at net.cumps.cissboschusb.CISSBoschApp.main(CISSBoschApp.java:35) May 03, 2019 2:07:39 PM net.cumps.cissboschusb.CISSBoschApp$1 run INFO: Shutdown hook
As root, then add the dialout group to user jancumps.
usermod -aG dialout jancumps
Log out and log in as jancumps again (group changes need a fresh logon to apply), and it succeeds:
$ ls -l /dev | grep ttyA crw-rw---- 1 root dialout 166, 0 May 3 14:05 ttyACM0 $ cd java $ java -cp ./CISSBoschUSB-1.0-SNAPSHOT.jar:./commons-cli-1.4.jar:jSerialComm-2.5.0.jar net.cumps.cissboschusb.CISSBoschApp -usb "/dev/ttyACM0" -baud 115200 May 03, 2019 2:08:08 PM net.cumps.cissboschusb.Cli parse INFO: Using cli argument -usb=/dev/ttyACM0 May 03, 2019 2:08:09 PM net.cumps.cissboschusb.Cli parse INFO: Using cli argument -baud=115200 May 03, 2019 2:08:10 PM net.cumps.cissboschusb.CISSNode connect INFO: Open port succeeeded
Summary: the device selection changes the group ownership of selected devices.
Non-selected devices can only be accessed by users belonging to the root group.
Selected devices can be accessed by users belonging to the dialout group - a group that you can safely assign to users without needing root level elevation.
This functionality is useful but requires that you properly set up users and groups in your container.
Top Comments