
NetBox LDAP 认证配置指南从安装到 Active Directory 实战【免费下载链接】netboxThe premier source of truth powering network automation. Open source under Apache 2. Try NetBox Cloud free: https://netboxlabs.com/products/free-netbox-cloud/项目地址: https://gitcode.com/gh_mirrors/ne/netboxNetBox 支持通过外部 LDAP 服务器如 OpenLDAP 或 Microsoft Active Directory完成用户认证本文基于官方安装文档 6-ldap.md 展开结合仓库源码深入讲解django-auth-ldap的接入方式、ldap_config.py各配置项含义、Active Directory 的 UPN 双格式登录技巧以及故障排查方法。读完本文你将能够在生产环境中完整落地一套LDAP 认证 Django 内置用户回退的 NetBox 认证体系并理解其底层加载与权限同步机制。1. 工作原理概述NetBox 使用 Django 的可插拔认证后端authentication backend机制。启用 LDAP 认证后认证流程如下用户在登录页输入用户名与密码NetBox 通过netbox.authentication.LDAPBackend将凭据交由django-auth-ldap处理向 LDAP 服务器发起绑定bind请求认证成功则根据 LDAP 目录中的属性与组成员关系创建/更新本地 Django 用户并映射权限若 LDAP 服务器不可用或认证失败认证会回退到内置 Django 用户认证即本地账号依然可用。这一LDAP 优先、本地回退的行为在文档开头即有明确说明也是 NetBox 与 LDAP 目录共存时的默认设计。从源码看LDAPBackend实际组合了 django-auth-ldap 的LDAPBackend与 NetBox 自己的ObjectPermissionMixin详见 authentication/init.py因此 LDAP 用户同样受 NetBox 对象权限体系约束。2. 安装依赖2.1 安装系统级包LDAP 绑定与 TLS 需要系统开发库Debian/Ubuntu 下执行sudo apt install -y libldap2-dev libsasl2-dev libssl-devlibldap2-devOpenLDAP 客户端开发库libsasl2-devSASL 认证库Active Directory 等场景需要libssl-devOpenSSL 开发库用于 LDAPS / STARTTLS 加密连接。2.2 安装 django-auth-ldap根据 NetBox 的安装方式有两种途径。方式一Release 归档或 Git 安装激活 Python 虚拟环境后用 pip 安装source /opt/netbox/venv/bin/activate pip3 install django-auth-ldap安装完成后将包名追加到local_requirements.txt确保后续重建虚拟环境时会自动重新安装sudo sh -c echo django-auth-ldap /opt/netbox/local_requirements.txt方式二Python 包安装实验性直接安装 NetBox 的ldap可选依赖组并固定到当前 NetBox 版本sudo /opt/netbox/venv/bin/python -m pip install netbox[ldap]X.Y.Z升级 NetBox 包时需再次指定ldapextra完整升级流程参见 Python 包升级指南。NetBox 的 pyproject 元数据中即声明了该可选依赖组见 pyproject.toml。注意django-auth-ldap是可选依赖未安装时 NetBox 仍可正常运行只有使用LDAPBackend时才必需。若未安装却启用了该后端源码会在 authentication/init.py 中抛出ImproperlyConfigured(LDAP authentication has been configured, but django-auth-ldap is not installed.)。3. 启用后端与创建配置文件3.1 指定认证后端在configuration.py中启用 LDAP 认证后端REMOTE_AUTH_BACKEND netbox.authentication.LDAPBackendREMOTE_AUTH_BACKEND是 NetBox 远程认证设置之一默认值为netbox.authentication.RemoteUserBackend见 remote-authentication.md。文档特别提醒若该参数已被设置为RemoteUserBackend务必覆盖。它既支持单个后端的字符串也支持按顺序尝试的迭代器。3.2 创建 ldap_config.py在与当前生效的configuration.py同目录下创建ldap_config.py。不同安装方式对应的典型位置Release 归档 / Git 安装/opt/netbox/netbox/netbox/Python 包安装/opt/netbox/conf/所有 LDAP 参数都定义在该文件中而不是configuration.py。这是 NetBox 特意设计的隔离机制源码中的load_ldap_config()会从settings.CONFIGURATION_DIR目录加载ldap_config.py模块见 settings_utils.py。对于 checkout 安装方式源码还保留了对历史路径netbox/netbox/ldap_config.py的兼容回退并会发出RuntimeWarning提示迁移未来版本可能移除。Python 包安装时建议收紧文件权限——属主为 root、属组为 netbox仅允许 NetBox 服务账号读取sudo chown root:netbox /opt/netbox/conf/ldap_config.py sudo chmod 640 /opt/netbox/conf/ldap_config.py3.3 配置加载的源码印证后端实例化时会完整读取ldap_config.py中所有以AUTH_LDAP_前缀开头的参数注入LDAPSettings同时处理三个 NetBox 自定义的 TLS 参数。核心逻辑位于 authentication/init.py# 读取 ldap_config.py 中的 AUTH_LDAP_* 参数 for param in dir(ldap_config): if param.startswith(ldap_settings._prefix): setattr(ldap_settings, param[10:], getattr(ldap_config, param)) # 可选忽略证书校验错误 if getattr(ldap_config, LDAP_IGNORE_CERT_ERRORS, False): ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) # 可选设置 CA 证书目录 / CA 证书文件 if ca_cert_dir : getattr(ldap_config, LDAP_CA_CERT_DIR, None): ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, ca_cert_dir) if ca_cert_file : getattr(ldap_config, LDAP_CA_CERT_FILE, None): ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, ca_cert_file)如果ldap_config.py中缺少必填的AUTH_LDAP_SERVER_URI后端会抛出ImproperlyConfigured异常。对应行为有单元测试覆盖LDAPBackendTest见 tests/test_authentication.py其中验证了 wheel 安装不会启用旧路径回退、而 checkout 安装会启用。4. 服务器通用配置以下为ldap_config.py中最基础的服务器连接配置import ldap # 服务器 URI AUTH_LDAP_SERVER_URI ldaps://ad.example.com # 绑定 Active Directory 时可能需要禁用引荐referral跟随 AUTH_LDAP_CONNECTION_OPTIONS { ldap.OPT_REFERRALS: 0 } # NetBox 服务账号的 DN 与密码 AUTH_LDAP_BIND_DN CNNETBOXSA, OUService Accounts,DCexample,DCcom AUTH_LDAP_BIND_PASSWORD demo # NetBox 自定义忽略证书校验错误适用于自签名证书 # 等价于 ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) LDAP_IGNORE_CERT_ERRORS True # NetBox 自定义使用服务器上的 CA 证书目录校验 LDAP 证书 # 等价于 ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, LDAP_CA_CERT_DIR) LDAP_CA_CERT_DIR /etc/ssl/certs # NetBox 自定义使用自有 CA 证书文件校验 LDAP 证书 # 等价于 ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, LDAP_CA_CERT_FILE) LDAP_CA_CERT_FILE /path/to/example-CA.crt各参数要点AUTH_LDAP_SERVER_URILDAP 服务地址。使用ldaps://表示隐式 TLS若同时设置AUTH_LDAP_START_TLS True则使用ldap://协议配合 STARTTLS 升级加密连接。AUTH_LDAP_BIND_DN/AUTH_LDAP_BIND_PASSWORDNetBox 服务账号service account用于初始绑定与目录查询。生产环境务必使用最小权限的专用账号切勿明文提交到版本库。AUTH_LDAP_CONNECTION_OPTIONS底层python-ldap的连接选项。OPT_REFERRALS: 0在 Active Directory 场景下通常是必需的。三个 NetBox 自定义的 TLS 参数LDAP_IGNORE_CERT_ERRORS、LDAP_CA_CERT_DIR、LDAP_CA_CERT_FILE是 NetBox 对 django-auth-ldap 的增强会直接转换为底层ldap.set_option()调用注意它们不带AUTH_LDAP_前缀。Active Directory 全局编录提示如果希望用户能跨林forest内所有域认证需要在AUTH_LDAP_SERVER_URI中显式指定全局编录Global Catalog端口——加密用3269非加密用3268。5. 用户认证配置认证的第一步是找到用户。NetBox 用户登录名Django username与 LDAP 目录条目之间的映射由以下几项控制from django_auth_ldap.config import LDAPSearch # 方式一通过目录搜索定位用户用户名的 DN 无法直接推导时如 Active Directory # 该搜索匹配 sAMAccountName 等于所输用户名的条目 AUTH_LDAP_USER_SEARCH LDAPSearch(ouUsers,dcexample,dccom, ldap.SCOPE_SUBTREE, (sAMAccountName%(user)s)) # 方式二用户名可以直接推导出 DN 时无需搜索 AUTH_LDAP_USER_DN_TEMPLATE uid%(user)s,ouusers,dcexample,dccom # 将 LDAP 属性映射到 Django User 模型字段 AUTH_LDAP_USER_ATTR_MAP { first_name: givenName, last_name: sn, email: mail }参数说明AUTH_LDAP_USER_SEARCHLDAPSearch(base, scope, filter)三元组。%(user)s是 django-auth-ldap 提供的占位符会被替换为用户输入的用户名。ldap.SCOPE_SUBTREE表示从ouUsers开始递归搜索整棵子树。AUTH_LDAP_USER_DN_TEMPLATE当用户 DN 可从用户名直接构造如 OpenLDAP 中uid即用户名时可跳过搜索直接绑定。使用 Windows Server 2012 时该参数应设为None。AUTH_LDAP_USER_ATTR_MAP将 LDAP 属性写入 Django 用户的字段映射方向是Django字段: LDAP属性。6. 用户组与权限映射通过 LDAP 组可以控制 NetBox 的登录资格、超级用户状态与细粒度权限from django_auth_ldap.config import LDAPSearch, GroupOfNamesType # 返回用户所属的全部组django-auth-ldap 据此判断组层级 AUTH_LDAP_GROUP_SEARCH LDAPSearch(dcexample,dccom, ldap.SCOPE_SUBTREE, (objectClassgroup)) AUTH_LDAP_GROUP_TYPE GroupOfNamesType() # 登录必需组不属于该组的用户无法登录 AUTH_LDAP_REQUIRE_GROUP CNNETBOX_USERS,DCexample,DCcom # 镜像 LDAP 组将用户的 LDAP 组成员关系同步到 Django 组 AUTH_LDAP_MIRROR_GROUPS True # 通过组定义特殊用户类型 AUTH_LDAP_USER_FLAGS_BY_GROUP { is_active: cnactive,ougroups,dcexample,dccom, is_superuser: cnsuperuser,ougroups,dcexample,dccom } # 将 LDAP 组映射为 Django 组权限实现更细粒度的授权 AUTH_LDAP_FIND_GROUP_PERMS True # 缓存组信息一小时降低 LDAP 流量 AUTH_LDAP_CACHE_TIMEOUT 3600各参数说明AUTH_LDAP_GROUP_TYPE组对象类型解析器。默认GroupOfNamesType()对应objectClassgroupOfNames。Microsoft Active Directory 请改用NestedGroupOfNamesType()同时修改 import 行以支持嵌套组。AUTH_LDAP_REQUIRE_GROUP登录门槛。若该组DN在目录中不存在认证将直接失败。AUTH_LDAP_MIRROR_GROUPS为True时将 LDAP 组成员关系镜像为 Django 组。NetBox 自定义了_mirror_groups()方法以适配自己的Group模型见 authentication/misc.py支持MIRROR_GROUPS/MIRROR_GROUPS_EXCEPT白名单/黑名单过滤对应测试LDAPMirrorGroupsTestCase见 tests/test_authentication.py验证了空组名不会被创建为 Django 组。AUTH_LDAP_USER_FLAGS_BY_GROUP按组成员关系设置用户标志is_active——所有用户至少要被映射到该组否则无法登录is_superuser——映射到该组的用户获得超级用户权限超级用户隐含全部权限授予时务必谨慎。AUTH_LDAP_FIND_GROUP_PERMS开启后 django-auth-ldap 会把 LDAP 组视为 Django 组进而叠加 NetBox 的ObjectPermission权限。NetBox 的NBLDAPBackend重写了get_permission_filter()将用户 LDAP 组名合并进对象权限过滤条件见 authentication/init.py。AUTH_LDAP_CACHE_TIMEOUT组信息缓存秒数避免每次登录都产生大量 LDAP 查询。警告认证会因组DN在 LDAP 目录中不存在而失败。配置前请用ldapsearch逐一核实文档中出现的每一个 DN 真实存在。7. 实战Active Directory 双格式登录Active Directory 集成的常见痛点是登录格式不统一。以下配置让用户既能用完整 UPNusernamedomain.tld登录也能仅用用户名username登录原理是对 DN 同时按sAMAccountName与userPrincipalName过滤。第一步修改AUTH_LDAP_USER_SEARCHAUTH_LDAP_USER_SEARCH LDAPSearch( ouUsers,dcexample,dccom, ldap.SCOPE_SUBTREE, (|(userPrincipalName%(user)s)(sAMAccountName%(user)s)) )(|(...)(...))是 LDAP 的 OR 过滤器任一属性匹配即命中。第二步将AUTH_LDAP_USER_DN_TEMPLATE设为NoneWindows Server 2012 场景下用户 DN 无法从用户名直接推导必须依赖搜索。第三步调整属性映射回写 AD 中的用户名AUTH_LDAP_USER_ATTR_MAP { username: sAMAccountName, email: mail, first_name: givenName, last_name: sn, }将username映射为sAMAccountName保证 Django 侧用户名是规范形式避免大小写与 UPN 后缀差异导致账号分裂。第四步指定查询字段AUTH_LDAP_USER_QUERY_FIELD username告诉 django-auth-ldap 以本地username字段作为匹配键。完成以上四步后用户即可带或不带 UPN 后缀登录。8. 完整示例配置以下是一个面向 Active Directory 生产环境的完整ldap_config.py模板可直接复制后按需修改文档明确提示该配置仅为模板需结合自身环境调整import ldap from django_auth_ldap.config import LDAPSearch, NestedGroupOfNamesType # Server URI使用全局编录加密端口 3269 AUTH_LDAP_SERVER_URI ldaps://ad.example.com:3269 # The following may be needed if you are binding to Active Directory. AUTH_LDAP_CONNECTION_OPTIONS { ldap.OPT_REFERRALS: 0 } # Set the DN and password for the NetBox service account. AUTH_LDAP_BIND_DN CNNETBOXSA,OUService Accounts,DCexample,DCcom AUTH_LDAP_BIND_PASSWORD demo # NetBox-specific: 忽略证书校验错误自签名证书场景 LDAP_IGNORE_CERT_ERRORS False # NetBox-specific: 使用服务器 CA 证书目录校验 LDAP_CA_CERT_DIR /etc/ssl/certs # NetBox-specific: 使用自有 CA 证书文件校验 LDAP_CA_CERT_FILE /path/to/example-CA.crt # 支持 UPN 与 sAMAccountName 双格式的用户搜索 AUTH_LDAP_USER_SEARCH LDAPSearch( ouUsers,dcexample,dccom, ldap.SCOPE_SUBTREE, (|(userPrincipalName%(user)s)(sAMAccountName%(user)s)) ) # 用户 DN 无法从用户名推导必须为 NoneWindows Server 2012 AUTH_LDAP_USER_DN_TEMPLATE None # LDAP 属性 → Django 用户字段映射 AUTH_LDAP_USER_ATTR_MAP { username: sAMAccountName, email: mail, first_name: givenName, last_name: sn, } AUTH_LDAP_USER_QUERY_FIELD username # 返回用户所属全部组供组层级判断 AUTH_LDAP_GROUP_SEARCH LDAPSearch( dcexample,dccom, ldap.SCOPE_SUBTREE, (objectClassgroup) ) # Active Directory 使用嵌套组类型 AUTH_LDAP_GROUP_TYPE NestedGroupOfNamesType() # 登录必需组 AUTH_LDAP_REQUIRE_GROUP CNNETBOX_USERS,DCexample,DCcom # 镜像 LDAP 组到 Django 组 AUTH_LDAP_MIRROR_GROUPS True # 通过组定义特殊用户类型 AUTH_LDAP_USER_FLAGS_BY_GROUP { is_active: cnactive,ougroups,dcexample,dccom, is_superuser: cnsuperuser,ougroups,dcexample,dccom } # 将 LDAP 组映射为 Django 组权限 AUTH_LDAP_FIND_GROUP_PERMS True # 组信息缓存一小时降低 LDAP 流量 AUTH_LDAP_CACHE_TIMEOUT 3600 # 每次登录都同步用户属性文档示例补充项 AUTH_LDAP_ALWAYS_UPDATE_USER True其中AUTH_LDAP_ALWAYS_UPDATE_USER True表示每次登录都重新同步用户属性适合目录属性频繁变化的场景。9. 故障排查9.1 应用配置与定位语法错误ldap_config.py属于启动时加载的配置模块修改后必须重启服务生效systemctl restart netbox如果文件存在语法错误NetBox 进程将无法启动错误通常记录在/var/log/messages。建议修改后用python -m py_compile ldap_config.py做本地语法校验再执行重启。9.2 开启 django-auth-ldap 调试日志将以下LOGGING配置合并到configuration.py详见 日志配置即可把django_auth_ldap的 DEBUG 日志写入独立文件LOGGING { version: 1, disable_existing_loggers: False, handlers: { netbox_auth_log: { level: DEBUG, class: logging.handlers.RotatingFileHandler, filename: /opt/netbox/local/logs/django-ldap-debug.log, maxBytes: 1024 * 500, backupCount: 5, }, }, loggers: { django_auth_ldap: { handlers: [netbox_auth_log], level: DEBUG, }, }, }使用要点确保日志文件路径存在且目录与应用服务账号可写、可执行重启 NetBox 服务后尝试登录网站即可在该文件看到完整的 LDAP 查询与绑定过程搜索基、过滤器、绑定的 DN、组解析结果等日志采用RotatingFileHandler单文件上限 500 KB、保留 5 个备份避免长期运行撑爆磁盘。9.3 常见问题速查现象排查方向认证失败组不存在核对AUTH_LDAP_REQUIRE_GROUP、AUTH_LDAP_USER_FLAGS_BY_GROUP中的 DN 是否真实存在自签名证书报错设置LDAP_IGNORE_CERT_ERRORS True或配置LDAP_CA_CERT_DIR/LDAP_CA_CERT_FILE进行正常校验仅 UPN 或仅用户名能登录检查AUTH_LDAP_USER_SEARCH是否为(|(userPrincipalName...)(sAMAccountName...))双条件过滤用户无法登录但目录正常确认is_active映射组已配置未映射该组的用户会被禁用修改配置不生效确认重启了netbox服务且ldap_config.py与configuration.py在同一目录跨林认证失败确认AUTH_LDAP_SERVER_URI使用了全局编录端口 3268/3269并设置了ldap.OPT_REFERRALS: 010. 相关文档导航安装前提与整体流程安装指南首页、NetBox 主安装文档远程认证设置总览REMOTE_AUTH_BACKEND等远程认证配置日志配置系统配置文档认证与权限体系认证与权限功能说明、对象权限配置后端源码LDAPBackend与NBLDAPBackend实现在 netbox/netbox/authentication/init.py配置加载逻辑在 netbox/netbox/settings_utils.py组镜像实现与测试分别在 netbox/netbox/authentication/misc.py 与 netbox/netbox/tests/test_authentication.py【免费下载链接】netboxThe premier source of truth powering network automation. Open source under Apache 2. Try NetBox Cloud free: https://netboxlabs.com/products/free-netbox-cloud/项目地址: https://gitcode.com/gh_mirrors/ne/netbox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考