我在 Ubuntu Server 22.04 上有一个现有的 openldap 服务器,并正在尝试按照以下指南使用它设置 kerberos 服务器:https://ubuntu.com/server/docs/service-kerberos-with-openldap-backend
帐户已创建并测试,它们工作正常(我通过 cn 引用它们,但它们有一个 uid;我只是先在 apache 目录工作室中创建它们)。我已经完成了“dpkg-reconfigure krb5-config”并编辑了 /etc/krb5.conf 以添加我的服务器和领域。该文档中没有但我在其他地方看到的一件事是创建一个部分“[domain_realm]”并将我的域添加到其中,我已经这样做了但没有帮助。我创建了一个日志记录部分,这需要修改 systemd 服务以允许写入 /var/log/kerberos,但这没问题。然后我运行列出的“kdb5_ldap_util”命令,输入密码后它似乎成功完成。我对 kdc-service 和 kadmin-service 密码进行了存储,成功完成。我创建了 kadm.acl 文件,这很好,然后当我尝试启动服务时,我在 krb5kdc.log 中得到了这个:
krb5kdc[712216](Error): Cannot find master key record in database - while fetching master keys list for realm SUBDOMAIN.DOMAIN.COM
如果我运行“kadmin.local”,我会得到以下结果:
Authenticating as principal root/[email protected] with password.
kadmin.local: Cannot find master key record in database while initializing kadmin.local interface
事实证明,文件 /var/lib/krb5kdc/principal 从未被创建。我不确定这里还有什么可以排除故障的,但目前我陷入困境,任何指导都将不胜感激。以下配置文件,域和子域已更改:
/etc/krb5.conf:
[libdefaults]
default_realm = SUBDOMAIN.DOMAIN.COM
# The following krb5.conf variables are only for MIT Kerberos.
kdc_timesync = 1
ccache_type = 4
forwardable = true
proxiable = true
# The following encryption type specification will be used by MIT Kerberos
# if uncommented. In general, the defaults in the MIT Kerberos code are
# correct and overriding these specifications only serves to disable new
# encryption types as they are added, creating interoperability problems.
#
# The only time when you might need to uncomment these lines and change
# the enctypes is if you have local software that will break on ticket
# caches containing ticket encryption types it doesn't know about (such as
# old versions of Sun Java).
# default_tgs_enctypes = des3-hmac-sha1
# default_tkt_enctypes = des3-hmac-sha1
# permitted_enctypes = des3-hmac-sha1
# The following libdefaults parameters are only for Heimdal Kerberos.
fcc-mit-ticketflags = true
[logging]
kdc = FILE:/var/log/kerberos/krb5kdc.log
admin_server = FILE:/var/log/kerberos/kadmin.log
default = FILE:/var/log/kerberos/krb5lib.log
[realms]
SUBDOMAIN.DOMAIN.COM = {
kdc = hostname.subdomain.domain.com
admin_server = hostname.subdomain.domain.com
default_domain = subdomain.domain.com
database_module = openldap_ldapconf
}
[domain_realm]
.subdomain.domain.com = SUBDOMAIN.DOMAIN.COM
subdomain.domain.com = SUBDOMAIN.DOMAIN.COM
[dbdefaults]
ldap_kerberos_container_dn = cn=krbContainer,dc=subdomain,dc=domain,dc=com
[dbmodules]
openldap_ldapconf = {
db_library = kldap
# if either of these is false, then the ldap_kdc_dn needs to
# have write access
disable_last_success = true
disable_lockout = true
# this object needs to have read rights on
# the realm container, principal container and realm sub-trees
ldap_kdc_dn = "cn=kdc-service,ou=accounts,dc=subdomain,dc=domain,dc=com"
# this object needs to have read and write rights on
# the realm container, principal container and realm sub-trees
ldap_kadmind_dn = "cn=kadmin-service,ou=accounts,dc=subdomain,dc=domain,dc=com"
ldap_service_password_file = /etc/krb5kdc/service.keyfile
ldap_servers = ldapi:///
ldap_conns_per_server = 5
}
/etc/krb5kdc/kadm5.acl:
*/[email protected] *
/etc/krb5kdc/kdc.conf:
[kdcdefaults]
kdc_ports = 750,88
[realms]
SUBDOMAIN.DOMAIN.COM = {
database_name = /var/lib/krb5kdc/principal
admin_keytab = FILE:/etc/krb5kdc/kadm5.keytab
acl_file = /etc/krb5kdc/kadm5.acl
key_stash_file = /etc/krb5kdc/stash
kdc_ports = 750,88
max_life = 10h 0m 0s
max_renewable_life = 7d 0h 0m 0s
master_key_type = des3-hmac-sha1
#supported_enctypes = aes256-cts:normal aes128-cts:normal
default_principal_flags = +preauth
}
编辑:根据 user1686 的评论,我现在发现我有一个潜在的帐户访问问题。我对这部分有点困惑,但使用“slapcat -b cn=config”,我有以下 olcAccess 规则:
olcAccess: {0}to * by dn="cn=admin,dc=subdomain,dc=domain,dc=com" manage by dn="cn=surfrock66,ou=accounts,dc=subdomain,dc=domain,dc=com" manage by dn="cn=ldapbinduser,ou=accounts,dc=subdomain,dc=domain,dc=com" read by * break
olcAccess: {1}to dn.children="ou=accounts,dc=subdomain,dc=domain,dc=com" attrs=userPassword,shadowExpire,shadowInactive,shadowLastChange,shadowMax,shadowMin,shadowWarning by self write by anonymous auth
olcAccess: {2}to attrs=krbPrincipalKey by anonymous auth by dn.exact="cn=kdc-service,ou=accounts,dc=subdomain,dc=domain,dc=com" read by dn.exact="cn=kadmin-service,ou=accounts,dc=subdomain,dc=domain,dc=com" write by self write by * none
olcAccess: {3}to dn.subtree="cn=krbContainer,dc=subdomain,dc=domain,dc=com" by dn.exact="cn=kdc-service,ou=accounts,dc=subdomain,dc=domain,dc=com" read by dn.exact="cn=kadmin-service,ou=accounts,dc=subdomain,dc=domain,dc=com" write by * none
olcAccess: {4}to dn.subtree="dc=subdomain,dc=domain,dc=com" by self read
2022.12.08-08-36 PST 编辑:所以我走得更远,并且做了以下事情:
addprinc ldap/[email protected]
ktadd -k /etc/ldap/kerberos.ldap.hostname.subdomain.domain.com.keytab ldap/hostname.subdomain.domain.com
chown openldap:openldap /etc/ldap/kerberos.ldap.hostname.subdomain.domain.com.keytab
chmod 640 /etc/ldap/kerberos.ldap.hostname.subdomain.domain.com.keytab
我编辑了 /etc/default/slapd 并将以下内容添加到其中:
export KRB5_KTNAME="FILE:/etc/ldap/kerberos.ldap.hostname.subdomain.domain.com.keytab"
当我重新启动服务时,testsaslauthd 仍然有效,但 ldapsearch -D 无效。我想知道我是否需要在 ldap 中进行配置更改?从我正在使用的资源之一中,我为配置构建了这个 ldif,但最终我认为我不明白它会做什么以及它是否正确:
dn: cn=config
changetype: modify
add: olcSaslHost
olcSaslHost: hostname.subdomain.domain.com
-
add: olcSaslRealm
olcSaslRealm: SUBDOMAIN.DOMAIN.COM
-
add: olcAuthzRegexp
olcAuthzRegexp: {0}"cn=([^/]*),cn=subdomain.domain.com,cn=GSSAPI,cn=auth" "cn=$1,ou=accounts,dc=subdomain,dc=domain,dc=com"
-
add: olcAuthzRegexp
olcAuthzRegexp: {1}"cn=host/([^/]*).subdomain.domain.com,cn=subdomain.domain.com,cn=GSSAPI,cn=auth" "cn=$1,ou=hosts,dc=subdomain,dc=domain,dc=com"
-
add: olcAuthzRegexp
olcAuthzRegexp: {2}"uid=ldap/admin,cn=subdomain.domain.com,cn=GSSAPI,cn=auth" "cn=admin,dc=subdomain,dc=domain,dc=com"
我认为这是最后一个缺失的步骤?配置中是否有东西将 LDAP 指向 sasl?还是我的方法完全错误?
答案1
principal
是包含 DB2 格式的 KDC 数据库的文件。它未在您的系统上创建,因为您不使用后端db2
——你正在使用 LDAP,它取代全部KDC 的本地存储——因此本地数据库文件是不必要的,并且与您遇到的问题无关。
如果您按照说明运行kdb5_ldap_util create
,则应通过 LDAP 检查它是否确实创建了必要的条目 — 至少应该有一个条目K/M@<realm>
和另一个条目krbtgt/<realm>@<realm>
。错误消息是关于“K/M”条目的,这是一个伪主体,其中包含数据库 mkey(使用“主密钥”密码加密)。
确保使用 KDC 的帐户检查 LDAP,以防它没有被授予读取 Kerberos LDAP 对象的必要权限。(帐户没有需要拥有一个 uid;它们仅用作 LDAP 绑定帐户,而不是本地 Unix 帐户。)
由于 Ubuntu 有时会使用 AppArmor,因此请务必检查dmesg
AVC 拒绝消息 - 可能是 KDC 不允许读取“service.keyfile”或访问您的 OpenLDAP 套接字。
此外,stats
在您的 LDAP 服务器中启用日志级别以让其记录所有查询 - 例如,这可以揭示 KDC 正在不同的 DN 下查找(通常“ldap_kerberos_container_dn”将设置在其他 dbmodules 参数旁边)。
最后,如果strace kadmin.local
显示该工具实际上并未连接到 LDAP,而是尝试访问本地 db2 文件,则可能是您在kdc.conf
(KDC 特定的配置文件)中的配置覆盖了 krb5.conf 中的系统范围设置。通常,KDC 配置从 krb5.conf 全局设置加载/var/lib/krb5kdc/kdc.conf
,并且优先级高于 krb5.conf 全局设置。
(此外,如果你是使用 db2,主体数据库仍然不会在首次启动时自动创建——这需要通过运行kdb5_util create [-s]
并提供主加密密钥手动完成,就像您使用“kdb5_ldap_util create”为 LDAP 后端所做的那样。)
该文档中没有提到但我在其他地方看到过的一件事是创建一个部分“[domain_realm]”并将我的域添加到其中,我已经这样做了但没有帮助。
仅当 Kerberos 客户端获取未 1:1 映射到其领域的主机名的票证时才需要此信息(典型示例为 mit.edu → ATHENA.MIT.EDU)。它与 KDC 的启动无关。
我创建了一个日志记录部分,它需要修改 systemd 服务以允许写入 /var/log/kerberos,
如果您登录则不会发生这种情况SYSLOG
,这可能是为 Ubuntu 编写 systemd 服务的人的意图。
由于我的存储在 LDAP 中,所以它不在那里吗?
不,/etc/krb5.keytab 文件不是 KDC 数据库的一部分 – 它属于主持人作为“域成员”,并存储相当于机器帐户的 Kerberos 密码的内容。Kerberos 域中的每台机器都应有自己的 /etc/krb5.keytab,其中至少包含主体host/<fqdn>
。
我正在尝试让 LDAP 直通身份验证工作,以便 kerberos 密码是真实的;我发现很多文档都比较旧。我看到大多数人推荐 saslauthd,我认为我已经设置了,但现在它正在寻找 /etc/krb5.keytab
对于 OpenLDAP,是的,通常您需要 saslauthd。
- 当绑定到具有的 DN 时
userPassword: {SASL}foo@BAR
,slapd 将使用 libsasl 的“密码检查”功能。 - 取决于配置pwcheck_方法,libsasl 将联系 saslauthd 来验证密码。
- saslauthd 将使用通过其选项配置的后端
-a
进行实际验证。 - 通过
-a krb5
后端,saslauthd 将尝试使用提供的用户名和密码从 KDC 获取初始 Kerberos 票证(相当于kinit
)。 - 如果成功获取初始票证,saslauthd 将另外请求自己的服务票并将尝试使用机器的密钥表对其进行解密。
- 如果可以获取服务票并解密,密码被接受。
最后一步是防止 KDC 欺骗攻击所必需的。传统上,Kerberos KDC 会在不验证您的密码的情况下颁发票证(错误的密码只意味着客户端无法解密收到的票证),而恶意 KDC 仍然可以这样做 - “预认证”在协议级别不是强制性的。因此,saslauthd 需要执行任何其他 Kerberized 服务所做的相同操作来验证票证是否合法 - 尝试使用服务密钥表对其进行解密。(pam_krb5 甚至 Windows 在 AD 登录期间都会执行相同的操作。)
我创建了 host/hostname.fqdn@REALM 和 ldap/hostname.fqdn@REALM。我为 ldap 创建了一个密钥表;我将 1 个用户的密码转换为“{SASL}name@REALM”。对该用户使用 testsaslauthd,我成功了。对该用户使用 ldapsearch,凭据无效。我认为 ldap 没有与 saslauthd 对话?在“Kerberos 身份验证”下,我添加了配置:help.ubuntu.com/community/OpenLDAPServer,但当我执行“ldapsearch -Y GSSAPI”时,我收到“GSSAPI 错误:未提供任何凭据...
-Y GSSAPI
是直接的Kerberos 身份验证 – 与 saslauthd 和密码传递完全分开。也就是说,slapd 甚至不会收到 Kerberos 密码 – 它只收到 Kerberos票并根据其服务密钥表进行内部验证。
对于 SASL GSSAPI,slapd 服务本身(而非 saslauthd)需要密钥表
ldap/<fqdn>
。(默认情况下,所有服务都在系统 /etc/krb5.keytab 中查找其密钥,但出于安全考虑,最好将它们分开并将 slapd 的 KRB5_KTNAME 设置为不同的路径 - 这样,您就不需要授予它对系统密钥表的读取权限。)客户还需要知道它旨在为 请求票证
ldap/<fqdn>
,因此连接到 IP 地址可能行不通(除非它设置了正确的 rDNS)——您应该专门连接到 ldap://<fqdn>。(这是一个与 TLS SNI 或 TLS 证书中的主机名非常相似的问题)。如果有疑问,请
KRB5_TRACE=/dev/stderr
在调用客户端之前导出以查明它试图为哪个主体发出 TGS-REQ(或查看 KDC 日志或网络捕获)。客户端必须已经拥有最初的Kerberos 票证 (krbtgt/REALM) 存在,也就是说,你必须
kinit
事先拥有。如果你还没有 TGT,Kerberos 客户端不会问您的密码——他们将立即无法进行身份验证。
密码传递仅与“简单”绑定 ( ldapsearch -D <user_dn> -W
) 和 SASL PLAIN 绑定相关。首先测试“简单”绑定(您基本上可以忽略 SASL PLAIN)。
答案2
您必须在您的操作系统上安装 libsasl2,并将您的 krb5.keytab 的所有权授予 openldap 用户。
在 Debian 上:
sudo apt 安装 libsasl2-2 libsasl2-modules-gssapi-mit
进而
sudo chown openldap:openldap /etc/krb5.keytab 或其他 keytab
编辑:但要小心同一台机器/容器(具有多个服务器)上的多个密钥表。