use*_*827 5 arch-linux nfs systemd netboot nfsv4
更新:5 (20171209)
更新:5 (20171210)
mount -t nfs4 [SERVER IP]:/archlinux /mnt 作品。ss -ntp | grep 2049 客户端在 systemd 开始之前建立到服务器的连接。我正在尝试设置无盘节点/工作站/系统。操作系统 (4.13.12-1-ARCH) 安装在 SERVER 上/srv/archlinux。经过一个从GRUB到NFSv4的成功网络启动,systemd开始,但未能在多个阶段,例如:
Not tainted 4.13.12-1-ARCH #1...或者,
Not tainted 4.13.12-1-ARCH #1...我怀疑这些故障是由 NFSv4 或本地网络的错误配置引起的。
/etc/idmapd.conf
[General]
Verbosity = 7
Pipefs-Directory = /var/lib/nfs/rpc_pipefs
Domain = localdomain
[Mapping]
Nobody-User = nobody
Nobody-Group = nobody
[Translation]
Method = nnswitch
/etc/exports
(printed using # exportfs -v)
/srv <world>(rw,sync,wdelay,hide,no_subtree_check,fsid=0,sec=sys,no_root_squash,no_all_squash)
/srv/archlinux <world>(rw,sync,wdelay,hide,no_subtree_check,sec=sys,no_root_squash,no_all_squash)
(Exposed to "world" for debugging purposes)
Run Code Online (Sandbox Code Playgroud)
在启动期间rpc.idmapd -fvvv单独运行会tty记录以下内容:
rpc.idmapd: libnfsidmap: using domain: localdomain
rpc.idmapd: libnfsidmap: Realms list: 'LOCALDOMAIN'
rpc.idmapd: libnfsidmap: processing 'Method' list
rpc.idmapd: libnfsidmap: loaded plugin /usr/lib/libnfsidmap/nsswitch.so for method nsswitch
rpc.idmapd: Expiration time is 600 seconds.
rpc.idmapd: Opened /proc/net/rpc/nfs4.nametoid/channel
rpc.idmapd: Opened /proc/net/rpc/nfs4.idtoname/channel
rpc.idmapd: nfsdcb: authbuf=* authtype=user
rpc.idmapd: nfs4_uid_to_name: calling nsswitch->uid_to_name
rpc.idmapd: nfs4_uid_to_name: nsswitch->uid_to_name returned 0
rpc.idmapd: nfs4_uid_to_name: final return value is 0
rpc.idmapd: Server : (user) id "0" -> name "root@localdomain"
Run Code Online (Sandbox Code Playgroud)
如果exportfs sec=sys,它会继续如下:
rpc.idmapd: nfsdch: authbuf=* authtype=user
rpc.idmapd: nfs4_name_to_uid: calling nsswitch->name_to_uid
rpc.idmapd: nss_getpwnam: name '0' domain 'localdomain': resulting localname '(null)'
rpc.idmapd: nss_getpwnam: name '0' does not map into domain 'localdomain'
rpc.idmapd: nfs4_name_to_uid: nsswitch->name_to_uid returned -22
rpc.idmapd: nfs4_name_to_uid: final return value is -22
rpc.idmapd: Server : (user) name "0" -> id "99"
(stops here)
Run Code Online (Sandbox Code Playgroud)
+(20171209) 在确保/etc/hostname为 CLIENT 设置为client2(duh) 后,如果exportfs sec=none 或 sec=sys,它会继续如下:
rpc.idmapd: nfsdch: authbuf=* authtype=group
rpc.idmapd: nfs4_gid_to_name: calling nsswitch->gid_to_name
rpc.idmapd: nfs4_gid_to_name: nsswitch->gid_to_name returned 0
rpc.idmapd: nfs4_gid_to_name: final return value is 0
rpc.idmapd: Server : (group) id "190" -> name "systemd-journal@localdomain"
rpc.idmapd: nfsdch: authbuf=* authtype=user
rpc.idmapd: nfs4_name_to_uid: calling nsswitch->name_to_uid
rpc.idmapd: nss_getpwnam: name '0' domain 'localdomain': resulting localname '(null)'
rpc.idmapd: nss_getpwnam: name '0' does not map into domain 'localdomain'
rpc.idmapd: nfs4_name_to_uid: nsswitch->name_to_uid returned -22
rpc.idmapd: nfs4_name_to_uid: final return value is -22
rpc.idmapd: Server : (user) name "0" -> id "99"
(stops here)
Run Code Online (Sandbox Code Playgroud)
如果我改为将方法更改nsswitch为static(NFS 中的 UID 映射)
/etc/idmapd.conf
...
[Translation]
Method = static
[Static]
root@localdomain = root
Run Code Online (Sandbox Code Playgroud)
在rpc.idmapd -fvvv一个单独的tty引导过程中记录的情况如下:
rpc.idmapd: libnfsidmap: using domain: localdomain
rpc.idmapd: libnfsidmap: Realms list: 'LOCALDOMAIN'
rpc.idmapd: libnfsidmap: processing 'Method' list
rpc.idmapd: static_getpwnam: name 'root@localdomain' mapped to 'root'
rpc.idmapd: static_getpwnam: group 'root@localdomain' mapped to ' root'
rpc.idmapd: libnfsidmap: loaded plugin /usr/lib/libnfsidmap/static.so for method static
rpc.idmapd: Expiration time is 600 seconds.
rpc.idmapd: Opened /proc/net/rpc/nfs4.nametoid/channel
rpc.idmapd: Opened /proc/net/rpc/nfs4.idtoname/channel
rpc.idmapd: nfsdcb: authbuf=* authtype=user
rpc.idmapd: nfs4_uid_to_name: calling static->uid_to_name
rpc.idmapd: nfs4_uid_to_name: static->uid_to_name returned 0
rpc.idmapd: nfs4_uid_to_name: final return value is 0
rpc.idmapd: Server : (user) id "0" -> name "root@localdomain"
Run Code Online (Sandbox Code Playgroud)
如果exportfs sec=sys,它会继续如下:
rpc.idmapd: nfsdch: authbuf=* authtype=user
rpc.idmapd: nfs4_name_to_uid: calling static->name_to_uid
rpc.idmapd: nfs4_name_to_uid: static->name_to_uid returned -2
rpc.idmapd: nfs4_name_to_uid: final return value is -2
rpc.idmapd: Server : (user) name "0" -> id "99"
(stops here)
Run Code Online (Sandbox Code Playgroud)
如果exportfs sec=none,它会继续如下:
rpc.idmapd: nfsdch: authbuf=* authtype=group
rpc.idmapd: nfs4_gid_to_name: calling static->gid_to_name
rpc.idmapd: nfs4_gid_to_name: static->gid_to_name returned -2
rpc.idmapd: nfs4_gid_to_name: final return value is -2
rpc.idmapd: Server : (group) id "190" -> name "nobody"
rpc.idmapd: nfsdch: authbuf=* authtype=user
rpc.idmapd: nfs4_name_to_uid: calling static->name_to_uid
rpc.idmapd: nfs4_name_to_uid: static->name_to_uid returned -2
rpc.idmapd: nfs4_name_to_uid: final return value is -2
rpc.idmapd: Server : (user) name "0" -> id "99"
(stops here)
Run Code Online (Sandbox Code Playgroud)
与用户 ID 映射类似的问题:
root存在于 SERVER 和 CLIENT 上,具有相同的密码。我可以在服务器上识别的 NFSv4 的所有其他相关配置文件。
/etc/nsswitch.conf
passwd: compat mymachines systemd
group: compat mymachines systemd
shadow: compat
publickey: files
hosts: files mymachines resolve [!UNAVAIL=return] dns myhostname
networks: files
protocols: files
services: files
ethers: files
rpc: files
netgroup: files
/etc/nfs.conf
(all settings commented out)
/etc/conf.d/nfs-common.conf
(all settings commented out)
Run Code Online (Sandbox Code Playgroud)
SERVER 主机名是server并且有 3 个网络设备 (nd[1-3])。网关default via 192.168.0.1 nd1。
/etc/hosts
127.0.0.1 localhost.localdomain localhost
::1 ip6.localhost localhost
192.168.0.101 nd1.localdomain server servernd1
192.168.1.101 nd2.localdomain server servernd2
192.168.2.101 nd3.localdomain server servernd2
192.168.1.102 client1.localdomain client1
192.168.2.102 client2.localdomain client2
/etc/resolveconf.conf
name_servers=192.168.0.1
# hostname -f
# nd1.localdomain
# hostname -i
192.168.0.101 192.168.1.101 192.168.2.101
# getent hosts IP -> the corresponding line in /etc/hosts
# getent ahosts HOSTNAME -> the corresponding line in /etc/hosts
# ping -c 3 server.localdomain -> 0% packet loss
# id -u root -> 0
# id -un 0 -> root
Display the system's effective NFSv4 domain name on stdout.
# nfsidmap -d -> localdomain
Display on stdout all keys currently in the keyring used to cache ID mapping results. These keys are visible only to the superuser.
# nfsidmap -l -> nfsidmap: '.id_resolver' keyring was not found.
Run Code Online (Sandbox Code Playgroud)
/etc/hostname +(20171209)
client2
/etc/hosts
(exactly the same as the hosts file on the server)
/etc/resolveconf.conf
name_servers=192.168.0.1
/etc/idmapd.conf
(exactly the same as the idmapd.conf file on the server)
/etc/fstab
# sys=sec or sys=none to correspond to server export settings.
/dev/nfs / nfs rw,hard,rsize=9151,sec=sys,clientaddr=192.168.2.102 0 0
devtmpfs /dev devtmpfs defaults
proc /proc proc defaults
none /run tmpfs defaults
sys /sys sysfs defaults
run /run tmpfs defaults
tmp /tmp tmpfs defaults
Run Code Online (Sandbox Code Playgroud)
在fstab通过使用在服务器上比较装入的目录定义findmnt -A。
net_nfs4cat /proc/fs/nfsd/versions -> -2 +3 +4 +4.1 +4.2 cat /sys/module/nfsd/parameters/nfs4_disable_idmapping -> N。echo "options nfsd nfs4_disable_idmapping=0" > /etc/modprobe.d/nfsd.conf。/sys/module/nfs/parameters/nfs4_disable_idmapping上不存在,并且不确定如何手动创建它,因为它/sys是只读的。echo "options nfs nfs4_disable_idmapping=0" > /etc/modprobe.d/nfs.conf。客户端 IP 是192.168.2.102/24. CLIENT 网络设备连接到 SERVER nd2 192.168.2.101/24(主机名:servernd2)。
开机时的网络信息:
:: running early hook [udev]
starting version 235
:: running hook [udev]
:: Triggering uevents...
:: running hook [net_nfs4]
IP-Config: eth0 hardware address [CLIENT NETWORK DEVICE MAC] mtu 1500 DHCP
hostname client2 IP-Config: eth0 guessed broadcast address 192.168.2.255
IP-Config: eth0 complete (from 192.168.0.101):
address: 192.168.2.102 broadcast: 192.168.2.255 netmask: 255.255.255.0
gateway: 192.168.2.101 dns0 : 192.168.0.1 dns1 : 0.0.0.0
host : client2
domain : localdomain
rootserver: 192.168.0.101 rootpath: /srv/archlinux
filename : /netboot/grub/i386-pc/core.0
NFS-Mount: 192.168.2.101:/archlinux
Waiting 10 seconds for device /dev/nfs ...
(systemd takes over from here)
Run Code Online (Sandbox Code Playgroud)
Server : (group) id "190" -> name "nobody"在 NFSv4 中,情况发生了变化:用户按用户名映射,用户名和用户 ID 之间的映射由称为“ID 映射守护程序”(idmapd) 的进程处理。特别是,NFSv4 客户端和服务器应该使用相同的域来使映射正常工作,否则请求将被映射到匿名用户/组。--试用 NFSv4(在 Linux 和 Solaris 上)-- 2012 年 3 月 15 日 - 13:03 / bronto
在理想情况下,请求客户端的用户和组将确定返回数据的权限。我们不是生活在理想的世界里。两个现实世界的问题介入:
- 您可能不信任对服务器文件具有 root 访问权限的客户端的 root 用户。
- 客户端和服务器上的相同用户名可能具有不同的数字 ID
问题 1 在概念上很简单。John Q. Programmer 获得了一台测试机器,他对其具有 root 访问权限。这绝不意味着 John Q. Programmer 应该能够更改服务器上的 root 拥有的文件。因此,NFS 提供了根压缩,这是一种将 uid 0(根)映射到匿名 (nfsnobody) uid 的功能,该 uid 默认为 -2(16 位数字上的 65534)。-- NFS:概述和问题 -- 版权所有 (C) 2003 by Steve Litt
rpc.idmapd: nss_getpwnam: name '0' domain 'localdomain': resulting localname '(null)'根据Steve Dickson 在评论 (2011-08-12 16:01:55 EDT) 中对 Red Hat Bugzilla 的评论 – Bug 715430 报告
[error] 语句说明了问题。本地机器上的 DNS 未设置(或返回 NULL)且 /etc/idmapd.conf 中的 Domain= 变量未设置。
nss_getpwnam: name '0' does not map into domain在 Debian 邮件列表中,Jonas Meurer 和 Christian Seiler (20150722) 之间关于“Kerberos-secured NFSv4”的电子邮件通信中详细解释了错误。我的讨论总结:
当 NFS 客户端发送 nss_getpwnam: name '8' domain 'freesources.org': resulting localname '(null)'
在某些情况下,NFS 客户端仅发送转换为字符串的 uid,而不是正确转换的 NFS 用户名,然后服务器会拒绝该用户名。
客户端应该发送 nss_getpwnam: name 'mail@freesources.org' domain 'freesources.org': resulting localname 'mail'
在这里您可以看到 NFS 客户端传输的所有者名称是“mail@freesources.org”(而不是简单的“8”),因此它包含一个 @;nss_getpwname 可以看到域名匹配并只是将其剥离,从而产生一个用户名“mail”,它在 /etc/passwd 中查找,返回用户 ID(在本例中为 8,因为它在客户端和服务器),服务器非常满意。
那么为什么客户端会发送错误的用户名呢?...每隔一段时间,idmapping 就会失败,所以内核只会发送一个数字。但是这个数字会导致 chown 命令失败,因为服务器不会将它翻译回来。
简短的回答:我不知道。
更长的答案:...
如果我正确理解了较长的答案,则可能会出现问题,因为 NFS 客户端依赖于“内核的密钥缓存”。对于 NFS 服务器,这应该永远不会成为问题,因为从不使用“内核密钥缓存”。
尽管如此,
由于您仅通过 /etc/passwd 使用常规 nsswitch,因此 nss_getpwnam在您的情况下永远不会失败,除非您同时使用 /etc/passwd 做一些奇怪的事情。
答案还提到了 idmapd 的替代方法;nfsidmap,虽然阅读man我不太明白它会如何取代idmapd.
nss_getpwnam: name 'root@domain.com' does not map into domain 'localdomain'我似乎没有出现此错误消息,但是我包含了来自SUSE 支持知识库的答案-- 10-DEC-13 修改日期:12-OCT-17 --因为描述了原因,以及建议的补救措施与其他发现的讨论形成对比。
NFSv4 处理用户身份的方式与 NFSv3 不同。在 v3 中,nfs 客户端将简单地在 chown(和其他请求)中传递一个 UID 号,nfs 服务器会接受它(即使 nfs 服务器不知道具有该 UID 号的帐户)。但是,v4 旨在以@ 的形式传递身份。要正常运行,通常需要 idmapd(id 映射守护进程)在客户端和服务器上处于活动状态,并且每个都将自己视为同一 id 映射域的一部分。
Chown 失败或 idmapd 错误(如上面记录的错误)通常是由以下任一原因造成的:
- 客户端知道用户名但服务器不知道用户名,或者
- idmapd 域名在客户端和服务器上的设置不同。
因此,可以通过确保 nfs 服务器和客户端配置相同的 idmapd 域名 (/etc/idmapd.conf) 并且都知道相关用户名/帐户来解决此问题。
但是,确保双方具有相同的用户帐户知识通常并不方便,尤其是在 nfs 服务器是文件管理器的情况下。NFS 社区已经认识到,NFSv4 的这个 idmapd 功能通常更麻烦,因此值得,因此有一些步骤和修改生效,以允许 NFSv3 行为即使在 NFSv4 下也能工作。
建议的补救措施是禁用 idmapd。
nfs.nfs4_disable_idmapping=1
Run Code Online (Sandbox Code Playgroud)
分析 Wireshark 日志,它非常广泛,但从以下内容开始:
[IP CLIENT] -> [IP SERVER] NFS 226 V4 Call ACCESS FH: [HEX VALUE], [Check: RD LU MD XT DL]
[IP SERVER] -> [IP CLIENT] NFS 238 V4 Reply (Call In 34) ACCESS, [Allowed: RD LU MD XT DL]
[IP CLIENT] -> [IP SERVER] NFS 246 V4 Call LOOKUP DH: [HEX VALUE]/archlinux
Run Code Online (Sandbox Code Playgroud)
其中[A HEX VALUE]/[PATH]可以识别出
类似的模式/sbin, /usr, /bin, /init, /lib, /systemd, /dev, /proc, /sys, /run, /, /lib64。
当 CLIENT 请求/Id-linux-x86-64.so.2第一个错误开始出现时:
[IP CLIENT] -> [IP SERVER] NFS 342 V4 Call OPEN DH: [HEX VALUE]/Id-linux-x86-64.so.2
[SERVER IP] -> [CLIENT IP] NFS 166 V4 Reply (Call In 124) OPEN Status: NFS4ERR_SYMLINK
Run Code Online (Sandbox Code Playgroud)
该模式或多或少地重复出现更频繁的错误,例如,LOOKUP Status;和OPEN Status:报告NFS4ERR_NOENT。
有趣的是,在日志的最后,首先且仅引用了用户权限,
[SERVER IP] -> [CLIENT IP] NFS 182 V4 Reply (Call In 9562) SETATTR Status: NFS4ERR_BADOWNER
Run Code Online (Sandbox Code Playgroud)
根据
当 ACL 属性值中的 owner 或 owner_group 属性值或 ACE 的 who 字段无法转换为本地表示时,将返回此错误。
规范在第 5.9 节中讨论。解释 owner 和 owner_group,我不确定引用什么是相关的。
当当前操作不允许符号链接作为目标时,当前文件句柄指定符号链接。
这表示没有这样的文件或目录。指定名称引用的文件系统对象不存在。
然而,错误是可以预料的......
假定当前文件句柄引用一个命名属性目录的常规目录。LOOKUPP 将其父目录的文件句柄指定为当前文件句柄。如果没有父目录,则必须返回 NFS4ERR_NOENT 错误。因此,当当前文件句柄位于服务器文件树的根或顶部时,服务器将返回 NFS4ERR_NOENT。
mount -t nfs4 [SERVER IP]:/archlinux /mnt在客户端计算机上,使用 Archlinux "LiveUSB" 我能够挂载网络驱动器,通过 SERVER 互联网连接下载最新的内核 (4.14-4-1-ARCH),并在[SERVER IP]/archlinux.
在安装期间rpc.idmapd -fvvv表示用户名映射成功,例如,
rpc.idmapd: Server : (user) id "0" -> name "root@localdomain"
rpc.idmapd: Server : (group) id "99" -> name "nobody@localdomain"
... -> name "tty@localdomain"
... -> name "systemd-journal-upload@localdomain"
... -> name rpc@localdomain
... -> name systemd-journal@localdomain
... -> name utmp@localdomain
Run Code Online (Sandbox Code Playgroud)
结果genfstab也不同:
[SERVER IP]:/archlinux / nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,times=600,retrans=2,sec=sys,clientaddr=[CLIENT IP],local_lock=none,addr=[SERVER IP] 0 0
Run Code Online (Sandbox Code Playgroud)
然而,重新启动systemd后再次失败,并出现与文章开头所述相同的失败。
/new_root?该mkinitcpio脚本使用变量mount_handler进行分配的“安装功能”,在这种情况下nfs_mount_handler(),把其中的“根路径”传递$1在稍后阶段; /new_root.
我想,以验证客户端已经安装了[SERVER IP]:/archlinux的/new_root。在服务器上,我只能观察到客户端已建立连接,但不能观察到目录是否已挂载以及挂载到何处?
showmount -a server -> All mount points on server: (empty)
ss -ntp | grep 2049 ->
ESTAB 0 0 192.168.2.101:2049 192.168.2.102:809 (random port)
Run Code Online (Sandbox Code Playgroud)
sec=sys和 id 映射器不兼容?读取 doco,它看起来像 sec=sys 并且可以使用 id 映射器将 uid/gid 正确映射到名称,其中客户端和服务器在 /etc/passwd 和 /etc/group 中有不同的映射。这根本不是真的。
那是因为使用 sec=sys id 映射器不会在 nfs 协议的身份验证部分发挥作用,仅在文件属性部分发挥作用。使用 sec=sys 身份验证,nfs 只传递服务器直接使用的客户端 uid/gid。因此,如果客户端和服务器的 uid 和 gid 不对齐,权限检查将被搞砸。更令人困惑的是,当客户端创建新文件时,使用的是身份验证凭据,因此该文件是在服务器上使用客户端的 uid/gid 创建的。之后,nfs 使用 idmap 获取文件属性,因此 uid/gid(最初来自客户端)在服务器上被映射,您最终会看到客户端 uid/gid 的服务器名称。波卡奇!另一方面,如果文件最初是在服务器上创建的,您将在客户端看到正确的名称,即使 uid/gid 不同。但是权限检查仍然会被破坏。——kimmie -- 发布时间:2013 年 2 月 20 日星期三上午 3:14 发布主题: -- 强调原文
[NFSv4] 当设置为默认值“1”时,如果挂载使用“sec=sys”安全风格,则此选项可确保 RPC 级别身份验证方案和 NFS 级别操作都同意使用数字 uids/gids。实际上,它禁用了 idmapping,这可以使从旧版 NFSv2/v3 系统迁移到 NFSv4 变得更容易。客户端将自动检测到不支持此操作模式的服务器,并且将回退到使用 idmapper。要关闭此行为,请将值设置为“0”。
[NFSv4] 当设置为默认值“1”时,NFSv4 服务器将仅向使用 auth_sys 的客户端返回数字 uid 和 gid,并将接受来自此类客户端的数字 uid 和 gid。这样做的目的是为了简化从 NFSv2/v3 的迁移。
nfs.nfs4_disable_idmapping=1和nfsd.nfs4_disable_idmapping=1在服务器和客户端上禁用 id 映射器会导致 systemd 启动时出现用户登录提示,仅出现 1 个nfsd.nfs4_disable_idmapping=1错误:nfs.nfs4_disable_idmapping=1
modconf这个问题mkinitcpio;一起block keyboard尝试解决其他明显的问题:没有rpc.idmapd -fvvv输出任何消息。
我可以使用外部 USB 键盘以 root 身份登录、读取和创建文件。我没有进行任何广泛的测试,因此该解决方案仍然可能存在问题。
nfs.nfs4_disable_idmapping=0和nfsd.nfs4_disable_idmapping=0看来echo "options nfs nfs4_disable_idmapping=0" >> /etc/modprobe.d/nfs.conf(或cat /sys/module/nfsd/parameters/nfs4_disable_idmapping -> N) 对 CLIENT 没有任何影响。
CLIENT id 映射器被禁用,直到我在引导期间 (GRUB) 明确地将参数传递nfs.nfs4_disable_idmapping=0给内核。
没有rpc.idmapd -fvvv输出任何投诉。另一方面,在建立第一个之后,它没有打印出任何其他内容rpc.idmapd: Server : (user) id "0" -> name "root@localdomain"......
然而,Wireshark 日志不再记录NFS4ERR_BADOWNER.
尽管如此,所有 systemd 启动失败仍然存在......
nfs.nfs4_disable_idmapping=0和nfsd.nfs4_disable_idmapping=0除了设置 Kerberos 和故障排除之外,我不知道下一步要尝试什么。似乎rpc.idmapd仍然无法映射正确的权限,但rpc.idmapd -fvvv不再输出任何错误......?该怎么办?启动错误可能是由其他原因引起的...我不知道...
nfs.nfs4_disable_idmapping=1和nfsd.nfs4_disable_idmapping=1虽然有效,但这种方法似乎是错误的。我不迁移,我应该能够使用rpc.idmapd. 现在必须这样做;以后它可能会回来咬我……