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

如何动态获取特定Active Directory域的所有服务器主机名?

获取Active Directory域控制器列表的实现方案

核心原理:DNS SRV记录查询

Active Directory确实通过DNS的SRV记录发布域控制器信息,这是标准机制。针对目标域SOME.AD.DOMAIN,需查询两类关键SRV记录:

  • _ldap._tcp.dc._msdcs.SOME.AD.DOMAIN:所有域控制器的LDAP服务记录
  • _ldap._tcp.pdc._msdcs.SOME.AD.DOMAIN:主域控制器(PDC)的专属记录

类UNIX系统下的实现步骤

1. 编程获取DC列表

在类UNIX环境中,有两种主流方式获取DC列表:

  • 调用系统DNS解析API(如res_query、dns_query)直接查询SRV记录
  • 调用系统命令(dig或nslookup)并解析输出:
    # 查询所有DC的LDAP SRV记录
    dig _ldap._tcp.dc._msdcs.SOME.AD.DOMAIN SRV +short
    # 查询PDC的LDAP SRV记录
    dig _ldap._tcp.pdc._msdcs.SOME.AD.DOMAIN SRV +short
    

SRV记录会返回优先级、权重、端口和主机名:优先级值越低的服务器越优先,同优先级按权重分配流量。

2. 排序DC列表

按照SRV规则排序:

  • 优先放置PDC(单独查询PDC记录,放在列表最前端)
  • 其他DC按SRV记录的优先级升序排列,同优先级按权重降序排列(权重高的优先)

3. 连接与验证流程

结合你的伪代码逻辑,给出Python示例实现:

import dns.resolver
import ldap3

def get_ad_dcs(domain):
    dcs = []
    # 查询PDC并加入列表
    try:
        answers = dns.resolver.resolve(f'_ldap._tcp.pdc._msdcs.{domain}', 'SRV')
        for rdata in answers:
            dcs.append((0, str(rdata.target).rstrip('.')))
    except dns.resolver.NXDOMAIN:
        pass
    
    # 查询所有DC并去重
    try:
        answers = dns.resolver.resolve(f'_ldap._tcp.dc._msdcs.{domain}', 'SRV')
        existing_dcs = [dc[1] for dc in dcs]
        for rdata in answers:
            dc_host = str(rdata.target).rstrip('.')
            if dc_host not in existing_dcs:
                dcs.append((rdata.priority, dc_host))
    except dns.resolver.NXDOMAIN:
        return []
    
    # 按优先级排序
    dcs.sort(key=lambda x: x[0])
    return [dc[1] for dc in dcs]

connection_successful = False
domain = "SOME.AD.DOMAIN"
dc_list = get_ad_dcs(domain)

for hostname in dc_list:
    try:
        server = ldap3.Server(hostname, get_info=ldap3.ALL)
        conn = ldap3.Connection(server, user='USERNAME', password='PASSWORD', auto_bind=True)
        connection_successful = True
        print(f"成功连接到域控制器: {hostname}")
        # 执行身份验证、授权等业务逻辑
        break
    except ldap3.core.exceptions.LDAPException:
        print(f"连接域控制器 {hostname} 失败")

if not connection_successful:
    print("无法连接到任何可用的域控制器")

注意事项

  • 确保主机DNS配置能正确解析AD域的SRV记录(主机需在AD域网络内,或DNS服务器可访问AD的DNS区域)
  • 添加DNS查询失败、连接超时的异常处理,避免程序崩溃
  • 可根据实际需求调整排序规则(如结合网络延迟检测优化优先级)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:22:25