shibboleth: Shibboleth Auth Request module for NGINX
安装
您可以在任何基于 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-shibboleth
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-shibboleth
通过在 /etc/nginx/nginx.conf 顶部添加以下内容来启用模块:
load_module modules/ngx_http_shibboleth_module.so;
本文档描述了 nginx-module-shibboleth v2.0.2,于 2023 年 5 月 26 日发布。
此模块允许 Nginx 与 Shibboleth 通过 Shibboleth 的 FastCGI 授权器一起工作。此模块需要特定的配置才能正常工作,以及系统上可用的 Shibboleth FastCGI 授权器应用程序。它旨在与 Apache 的 mod_shib 的某些部分相似,尽管 Shibboleth 的授权和身份验证设置是通过 shibboleth2.xml 配置的,而不是在 Web 服务器配置中。
通过在 location 块中配置此模块,传入请求将在 Nginx 中根据对 Shibboleth FastCGI 授权器的子请求结果进行授权。在此过程中,此模块可以用于将成功授权器响应中的用户属性复制到 Nginx 的原始请求中,作为头部或环境参数供任何后端应用程序使用。如果授权不成功,授权器响应状态和头部将返回给客户端,拒绝访问或相应地重定向用户的浏览器(例如,如果配置了 WAYF 页面)。
此模块在访问阶段工作,因此可以通过 satisfy 指令与其他访问模块(如 access、auth_basic)结合使用。此模块也可以与 ngx_http_auth_request_module 一起编译,但在同一 location 块中使用这两个模块未经测试且不建议。
请阅读下面的 行为 以了解更多信息,并查阅 配置 以获取有关使用头部进行属性时避免欺骗的重要说明。
有关此模块为何是专用模块的更多信息,请参见 https://forum.nginx.org/read.php?2,238523,238523#msg-238523
指令
以下指令将添加到您的 Nginx 配置文件中。下面提到的上下文显示了它们可以添加的位置。
shib_request \<uri>|off | 上下文: http、server、location
默认值: off
启用 Shibboleth 授权请求模块并设置将请求授权的 URI。配置的 URI 应指向您的 Shibboleth FastCGI 授权器的 Nginx 位置块。
来自对配置 URI 的子请求的响应的 HTTP 状态和头部将根据 FastCGI 授权器规范 返回给用户。一个(可能显著的)警告是,由于 Nginx 当前在处理子请求时的操作方式(授权器实际上所需的),请求体将 不 被转发到授权器,类似地,来自授权器的响应体将 不 返回给客户端。
配置的 URI 不限于使用 FastCGI 后端生成响应。然而,这在测试或其他情况下可能很有用,因为您可以使用 Nginx 内置的 return 和 rewrite 指令生成合适的响应。此外,此模块可以与 任何 FastCGI 授权器一起使用,尽管上述警告可能会影响其操作。
[!WARNING]
shib_request指令不再需要shib_authorizer标志。必须删除此标志以启动 Nginx。无需其他更改。
shib_request_set \<variable> \<value>
上下文: http、server、location
默认值: none
在授权请求完成后,将 variable 设置为指定的 value。value 可以包含来自授权请求响应的变量。例如,$upstream_http_*、$upstream_status 和在 nginx_http_upstream_module 文档中提到的任何其他变量。
此指令可用于将 Shibboleth 属性引入后端应用程序的环境中,例如 FastCGI PHP 应用程序的 $_SERVER,并且这是推荐的方法。有关示例,请参见 配置 文档。
shib_request_use_headers on|off | 上下文: http、server、location
默认值: off
[!NOTE] 在 v2.0.0 中添加。
将 Shibboleth 授权器响应中的属性复制到主请求作为头部,使其可供上游服务器和应用程序使用。仅在您的上游/应用程序不支持通过 shib_request_set 的服务器参数时使用此选项。
启用此设置后,以 Variable-\* 开头的授权器响应头将被提取,去掉头部名称中的 Variable- 子字符串,并在发送到后端之前复制到主请求中。例如,授权器响应头 Variable-Commonname: John Smith 将导致 Commonname: John Smith 被添加到主请求中,从而发送到后端。
注意欺骗 - 您必须确保您的后端应用程序受到保护,以防止头部注入。请查阅 配置 示例以了解如何实现这一点。
配置
有关配置 Nginx/Shibboleth 环境的完整详细信息,请参见文档 https://github.com/nginx-shib/nginx-http-shibboleth/blob/master/CONFIG.rst。
一个示例 server 块包含以下内容:
#FastCGI 授权器用于授权请求模块
location = /shibauthorizer {
internal;
include fastcgi_params;
fastcgi_pass unix:/opt/shibboleth/shibauthorizer.sock;
}
#FastCGI 响应器
location /Shibboleth.sso {
include fastcgi_params;
fastcgi_pass unix:/opt/shibboleth/shibresponder.sock;
}
## 使用 ``shib_request_set`` 指令,我们可以将属性引入
## 后端应用程序的环境变量。在此示例中,我们
## 设置 ``fastcgi_param``,但这可以是任何支持参数的 Nginx 后端
## (通过使用适当的 *_param 选项)
#
## ``shib_fastcgi_params`` 是一组可选的默认参数,
## 可在此存储库的 ``includes/`` 目录中找到。
#
## 除非您的后端应用程序不支持服务器参数或特别需要头部,
## 否则选择此类型的配置。
location /secure-environment-vars {
shib_request /shibauthorizer;
include shib_fastcgi_params;
shib_request_set $shib_commonname $upstream_http_variable_commonname;
shib_request_set $shib_email $upstream_http_variable_email;
fastcgi_param COMMONNAME $shib_commonname;
fastcgi_param EMAIL $shib_email;
fastcgi_pass unix:/path/to/backend.socket;
}
## 一个安全的位置。所有传入请求查询 Shibboleth FastCGI 授权器。
## 注意性能问题和欺骗!
#
## 对于 ``proxy_pass`` 应用程序或不支持服务器参数的后端,
## 选择此类型的配置。
location /secure {
shib_request /shibauthorizer;
shib_request_use_headers on;
# Shibboleth 的属性由 FastCGI
# 授权器作为头部引入,因此我们必须防止欺骗。
# ``shib_clear_headers`` 是一组默认的头部指令,
# 可在此存储库的 `includes/` 目录中找到。
include shib_clear_headers;
# 添加您的应用程序使用的 *所有* 属性,包括所有
# 变体。
more_clear_input_headers 'displayName' 'mail' 'persistent-id';
# 此后端应用程序将接收 Shibboleth 变量作为请求
# 头部(来自 Shibboleth 的 FastCGI 授权器)
proxy_pass http://localhost:8080;
}
请注意,我们使用 headers-more-nginx-module 来清除潜在危险的输入头部并避免欺骗的可能性。带环境变量的后一个示例不易受到头部欺骗,只要后端仅从环境参数读取数据即可。
可以使用 default configuration 清除 Shibboleth 授权器的基本头部,但您必须确保为应用程序使用的所有属性编写自己的清除指令。请记住,一些应用程序会尝试从环境中读取 Shibboleth 属性,然后回退到头部,因此即使您不使用 shib_request_use_headers,也要检查应用程序的代码。
使用 shib_request_set,可以使用 default params 文件,您可以将其作为 Nginx include 使用,以确保所有核心 Shibboleth 变量从 FastCGI 授权器传递到应用程序。包含许多默认属性,因此请删除应用程序不需要的属性,并添加所需的 Federation 或 IDP 属性。此默认参数文件可以通过简单地将 fastcgi_param 指令更改为 uwsgi_param、scgi_param 等来重复使用于非 FastCGI 的上游。
注意事项
- 子请求,例如 Shibboleth 授权请求,不会通过头部过滤器处理。这意味着像
add_header这样的内置指令如果作为/shibauthorizer块的一部分配置,将 不 起作用。如果您需要操作子请求头部,请使用来自headers-more模块的more_set_headers。
请参见 https://forum.nginx.org/read.php?29,257271,257272#msg-257272。
行为
此模块在可能的情况下遵循 FastCGI 授权器规范,但有一些显著的偏差 - 这是有充分理由的。行为如下:
-
授权器子请求包含原始请求的所有方面,除了请求体,因为 Nginx 不支持请求体的缓冲。由于 Shibboleth FastCGI 授权器不考虑请求体,因此这不是问题。
-
如果授权器子请求返回
200状态,则允许访问。
如果启用了 shib_request_use_headers,并且提取以 Variable-\* 开头的响应头,去掉头部名称中的 Variable- 子字符串,并复制到主请求中。其他未以 Variable- 开头的授权器响应头和响应体将被忽略。FastCGI 规范要求将 Variable-* 名称值对包含在 FastCGI 环境中,但我们将其作为头部传递,以便可以与 任何 后端(例如 proxy_pass)一起使用,而不仅仅限于 FastCGI 应用程序。通过将 Variable-* 数据作为头部传递,我们最终遵循了 Apache 中 mod_shib 的 ShibUseHeaders On 的行为,该行为将这些用户属性作为头部传递。
为了将属性作为环境变量传递(相当于 mod_shib 中的 ShibUseEnvironment On),必须使用 shib_request_set 指令手动提取每个属性。目前不能对所有属性进行 批量 提取,因为每个后端可能以不同的方式接受参数(fastcgi_param、uwsgi_param 等)。欢迎拉取请求以自动化此行为。
- 如果授权器子请求返回 任何 其他状态(包括重定向或错误),则将授权器响应的状态和头部返回给客户端。
这意味着在 401 Unauthorized 或 403 Forbidden 时,将拒绝访问,并将来自授权器的头部(例如 WWW-Authenticate)传递给客户端。所有其他授权器响应(例如 3xx 重定向)将返回给客户端,包括状态和头部,允许重定向到 WAYF 页面和 Shibboleth 响应器(Shibboleth.sso)正常工作。
FastCGI 授权器规范要求将响应体返回给客户端,但由于 Nginx 当前不支持缓冲子请求响应(NGX_HTTP_SUBREQUEST_IN_MEMORY),因此授权器响应体实际上被忽略。解决方法是让 Nginx 提供自己的 error_page,如下所示:
location /secure {
shib_request /shibauthorizer;
error_page 403 /shibboleth-forbidden.html;
...
}
如果 Shibboleth 授权器拒绝用户访问此位置,则会提供给定的错误页面。如果未指定 error_page,Nginx 将提供其通用错误页面。
请注意,这 不 适用于 Shibboleth 响应器(通常托管在 Shibboleth.sso),因为它是 FastCGI 响应器,Nginx 完全兼容,因为不使用子请求。
有关更多详细信息,请参见 https://forum.nginx.org/read.php?2,238444,238453。
虽然此模块专门针对 Shibboleth 的 FastCGI 授权器,但它可能也适用于其他授权器,需考虑上述规范的偏差。
测试
每当对存储库进行新提交或打开新拉取请求时,测试将在 GitHub Actions 上自动运行(使用 此配置)。如果出现问题,您将收到通知,并且结果将在 GitHub 上报告。
测试使用简单的 Bash 脚本组合编写,用于编译我们的模块与不同版本和配置的 Nginx,以及用于集成测试的 Test::Nginx Perl 测试框架。有关如何扩展测试的信息,请查阅前面的链接,并参考底层的 Test::Base 文档,了解有关 blocks() 函数的内容。
集成测试由 CI 自动运行,但也可以手动运行(需要安装 Perl 和 CPAN):
cd nginx-http-shibboleth
cpanm --notest --local-lib=$HOME/perl5 Test::Nginx
## nginx 必须在 PATH 中并构建了调试符号
PERL5LIB=$HOME/perl5/lib/perl5 prove
帮助与支持
有关 Shibboleth 配置和 Nginx 或 Web 服务器设置的支持请求应直接发送到 Shibboleth 社区用户邮件列表。有关详细信息,请参见 https://www.shibboleth.net/community/lists/。
调试
由于 nginx/FastCGI/Shibboleth 堆栈的复杂性,调试配置问题可能很困难。以下是一些关键点:
-
确认
nginx-http-shibboleth已成功构建并安装在 nginx 中。您可以通过运行nginx -V并检查输出中的--add-module=[path]/nginx-http-shibboleth或--add-dynamic-module=[path]/nginx-http-shibboleth来检查。 -
如果使用动态模块的 nginx,请确认您已使用
load_module指令加载此模块。如果您忘记加载模块,使用shib_request和其他指令将失败。 -
如果使用的 nginx 版本与我们 测试的版本 不同,或者您使用其他第三方模块,则应运行上述测试套件以确认兼容性。如果任何测试失败,请检查您的配置或考虑更新您的 nginx 版本。
-
Shibboleth 配置:检查您的
shibboleth2.xml和相关配置,以确保您的主机、路径和属性被正确释放。一个 示例配置 可以帮助您识别配置shibboleth2.xml以与 FastCGI 授权器配合使用的关键“注意事项”。 -
应用程序级别:在您的代码中,始终从最简单的调试输出(例如打印请求环境)开始,然后逐步深入。如果您想创建一个基本的独立应用程序,请查看 wiki 上的 Bottle 配置。
-
调试模块内部:如果您仔细检查了上述所有内容,那么您还可以调试此模块本身的行为。您需要编译带有调试支持的 nginx(通过
./auto/configure --with-debug ...),并在运行 nginx 时,最好能够在前台运行并启用调试日志。将以下内容添加到您的nginx.conf中:daemon off; error_log stderr debug;然后运行 nginx。启动 nginx 时,您应该看到包含 [debug] 的行,并且在您发出请求时,控制台日志将继续。如果没有发生这种情况,请检查您的 nginx 配置和编译过程。
当您最终发出请求命中(或应该调用)
shib_request位置块时,您将在输出中看到类似以下的行:[debug] 1234#0: shib request handler [debug] 1234#0: shib request set variables [debug] 1234#0: shib request authorizer handler [debug] 1234#0: shib request authorizer allows access [debug] 1234#0: shib request authorizer copied header: "AUTH_TYPE: shibboleth" [debug] 1234#0: shib request authorizer copied header: "REMOTE_USER: [email protected]" ...如果您没有看到这些包含 shib request ... 的行,或者如果您看到 某些 行但没有看到头部/变量被复制的地方,请仔细检查您的 nginx 配置。如果您仍然没有进展,可以在源代码中添加自己的调试行(遵循此模块的示例),以最终确定出错的原因和时机。如果这样做,请记得在每次更改后重新编译 nginx 和/或
nginx-http-shibboleth。
如果您认为在核心模块代码中发现了错误,请 创建一个问题。
您还可以搜索现有问题,因为可能有人之前遇到过类似的问题。
GitHub
您可以在 nginx-module-shibboleth 的 GitHub 存储库 中找到有关此模块的其他配置提示和文档。