spnego-http-auth: Nginx 模块用于 HTTP SPNEGO 认证
安装
您可以在任何基于 RHEL 的发行版中安装此模块,包括但不限于:
- RedHat Enterprise Linux 7、8、9 和 10
- CentOS 7、8、9
- AlmaLinux 8、9
- Rocky Linux 8、9
- Amazon Linux 2 和 Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-spnego-http-auth
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-spnego-http-auth
通过在 /etc/nginx/nginx.conf 顶部添加以下内容来启用该模块:
load_module modules/ngx_http_auth_spnego_module.so;
本文档描述了 nginx-module-spnego-http-auth v1.1.3,于 2025 年 5 月 12 日发布。
该模块为 nginx(http://nginx.org) 实现了 SPNEGO 支持。它目前仅支持通过 GSSAPI 的 Kerberos 认证。
先决条件
认证已在以下环境中进行了测试(至少):
- Nginx 1.2 到 1.15
- Internet Explorer 8 及以上
- Firefox 10 及以上
- Chrome 20 及以上
- Curl 7.x (GSS-Negotiate), 7.x (SPNEGO/fbopenssl)
用于这些测试的底层 Kerberos 库是 MIT KRB5 v1.12。
配置参考
您可以在每个位置和/或全局范围内配置 GSS 认证:
这些选项是必需的。
* auth_gss: 开/关,便于在保留其他选项的同时取消安全性
* auth_gss_keytab: 包含服务凭据的 keytab 文件的绝对路径
这些选项仅应在您有包含特权主体的 keytab 时指定。在几乎所有情况下,您不应将这些放入配置文件,因为 gss_accept_sec_context 会执行正确的操作。
* auth_gss_realm: Kerberos 领域名称。如果指定,则仅在与此默认值不同的情况下将领域传递给 nginx 变量 $remote_user。要覆盖此行为,请在配置中将 auth_gss_format_full 设置为 1。
* auth_gss_service_name: 获取凭据时使用的服务主体名称。
如果您只想授权特定的主体集,可以使用 auth_gss_authorized_principal 指令。配置语法支持多条条目,每行一条。
auth_gss_authorized_principal <primary1>@<realm>
auth_gss_authorized_principal <primary2>@<realm>
也可以通过 auth_gss_authorized_principal_regex 指令使用正则表达式模式授权主体。该指令可以与 auth_gss_authorized_principal 指令一起使用。
auth_gss_authorized_principal <primary1>@<realm>
auth_gss_authorized_principal_regex ^(<primary2>)/(<instance>)@<realm>$
nginx 中的远程用户头只能通过基本认证设置。因此,该模块设置了一个虚假的基本认证头,以便到达您的后端应用程序以设置此头/nginx 变量。禁用此行为的最简单方法是在您的位置配置中添加以下配置。
proxy_set_header Authorization "";
模块的未来版本可能会将此行为作为选项,但目前这应该是一个足够的解决方法。
如果您希望启用 GSS 本地名称规则以重写用户名,可以指定 auth_gss_map_to_local 选项。
凭据委派
用户凭据可以通过 auth_gss_delegate_credentials 指令委派给 nginx。此指令将在用户选择委派其凭据时启用不受限制的委派。可以使用 auth_gss_constrained_delegation 指令与 auth_gss_delegate_credentials 指令一起启用受限委派 (S4U2proxy)。要指定用于存储受限委派的服务票证的 ccache 文件名,请设置 auth_gss_service_ccache 指令。否则,将使用默认的 ccache 名称。
auth_gss_service_ccache /tmp/krb5cc_0;
auth_gss_delegate_credentials on;
auth_gss_constrained_delegation on;
委派的凭据将存储在系统的临时目录中。一旦请求完成,凭据文件将被销毁。凭据文件的名称将在 nginx 变量 $krb5_cc_name 中指定。使用该变量可以包括将其传递给 fcgi 程序,使用 fastcgi_param 指令。
fastcgi_param KRB5CCNAME $krb5_cc_name;
受限委派目前仅支持使用协商认证方案,并且仅在 MIT Kerberos 中进行了测试(如果使用 Heimdal Kerberos,请自行承担风险)。
基本认证回退
如果客户端未尝试协商,模块默认会回退到基本认证。如果您在没有 SSL 的情况下使用 SPNEGO,建议您禁用基本认证回退,因为密码将以明文形式发送。这可以通过在配置文件中设置 auth_gss_allow_basic_fallback 来完成。
auth_gss_allow_basic_fallback off
这些选项会影响基本认证的操作:
* auth_gss_realm: Kerberos 领域名称。如果指定,则仅在与此默认值不同的情况下将领域传递给 nginx 变量 $remote_user。要覆盖此行为,请在配置中将 auth_gss_format_full 设置为 1。
* auth_gss_force_realm: 强制使用在 auth_gss_realm 中配置的领域进行认证,或者如果未设置 auth_gss_realm 则使用系统默认领域。如果客户端提供了不同的领域,这将重写 $remote_user。如果未设置 auth_gss_format_full,即使客户端指定了领域,$remote_user 也不会包含领域。
故障排除
检查日志。如果您看到提到 NTLM,您的客户端正在尝试使用 NTLMSSP 连接,这是不受支持且不安全的。
验证您在 keytab 中是否有 HTTP 主体
MIT Kerberos 工具
$ KRB5_KTNAME=FILE:<path to your keytab> klist -k
或
$ ktutil
ktutil: read_kt <path to your keytab>
ktutil: list
Heimdal Kerberos 工具
$ ktutil -k <path to your keytab> list
获取 HTTP 主体
如果您发现没有 HTTP 服务主体,正在运行在 Active Directory 环境中,并且绑定到域以使 Samba 工具正常工作
$ env KRB5_KTNAME=FILE:<path to your keytab> net ads -P keytab add HTTP
如果您在不同的 Kerberos 环境中运行,您可能可以运行
$ env KRB5_KTNAME=FILE:<path to your keytab> krb5_keytab HTTP
增加最大允许的头部大小
在 Active Directory 环境中,Authorization 头中的 SPNEGO 令牌包括 PAC(特权访问证书)信息,其中包含用户所属的所有安全组。这可能导致头部超出默认的 8kB 限制,并导致以下错误消息:
400 Bad Request
Request Header Or Cookie Too Large
出于性能原因,最佳解决方案是减少用户所属的组数。当这不切实际时,您也可以选择通过显式设置 Nginx 头部缓冲区的数量和大小来增加允许的头部大小:
large_client_header_buffers 8 32k;
调试
如果 nginx 是使用 --with-debug 选项编译的,模块会打印各种调试信息,并且 error_log 指令具有 debug 级别。
NTLM
请注意,该模块不支持 NTLMSSP 在协商中。NTLM,无论是 v1 还是 v2,都是一个可被利用的协议,应尽量避免使用。
Windows
有关 Windows KDC/AD 环境的信息,请参见 此处 的文档。
帮助
如果您无法解决问题,请随时在 GitHub 上打开一个问题,我会尽力帮助您。
GitHub
您可以在 nginx-module-spnego-http-auth 的 GitHub 仓库 中找到此模块的其他配置提示和文档。