我有一个包含文件的文件夹
/path/to/data/one/it_works.txt
我有一个空文件夹:
/path/to/user/bob
我有一个应该由 Tomcat 中的 Web 应用程序执行的脚本,它是:
#!/bin/sh
Source="$1"
Target="$2"
/bin/mkdir "$Target"
/bin/touch "$Target/it_failed.txt"
sudo /bin/mount --bind "$Source" "$Target" || exit 1
ls "$Target"
exit 1
(这exit 1
是为了获取 Web 应用程序记录的输出。一旦有效,我将其删除。)
Sudo 似乎设置正确。
当我执行时,sudo -u tomcat ./the-script.sh /path/to/data/one /path/to/user/bob/one
它会it_works.txt
按预期打印。如果我然后cd /path/to/user/bob/one
和ls
,我it_works.txt
也会找到。 (然后,umount 和 rmdir $Target。)当我从 Web 应用程序执行脚本时,我也会被it_works.txt
记录(预期)。但是,如果我然后cd /path/to/user/bob/one
和ls
,我发现it_failed.txt
。对于其他进程也是如此(在我的例子中是 WebDAV;这就是为什么我不能使用符号链接,因为 WebDAV 不支持它们)。
看起来挂载绑定仅适用于执行它的进程(尽管sudo
),但不适用于系统的其余部分。
我一开始以为这个效果是systemd
沙箱造成的,但是我设置了ProtectSystem=false
,还是出现同样的情况...
如何让挂载绑定在 Tomcat 进程范围之外生效?
(发行版是 Debian 10.10)
答案1
行为曾是由 引起systemd
,它在unshare
(1)环境如果任何指令中InaccessiblePaths
,PrivateMounts
、PrivateTmp
、PrivateDevices
、 、ProtectSystem
、ProtectHome
、ReadOnlyPaths
或在文件ReadWritePaths
中启用tomcat9.service
。
我通过注释掉其中的任何一个来摆脱这个问题。这就是现在的安全部分的样子[Service]
:
# Security
User=tomcat
Group=tomcat
# PrivateTmp=yes
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=false
CacheDirectory=tomcat9
CacheDirectoryMode=750
# ProtectSystem=strict
# ReadWritePaths=/etc/tomcat9/Catalina/
# ReadWritePaths=/var/lib/tomcat9/webapps/
# ReadWritePaths=/var/log/tomcat9/
# ReadWritePaths=/path/to/data/
# ReadWritePaths=/path/to/user/
(NoNewPrivileges=false
成功所必需的sudo
。)