基于Python-LDAP3库获取AD域控用户信息

23 阅读2分钟

前言

Python-LDAP3库是一个功能强大且安全的LDAP客户端库,专门用于与各种LDAP服务器(包括Active Directory)进行交互。与传统的python-ldap库相比,LDAP3库提供了更现代化的API设计、更好的Python 3兼容性以及更完善的安全特性支持。通过该库,开发人员可以轻松实现对AD域控的用户信息查询、管理操作,而无需依赖复杂的Windows API或昂贵的第三方工具。

本方案将详细介绍如何使用Python-LDAP3库连接AD域控,执行用户信息检索,并生成格式化的用户简介。方案特别适用于需要批量处理AD用户信息、自动化用户管理任务或集成AD用户数据到其他企业系统的场景。

环境准备

Windows Server 2025
    - Active Directory 服务
        - 查询目录 OU=信网部,DC=euyan,DC=cloud
        - 管理账号 user=Administrator,password=xxxxxx
    - 证书签发服务
        - 自签发CA证书
Ubuntu Server 24.04
    - Wireguard
    - Python 3.13.1
        - ldap3
        - ssl

环境验证

# xxx.xxx.xxx.xxx为服务器IP

# 测试连通性
ping xxx.xxx.xxx.xxx

# 验证ldaps端口
telnet xxx.xxx.xxx.xxx 636

# 验证DNS (查看返回值是否为域控服务器地址)
nslookup WIN-SERVER.euyan.cloud

修改客户端DNS(域控服务器地址)

image.png

导出域控CA证书(Python脚本所需)

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

选择Base64编码 X.509(.CER) image.png

image.png

Python脚本(用于获取用户信息)

脚本使用ldap3的ldaps获取用户信息,AD域控不支持明文传输管理账户信息,必须采用加密或者SSL形式。本次实验采用ldaps加密形式

from ldap3 import Server, Connection, Tls
import ssl

tls = Tls(
    # 刚才导出的域控服务器CA证书
    ca_certs_file='./ca.pem',
    validate=ssl.CERT_REQUIRED
)

# 服务器信息
server = Server(
    'WIN-SERVER.euyan.cloud',   # !!! 必须是CA证书里对应的域名
    port=636,
    use_ssl=True,
    tls=tls
)

# 管理员账号信息
conn = Connection(
    server,
    user='Administrator@euyan.cloud',
    password='xxxxxxxxx',     # 根据现场情况设置密码
    auto_bind=True
)

# 检查绑定是否成功
print("LDAPS 绑定成功:", conn.bound)

# 查询用户信息
base_dn = 'OU=信网部,DC=euyan,DC=cloud'  # 基础 DN,根据实际域结构调整
search_filter = '(objectClass=user)'  # 查询所有用户
attributes = ['cn', 'sAMAccountName', 'mail', 'displayName', 'distinguishedName']  # 需要返回的属性

# 执行查询
conn.search(
    search_base=base_dn,
    search_filter=search_filter,
    attributes=attributes
)

# 处理查询结果
print(f"\n查询到 {len(conn.entries)} 个用户:")
for entry in conn.entries:
    print(f"\n用户: {entry.cn.value if hasattr(entry, 'cn') and entry.cn else 'N/A'}")
    print(f"账号: {entry.sAMAccountName.value if hasattr(entry, 'sAMAccountName') and entry.sAMAccountName else 'N/A'}")
    print(f"邮箱: {entry.mail.value if hasattr(entry, 'mail') and entry.mail else 'N/A'}")
    print(f"显示名: {entry.displayName.value if hasattr(entry, 'displayName') and entry.displayName else 'N/A'}")
    print(f"DN: {entry.distinguishedName.value if hasattr(entry, 'distinguishedName') and entry.distinguishedName else 'N/A'}")

# 结束会话
conn.unbind()

效果验证

image.png

image.png

后续我们可以根据获取到的用户信息,批量创建Wireguard所需的客户端配置。达到自动化的目的