You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kerberos认证下Ansible通过管理主机访问AD失败的问题排查

问题描述

环境架构

ansible(由AWX管理)<-WinRM-> 管理主机 <-ADWS-> Active Directory

当前状态

  • 使用CredSSP作为Ansible与管理主机的认证机制时,访问AD的模块(如ADSI、Get-ADUser)可正常工作
  • 已完成Kerberos认证配置,Ansible与管理主机的Kerberos连接正常(可观测到kinit调用)
  • 此前通过配置管理主机的委派权限解决了共享访问问题:执行Get-ADComputer 'managementserver' | Set-ADComputer -PrincipalsAllowedToDelegateToAccount (Get-ADComputer shareserver)

问题现象

切换到Kerberos认证后,无法访问Active Directory,出现以下报错:

ADSI调用报错

执行代码:

try {
  $ADObject = [ADSI]"LDAP://$OU"
  $ADObject.distinguishedname[0] | Out-Null
  return
}
catch {
  $ADObject | Out-File $inputPath\log.txt -Append
  $Error[0] | Format-List * -Force | Out-File $inputPath\log.txt -Append
  $Error[0].Exception.Message | Out-File $inputPath\log.txt -Append
  $Error[0].StackTrace | Out-File $inputPath\log.txt -Append
}

Ansible返回:

The following exception occurred while retrieving member "distinguishedName": "An operations error occurred.\r\n""

Get-ADUser命令报错

执行代码:

$ADUsers = Get-ADUser -SearchBase $baseOU -LDAPFilter '(employeeNumber=*)' -Properties *

返回错误栈:

Unable to contact the server. This may be because this server does not exist, it is currently down, or it does not have the Active Directory Web Services running.
At line:28 char:13
+ $allusers = Get-ADUser -SearchBase $OU -SearchScope Subtree -Filter " ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (:) [Get-ADUser], ADServerDownException
    + FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.GetADUser

ScriptStackTrace:
at <ScriptBlock>, <No file>: line 28

Microsoft.ActiveDirectory.Management.ADServerDownException: Unable to contact the server. This may be because this server does not exist, it is currently down, or it does not have the Active Directory Web Services running. ---> System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:01:59.9897144'. ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:01:59.9897144'. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
   --- End of inner exception stack trace ---
   at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
   at System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   at System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   at System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Security.NegotiateStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   --- End of inner exception stack trace ---
   at System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.NegotiateStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   --- End of inner exception stack trace ---

Server stack trace: 
   at System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
   at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at Microsoft.ActiveDirectory.WebServices.Proxy.Resource.Get(Message request)
   at Microsoft.ActiveDirectory.Management.AdwsConnection.SearchAnObject(ADSearchRequest request)
   --- End of inner exception stack trace ---
   at Microsoft.ActiveDirectory.Management.AdwsConnection.InitializeForAutoReconnect[TChannel](Boolean& isAutoReconnecting, TChannel& channel, ChannelFactory`1& chFactory, String endpointName, CommunicationException& commException)
   at Microsoft.ActiveDirectory.Management.AdwsConnection.SearchAnObject(ADSearchRequest request)
   at Microsoft.ActiveDirectory.Management.AdwsConnection.Search(ADSearchRequest request)
   at Microsoft.ActiveDirectory.Management.ADWebServiceStoreAccess.Microsoft.ActiveDirectory.Management.IADSyncOperations.Search(ADSessionHandle handle, ADSearchRequest request)
   at Microsoft.ActiveDirectory.Management.ADObjectSearcher.GetRootDSE()
   at Microsoft.ActiveDirectory.Management.Commands.ADCmdletBase`1.GetRootDSE()
   at Microsoft.ActiveDirectory.Management.Commands.ADCmdletBase`1.GetConnectedStore()
   at Microsoft.ActiveDirectory.Management.Commands.ADCmdletBase`1.GetCmdletSessionInfo()
   at Microsoft.ActiveDirectory.Management.Commands.ADGetCmdletBase`3.ADGetCmdletBaseBeginCSRoutine()
   at Microsoft.ActiveDirectory.Management.CmdletSubroutinePipeline.Invoke()
   at Microsoft.ActiveDirectory.Management.Commands.ADCmdletBase`1.BeginProcessing()

已尝试的排查动作

  • 将管理服务器计算机对象设置为Trust this computer for delegation to any service (Kerberos only)
  • 将两台域控制器添加到PrincipalsAllowedToDelegateToAccount中
  • 搜索相关关键词未找到有效解决方案

解决方案建议

核心问题定位

这是Kerberos约束委派的精准配置缺失问题:仅配置对域控制器的委派权限,未针对AD依赖的LDAP、ADWS服务做定向委派,导致管理主机无法将Ansible的Kerberos票据传递给AD后端服务。

具体配置步骤

1. 配置管理主机对LDAP服务的约束委派

在Active Directory用户和计算机控制台中操作:

  • 找到管理主机的计算机对象,打开属性→【委派】选项卡
  • 选择Trust this computer for delegation to specified services only,并勾选Use Kerberos only
  • 点击【添加】→【用户或计算机】,选择目标域控制器的计算机对象
  • 在可用服务列表中选择ldap服务,添加后确认保存

2. 配置管理主机对ADWS服务的约束委派

重复上述步骤,在选择服务时添加HTTP服务(ADWS依赖HTTP服务的Kerberos票据完成认证)

3. 验证Kerberos委派票据

在管理主机上执行以下命令,确认能获取到AD服务的委派票据:

klist get ldap/[域控制器FQDN]
klist get HTTP/[域控制器FQDN]

若返回有效票据信息,则配置生效。

4. 调整Ansible WinRM配置

确保inventory或playbook中开启Kerberos委派参数:

[windows]
managementserver.domain.com

[windows:vars]
ansible_connection=winrm
ansible_winrm_transport=kerberos
ansible_winrm_kerberos_delegation=true
ansible_winrm_server_cert_validation=ignore

关键参数为ansible_winrm_kerberos_delegation=true,允许WinRM将Kerberos票据委派给后端服务。

5. 重启WinRM服务

在管理主机上执行命令,确保配置生效:

Restart-Service WinRM

内容的提问来源于stack exchange,提问作者Haruka Shitou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 13:07:02