![NFSv4 错误的有效用户/所有者,sec=krb5 安装压缩为匿名用户](https://linux22.com/image/15393/NFSv4%20%E9%94%99%E8%AF%AF%E7%9A%84%E6%9C%89%E6%95%88%E7%94%A8%E6%88%B7%2F%E6%89%80%E6%9C%89%E8%80%85%EF%BC%8Csec%3Dkrb5%20%E5%AE%89%E8%A3%85%E5%8E%8B%E7%BC%A9%E4%B8%BA%E5%8C%BF%E5%90%8D%E7%94%A8%E6%88%B7.png)
我正在设置 Kerberized NFSv4 供个人使用
- 手动配置NFS、KDC
- 没有名称服务器(使用
/etc/hosts
替代),没有 LDAP - 所有计算机上的相同用户(不一定是相同的 id)并对所有安全模式使用 id 映射(
nfs4_disable_idmapping
设置为“N”)
我有两台机器,都运行 Ubuntu 20.04 LTS
arhiv.pecar
(本地地址192.168.56.200
)有 NFS 服务器和 KDCclient.pecar
(本地地址192.158.56.100
)是客户端
所有管道似乎都可以工作,我可以很好地安装共享,但是
如果共享导出为
sec=sys
服务器
exportfs -v
输出/srv/export <world>(rw,async,wdelay,no_root_squash,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)
客户端
mount
输出arhiv.pecar:/srv/export on /mnt type nfs4 (rw,relatime,vers=4.2,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=krb5,clientaddr=192.168.56.100,local_lock=none,addr=192.168.56.200)
- root 拥有完全的读/写访问权限
- 如果设置了足够的权限,其他用户可以读/写文件
nfsidmap
处于活动状态,列出客户端上的文件正确翻译用户名/组chown
来自客户的是可能的,并正确翻译用户名/组
文件是在 uid/gid 下创建的客户,这意味着它们是用错误的服务器上的 uid / gid
如果服务器碰巧有具有相同 uid 的用户,它会映射到错误的所有者,否则所有者是
nobody:4294967294
有效用户似乎是由客户端 uid 指定的用户。
我想这是一个已知的缺点使用时
sec=sys
如果共享导出为
sec=krb5
服务器
exportfs -v
输出/srv/export <world>(rw,async,wdelay,no_root_squash,no_subtree_check,sec=krb5p:krb5,rw,secure,no_root_squash,no_all_squash)
客户端
mount
输出arhiv.pecar:/srv/export on /mnt type nfs4 (rw,relatime,vers=4.2,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.56.100,local_lock=none,addr=192.168.56.200)
- 所有用户都具有读取权限,没有用户(包括 root)对其拥有的文件/文件夹具有写入权限
- 在文件夹中创建文件
o+w
将在匿名用户下创建它们(nobody:nogroup
或者anonuid:anongid
如果在导出条目中指定) nfsidmap
处于活动状态,列出客户端上的文件正确翻译用户名/组chown
来自客户失败和Operation not permitted.
有效用户似乎是匿名用户。
我不知道这里可能出了什么问题,所以我希望社区能够提供见解。
我可以根据要求提供相关的配置文件(/etc/hosts
、、、、、服务、内核模块列表)。/etc/krb5.conf
/etc/idmapd.conf
/etc/default/nfs-common
答案1
嗯,我发现这是值得理解的如何NFS 和 Kerberos 与用户打交道,以及主体名称如何在这里发挥作用 - 大多数指南中经常忽略的主题。
在基于 Kerberos 的 NFS 中,需要了解以下两者之间的区别:
执行文件操作的有效用户
文件操作的有效(服务器本地)用户由 Kerberos 确定本地授权接口,即通过
auth_to_local
标签配置,如果没有给出,则默认为auth_to_local = DEFAULT
,其操作定义为主体名称将用作本地用户名。如果主体有多个组件或不在默认领域中,则此规则不适用并且转换将失败。
如果转换失败,它假定为匿名用户(
nobody:nogroup
或者anonuid:anongid
如果在导出条目中指定)该文件操作的参数/结果
当NFS服务器执行文件操作时
- 参数需要从客户端提供的用户映射到服务器本地用户(
chown
命令) - 结果需要映射回客户端本地用户(
ls
命令)
这是由或(通常)
id_resolver
中指定的上行调用程序处理的。/etc/request-key.conf
/etc/request-key.d/*
nfsidmap
用户名作为字符串在主机之间传输
user@dns_domain
,并映射到每一侧的本地 uid/gid。- 参数需要从客户端提供的用户映射到服务器本地用户(
执行文件操作的有效用户源自票证(因此我们根据哪个主体进行身份验证很重要),并且不是来自请求文件操作的本地运行进程的 uid(这可能是天真的期望的)。
因此,为了使有效的用户映射发挥作用,需要username
(有效地username@REALM
)创建一个主体,或者,如果使用更复杂的主体名称,请auth_to_local
在 中提供适当的映射/etc/krb5.conf
,如此处所述
- https://access.redhat.com/articles/4040141
- https://blog.samoylenko.me/2015/04/15/hadoop-security-auth_to_local-examples/
- https://community.cloudera.com/t5/Community-Articles/Auth-to-local-Rules-Syntax/ta-p/245316
每个用户应该有自己的默认主体 ( user/client-fqdn
),用于映射到服务器本地用户。
服务主体由服务本身使用和授权,大概用户不需要访问它们(它们应该保留在用户密钥表中/etc/krb5.keytab
,但不应该保留在用户密钥表中)
用户密钥表位置因发行版而异 - 用于krb5-config
确定您的构建所期望的内容
USER_KEYTAB=$(euid=$EUID; eval echo $(krb5-config --defcktname | tr % $ | sed 's/FILE://'))
下面是有关如何通过 Kerberized NFS 为用户正确配置映射的快速演示。
以下配置在通过本指南配置的 CentOS 系统上进行了测试(指南适用于 Centos 7,在 8 上进行了测试,需要进行少量补充)
https://www.linuxhelp.com/how-to-set-up-nfs-server-with-kerberos-based-authentication
# Start kadmin on client machine (I assume that you have the root/admin principal already set up)
#
[root@nfsclient ~]# kadmin -p root/admin
Authenticating as principal root/admin with password.
Password for root/[email protected]:
kadmin: addprinc -randkey -clearpolicy host/nfsclient
Principal "host/[email protected]" created.
kadmin: addprinc -randkey -clearpolicy nfs/nfsclient
Principal "nfs/[email protected]" created.
kadmin: ktadd -k /tmp/krb5.keytab host/nfsclient
Entry for principal host/nfsclient with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/krb5.keytab.
...
kadmin: ktadd -k /tmp/krb5.keytab nfs/nfsclient
Entry for principal nfs/nfsclient with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/krb5.keytab.
...
kadmin: addprinc -randkey -clearpolicy testuser
Principal "[email protected]" created.
kadmin: ktadd -k /tmp/client.keytab testuser
Entry for principal testuser with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/client.keytab.
...
kadmin: quit
# Set up the default keytab (service principals)
[root@nfsclient ~]# mv /tmp/krb5.keytab /etc/krb5.keytab
[root@nfsclient ~]# chown root:root /etc/krb5.keytab
# Set up user keytab
[root@nfsclient ~]# mv /tmp/client.keytab /var/kerberos/krb5/user/$(id -u testuser)/client.keytab
[root@nfsclient ~]# chown testuser:testuser /var/kerberos/krb5/user/$(id -u testuser)/client.keytab
# Mount the filesystem
mount nfsserver.kdc.com:/kerberos /mnt
# Test the user
[root@nfsclient ~]# sudo -i -u testuser
# Check that the users client.keytab, is being picked up
# (can access nfs share)
#
# and that the correct effective user is now used for file operation
# (derived from default principal and mapped to server-local user)
# - the server should also have a `testuser` user
#
[testuser@nfsclient ~]$ touch /mnt/testfile
[testuser@nfsclient ~]$ ls -la /mnt/testfile
-rw-rw-r--. 1 testuser testuser 0 Jun 23 16:31 /mnt/testfile
# After accesses one can check the keys that have been retrieved on
[testuser@nfsclient ~]$ klist
Ticket cache: KCM:1051:17737
Default principal: [email protected]
Valid starting Expires Service principal
06/23/2021 16:06:12 06/24/2021 16:06:12 krbtgt/[email protected]
renew until 06/23/2021 16:06:12
06/23/2021 16:06:12 06/24/2021 16:06:12 nfs/[email protected]
renew until 06/23/2021 16:06:12
答案2
造成这种情况的原因之一可能是,对于那些使用温宾德,是 的 samba (smb.conf) 配置winbind use default domain = no
。
此默认配置使身份验证期望用户名带有前缀DOMAIN\
(例如DOMAIN\alice
:)。
看:https://www.samba.org/samba/docs/current/man-html/smb.conf.5.html#winbindusedefaultdomain
您应该将此参数配置为yes
(在客户端和服务器中),以便能够简单地以 身份登录,su - alice
而不是以 身份登录su - DOMAIN\\alice
。
nfs 服务器将与 kerberos 票证进行比较的名称将是较短的一个。使用默认的较长版本,gss 无法找到用户,因此将其压缩为“nobody”。
至于答案@tpecarkinit
:我自己,通过用户的简单调用,我就正确创建了客户端密钥表。不需要其他任何东西。