如何让SYSTEM级systemd服务写入root级USB sysfs节点?
1. 用udev规则配置USB节点专属权限
这是最安全且标准的Linux设备权限管理方式,能在USB设备接入时自动应用专属权限。
第一步:获取USB设备的唯一标识
运行udevadm info -a /dev/your-usb-node(替换为实际节点路径,比如/dev/ttyUSB0),从输出中提取能唯一识别该设备的属性,比如ATTRS{idVendor}、ATTRS{idProduct}、KERNEL字段,示例标识:KERNEL=="ttyUSB*", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678"第二步:创建udev规则文件
在/etc/udev/rules.d/目录下新建规则文件,比如99-usb-write-access.rules,写入内容:KERNEL=="ttyUSB*", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", GROUP="service-x-group", MODE="0660"其中
service-x-group是服务X运行时所属的用户组(可通过systemctl show -p Group your-service-name查询),MODE="0660"仅允许该组内用户读写节点,比全局开放的646更安全。第三步:加载规则并生效
执行以下命令重载udev规则并触发设备重新识别:udevadm control --reload-rules udevadm trigger /dev/your-usb-node重新插拔USB设备后,权限设置会自动生效。
2. 用ACL给服务X单独添加节点权限
如果udev规则适配有困难,可通过ACL给服务X的运行用户单独赋予读写权限:
第一步:安装ACL工具(未安装时执行)
apt install acl # Debian/Ubuntu系 yum install acl # RHEL/CentOS系第二步:添加ACL规则
假设服务X的运行用户是service-x-user,执行:setfacl -m u:service-x-user:rw /dev/your-usb-node该命令仅给指定用户添加读写权限,不影响其他用户的原有权限配置。
第三步:持久化ACL规则
由于USB节点重启或插拔后权限会重置,可将setfacl命令添加到服务X的systemd配置文件的ExecStartPre字段,或写入udev规则(在规则中添加RUN+="/usr/bin/setfacl -m u:service-x-user:rw /dev/%k")。
3. 修复root脚本Y的调用问题(可选)
你之前的777脚本在服务中调用失败,通常是systemd服务的环境变量限制或脚本路径问题导致:
- 确保脚本中所有命令使用绝对路径(比如
/usr/bin/echo "data" > /dev/your-usb-node,而非相对路径) - 在systemd服务文件中添加
CapabilityBoundingSet=CAP_DAC_OVERRIDE,但此方式安全性不如前两种方案,仅作为临时替代。
内容的提问来源于stack exchange,提问作者Harsh Agarwal

