树莓派上/dev/mem访问被拒绝

3 投票
2 回答
5065 浏览
提问于 2025-04-18 13:19

我正在使用我的树莓派,写一个cgi的python脚本来创建一个网页,以控制我的gpio输出引脚。当我尝试导入RPi.GPIO作为GPIO时,我的脚本崩溃了。出现的错误是:

File "./coffee.py", line 7, in <module>
    import RPi.GPIO as GPIO
RuntimeError: No access to /dev/mem.  Try running as root!

我的代码在使用sudo命令运行时完全正常,但当我通过apache2服务器的URL运行时,它提示我没有权限访问/dev/mem。我已经尝试过编辑visudo文件,但没有成功。我的visudo文件内容如下:

#includedir /etc/sudoers.d
pi ALL=(ALL) NOPASSWD: ALL
www-data ALL=(root) NOPASSWD: /usr/bin/python3 /usr/lib/cgi-bin/coffee.py *
apache2 ALL = (root) NOPASSWD: /usr/lib/cgi-bin/coffee.py

有没有办法让我通过URL调用以root身份运行我的脚本?有人能告诉我我哪里做错了吗?

2 个回答

0

你的问题是这个脚本没有以管理员身份运行,而是以Apache服务器的用户身份运行。

Apache进程是以一个特定的用户身份运行的,通常是www-data。你可以改变Apache运行的用户,这个设置一般在/etc/apache2/envvars文件里。

# Since there is no sane way to get the parsed apache2 config in scripts, some
# settings are defined via environment variables and then used in apache2ctl,
# /etc/init.d/apache2, /etc/logrotate.d/apache2, etc.
export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data

如果你把这个用户改成root,你就应该能获得访问权限。通常这样做会有很大的安全隐患,但你现在已经在进行直接的内存访问了,所以要非常小心!

如果你觉得这样不安全,那你需要更新你的命令,让它以管理员身份执行(这是个不错的方法,但需要你了解自己在做什么!)。你可以通过改变调用方式,或者把调用放在一个脚本里,该脚本会改变用户身份,或者使用setuid(这和之前提到的suEXEC方法很相似)。我觉得把它放在脚本里是最好的方法,因为这样可以确保你的sudoers设置只对那个命令生效,而且不需要你完全理解setuid的所有影响。

1

我发现把www-data这个用户加入到gpio用户组里是可以的:

sudo usermod -aG gpio www-data

你也可以把www-data加入到内存用户组:

sudo usermod -aG kmem www-data

虽然这样做不太好,但对我来说是必须的。

撰写回答