症状:AD 模式登录失败 - 不受信任的域(大数据群集)

Important

Microsoft SQL Server 2019 大数据群集已停用。 对 SQL Server 2019 大数据群集的支持已于 2025 年 2 月 28 日结束。 有关详细信息,请参阅Microsoft SQL Server 平台上的公告博客文章和大数据选项。

在 Active Directory 模式下的 SQL Server 大数据群集上,连接尝试可能会失败,并且连接尝试返回以下错误:

Login failed. The login is from an untrusted domain and cannot be used with Integrated authentication.

这可能在您将 DNS 条目配置为 CNAME 并指向将流量分配到 Kubernetes 节点的反向代理的别名时发生。

Root cause

将终结点配置为 DNS 条目时,CNAME 指向反向代理的别名,用于将流量分发到 Kubernetes 节点:

  • Kerberos 身份验证过程查找与 CNAME 条目匹配的服务主体名称(SPN);不是 BDC 在 Active Directory 中注册的真实 SPN
  • Authentication fails

确认根本原因

身份验证失败后,请检查 Kerberos 票证的缓存。

若要检查票证的缓存,请使用 klist 命令。

查找票证中的 SPN 与您尝试连接的端点是否匹配。

预期的票证不存在。

在此示例中,主终结点的 bdc-sql DNS 记录为 CNAME,设置为指向名为 ServerReverseProxy 的反向代理。

Resolve-DnsName bdc-sql

以下部分显示了上一命令的结果。

Name                           Type   TTL   Section    NameHost
----                           ----   ---   -------    --------
bdc-sql.mydomain.com           CNAME  3600  Answer     ReverseProxyServer.mydomain.com

Name       : ReverseProxyServer.mydomain.com
QueryType  : A
TTL        : 3600
Section    : Answer
IP4Address : 193.168.5.10

Note

以下部分引用 tsharktshark作为 Wireshark 网络跟踪实用工具的一部分安装的命令行实用工具。

若要查看从 Active Directory 请求的 SPN,请使用 tshark。 以下命令将网络跟踪捕获限制为 Kerberos 协议通信,并仅显示 krb-error (30) 消息。 这些消息应包含失败的 SPN 请求消息。

tshark -Y "kerberos && kerberos.msg_type == 30" -T fields -e kerberos.error_code -e kerberos.SNameString

从不同的命令行终端尝试连接到主 Pod:

klist purge

sqlcmd -S bdc-sql.mydomain.com,31433 -E

请参阅以下示例输出。

klist purge

Current LogonId is 0:0xf6b58
        Deleting all tickets:
        Ticket(s) purged!

sqlcmd -S bdc-sql.mydomain.com,31433 -E
sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Login failed. The login is from an untrusted domain and cannot be used with Integrated authentication.

检查tshark输出。

Capturing on 'Ethernet 3'
25      krbtgt,RLAZURE.COM
7       MSSQLSvc,ReverseProxyServer.mydomain.com:31433
2 packets captured

请注意不存在的客户端请求 SPN MSSQLSvc,ReverseProxyServer.mydomain.com:31433 。 连接尝试最终失败,出现错误 7。 错误 7 表示 KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN Server not found in Kerberos database

在正确的配置中,客户端请求 BDC 注册的 SPN。 在此示例中,正确的 SPN 是 MSSQLSvc,bdc-sql.mydomain.com:31433

Note

错误 25 表示 KDC_ERR_PREAUTH_REQUIRED - 需要额外的预身份验证。 可以安全地忽略它。 KDC_ERR_PREAUTH_REQUIRED 在初始 Kerberos AD 请求时返回。 默认情况下,Windows Kerberos 客户端不包括此第一个请求中的预身份验证信息。

若要查看 BDC 为主终结点注册的 SPN 列表,请运行 setspn -L mssql-master

请参阅以下示例输出:

Registered ServicePrincipalNames for CN=mssql-master,OU=bdc,DC=mydomain,DC=com:
        MSSQLSvc/bdc-sqlread.mydomain.com:31436
        MSSQLSvc/-sqlread:31436
        MSSQLSvc/bdc-sqlread.mydomain.com
        MSSQLSvc/bdc-sqlread
        MSSQLSvc/bdc-sql.mydomain.com:31433
        MSSQLSvc/bdc-sql:31433
        MSSQLSvc/bdc-sql.mydomain.com
        MSSQLSvc/bdc-sql
        MSSQLSvc/master-p-svc.mydomain.com:1533
        MSSQLSvc/master-p-svc:1533
        MSSQLSvc/master-p-svc.mydomain.com:1433
        MSSQLSvc/master-p-svc:1433
        MSSQLSvc/master-p-svc.mydomain.com
        MSSQLSvc/master-p-svc
        MSSQLSvc/master-svc.mydomain.com:1533
        MSSQLSvc/master-svc:1533
        MSSQLSvc/master-svc.mydomain.com:1433
        MSSQLSvc/master-svc:1433
        MSSQLSvc/master-svc.mydomain.com
        MSSQLSvc/master-svc

在上述结果中,不应注册反向代理地址。

Resolve

本部分演示了两种解决问题的方法。 在进行适当的更改后,先在客户端中运行ipconfig -flushdns,然后运行klist purge。 然后再次尝试连接。

Option 1

删除 DNS 中每个 BDC 终结点的 CNAME 记录,并替换为指向每个 Kubernetes 节点或每个 Kubernetes 主节点的多个 A 记录(如果有多个主节点)。

Tip

下面所述的脚本使用 PowerShell。 有关详细信息,请参阅 在 Linux 上安装 PowerShell

可以使用以下 PowerShell 脚本更新 DNS 终结点记录。 从连接到同一域的任何计算机运行脚本:

#Specify the DNS server, example contoso.local
$Domain_DNS_name=mydomain.com'

#DNS records for bdc endpoints
$Controller_DNS_name = 'bdc-control'
$Managment_proxy_DNS_name= 'bdc-proxy'
$Master_Primary_DNS_name = 'bdc-sql'
$Master_Secondary_DNS_name = 'bdc-sqlread'
$Gateway_DNS_name = 'bdc-gateway'
$AppProxy_DNS_name = 'bdc-appproxy'

#Performing Endpoint DNS records Checks..

#Build array of endpoints 
$BdcEndpointsDns = New-Object System.Collections.ArrayList

[void]$BdcEndpointsDns.Add($Controller_DNS_name)
[void]$BdcEndpointsDns.Add($Managment_proxy_DNS_name)
[void]$BdcEndpointsDns.Add($Master_Primary_DNS_name)
[void]$BdcEndpointsDns.Add($Master_Secondary_DNS_name)
[void]$BdcEndpointsDns.Add($Gateway_DNS_name)
[void]$BdcEndpointsDns.Add($AppProxy_DNS_name)

#Build array for results 
$BdcEndpointsDns_Result = New-Object System.Collections.ArrayList

foreach ($DnsName in $BdcEndpointsDns) {
    try {
        $endpoint_DNS_record = Resolve-DnsName $DnsName -Type A -Server $Domain_DNS_IP_address -ErrorAction Stop 
        foreach ($ip in $endpoint_DNS_record.IPAddress) {
            [void]$BdcEndpointsDns_Result.Add("OK - $DnsName is an A record with an IP $ip")
        }
    }
    catch {
        [void]$BdcEndpointsDns_Result.Add("MisConfiguration - $DnsName is not an A record or does not exists")
    }  
}

#show the results 
$BdcEndpointsDns_Result

Option 2

或者,可以通过修改 CNAME 来指向反向代理的 IP 地址而不是反向代理的名称来解决此问题。

Confirm Resolution

解决故障后,使用 Active Directory 连接到大数据群集,以验证修复是否成功。

Next steps

验证域控制器的反向 DNS 记录(PTR 记录)