LDAP 连接指南
本指南涵盖了关于从 Ansible 主机与 LDAP 服务器(如 Microsoft Active Directory)通信的信息。与 Windows 主机不同,它没有内置的机制来与 LDAP 服务器通信和身份验证,因此在 Ansible 主机上运行的插件需要一些额外的配置才能正常工作。
注意
本指南涵盖了从 Ansible 主机进行的 LDAP 通信。这不适用于在远程 Windows 主机上运行的模块。有关如何配置模块身份验证的信息,请参阅 模块中的 AD 身份验证。
要求
LDAP 连接代码需要 sansldap 和 pyspnego 库。可以使用 pip
安装它们,命令如下:
$ python3 -m pip install --user \
'pyspnego >= 0.8.0'
sansldap
注意
本指南假设 python3
与 Ansible 使用的 Python 相同,有关 Python 版本/位置的详细信息,请参阅 ansible --version
。
还有一些可选的依赖项提供额外的功能
功能 |
软件包 |
---|---|
Kerberos 身份验证 |
pyspnego[kerberos] >= 0.8.0 |
服务器查找 |
dnspython |
LAPS 解密 |
dpapi-ng |
要安装所有可选功能,请运行
$ python3 -m pip install --user \
dnspython \
dpapi-ng \
'pyspnego[kerberos] >= 0.8.0'
Kerberos 身份验证组件需要存在 Kerberos 系统库。对于基于 RPM 的系统,这些是
$ dnf install gcc python3-devel krb5-libs krb5-devel
其他 Linux 发行版需要上面列出的相同软件包,但它们可能使用与 dnf
使用的名称不同的名称。
可以使用 microsoft.ad.debug_ldap_client 操作插件来调试 Ansible 主机的设置及其 LDAP 功能。它包括以下详细信息:
已安装的与 LDAP 相关的 Python 软件包,如果未安装,则会显示导入失败消息
如果安装了 Kerberos 扩展,则会显示 Kerberos 主机和凭据缓存信息
如果安装了
dnspython
和 Kerberos 扩展,则会显示 SRV 查找信息
要使用此模块,只需运行
$ ansible localhost -m microsoft.ad.debug_ldap_client
连接选项
连接到 Microsoft Active Directory 或 LDAP 服务器需要域名控制器主机名、端口、是否使用 LDAPS 或 StartTLS 以及身份验证信息等信息。其中一些信息可以根据 Ansible 主机环境检索,但也可以通过插件选项手动指定。这些选项包括:
选项 |
默认值 |
目的 |
---|---|---|
服务器 |
通过 Kerberos 查找服务器 |
LDAP 服务器主机名 |
端口 |
389 或 686 (如果 tls_mode=ldaps) |
LDAP 端口 |
tls_mode |
如果 port=686 则为 LDAPS,否则为 None |
TLS 详细信息 - LDAP、LDAP + StartTLS、LDAPS |
auth_protocol |
协商 |
身份验证协议 |
用户名 |
无 |
尝试使用可用的 Kerberos 缓存 |
密码 |
无 |
尝试使用可用的 Kerberos 缓存 |
服务器查找的详细信息如下所述。除非指定了 tls_mode: ldaps
,否则端口默认为 389
。如果端口显式设置为 686
,则 TLS 模式默认为 ldaps
,否则默认为 389
。身份验证协议默认为 协商
,同时尝试使用可用的隐式凭据。
服务器查找
如果未显式设置服务器选项,则插件将尝试根据当前环境配置查找 LDAP 服务器。只有在以下情况下才有可能:
已安装
dnspython
Python 软件包已安装用于 Kerberos 的
pyspnego[kerberos]
Python 软件包底层 Kerberos 库在 MIT krb5.conf 中设置了
default_realm
如果以上条件都不满足,则连接将失败,并且必须提供显式服务器。如果满足所有要求,则这是服务器查找工作流程:
检索本地 Kerberos 配置的
default_realm
对
_ldap._tcp.dc._msdcs.{{ default_realm }}
记录执行 DNS SRV 查找DNS 记录按优先级和权重排序,并选择第一个
所选 SRV 记录上的主机名和端口用于查找
注意
如果指定了显式端口,则它将优先于 SRV 记录返回的端口。
身份验证
LDAP 连接的一个关键组件是用户如何向服务器进行身份验证。支持以下身份验证机制:
身份验证 |
支持加密 |
隐式凭据 |
---|---|---|
简单 |
否 - 需要 TLS |
是 - 显示为匿名 |
证书 |
是 |
否 |
协商 |
是 |
是 - 使用 Kerberos |
kerberos |
是 |
是 |
ntlm |
是 |
否 |
除非另有说明,默认使用的身份验证协议是 negotiate
,它依赖于 pyspnego
库。有关如何安装此要求的更多信息,请参阅 要求。
任何不支持加密的协议都必须与 LDAPS 或 StartTLS 一起使用,或者必须使用 encrypt: false
选项显式禁用加密检查。不建议禁用加密,因为它会在没有任何保护的情况下发送凭据,并且任何人都可以看到交换的任何数据。它还要求目标服务器允许未加密的连接,因为它们可能会拒绝此类连接。
隐式凭据支持文档说明身份验证协议是否可以在不指定显式的 username
和 password
的情况下进行身份验证。目前只有 simple
和 negotiate/kerberos
支持隐式凭据。有关更多详细信息,请参阅每个协议部分。
简单
简单身份验证是支持的最基本的身份验证协议。它的工作原理是将用户名和密码以明文形式发送到服务器,类似于 HTTP 基本身份验证。Microsoft AD 要求用户名是帐户的 sAMAccountName
或 userPrincipalName
,但其他 LDAP 实现要求 LDAP distinguishedName
。虽然在未指定用户名或密码时可以进行匿名绑定,但除非使用实际用户的凭据进行身份验证,否则服务器很可能会拒绝任何搜索操作。不允许在不受 TLS 保护的连接上进行简单身份验证。可以通过禁用加密检查来允许在这样的连接上进行简单身份验证,但不建议这样做。
警告
除非使用 TLS(通过 LDAPS 或 StartTLS),否则应避免使用简单身份验证。如果不使用 LDAPS,将会暴露身份验证期间使用的凭据以及随后不受窃听或篡改保护的数据。
证书
证书身份验证使用 TLS 客户端身份验证作为 TLS 握手的一部分,以向主机验证用户身份。由于它是 TLS 握手的一部分,因此只能在 LDAPS 连接上或使用 StartTLS 使用。它使用用户的证书和证书密钥进行身份验证。可以使用三个选项来指定用于身份验证的客户端证书和密钥
certificate
- 证书,以及可选的捆绑密钥certificate_key
- 如果未捆绑在certificate
中,则为证书密钥certificate_password
- 用于解密证书密钥的密码
certificate
和 certificate_key
可以是证书和密钥的文件路径,也可以是 PEM 编码的证书/密钥字符串。certificate
文件路径可以是具有可选密钥捆绑的 PEM、DER 或 PKCS12/PFX 编码的证书,而 certificate_key
文件路径可以是 PEM 或 DER 编码的密钥。如果 PEM、DER 或 PKCS12/PFX 内容中的密钥已加密,则可以使用 certificate_password
来指定用于解密密钥的密码。
注意
设置这些选项取决于插件本身,此处的键反映了选项名称,而不一定是插件可以自动设置和读取的 Ansible 变量。
协商
协商身份验证是 LDAP 连接使用的默认身份验证协议。它是 kerberos
和 ntlm
的组合,客户端协商使用哪一个。如果 kerberos
可用,它将优先使用 kerberos
,如果不可用,则回退到 ntlm
。pyspnego
Python 包仅提供具有 ntlm
支持的 negotiate
,kerberos
支持由 pyspnego[kerberos]
额外选项提供。有关如何安装此要求的更多信息,请参阅 要求。
Kerberos
Kerberos 身份验证是 Microsoft AD 服务器支持的现代身份验证协议,是首选的身份验证协议。只有在安装了 pyspnego[kerberos]
附加包并且主机已正确配置的情况下才可用。通常,此配置是通过系统上的 /etc/krb5.conf 文件完成的。本指南不会介绍如何配置主机的 Kerberos 设置,因为它特定于环境。
确保主机已配置为正确使用 Kerberos 的一个好方法是确保以下命令有效
$ python -c "import krb5"
$ kinit [email protected]
$ kvno ldap/dc.domain.realm
注意
kvno
命令是 MIT krb5 特定的命令,它在像 macOS 这样使用 Heimdal krb5 的主机上不可用。
python
命令确保已安装所需的 Python 库。kinit
命令将检索为指定用户提供的 Kerberos 票证,kvno
命令将尝试检索为所请求的服务主体名称 (SPN) 提供的服务票证。如果这两个命令都有效,则 Kerberos 身份验证很有可能与 LDAP 连接一起使用。
使用 kinit
命令,可以设置一个凭据缓存供 Ansible 用于身份验证。通过使用 kinit
检索的凭据,可以在 Ansible 中不设置任何显式用户名和密码的情况下使用 LDAP 服务器进行身份验证。仍然可以使用显式凭据来使用 Kerberos。
NTLM
NTLM 身份验证是一个简单的身份验证协议,可以单独使用,也可以作为 negotiate
回退的一部分(如果 kerberos
不可用)。与 kerberos
支持不同,它通常不支持隐式凭据,因此通常需要指定显式的用户名和密码才能使用。它不需要额外的宿主机配置,一旦安装了 pyspnego
,它应该就可以工作了。
警告
虽然 NTLM 支持加密,但按照现代标准,它被认为是弱的。建议仅将 NTLM 与 LDAPS 或 StartTLS 连接一起使用,其中 TLS 提供的更强的加密和服务器检查可以缓解 NTLM 中的弱点。
证书验证
通过 StartTLS 使用 LDAPS 或 LDAP 将执行 TLS 握手,默认情况下,客户端会尝试验证服务器提供的证书。如果证书链不可信,或者主机名与请求的主机名不匹配,则连接将失败,并显示指示原因的错误。默认信任存储位置取决于 Python 配置及其链接的 SSL 库。通常它是操作系统的默认信任存储,但如果有疑问,可以使用以下 Python 代码来验证 LDAPS 证书。请确保将 hostname
更改为应测试的 LDAP 服务器的主机名。
import socket
import ssl
hostname = 'dc.domain.com'
port = 636
context = ssl.create_default_context()
with socket.create_connection((hostname, port)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
print(ssock.version())
可以使用 ca_cert
连接选项来设置用于验证的显式 CA 捆绑包。如果 CA 捆绑包不是操作系统存储的一部分,而是位于文件系统上的其他位置,则此选项很有用。该值可以是以下形式
PEM 或 DER 编码的证书捆绑包的文件路径
一个目录路径,其中包含多个 PEM 格式的 CA 证书,遵循 OpenSSL 特定的布局,如 CApath 所述
包含 PEM 编码证书的字符串
还可以使用 cert_validation
连接选项禁用证书验证。默认值为 always
,但可以设置为 ignore
以禁用所有检查,或设置为 ignore_hostname
以仅禁用主机名检查。这对于使用自签名证书的测试环境很有用,但不应在生产环境中使用。
警告
禁用证书验证会消除 TLS 提供的许多好处。无法验证目标服务器是否是它所声称的那样。