![在 apache2 中使用 encfs 时,/etc/mtab 中没有挂载点](https://linux22.com/image/1581485/%E5%9C%A8%20apache2%20%E4%B8%AD%E4%BD%BF%E7%94%A8%20encfs%20%E6%97%B6%EF%BC%8C%2Fetc%2Fmtab%20%E4%B8%AD%E6%B2%A1%E6%9C%89%E6%8C%82%E8%BD%BD%E7%82%B9.png)
我编写了一个网页,让我可以远程挂载 encfs 加密文件夹,然后可以通过 WebDAV 访问该文件夹。它基本上只是一个带有挂载/卸载按钮的密码表单,它尝试使用通过表单提供的密码挂载/卸载预定义的 encfs 加密驱动器。基本上是一个可通过互联网访问的包装器
encfs --stdinpass /encfs/drive/encrypted/ /var/www/unencrypted
这按预期工作,因为我可以安装/卸载加密驱动器,并且可以通过 WebDAV 查看/读取未加密的数据。
但奇怪的事情发生了: 该文件夹的未加密视图只能通过 WebDAV 访问。
如果我跑sudo -u www-data ls -la /var/www(www-data 是运行 Web 服务器的用户,因此也是挂载驱动器的用户,我已经通过 htop 确认了这一点)或者作为任何其他用户,我将挂载点(在上面的例子中是 /var/www/unencrypted)视为常规文件夹,不像典型的 encfs 文件夹,后者通常看起来像这样:
drwxr-xr-x 5 www-data www-data 4096 Feb 1 02:25 .
drwxr-xr-x 15 root root 4096 Jan 31 11:46 ..
d????????? ? ? ? ? ? unencrypted
但实际上它看起来像这样:
drwxr-xr-x 5 www-data www-data 4096 Feb 1 02:25 .
drwxr-xr-x 15 root root 4096 Jan 31 11:46 ..
drwxr-xr-x 2 www-data www-data 4096 Jan 31 21:47 unencrypted
就像一个普通文件夹一样(报告为空,但通过 WebDAV 访问时同一个文件夹中有数据)。
此外,/etc/mtab 中没有任何条目表明 encfs 驱动器曾经被挂载过。无论出于何种目的,看起来好像驱动器从未被挂载过,但事实上肯定是被挂载了,因为我可以通过 WebDAV 访问它,而且 ecnfs 进程显然正在运行,如 htop 中所示。
这是怎么发生的以及如何解决?
附言:如果我跑
sudo -u www-data bash -c "echo $(cat /tmp/passwort_file) | encfs --stdinpass /encfs/drive/encrypted/ /var/www/unencrypted"
从终端来看,没有这种行为。该文件夹仍然可以通过 WebDAV 访问,但在这种情况下,它也正确显示在 /etc/mtab 中,并且在使用时也显示为 encfs 驱动器ls-la。
答案1
我假设这是 Debian Linux 或 Ubuntu,以 systemd 作为服务管理器。
Linux 支持“挂载命名空间”,它为不同的进程提供文件系统的不同视图(类似于 chroot,但更加灵活且令人头疼)。Systemd 允许使用此功能来加强系统的安全问题和攻击;例如,某些服务可能会将 /home 视为空或将 /etc 视为只读。
大多数发行版在 apache2.service 中使用这些安全设置 - 如果您运行systemctl cat apache2
,您会看到它配置为拥有自己的私有/tmp
目录:
[Service]
...
PrivateTmp=true
挂载命名空间的副作用是它们在某种程度上是全局的:一旦 systemd “取消共享”/
以便能够在其下创建仅 Apache 的挂载,即使它只需要一个挂载,同样的效果仍然适用于全部Apache 服务创建的挂载。(对于服务而言,这在某种程度上是故意的:为什么 Web 服务器真的需要挂载文件系统?最小特权原则。)
因此,如果您运行findmnt
或cat /proc/self/mounts
,您将只能看到根命名空间中的挂载。但是,如果您运行nsenter --mount --target <APACHE_PID> findmnt
或cat /proc/<APACHE_PID>/mounts
,您将同时看到从根命名空间继承的挂载和 Apache 进程私有的挂载。
要禁用此保护,请运行并删除所有以、或systemctl edit --full apache2
开头的设置。Private*
ReadOnly*
Inaccessible*