Web 环境中文件访问的权限提升
我遇到一种情况,我想提升在 Web 环境中的权限,以便可以访问串行设备。
具体情况是我有一个用于配置 /dev/ttyUSB[0-9]
上出现的调制解调器的 Web 界面。
最终用户将插入零个或多个调制解调器。 我正在编写一些软件,能够通过读取 /sys/devices
并使用一些 AT 命令与调制解调器对话来识别哪个是 USB 无线调制解调器。
我希望能够打开设备并执行类似的操作:
ser = serial.Serial(tty, baudrate=115200, timeout=10)
ser.write('AT+CGSN\r\n')
imei = ser.readline()
问题是 pyserial 会执行以下操作: self.fd = os.open(self.portstr, os.O_RDWR|os .O_NOCTTY|os.O_NONBLOCK) 打开串口,其中 portstr 是 /dev/ttyUSB0
,但它以 nobody
用户身份执行,即没有特权。
该系统上的串行端口属于root:uucp,并设置为0660(即rw-rw----
)。
对于像 nobody
这样应该拥有尽可能少的权限在 dev 中打开文件的用户来说,最好的方法是什么?
我会考虑的想法:
- 使用 sudo 在子进程中执行操作。
- 更改
/dev/
中文件的权限(感谢有关如何使用 udev 正确执行此操作的说明!) - 使用我没有考虑过的其他 API 或软件。
I have a situation where I would like to elevate the permissions I have in a web environment so that I can access a serial device.
The specific case is where I have a web interface for configuring a modem that comes up on /dev/ttyUSB[0-9]
.
Zero or more modems will be plugged in by an end user. I am writing some software that is capable of discerning which is a USB Wireless Modem by reading /sys/devices
and talking to the modem using some AT commands.
I would like to be able to open the device and do something like:
ser = serial.Serial(tty, baudrate=115200, timeout=10)
ser.write('AT+CGSN\r\n')
imei = ser.readline()
The problem is that pyserial
does this: self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK)
to open the serial port, where portstr is /dev/ttyUSB0
, but it does it as the nobody
user, which is unprivileged.
Serial ports on this system are owned by root:uucp and are set as 0660 (i.e. rw-rw----
).
What is the best way for a user such as nobody
who should have as few permissions as possible to open a file in dev?
Ideas I will consider:
- Doing things in a subprocess using
sudo
. - Changing permissions of the files in
/dev/
(instructions on how to do this properly using udev are appreciated!) - Using another API or piece of software I have not considered.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在这种情况下,我将编写一个由系统用户运行的守护程序,该守护程序接受套接字连接并将其中继到适当的设备,然后使用 Web 应用程序中的套接字与守护程序进行通信。 这也有助于防止 Web 应用程序在打开尚未准备好处理用户的设备时被阻止,比使用 CGI 等更明智地解决锁定问题。
但是,如果您希望赋予应用程序以下能力:直接与设备对话,给予它们与 null 相同的权限。
In this case, I would write a daemon run by a system user that accepted socket connections and relayed them to the appropriate device, then use sockets within the web application to talk to the daemon. This also helps keep the web app from blocking when opening a device that isn't quite ready to deal with users, settle locks a little more sanely than you could with CGI, etc.
However, if you wish to give the application the ability to talk to the devices directly, give them the same permissions that null has.
还有另一种方法可以做到这一点:Unix/Linux 允许通过 Unix 套接字发送文件描述符。 甚至还有一个 Perl 模块: PassAccessRights.pm 。 没有找到类似的 Python 模块,但它可以很容易实现。
There's another way of doing this: Unix/Linux allows sending file descriptors via Unix sockets. There's even a Perl module for that: PassAccessRights.pm. Didn't find similar module for Python but it could be easily implemented.
配置 udev 规则,将新设备 chgrp 发送给 nobody(如果允许通过 Web 界面进行的每次访问都允许相同的访问权限)装置。 这是我在 /etc/udev/rules.d/99-bpw.rules 文件中放入 eee-bpw 包中的内容。
将 nobody 替换为 dialout。 此特定规则假定设备名称为 /dev/ttyUSB2,但您可以大幅扩展该规则,请参阅 udev 文档。
Configure a udev rule to chgrp the new device to nobody, if it is acceptable that every access via the web interface be permitted the same access to the device. Here's what I put in my eee-bpw package in file /etc/udev/rules.d/99-bpw.rules.
Substitute nobody for dialout. This particular rule assumes the device name to be /dev/ttyUSB2, but you can extend the rule considerably, see the udev documentation.
“对于应该拥有尽可能少的权限的用户(例如没有人)在开发中打开文件的最佳方法是什么?”
实际上,您最好在 Web 应用程序的守护进程模式下使用 mod_wsgi。 mod_wsgi 用户可以是您提供的任何用户名(和组)。
您可以以具有适当定义的权限的用户身份运行。
请参阅 http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives #WSGIDaemonProcess
"What is the best way for a user such as nobody who should have as few permissions as possible to open a file in dev?"
Actually, you're better off using mod_wsgi in daemon mode for your web application. The mod_wsgi user can be any username (and group) you provide.
You can run as a user with appropriately defined privileges.
See http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIDaemonProcess
sudo 的想法是可能的。 IIRC,您可以将特定命令设置为可 sudo,但不需要密码。
另一种选择是将
nobody
放入有权访问所需设备的组中,或者将 Apache 作为有权访问的组启动。如果您使用 fastcgi (或等效),我认为您可以让它以拥有用户的身份运行脚本(某些共享主机会这样做)。
要更改
/dev
中文件的权限,只需 chmod 它们即可。The sudo idea could be possible. IIRC, you can set specific commands to be sudo-able, but without requiring a password.
The other option is to put
nobody
in a group that has access to the device you want, or to start Apache as the group that does have access.If you're using fastcgi (or equiv), I think you can have it run scripts as the owning user (some shared hosts do this).
To change permissions of files in
/dev
, just chmod them.