尝试浏览 Samba 共享时出现以下错误:
session setup failed: NT_STATUS_NO_IMPERSONATION_TOKEN
我的 Samba 配置用于将独立服务器smbd
与其 MIT Kerberos 和 OpenLDAP 设置绑定在一起,以前可以正常工作(在 Ubuntu 20.04 上肯定可以正常工作,不记得是否在 Ubuntu 22.04 上也曾正常工作过):
<smb.conf>
[global]
# Change this to the workgroup/NT-domain name your Samba server will part of
workgroup = EXAMPLE
# The 'auto' setting here configures Samba based on the value of the
# 'security' setting.
server role = auto
# Configure Samba to call out to Kerberos for all authentication. Because we're
# not also configuring a passdb, Samba will look to the system accounts for all
# authorization info (e.g. UIDs, groups, etc.). This setup was taken from
# https://help.ubuntu.com/lts/serverguide/samba-ldap.html.
security = ads
realm = EXAMPLE.COM
kerberos method = dedicated keytab
dedicated keytab file = /etc/samba/smbd.keytab
idmap config * : backend = tdb
idmap config * : range = 20001-30000
idmap config {{ domain | upper }} : backend = rfc2307
idmap config {{ domain | upper }} : range = 10000-20000
然后我可以获取 Kerberos 票证并浏览和/或挂载 Samba 共享,例如:
$ kinit
Password for [email protected]:
$ /usr/bin/smbclient //neatbox.example.com/share --use-kerberos=required --no-pass --directory somepath --command ls
. D 0 Fri May 6 07:10:08 2022
.. D 0 Fri May 6 07:10:08 2022
stuff D 0 Fri May 6 07:10:08 2022
otherstuff D 0 Fri May 6 07:10:13 2022
957134040 blocks of size 1024. 620537476 blocks available
然而,很久以前,这种方法就失效了(大概一两年前;直到现在才有时间坐下来好好想想;养育孩子是一件很辛苦的事,你知道吗?)。现在我明白了:
$ /usr/bin/smbclient //neatbox.example.com/share --use-kerberos=required --no-pass --directory somepath --command ls
session setup failed: NT_STATUS_NO_IMPERSONATION_TOKEN
我已经花了几个晚上研究,我认为在 Samba 4.14 左右有东西坏了或者被删除了?关于 PAC 的事情,它显然是 Kerberos 票证的一部分...不知何故?[1, 2, 3] 我不知道,我不是 Kerberos 专家;我只是在键盘上乱按,直到一切正常,就像大多数人一样。
所以这是我的主要问题:Samba 是否像以前一样支持通过 MIT Kerberos 和 OpenLDAP 进行身份验证,或者现在是否已被弃用/不受支持?
杂项
smbd
启动/重新启动后,日志中始终会出现以下信息:
$ sudo systemctl status smbd
...
Dec 24 20:53:29 eddings systemd[1]: Starting Samba SMB Daemon...
Dec 24 20:53:29 eddings smbd[782101]: [2023/12/24 20:53:29.593145, 0] ../../source3/smbd/server.c:1734(main)
Dec 24 20:53:29 eddings smbd[782101]: smbd version 4.15.13-Ubuntu started.
Dec 24 20:53:29 eddings smbd[782101]: Copyright Andrew Tridgell and the Samba Team 1992-2021
Dec 24 20:53:29 eddings systemd[1]: Started Samba SMB Daemon.
Dec 24 20:53:30 eddings smbd[782101]: [2023/12/24 20:53:30.244701, 0] ../../source3/printing/nt_printing.c:233(nt_printing_init)
Dec 24 20:53:30 eddings smbd[782101]: nt_printing_init: error checking published printers: WERR_ACCESS_DENIED
有时,它还会出现一系列不可重现的错误:
Dec 24 11:06:27 eddings smbd[766136]: [2023/12/24 11:06:27.972690, 0] ../../source3/auth/auth_winbind.c:120(check_winbind_security)
Dec 24 11:06:27 eddings smbd[766136]: check_winbind_security: winbindd not running - but required as domain member: NT_STATUS_NO_LOGON_SERVERS
不确定它们是否相关,但smbclient
失败似乎不会触发它们,所以......它们是可能无关。
[1]https://bugzilla.samba.org/show_bug.cgi?id=14901(我尝试了那里的username map script
设置local nt token from
,但没有作用)
答案1
PAC,即“特权属性证书”,是 KDC 向 Kerberos 票证附加额外信息的一种方式。虽然票证通常只指示主体名称而不指示其他任何内容,但 PAC 还可以提供 Windows SID、组成员身份、主目录……避免服务器从 LDAP 或其他地方获取这些信息。DCE 和 Active Directory 到处都使用 PAC;MIT/Heimdal Kerberos 传统上不使用。
Samba 在最新版本中重新设计了其 Kerberos 支持,以弥补几个主要的安全漏洞。作为重新设计的一部分(也许是不必要的部分,但它确实降低了代码复杂性),作为 Active Directory 域一部分的 Samba 服务器需要 PAC,而作为 Active Directory 域一部分的 Samba 服务器不是AD 成员则采取相反的做法,完全拒绝带有 PAC 的票证(因为传统上 MIT Kerberos 和 Heimdal 根本不使用它们)。
因此,第一个问题是您在使用security = ads
时实际上根本没有 ADS。此选项启用 Samba 的“Active Directory”模式,并要求 PAC 在 Kerberos 票证中包含特定于 AD 的信息,而您无法提供这些信息,这会导致“NO_IMPERSONATION_TOKEN”错误。
您不需要security = ads
只在 Samba 中使用 Kerberos。删除它并使用默认安全模式。
第二个问题是,上面的内容有点谎言,最近 MIT Kerberos做过开始使用 PAC 发出票证(以解决与 S4U 相关的另一个安全问题)...尽管它们是空的 PAC,没有 Sambaads
模式所需的任何 AD 属性(没有 SID,没有组成员身份)——这些 PAC 仅仅因为它们携带的数字签名而存在——所以它们不会满足 Samba 的广告模式要求。
然而,这些空的 PAC 仍然是 PAC,当 Samba 用作独立服务器时,它们将被拒绝,并出现略有不同的“BAD_TOKEN”错误。要解决这个问题,您需要将 Samba 主体标记cifs/*
为不需要 PAC:
# kadmin
kadmin: modprinc +no_auth_data_required cifs/neatbox.example.com
...并丢弃您可能拥有的该服务的所有缓存票:
$ kinit -R
答案2
Samba 是一套协同工作的守护进程。如果您运行域成员配置,winbindd 也必须运行,这种情况已经持续了好几年了。请确保 smbd 和 winbindd 都在运行。smbd 过去有一个后备代码来处理现在完全由 winbindd 处理的任务。