在本系列文章的第二篇中,我演示了如何在混合环境中使用 NGINX Plus 配置基于身份验证的零信任用例,并部署了 NGINX Plus 作为外部负载均衡器,用于对连接到 Kubernetes 应用的用户进行路由和身份验证。
在本文中,我们将探讨可在外部负载均衡服务上配置的其他零信任用例,包括:
- 授权和访问
- 加密 mTLS
- 监控/审计
零信任用例 1:授权
许多人认为身份验证和授权可以互换使用,但其实二者并非一回事。“身份验证”是指根据所提供的凭证验证用户身份的流程。
即使经过身份验证的用户通过了系统验证,他们也不一定有权访问受保护的应用。这就涉及到了授权。授权是指在验证身份权限后授予应用访问权限的流程。
OIDC 身份验证中的授权需要从用户 ID 令牌中检索声明,并设置条件来验证用户是否有权进入系统。
通过 JWT 声明,身份验证供应商 (IdP) 会向经过身份验证的用户授予一个 ID 令牌,其中包含特定的用户信息。这些声明的配置通常由 IdP 进行设置。回顾上一节中配置的 OIDC 身份验证用例,我们可以从 NGINX 键值存储中检索经过身份验证的用户的 ID 令牌。
$ curl -i http://localhost:8010/api/9/http/keyvals/oidc_acess_tokens
然后,我们可使用 jwt.io 查看 ID 令牌的解码值。下面是 ID 令牌有效载荷数据的解码示例。
{
"exp": 1716219261,
"iat": 1716219201,
"admin": true,
"name": "Micash",
"zone_info": "America/Los_Angeles"
"jti": "9f8ff4bd-4857-4e12-9634-e5876f786f98",
"iss": "http://idp.f5lab.com:8080/auth/realms/master",
"aud": "account", "typ": "Bearer",
"azp": "appworld2024",
"nonce": "gMNK3tu06j6tp5-jGa3aRhkj4F0P-Z3e04UfcFeqbes"
}
NGINX Plus 可以访问这些作为内置变量的声明,后者可通过将 $jwt_claim_ 前缀添加到所需字段(例如 admin 声明的 $jwt_claim_admin)来访问。我们可以轻松地对这些声明设置条件,以便及时拦截未经授权的用户,防止其进入后端应用。
再来看看本系列文章上一篇中的 frontend.conf 文件。我们可以根据 admin JWT 声明的值将 $jwt_flag 变量设置为 0 或 1,然后使用 jwt_claim_require 指令来验证 ID 令牌。如果 ID 令牌的 admin 声明设置为 false,则会被拒绝。
map $jwt_claim_admin $jwt_status {
"true" 1;
default 0;
}
server {
include conf.d/openid_connect.server_conf; # 授权代码流和中继方处理
error_log /var/log/nginx/error.log debug; # 按需降低严重性级别
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
server_name example.work.gd;
ssl_certificate /etc/ssl/nginx/default.crt; # 自签名证书,仅作为示例
ssl_certificate_key /etc/ssl/nginx/default.key;
location / {
# 本站点受 OpenID Connect 保护
auth_jwt "" token=$session_jwt;
error_page 401 = @do_oidc_flow;
auth_jwt_key_request /_jwks_uri; # 使用 URL 时启用
auth_jwt_require $jwt_status;
proxy_pass https://cluster1-https; # 使用 URL 时启用
}
}
注:NGINX Plus 的授权不仅限于 JWT token。从技术上讲,您可以对各种属性设置条件,例如:
- 会话 cookie
- HTTP 请求头
- 源/目标 IP 地址
零信任用例 2:双向 TLS 认证 (mTLS)
就零信任而言,mTLS 是属于零信任范畴的主流用例之一。举例来说,企业广泛使用 service mesh(服务网格)技术以符合零信任标准。这是因为 service mesh 技术旨在通过使用 mTLS 来保护 service 到 service 通信。
从很多方面来说,mTLS 类似于我们在上一节中实现的 OIDC 用例。我们只在此处利用数字证书对流量进行加密和身份验证。这一底层框架由 PKI(公钥基础设施)定义。
下面举一个简单的例子来深入浅出地介绍一下此框架,比如您随身携带的驾照。正如驾照可用于验证持有人的身份一样,数字证书能够用来验证应用的身份。只有国家相关部门才能颁发有效的驾照,同样,只有证书颁发机构 (CA) 才可向应用颁发有效证书。同时,确保这些机构的真实性也很重要。因此,每个 CA 都必须使用专用安全密钥来签发有效证书。
使用 NGINX 配置 mTLS 可分为以下两部分:
- 入向 mTLS;确保 SSL 客户端流量安全,并依据受信任 CA 验证客户端证书。
- 出向 mTLS;确保 SSL 上游流量安全,并将 TLS 材料的身份验证卸载到受信任的 HTTPS 后端服务器。
入向 mTLS
只需在 server 上下文中添加 ssl_client_certificate 指令,引用受信任的证书颁发机构,即可在 NLK 部署中配置入向 mTLS。这将配置 NGINX 通过引用的 CA 验证客户端证书。
注:如果没有引用的 CA,则可使用 OpenSSL 或 Cloudflare PKI 和 TLS 工具套件创建一个。
server {
listen 443 ssl;
status_zone https://cafe.example.com;
server_name cafe.example.com;
ssl_certificate /etc/ssl/nginx/default.crt;
ssl_certificate_key /etc/ssl/nginx/default.key;
ssl_client_certificate /etc/ssl/ca.crt;
}
出向 mTLS
出向 mTLS 与入向 mTLS 类似,其中 NGINX 会验证上游应用的证书,而非来自客户端的证书。只需将 proxy_ssl_trusted_certificate 指令添加到 server 上下文,即可启用此功能。您既可引用我们在配置入向 mTLS 时用于验证的同一受信任 CA,也可以引用不同的 CA。
除了验证服务器证书以外,作为反向代理的 NGINX 还能传递证书/密钥,并将验证卸载到 HTTPS 上游应用。具体方法是,在 server 上下文中添加 proxy_ssl_certificate 和 proxy_ssl_certificate_key 指令。
server {
listen 443 ssl;
status_zone https://cafe.example.com;
server_name cafe.example.com;
ssl_certificate /etc/ssl/nginx/default.crt;
ssl_certificate_key /etc/ssl/nginx/default.key;
#入向 mTLS
ssl_client_certificate /etc/ssl/ca.crt;
#出向 mTLS
proxy_ssl_certificate /etc/nginx/secrets/default-egress.crt;
proxy_ssl_certificate_key /etc/nginx/secrets/default-egress.key;
proxy_ssl_trusted_certificate /etc/nginx/secrets/default-egress-ca.crt;
}
零信任用例 3:安全防护声明标记语言 (SAML)
SAML(安全防护声明标记语言)是替代 OIDC 的 SSO 解决方案。许多企业可能需要在 SAML 和 OIDC 之间做出选择,具体取决于其要求及当前生产环境中运行的 IdP。SAML 要求 SP(服务提供商)通过绑定到 SAML IdP 的 HTTP POST 来交换 XML 消息。若 SP 和 IdP 之间交换消息成功,则用户可使用一套用户凭证对受保护的后端应用进行会话访问。
在本节中,我们将把 NGINX Plus 配置为 SP,并通过 IdP 启用 SAML。这就像我们将 NGINX Plus 配置为 OIDC 授权代码流中的中继方一样(参见零信任用例 1)。
设置 IdP
一个前提条件是设置 IdP。在示例中,我们将在 Azure 上设置 Microsoft Entra ID。您可以使用所选的 SAML IdP。在 IdP 中创建 SAML 应用后,您便可访问所需的 SSO 字段以将 SP (NGINX Plus) 链接到 IdP (Microsoft Entra ID) 。
如上图所示,您将需要点击 Basic SAML Configuration(基本 SAML 配置)中 Edit(编辑) 旁边的铅笔图标来编辑基本 SAML 配置。
填写以下值,然后点击 Save(保存) :
- Identifier (Entity ID)(标识符(实体 ID)) — https://fourth.run.place
- Reply URL (Assertion Consumer Service URL)(回复 URL(断言消费者服务 URL)) — https://fourth.run.place/saml/acs
- Sign on URL(登录 URL): https://fourth.run.place
- Logout URL (Optional)(注销 URL(可选)): https://fourth.run.place/saml/sls
最后,从 Microsoft Entra ID 下载 Certificate (Raw)(证书(原始格式)),并将其保存到 NGINX Plus 实例中。该证书用于验证从 IdP 收到的已签名 SAML 断言。在将证书保存到 NGINX Plus 实例后,从下载的证书中提取公钥并将其转换为 SPKI 格式。此证书将在下一节配置 NGINX Plus 时用到。
$ openssl x509 -in demo-nginx.der -outform DER -out demo-nginx.der
$ openssl x509 -inform DER -in demo-nginx.der -pubkey -noout > demo-nginx.spki
将 NGINX Plus 配置为 SAML 服务提供商
IdP 设置完成后,我们便可将 NGINX Plus 配置为 SP,以便与 IdP 交换 XML 消息并进行验证。在登录 NGINX Plus 实例后,只需复制 nginx SAML GitHub 仓库即可。
$ git clone https://github.com/nginxinc/nginx-saml.git && cd nginx-saml
将配置文件复制到 /etc/nginx/conf.d 目录中。
$ cp frontend.conf saml_sp.js saml_sp.server_conf saml_sp_configuration.conf /etc/nginx/conf.d/
请注意,默认情况下,frontend.conf 会以明文 http 方式监听 8010 端口。您可将 kube_lb.conf 合并到 frontend.conf 中,以启用 TLS 卸载,并将 upstream 上下文更新为您希望使用 SAML 保护的应用端点。
最后,我们需要编辑 saml_sp_configuration.conf 文件,并根据 SP 和 IdP 的参数更新 map 上下文中的变量:
- $saml_sp_entity_id; https://fourth.run.place
- $saml_sp_acs_url; https://fourth.run.place/saml/acs
- $saml_sp_sign_authn; false
- $saml_sp_want_signed_response; false
- $saml_sp_want_signed_assertion; true
- $saml_sp_want_encrypted_assertion; false
- $saml_idp_entity_id; 向 SP 标识 IdP 的唯一标识符。该字段可从 IdP 中检索出来
- $saml_idp_sso_url; 这是登录 URL,也可从 IdP 中检索出来
- $saml_idp_verification_certificate; 变量,引用设置 IdP 时从上一节下载的证书。该证书将验证从 IdP 收到的已签名断言。使用完整目录(/etc/nginx/conf.d/demo-nginx.spki)
- $saml_sp_slo_url; https://fourth.run.place/saml/sls
- $saml_idp_slo_url; 这是从 IdP 中检索出来的注销 URL
- $saml_sp_want_signed_slo; true
除非有特定的启用要求,否则在 saml_sp_configuration.conf 中定义的其余变量均可保持不变。在正确设置变量后,即可重新加载 NGINX Plus。
$ nginx -s reload
测试
现在,我们将验证 SAML 流。打开浏览器,然后在地址栏中输入 https://fourth.run.place。此操作会将我重定向到 IdP 登录页面。
在使用凭证登录后,我将可以访问受保护的应用
零信任用例 4:监控/审计
NGINX 日志/指标可导出到各种第三方提供商,包括 Splunk、Prometheus/Grafana、云提供商(AWS CloudWatch 和 Azure Monitor Logs)、Datadog、ELK 堆栈等。
借助 NGINX Instance Manager 或 NGINX SaaS,您可以原生监控 NGINX 指标和日志。NGINX Plus API 支持灵活地将指标导出到任何接受 JSON 的第三方工具。例如,在第一篇文章中,您可将 NGINX Plus API 指标导出到我们的原生实时仪表盘中。(查看本系列第一篇文章,了解更多有关原生实时仪表盘的信息。)
无论选择哪种工具,监控/审计 IT 系统生成的数据都是了解和优化应用的关键。
结语
云提供商提供了一种便捷的方法来将 Kubernetes Service 暴露到互联网上。只需创建 Kubernetes service 类型 LoadBalancer,外部用户即可通过公共入口点连接到您的服务。但云负载均衡器只能实现基本的 TCP/HTTP 负载均衡。因此,在将环境扩展到不同区域的多个集群时,您可为 NGINX Plus 配置许多零信任功能。在本系列文章的下一篇中,我们将对此进行详细介绍。