Nginx不支持原生LDAP认证,仅能通过stream模块进行TCP层透明转发;其http模块无法处理LDAP二进制协议,LDAPS也非HTTPS;正确做法是启用stream模块代理389/636端口,且不参与认证逻辑。

Nginx 本身不支持原生 LDAP 协议代理或身份认证,它无法直接解析 LDAP 请求(如 Bind、Search 等)并转发给后端 LDAP 服务器(如 OpenLDAP、Active Directory)。所谓“Nginx 利用 TCP 代理模块实现 LDAP 身份认证转发”,实质是通过 stream 模块进行四层(TCP 层)透明转发,将客户端的 LDAP 流量(默认端口 389 或 636)原封不动地转给后端 LDAP 服务,由后端完成实际认证逻辑 —— Nginx 在这里仅充当“管道”,不参与任何认证决策。
为什么不能用 HTTP 模块做 LDAP 认证?
LDAP 是基于 TCP 的二进制协议,不是文本协议,也不走 HTTP。Nginx 的 http 模块只处理 HTTP/HTTPS 流量,无法识别、解析或重写 LDAP PDU(Protocol Data Unit)。试图用 proxy_pass http://ldap-server 会失败,因为 LDAP 服务器不响应 HTTP 请求。
常见误解:把 LDAP over SSL/TLS(LDAPS)误当作 HTTPS;实际上 LDAPS 是 LDAP 协议在 TLS 之上的封装(端口 636),仍属 TCP 流,与 HTTP 无关。
正确做法:启用 stream 模块做纯 TCP 代理
Nginx 1.9.0+ 内置 stream 模块(需编译时启用 --with-stream),支持监听 TCP/UDP 端口并转发原始字节流。配置示例如下:
# /etc/nginx/nginx.conf
stream {
upstream ldap_backend {
server 192.168.10.5:389; # 实际 OpenLDAP 或域控地址
# 可加多台实现简单负载(但注意 LDAP 会话状态)
}
<pre class='brush:php;toolbar:false;'>server {
listen 389;
proxy_pass ldap_backend;
proxy_timeout 1s;
proxy_responses 1;
}
# 若需 LDAPS(端口 636),再加一个 server 块
server {
listen 636 ssl;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
proxy_pass ldap_backend;
}}
关键注意事项
-
不支持健康检查:stream 模块默认无主动探活机制,建议配合
health_check(需 Nginx Plus)或用外部脚本 +nginx -s reload维护 upstream 状态。 - 无法做认证前置:Nginx 不校验用户名密码,所有认证逻辑完全交由后端 LDAP 执行。若需统一认证网关(如先验 token 再透传 LDAP),需额外部署反向代理层(如 Envoy、HAProxy)或使用支持 LDAP 的应用网关。
-
SSL 终止谨慎使用:对 LDAPS 做 SSL 终止(即 Nginx 解密再明文发给后端)会破坏 LDAP 客户端信任链,通常应直通 TLS(
listen 636 ssl+ssl_preread on),或让后端自行处理加密。 -
防火墙与 SELinux:确保系统允许 Nginx 绑定 389/636(可能需要
setsebool -P nginx_can_network_connect 1)。
替代方案参考
若需真正“在 Nginx 层集成 LDAP 认证”,可行路径只有两种:
- HTTP 应用场景:前端 Web 应用(如 Kibana、Grafana)开启 LDAP 登录,由应用自身连接 LDAP;Nginx 仅作 HTTPS 终止和反向代理(HTTP 模块),不碰 LDAP 协议。
-
专用中间件:用
auth_request指令调用一个小型认证服务(如 Python Flask 接口),该服务完成 LDAP Bind 验证后返回 2xx,Nginx 根据响应放行请求 —— 此时 LDAP 交互发生在后端服务内,Nginx 仍是 HTTP 层角色。










