不要问我为什么,但我必须找到办法允许 Apache 用户www-data
挂载和卸载设备在主机系统运行时。此类设备例如是/dev/sdaXY
使用 NTFS 文件系统格式化的外部 USB 驱动器。
我在 Debian 机器上使用 Apache 2.2 和 PHP 5.3 运行 Web 服务。当我尝试mount
通过 PHP 运行命令时exec()
,我显然收到以下错误消息:
exec('mount /dev/sda1 /media/usb_flash');
// -> mount: only root can do that
exec('sudo mount /dev/sda1 /media/usb_flash');
// -> sudo: no tty present and no askpass program specified
exec('sudo -n mount /dev/sda1 /media/usb_flash');
// -> sudo: sorry, a password is required to run sudo
我知道只有 root 才能执行此操作(实际上,sudo
在挂载时我总是需要通过 SSH 执行此操作),并且这www-data
不可能是须知。但我确信有一种方法,一种变通方法,可以让我完成任务。我不知道从哪里开始看:谷歌搜索我的问题是没用的,我敢打赌这不是一个常见的情况。
答案1
- 尝试 sudoers 中的选项 requiretty。
- 另一种方法是在屏幕内运行 sudo。
- 如果挂载点是静态的(并且不存在其他用户利用此进行损害的风险),则您可以使用选项为每个挂载点创建一个 fstab 条目
user
。
答案2
我解决了使用pmount
。在我找到这个工具之后,它对我来说看起来是最简单的解决方案(无需sudoers
编辑、无需fstab
填充、什么都没有)。
pmount
- 以普通用户身份安装任意热插拔设备
pmount
(“策略挂载”)是标准mount
程序的包装器,它允许普通用户挂载无需匹配 /etc/fstab 条目的可移动设备。
正如手册所述,在 Debian 上,执行权限 pmount
仅限于系统组的成员plugdev
。我必须通过 SSH 运行以下命令,将 Apache usar 添加到该plugdev
组:
sudo adduser www-data plugdev
我重新启动了 Apache,现在我可以从 PHP 挂载和卸载我的 USB 驱动器,无需sudo
:
exec('pmount /dev/sda1 usb_flash'); // Mounted on /media/usb_flash
exec('ls -al /media/usb_flash'); // List files, owned by www-data:600
exec('pumount usb_flash'); // Unmounted
答案3
该setuid
标志可能会起到作用:创建安装驱动器的脚本,由根,setuid
在其上设置标志并从 apache 调用该脚本。
您可以用以下命令设置所需的权限(setuid 和 exec):
chmod 4711 <your/script>
第一个4是 setuid...
请参阅 setuid wiki 以获取更多参考。