Microsoft Active Directory Federation Services(AD FS)支持在Windows Server上托管应用的组织通过外联网,将单点登录(SSO)访问权限扩展至可信业务合作伙伴的员工。业务合作伙伴之间共享身份信息称为“联合身份认证”。
在实际应用中,使用AD FS意味着联盟中各公司的员工只需登录本地环境。当员工访问可信业务合作伙伴的Web应用时,本地AD FS服务器会以安全令牌的形式将其身份信息传递给合作伙伴的AD FS服务器。该令牌包含多项声明,即本地Active Directory中存储的员工个人属性(用户名、业务角色、员工ID等)。合作伙伴的AD FS服务器会将令牌中的声明映射为合作伙伴应用可识别的声明,然后确定是否授权该员工进行所请求的访问。
对于AD FS 2.0及更高版本,可以启用高可用性(HA),从而增强应用身份验证服务的韧性和可扩展性。在AD FS HA集群(也称为AD FS场)中,可在单个数据中心内部署多台AD FS服务器,也可将其分布在多个数据中心。配置为全主动HA的集群需要使用负载均衡器,将流量均匀分配到各AD FS服务器。在主动-被动HA部署中,当主AD FS服务器发生故障时,负载均衡器可将服务故障转移到备用AD FS服务器。
本文介绍如何配置NGINX Plus,以便在分别运行于Windows Server 2012 R2和Windows Server 2016上的AD FS 3.0和AD FS 4.0环境中提供高可用性。
AD FS标准高可用性拓扑
本文使用标准AD FS场拓扑进行说明。这并非建议,也不涵盖所有可能的部署场景。对于本地部署,标准场由企业内部网中的一台或多台AD FS服务器组成,其前端是在DMZ网络中部署的一台或多台Web Application Proxy(WAP)服务器。WAP服务器充当反向代理,使外部用户能够访问托管在企业内部网上的Web应用。
但是,WAP没有内置的服务器集群配置或高可用性(HA)支持,因此必须在WAP服务器前端部署负载均衡器。此外,还需在DMZ与内网的边界部署负载均衡器,以实现AD FS高可用性。在标准AD FS场中,Windows Server 2012和2016的网络负载均衡(NLB)功能充当负载均衡器。最后,通常会在负载均衡器的外部IP地址前端以及各网络区域之间部署防火墙。

在标准HA拓扑中使用NGINX Plus
如前所述,NLB可以为AD FS服务器场执行负载均衡。不过,其功能集较为基础(仅提供基本的运行状况检查和有限的监控功能)。NGINX Plus具备生产AD FS环境实现高可用性所需的多项关键功能,同时保持轻量。
在部署本文所述的标准拓扑时,NGINX Plus将取代NLB,为所有WAP和AD FS服务器场的流量提供负载均衡。但请注意,我们不会让NGINX Plus终止与AD FS服务器的SSL连接,因为AD FS要正常运行,必须能够看到来自WAP服务器的实际SSL证书(有关详细信息,请参阅这篇Microsoft TechNet文章)。
建议在生产环境中也为NGINX Plus本身实施高可用性(HA),但此处未予展示。有关说明,请参阅《NGINX Plus管理指南》中的“本地部署中的NGINX Plus高可用性支持”。

配置NGINX Plus以对AD FS服务器进行负载均衡
用于对 AD FS 服务器进行负载均衡的 NGINX Plus 配置非常简单。如上所述,AD FS 服务器必须能够看到来自 WAP 服务器的实际 SSL 证书,因此,我们将位于 DMZ 与内网边界的 NGINX Plus 实例配置为直接将 SSL 加密流量传递到 AD FS 服务器,而不终止或以其他方式处理该流量。
除必需的指令外,我们还在配置中加入以下指令:
zone在共享内存中分配一个区域,所有NGINX Plus工作进程均可在其中访问上游组中服务器的配置和运行时状态信息。hash根据源IP地址(客户端的IP地址)在客户端与AD FS服务器之间建立会话持久性。即使客户端仅与AD FS服务器建立一个TCP连接,也必须启用此功能,因为在某些情况下,如果未启用会话持久性,某些应用可能会发生多次登录重定向。status_zone表示NGINX Plus API会收集此服务器的指标,并可在内置的实时活动监控仪表板上显示(API和仪表板需分别配置)。
stream { upstream adfs_ssl {
zone adfs_ssl 64k;
server 10.11.0.5:443; # AD FS server 1
server 10.11.0.6:443; # AD FS server 2
hash $remote_addr;
}
server {
status_zone adfs_ssl;
listen 10.0.5.15:443;
proxy_pass adfs_ssl;
}
}
要使来自WAP服务器的流量通过NGINX Plus转发到AD FS服务器,还需要将联合身份验证服务名称(本例中为fs.example.com)映射到NGINX Plus侦听的IP地址。对于生产部署,请在DMZ中添加一条DNS主机A记录。对于测试部署,只需在每台WAP服务器的hosts文件中添加一个条目;本例采用这种方式,在fs.example.com文件中将其绑定到10.0.5.15:hosts file:

为测试从WAP服务器发出的流量能否到达AD FS服务器,请运行ipconfig /flushdns命令刷新DNS,然后在浏览器中通过SSO页面登录AD FS:https://fs.example.com/adfs/ls/idpinitiatedsignon.htm:

配置NGINX Plus以对WAP服务器进行负载均衡
现在,我们配置 NGINX Plus,对从外部客户端到 WAP 服务器的 HTTPS 连接进行负载均衡。根据最佳实践,流量到达 AD FS 服务器时仍应采用 SSL 加密,因此可采用以下两种方法之一配置 NGINX Plus,将 HTTPS 流量传递到 WAP 服务器:SSL 直通或 SSL 重新加密。
配置SSL透传
更简单的配置方式是让NGINX Plus将SSL加密的TCP流量原样转发到WAP服务器。为此,我们在stream上下文中配置一个虚拟服务器,类似于之前为AD FS服务器配置的负载均衡虚拟服务器。
此处,NGINX Plus在另一个唯一IP地址10.0.5.100上侦听外部流量。在生产环境中,已发布应用的外部FQDN必须通过公共区域中的DNS主机A记录指向此地址。测试时,只需在客户端计算机的hosts文件中添加一个条目即可。
注意:如果要在stream上下文中配置其他HTTPS服务,使其侦听与此服务器相同的IP地址,则必须使用ssl_preread指令和map启用服务器名称指示(SNI),以便将流量正确路由到不同的上游。此内容不在本博客的讨论范围内,但NGINX参考文档中提供了示例。
stream { upstream wap {
zone wap 64k;
server 10.11.0.5:443; #WAP server 1
server 10.11.0.6:443; #WAP server 2
least_time connect;
}
server {
status_zone wap_adfs;
listen 10.0.5.100:443;
proxy_pass wap;
}
}配置 HTTPS 重新加密
作为SSL直通的替代方案,可以在http上下文中配置虚拟服务器来接受HTTPS流量,从而充分利用NGINX Plus的第7层功能。NGINX Plus会终止来自客户端的HTTPS连接,并与WAP服务器建立新的HTTPS连接。
证书和私钥文件example.com.crt和example.com.key的公用名称(CN)或使用者可选名称(SAN)属性中包含已发布应用的外部FQDN;在本例中,该FQDN为fs.example.com。
The proxy_ssl_server_name和proxy_ssl_name指令会启用所需的服务器名称指示(SNI)标头,用于指定要在SSL Client Hello中发送的远程主机名。该标头必须与已发布应用的外部FQDN匹配,本例中为fs.example.com。
我们使用“proxy_set_header”指令将相关信息传递给WAP服务器,并将其记录在日志中:
- The
X-Real-IP标头包含$remote_addr变量捕获的源(客户端)IP地址。 - The
X-Forwarded-For传递客户端请求中的该标头,并在其中附加客户端的IP地址(如果客户端请求不含该标头,则仅传递该IP地址)。 - The
x-ms-proxy标头表示用户流量经由代理服务器路由,并将该NGINX Plus实例标识为该代理服务器。
除了此处所示的指令外,NGINX和NGINX Plus还提供多项功能,可提升SSL/TLS的性能和安全性。有关更多信息,请参阅我们的博客。
http { upstream wap {
zone wap 64k;
server 10.0.5.11:443;
server 10.0.5.10:443;
least_time header;
}
server {
listen 10.0.5.100:443 ssl;
status_zone fs.example.com;
server_name fs.example.com;
ssl_certificate /etc/ssl/example.com/example.com.crt;
ssl_certificate_key /etc/ssl/example.com/example.com.key;
location / {
proxy_pass https://wap; # 'https' enables reencrypt
proxy_ssl_server_name on;
proxy_ssl_name $host;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header x-ms-proxy $server_name;
}
}
}在无 WAP 服务器的拓扑中配置 NGINX Plus
允许外部客户端访问AD FS服务器时,最佳做法是在DMZ与企业内部网的边界处终止外部流量,并通过插入x-ms-proxy标头来识别外部身份验证尝试。WAP服务器可执行这两项功能,而按照上一节所述进行配置后,NGINX Plus也可执行这两项功能。
在某些用例中不需要WAP服务器,例如不使用IP网络和信任级别等高级声明规则时。在这些情况下,可以移除WAP服务器,并将NGINX Plus部署在DMZ与内网的边界,对发往内部AD FS服务器的请求进行身份验证,从而降低硬件、软件和运营成本。

此配置取代了标准高可用性拓扑所使用的配置。它与用于对WAP服务器进行负载均衡的HTTPS重新加密配置几乎相同,但在此配置中,NGINX Plus会将外部请求直接负载均衡到内部网络中的AD FS服务器。
upstream adfs { zone adfs 64k;
server 192.168.5.5:443; # AD FS Server 1
server 192.168.5.6:443; # AD FS Server 2
least_time header;
}
server {
listen 10.0.5.110:443 ssl;
status_zone adfs_proxy;
server_name fs.example.com;
ssl_certificate /etc/ssl/example.com/example.com.crt;
ssl_certificate_key /etc/ssl/example.com/example.com.key;
location / {
proxy_pass https://adfs;
proxy_ssl_server_name on;
proxy_ssl_name $host;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header x-ms-proxy $server_name;
}
}在AD FS部署中试用NGINX Plus,立即开始30天免费试用,或联系我们讨论您的使用场景。
相关博客文章
NGINX Plus R26 正式发布
NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。
使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。
Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。
NGINX Plus R19 正式发布
NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。
NGINX现已正式加入F5
NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。
