NFSv4 用户映射

mat*_*pen 14 ubuntu nfs

这个问题似乎已经被问过很多次了,但其他答案不知何故不适用于我。

基本上我只是设置了一个新的 NFSv4 服务器,我面临着服务器和客户端之间 UID 和 GID 不匹配的经典问题。但是,在我的场景中,同步 /etc/passwd 和 /etc/group 是不可行的。请注意,我在两台机器上都有相同的用户(与此问题相反)。

因此,我正在研究 idmap:根据一些消息来源,似乎 NFSv4 发送用户名(与 NFSv3 发送 UID/GID 的行为相反),而 idmap 的作用是将这些用户名转换为服务器 UID/GID。

但是,这在我的情况下似乎不起作用(下面的设置详细信息),我认为这是非常标准的(几乎只从 repo 安装了 NFS)。

我错过了什么吗?有没有办法在不设置 LDAP 或 Kerberos 的情况下完成这项工作?


服务器设置

服务器已Ubuntu 16.04安装和两个用户。

user1@server:~$ id user1
uid=1000(user1) gid=1000(user1) groups=1000(user1),27(sudo)
user1@server:~$ id user2
uid=1001(user2) gid=1001(user2) groups=1001(user2)
Run Code Online (Sandbox Code Playgroud)

NFS 从 repo 安装并配置为导出测试文件夹。

user1@server:~$ sudo apt-get install nfs-kernel-server

user1@server:~$ sudo cat /proc/fs/nfsd/versions 
+2 +3 +4 +4.1 +4.2

user1@server:~$ ls -ld /srv/nfs/test/
drwxrwxrwx 2 nobody nogroup 4096 nov  2 17:34 /srv/nfs/test/

user1@server:~$ cat /etc/exports 
"/srv/nfs/test" 192.168.x.x(rw,sync,no_subtree_check)
Run Code Online (Sandbox Code Playgroud)

由于服务器和客户端的主机名不同,我更改了 idmapd 配置文件中的“域”值。否则,该文件与包管理器安装的文件相同。请注意,此文件的内容在服务器和客户端上是相同的。

user1@server:~$ cat /etc/idmapd.conf
[General]

Verbosity = 0
Pipefs-Directory = /run/rpc_pipefs
# set your own domain here, if id differs from FQDN minus hostname
Domain = mydomain

[Mapping]

Nobody-User = nobody
Nobody-Group = nogroup
Run Code Online (Sandbox Code Playgroud)

客户端设置

客户端也有Ubuntu 16.04两个用户,但用户名相同但 UID/GID 不同

user1@client:~$ id user1
uid=1001(user1) gid=1002(user1) groups=1002(user1),27(sudo)
user1@client:~$ id user2
uid=1000(user2) gid=1000(user2) groups=1000(user2),27(sudo)
Run Code Online (Sandbox Code Playgroud)

NFS 是从 repo 安装的,并安装了测试共享。

user1@client:~$ sudo apt-get install nfs-common

user1@client:~$ mkdir ./test
user1@client:~$ sudo mount -t nfs4 192.168.x.x:/srv/nfs/test ./test
Run Code Online (Sandbox Code Playgroud)

测试

首先我在客户端创建一个文件,这看起来没问题:

user1@client:~$ touch test/testfile
user1@client:~$ ls -l ./test
total 0
-rw-rw-r-- 1 user1 user1 0 nov  2 17:24 testfile
Run Code Online (Sandbox Code Playgroud)

但是当我从服务器查看文件时,我注意到所有者是错误的,而组不存在。

user1@server:~$ ls -l /srv/nfs/test
total 0
-rw-rw-r-- 1 user2 1002 0 nov  2 17:24 testfile
Run Code Online (Sandbox Code Playgroud)

实验

根据这个对类似问题的回答,应该在服务器上按如下方式激活 id-mapping(注意错误):

user1@server:~$ sudo tee /sys/module/nfsd/parameters/nfs4_disable_idmapping <<< "N"
user1@server:~$ sudo nfsidmap -c
nfsidmap: 'id_resolver' keyring was not found.
user1@server:~$ sudo service rpcidmapd restart
Failed to restart rpcidmapd.service: Unit rpcidmapd.service not found.
user1@server:~$ sudo service nfs-kernel-server restart
Run Code Online (Sandbox Code Playgroud)

在客户端时(注意没有错误):

user1@client:~$ sudo tee /sys/module/nfs/parameters/nfs4_disable_idmapping <<< "N"
user1@client:~$ sudo nfsidmap -c
Run Code Online (Sandbox Code Playgroud)

但结果很奇怪:

user1@client:~$ touch test/testfile
user1@client:~$ ls -l test
total 0
-rw-rw-r-- 1 user2 4294967294 0 nov  2 19:16 testfile
user1@server:~$ ls -l /srv/nfs/project/
total 0
-rw-rw-r-- 1 user2 1002 0 nov  2 19:16 prova
Run Code Online (Sandbox Code Playgroud)

另一个答案建议修改 idmapd 配置如下(两台机器上的内容相同):

user1@server:~$ cat /etc/idmapd.conf 
[General]

Verbosity = 0
Pipefs-Directory = /run/rpc_pipefs
# set your own domain here, if id differs from FQDN minus hostname
Domain = mydomain

[Translation]
   Method=static
[Static]
   user1@mydomain = user1

[Mapping]

Nobody-User = nobody
Nobody-Group = nogroup
Run Code Online (Sandbox Code Playgroud)

但这似乎没有任何区别。

Tho*_*mas 9

NFSv4 不会像您在不使用 Kerberos 和安全风格时所想的那样转换 UID 和 GID。但它确实像你描述的那样起作用。原因是 NFSv4 将使用AUTH_SYS安全性。可以在此处找到更详细的说明。

  • 感谢您的回答和链接,非常有用。但仍然无法将其融入上下文……那么 idmapping 的目的是什么?如果它不适用于 rpc,为什么它被称为“rpcidmapd”?[这些](http://serverfault.com/a/632315/178226) 命令的作用是什么? (2认同)
  • @托马斯正确。当使用“sec=sys”将 ID 映射调为 ON 时,文件会按照 ID mappig 出现,但写入工作就好像根本没有发生 ID 映射一样。另一个[参考](https://www.freebsd.org/cgi/man.cgi?query=nfsv4&amp;manpath=FreeBSD+11.2-RELEASE+and+Ports): *"虽然 NFSv4 中不再使用 uid/gid 数字协议除了上述字符串中的可选内容外,当使用 AUTH_SYS (sec=sys) 时,它们仍将位于 RPC 身份验证字段中,这是默认值。因此,在这种情况下,**用户/组名称和数字空间都必须是客户端和服务器之间保持一致。**"* (2认同)