我有一个 NFS 共享。此共享由多个不同的应用程序共享。我们的 Web 服务器正在运行 PHP,当它创建目录时,它没有正确设置权限,因此它无法写入创建的目录。如何将此 NFS 共享挂载到 PHP 具有完全读/写访问权限的位置?以下是已创建的目录以及媒体服务器导出选项和 Web 服务器上的挂载选项。理想情况下,我可以设置 /opt/mount 上的权限,并且当我挂载到该点时,该目录上的任何组/用户都会获得这些权限。
dr----x--t. 2 nobody nobody 4096 Jun 5 2014 user_2
安装输出:
media.dc1:/home/fs_share on /opt/mount type nfs (rw,vers=4,addr=10.10.20.127,clientaddr=10.10.20.42)
从媒体服务器导出文件:
/home/fs_share 10.10.20.0/255.255.255.0(rw,sync,no_root_squash)
答案1
您使用的是 NFSv4。很遗憾您没有指定操作系统版本,因为这在这里相当重要。
旧版本的 NFS 严格使用 UID/GID 号码,因此 NFS 服务器可能不知道客户端上的所有用户和组,反之亦然 - 只要 UID/GID 号码不冲突,一切就都好。
但 NFSv4 可以选择使用用户/组名而不是 UID/GID 编号。如果使用名称,则它们以 的形式传输user@domain
,其中domain
通常默认为每个系统的 DNS 域,但可以根据需要更改为任意字符串。如果 NFSv4 服务器和 NFSv4 客户端的域设置不匹配,或者用户/组名映射由于任何其他原因失败,您可能会看到所有权映射到nobody
并且文件权限最小化 - 就像您看到的那样。
在 Linux 中,此用户/组名称映射由服务完成rpc.idmapd
。如果此服务未运行,则也可能是文件所有权映射到的原因nobody
。在 RHEL/CentOS/OEL 6.5 及更早版本中,此守护进程应在 NFS 客户端和服务器上运行。(是的,客户端有一个/usr/sbin/nfsidmap
upcall 程序,从 6.3 版开始,它应该使rpc.idmapd
NFS 客户端不再需要它……但它有一个仅在 RHEL/CentOS/OEL 6.6 及更新版本中修复的错误。)
在 Linux 中,NFS 域设置默认为主机的 DNS 域名,但可以使用文件Domain =
中的设置进行更改/etc/idmapd.conf
。在 RHEL 6.3 及更早版本中,有一个错误导致此设置被忽略:如果您使用的是 NFSv4,则应升级到 6.4 或更高版本。更改域后,您应该nfsidmap -c
在 6.3 及更新版本中运行;在较旧的系统中,您需要重新启动rpc.idmapd
守护程序并重新挂载所有 NFS 挂载。
如果您希望禁用 NFSv4 的 idmapping 功能并转而使用 NFSv3 样式的仅使用 UID/GID 编号(如果您的 NFS 服务器是例如没有客户端系统上的用户帐户信息的 NAS 盒,这可能会很有用),您需要确保nfs
内核模块选项nfsv4_disable_idmapping
已启用:
echo "options nfs nfs4_disable_idmapping=Y" >> /etc/modprobe.d/nfs.conf
此模块选项存在于 RHEL 6.3 及更新版本中,并且应默认启用,但最好确保这一点。
在服务器端,要在 NFSv4 上恢复到 NFSv3 样式的 UID/GID 行为,需要做两件事。首先,需要在nfsd
内核模块上验证(或明确设置)类似的内核选项:
echo "options nfsd nfs4_disable_idmapping=Y" >> /etc/modprobe.d/nfs.conf
其次,NFS 导出的安全性必须sec=sys
。
再次强调,这两个设置在现代系统上都应该是默认设置,但在旧系统上工作时最好验证它们。
在 NetApp NAS 上,在 NFSv4 上启用数字 UID/GID 值的设置如下:
options nfs.v4.id.allow_numerics on
或者:
cluster::> set diag
cluster::*> nfs server modify -vserver vs0 -v4-numeric-ids enabled
取决于 NetApp 版本。
答案2
/home/user/.profile 中的“umask”参数控制授予该用户所创建文件的权限。标准是 umask=022,这意味着文件权限为 755,目录权限为 644。如果您希望所有者和组拥有完全权限,则应为“umask=002”
答案3
这需要比 UNIX 权限能够有效处理的更复杂的权限处理。文件系统 ACL 是您的解决方案。
使用 ACL,您可以从父目录继承权限以及所有权。这将确保无论谁在特定子树中创建了文件或目录,他们都可以从父目录(而不是 umask)获得权限。
深入研究命令 getfacl 和 setfacl。使用默认 ACL,您可以控制此所有权和权限继承。
RHEL 存储管理指南的这一章是有关 ACL 的非常完整的指南,并且它是一个相当权威的资源:https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/ch-acls.html
答案4
如果 PHP 代码可以创建这些文件,那么它应该能够“chmod”它们。
<?php
chmod("/mydir/myfile", 0660);
?>
这里是对 chmod PHP 函数的引用。
如果你想挂载特定 uid/gid(其他 tah nobody/nogroup)的共享,你可以尝试使用 all_squash 导出
/export/myshare x.x.x.x(rw,all_squash,anonuid=<newUID>,anongid=<newGID>,sync)
从https://linux.die.net/man/5/exports:
全部_南瓜
将所有 uid 和 gid 映射到匿名用户。适用于 NFS 导出的公共 FTP 目录、新闻假脱机目录等。相反的选项是 no_all_squash,这是默认设置。
anonuid 和 anongid
这些选项明确设置了匿名帐户的 uid 和 gid。此选项主要用于 PC/NFS 客户端,您可能希望所有请求都来自同一个用户。例如,请考虑下面示例部分中 /home/joe 的导出条目,它将所有请求映射到 uid 150(据称是用户 joe 的 uid)。