我想挂载 NFS4 共享,但启用 Kerberos 安全性。这是我的设置:
Debian 服务器(dns fqdn:nfsv4test.subnet.example.org)
Debian 客户端(dns fqdn:nfsv4client.subnet.example.org)
Windows ADC,也可用作 KDC
我的领域是 REALM.EXAMPLE.ORG
两台 Debian 机器所在的子网称为 subnet.example.org
没有进行 NAT。
两台机器都是最新的。
因此,当我仍在努力解决 Kerberos 问题时,我便尝试实现我的目标:
第一章:设置
1- 将两台机器放在同一个领域/域中(这已经由其他人设置并且可以工作)
2- 每台机器创建两个用户(用户,不是计算机!):nfs-nfsv4client、host-nfsv4client、nfs-nfsv4test 和 host-nfsv4test 创建后,我为所有帐户启用了 AES256 位加密。
3- 为用户设置服务主体:
setspn -S nfs/[email protected] nfs-nfsv4test
我为所有 4 位用户/负责人都执行了此操作。
3-在Windows KDC上创建密钥表:
ktpass -princ host/[email protected] +rndPass -mapuser [email protected] -pType KRB5_NT_PRINCIPAL -out c:\temp\host-nfsv4test.keytab -crypto AES256-SHA1
所以从那以后我就有了 4 个 keytab。
4-合并服务器(和客户端)上的密钥表:
ktutil
read_kt host-nfsv4test.keytab
read_kt nfs-nfsv4test.keytab
write_kt /etc/krb5.keytab
该文件有 640 个权限。
5- 导出服务器上的目录;这在没有 kerberos 的情况下已经起作用了。启用 Kerberos 后,导出文件如下所示:
/srv/kerbnfs4 gss/krb5(rw,sync,fsid=0,crossmnt,no_subtree_check,insecure)
/srv/kerbnfs4/homes gss/krb5(rw,sync,no_subtree_check,insecure)
运行 exportfs -rav 有效:
root@nfsv4test:~# exportfs -rav
exporting gss/krb5:/srv/kerbnfs4/homes
exporting gss/krb5:/srv/kerbnfs4
...并且在客户端上我可以看到服务器上的挂载:
root@nfsv4client:~# showmount -e nfsv4test.subnet.example.org
Export list for nfsv4test.subnet.example.org:
/srv/kerbnfs4/homes gss/krb5
/srv/kerbnfs4 gss/krb5
6a- krb5.conf 具有其设置环境的默认配置,我没有更改任何内容:
[libdefaults]
ticket_lifetime = 24000
default_realm = REALM.EXAMPLE.ORG
default_tgs_entypes = rc4-hmac des-cbc-md5
default_tkt__enctypes = rc4-hmac des-cbc-md5
permitted_enctypes = rc4-hmac des-cbc-md5
dns_lookup_realm = true
dns_lookup_kdc = true
dns_fallback = yes
# The following krb5.conf variables are only for MIT Kerberos.
kdc_timesync = 1
ccache_type = 4
forwardable = true
proxiable = true
# The following libdefaults parameters are only for Heimdal Kerberos.
fcc-mit-ticketflags = true
[realms]
REALM.EXAMPLE.ORG = {
kdc = kdc.realm.example.org
default_domain = kds.realm.example.org
}
[domain_realm]
.realm.example.org = KDC.REALM.EXAMPLE.ORG
realm.example.org = KDC.REALM.EXAMPLE.ORG
[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}
6-然后我像这样设置了我的 sssd.conf,但我还没有真正明白这里发生了什么:
[sssd]
domains = realm.example.org
services = nss, pam
config_file_version = 2
[nss]
filter_groups = root
filter_users = root
default_shell = /bin/bash
[pam]
reconnection_retries = 3
[domain/realm.example.org]
krb5_validate = True
krb5_realm = REALM.EXAMPLE.ORG
subdomain_homedir = %o
default_shell = /bin/bash
cache_credentials = True
id_provider = ad
access_provider = ad
chpass_provider = ad
auth_provide = ad
ldap_schema = ad
ad_server = kdc.realm.example.org
ad_hostname = nfsv4test.realm.example.org
ad_domain = realm.example.org
ad_gpo_access_control = permissive
use_fully_qualified_names = False
ad_enable_gc = False
7- 两台机器上的 idmap.conf:
[General]
Verbosity = 0
Pipefs-Directory = /run/rpc_pipefs
Domain = realm.example.org
[Mapping]
Nobody-User = nobody
Nobody-Group = nogroup
8- 两台机器上的 /etc/default/nfs-common:
NEED_STATD=yes
NEED_IDMAPD=yes
NEED_GSSD=yes
9- 最后但同样重要的是,服务器上的 nfs-kernel-server:
RPCNFSDCOUNT=8
RPCNFSDPRIORITY=0
RPCMOUNTDOPTS="--manage-gids --no-nfs-version 3"
NEED_SVCGSSD="yes"
RPCSVCGSSDOPTS=""
10-然后,重新启动服务器和客户端后,我尝试挂载共享(以 root 用户身份):
mount -t nfs4 -o sec=krb5 nfsv4test.subnet.example.org:/srv/kerbnfs4/homes /media/kerbhomes -vvvv
但遗憾的是,挂载不起作用。我没有访问权限。第一次尝试时,花了很长时间,这是输出:
root@nfsv4client:~# mount -t nfs4 -o sec=krb5 nfsv4test.subnet.example.org:/srv/kerbnfs4/homes /media/kerbhomes
mount.nfs4: timeout set for Wed Dec 15 15:38:09 2021
mount.nfs4: trying text-based options 'sec=krb5,vers=4.2,addr=********,clientaddr=*******'
mount.nfs4: mount(2): Permission denied
mount.nfs4: access denied by server while mounting nfsv4test.subnet.example.org:/srv/kerbnfs4/homes
第二章:调试
为了获得更详细的日志,我运行
rpcdebug -m nfsd -s lockd
rpcdebug -m rpc -s call
在服务器上,但我并没有得到那么多日志。
但是,尝试挂载时,系统日志告诉我:
Dec 6 11:20:02 testserver kernel: [ 2088.771800] svc: server 00000000c1c7fb25, pool 0, transport 00000000c5641df0, inuse=2
Dec 6 11:20:02 testserver kernel: [ 2088.771808] svc: svc_authenticate (0)
Dec 6 11:20:02 testserver kernel: [ 2088.771811] svc: calling dispatcher
Dec 6 11:20:02 testserver kernel: [ 2088.771840] svc: server 00000000c1c7fb25, pool 0, transport 00000000c5641df0, inuse=2
Dec 6 11:20:02 testserver kernel: [ 2088.773222] svc: server 00000000c1c7fb25, pool 0, transport 00000000fc9bd395, inuse=2
Dec 6 11:20:02 testserver kernel: [ 2088.774697] svc: server 00000000c1c7fb25, pool 0, transport 00000000fc9bd395, inuse=2
Dec 6 11:20:02 testserver kernel: [ 2088.774705] svc: svc_authenticate (6)
Dec 6 11:20:02 testserver kernel: [ 2088.774711] RPC: Want update, refage=120, age=0
Dec 6 11:20:02 testserver kernel: [ 2088.774712] svc: svc_process close
[... 7x same message ]
Dec 6 11:20:02 testserver kernel: [ 2088.791514] svc: server 00000000c1c7fb25, pool 0, transport 00000000c5641df0, inuse=2
Dec 6 11:20:02 testserver kernel: [ 2088.791519] svc: svc_authenticate (1)
Dec 6 11:20:02 testserver kernel: [ 2088.791521] svc: authentication failed (1)
Dec 6 11:20:02 testserver kernel: [ 2088.791538] svc: server 00000000c1c7fb25, pool 0, transport 00000000c5641df0, inuse=2
Dec 6 11:20:02 testserver kernel: [ 2088.791913] svc: server 00000000c1c7fb25, pool 0, transport 00000000c5641df0, inuse=2
Dec 6 11:20:02 testserver kernel: [ 2088.791918] svc: svc_authenticate (1)
Dec 6 11:20:02 testserver kernel: [ 2088.791920] svc: authentication failed (1)
Dec 6 11:20:02 testserver kernel: [ 2088.791940] svc: server 00000000c1c7fb25, pool 0, transport 00000000c5641df0, inuse=2
Dec 6 11:20:02 testserver kernel: [ 2088.792292] svc: server 00000000c1c7fb25, pool 0, transport 00000000c5641df0, inuse=2
Dec 6 11:20:02 testserver kernel: [ 2088.792296] svc: svc_authenticate (1)
Dec 6 11:20:02 testserver kernel: [ 2088.792298] svc: authentication failed (1)
Dec 6 11:20:02 testserver kernel: [ 2088.792316] svc: server 00000000c1c7fb25, pool 0, transport 00000000c5641df0, inuse=2
由于这实际上对我没有任何帮助,我使用 tcpdump 记录了流量,结果如下:
11:12:02.856200 IP ip-client.740 > ip-server.nfs: Flags [S], seq 763536441, win 65160, options [mss 1460,sackOK,TS val 2364952579 ecr 2826266858,nop,wscale 7], length 0
11:12:02.856295 IP ip-server.nfs > ip-client.740: Flags [S.], seq 2444950221, ack 763536442, win 65160, options [mss 1460,sackOK,TS val 2826266858 ecr 2364952579,nop,wscale 7], length 0
11:12:02.856304 IP ip-client.740 > ip-server.nfs: Flags [.], ack 1, win 510, options [nop,nop,TS val 2364952579 ecr 2826266858], length 0
11:12:02.856324 IP ip-client.740 > ip-server.nfs: Flags [P.], seq 1:245, ack 1, win 510, options [nop,nop,TS val 2364952579 ecr 2826266858], length 244: NFS request xid 4035461122 240 getattr fh 0,2/42
11:12:02.856408 IP ip-server.nfs > ip-client.740: Flags [.], ack 245, win 508, options [nop,nop,TS val 2826266858 ecr 2364952579], length 0
11:12:02.856421 IP ip-server.nfs > ip-client.740: Flags [P.], seq 1:25, ack 245, win 508, options [nop,nop,TS val 2826266858 ecr 2364952579], length 24: NFS reply xid 4035461122 reply ERR 20: Auth Bogus Credentials (seal broken)
11:12:02.856425 IP ip-client.740 > ip-server.nfs: Flags [.], ack 25, win 510, options [nop,nop,TS val 2364952579 ecr 2826266858], length 0
11:12:02.867582 IP ip-client.740 > ip-server.nfs: Flags [F.], seq 245, ack 25, win 510, options [nop,nop,TS val 2364952590 ecr 2826266858], length 0
11:12:02.867751 IP ip-server.nfs > ip-client.740: Flags [F.], seq 25, ack 246, win 508, options [nop,nop,TS val 2826266869 ecr 2364952590], length 0
11:12:02.867759 IP ip-client.740 > ip-server.nfs: Flags [.], ack 26, win 510, options [nop,nop,TS val 2364952590 ecr 2826266869], length 0
(我删除了真实的 IP 地址)
所以这里最有趣的部分是 Auth Bogus(封条破损)?真的有什么问题吗?还是只是在出现问题时出现的错误?我在网上找不到有关此错误的任何有用信息。
回到 Kerberos 本身,密钥表似乎没问题:
root@nfsv4client:~# klist -k -e
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
7 host/[email protected]
6 nfs/[email protected]
当尝试测试 keytab 文件时,它似乎有效:
root@nfsv4client:~# kinit -k nfs/nfsv4client.realm.example.org
root@nfsv4client:~#
但在这一页据称应该使用以下方法测试 keytab
kinit -k `hostname -s`$
其解析为
kinit -k nfsv4client
由于没有找到密钥,因此不起作用[email protected]
。那么是密钥表错误还是测试方法错误?
我在安装客户端机器上发现的另一个日志(在消息中):
nfsv4client kernel: [ 4355.170940] svc: initialising pool 0 for NFSv4 callback
nfsv4client kernel: [ 4355.170940] nfs_callback_create_svc: service created
nfsv4client kernel: [ 4355.170941] NFS: create per-net callback data; net=f0000098
nfsv4client kernel: [ 4355.170942] svc: creating transport tcp-bc[0]
nfsv4client kernel: [ 4355.171032] nfs_callback_up: service started
nfsv4client kernel: [ 4355.171033] svc: svc_destroy(NFSv4 callback, 2)
nfsv4client kernel: [ 4355.171034] NFS: nfs4_discover_server_trunking: testing 'nfsv4test.subnet.example.org'
nfsv4client kernel: [ 4355.171040] RPC: new task initialized, procpid 9204
nfsv4client kernel: [ 4355.171041] RPC: allocated task 000000006bdb9e01
nfsv4client kernel: [ 4355.171042] RPC: 110 __rpc_execute flags=0x5280
nfsv4client kernel: [ 4355.171044] RPC: 110 call_start nfs4 proc EXCHANGE_ID (sync)
nfsv4client kernel: [ 4355.171045] RPC: 110 call_reserve (status 0)
nfsv4client kernel: [ 4355.171046] RPC: wake_up_first(000000005af696f3 "xprt_sending")
nfsv4client kernel: [ 4355.171047] RPC: 110 reserved req 00000000d1a7d1a4 xid 04f914c3
nfsv4client kernel: [ 4355.171047] RPC: 110 call_reserveresult (status 0)
nfsv4client kernel: [ 4355.171048] RPC: 110 call_refresh (status 0)
nfsv4client kernel: [ 4355.171049] RPC: gss_create_cred for uid 0, flavor 390004
nfsv4client kernel: [ 4355.171050] RPC: gss_create_upcall for uid 0
nfsv4client kernel: [ 4355.171052] RPC: __gss_find_upcall found nothing
nfsv4client kernel: [ 4355.201976] RPC: __gss_find_upcall found msg 000000000e5abcbc
nfsv4client kernel: [ 4355.201978] RPC: gss_fill_context returns error 13
nfsv4client kernel: [ 4355.201982] RPC: gss_pipe_downcall returning 16
nfsv4client kernel: [ 4355.201986] RPC: gss_create_upcall for uid 0 result -13
nfsv4client kernel: [ 4355.201987] RPC: 110 call_refreshresult (status -13)
nfsv4client kernel: [ 4355.201988] RPC: 110 call_refreshresult: refresh creds failed with error -13
nfsv4client kernel: [ 4355.201989] RPC: 110 return 0, status -13
nfsv4client kernel: [ 4355.201990] RPC: 110 release task
内容很多,但是我找不到错误 -13 的含义,只知道它是“权限被拒绝”。
第三章:问题
主体位于密钥表中。因此,当客户端向服务器询问 NFS 共享并尝试访问它时,双方都应该拥有密钥才能相互交互。但由于某种原因,它不起作用。可能是因为将主体分配给了用户帐户?
我该如何让它工作?如何在调试时获取更好的信息?抱歉,文字太多了。
PS.我主要关注的是本教程。它看起来与我的环境完美匹配。
答案1
将我的评论变成答案......
SUBNET.EXAMPLE.ORG
实际上不存在(很可能)。您的领域/域/森林是REALM.EXAMPLE.ORG
,因此该域中的每个对象都有该领域。看来 subnet.example.org 只是您为了命名方便而编造的,很可能。
因此,如果您想使用SUBNET.EXAMPLE.ORG
,则需要为领域 subnet.example.org 拥有适当的 SRV 记录,它们需要指向 AD 域控制器,必须将 AD 配置为将其用作别名领域(不确定 Microsoft 的实现是否严格可行)。此外,连接的客户端和域控制器应将 FQDN 解析为 IP,并将 IP 解析为 FQDN。
我还会从您的 SPN 中删除所有“简称”。坚持使用<service>\<FQDN>
或host\<FQDN>
UserPrincipalName
您的 sssd.conf 中的此行无效。
ad_hostname = nfsv4test.subnet.example.org
域中的所有计算机realm.example.com
的 FQDN 都是<computername>@realm.example.com
。故事结束。您可以使用 DNS 来解析具有其他名称的计算机,但在 AD/LDAP 中,计算机帐户将永远只能通过<computername>@realm.example.com
简而言之,为了使其立即工作,请subnet.example.org
在realm.example.org
您尝试过的所有操作中替换它,然后它就应该可以正常工作了。