我在阅读 NFS 安装上的手册页时遇到问题。我设法将其隔离为以下最小示例。手册页文件位于 NFS 挂载上/data
,其路径为/data/program.1
我可以将文件打印到控制台,cat /data/program.1
因此我绝对具有读取权限(所涉及的目录为 755,文件为 644,没有其他任何内容,例如 ACL 或粘性位等)
然而,man -l /data/program.1
一般情况下不起作用。
但奇怪的是,在读取文件或其元数据(例如成功的ls /data/program.1
)后,立即突然man -l /data/program.1
在短时间内(约 30 秒)起作用,看起来与某些缓存有关。虽然它看起来仍然是不确定的(在 ls 之后,它大部分都有效,但如果我重复执行,某些尝试不起作用,然后再次来回工作)
然而,奇怪的是,整个问题只存在于某些客户端计算机上,在同一 NFS 服务器(具有相同的安装选项)的其他客户端计算机上没有任何问题。
当它“不起作用”时,它会输出man: /data/program.1: Permission denied
使用strace man -l /data/program.1
我看到以下相关行:
stat("/data/program.1", 0x7ffe5ac9c9e0) = -1 EACCES (Permission denied)
如果我只是运行man program
(使用适当的 MANPATH),我会看到:
access("/data/program.1", R_OK) = -1 EACCES (Permission denied)
因此,我认为该access
调用无法完成,但是当我编译自己的 C 程序来调用它时,它可以工作(打印 0):
#include <unistd.h>
#include <stdio.h>
int main(){
printf("%d", access("/data/program.1", R_OK));
}
这里可能有什么问题?
我查看了 man 的源代码,也许它与这一行有关(https://git.savannah.gnu.org/cgit/man-db.git/tree/src/man.c#n3746)drop_effective_privs()
?否则我无法解释为什么所有东西都可以访问该文件(cat、head、我自己的 C 程序等),但又man
不能(除非另一个程序最近读取了元数据)。
客户端和服务器上均安装了 Ubuntu 18.04。坐骑看起来像这样:
x.x.x.x:/srv/nfs/data on /data type nfs4 (rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=x.x.x.x,fsc,local_lock=none,addr=x.x.x.x)
答案1
Ubuntu 18.04 默认启用 AppArmor,它会阻止来自 的网络访问man
,包括通过 NFS 访问文件。
要允许 的网络/NFS 访问man
,请将以下内容添加到/etc/apparmor.d/local/usr.bin.man
:
# TCP/UDP network access for NFS
network inet stream,
network inet6 stream,
network inet dgram,
network inet6 dgram,
然后跑systemctl reload apparmor
。
或者,禁用 AppArmor,例如通过设置apparmor=0
内核参数。