9.3. 设置负载均衡器或代理
本节讨论在集群的 Red Hat Single Sign-On 部署前放置反向代理或负载均衡器前需要配置的一些事项。它还涵盖了配置 集群域示例 的内置负载均衡器。
下图演示了负载平衡器的使用。在本例中,负载均衡器充当三个客户端和三个红帽单点登录服务器集群之间的反向代理。
Load Balancer 图表示例
9.3.1. 识别客户端 IP 地址
Red Hat Single Sign-On 中的一些功能依赖于连接到身份验证服务器的 HTTP 客户端的远程地址是客户端机器的实际 IP 地址。示例包括:
- 事件日志 - 失败的登录尝试使用错误的源 IP 地址记录
- SSL 必需 - 如果需要 SSL,则需要对所有外部请求设置为外部(默认值)
- 身份验证流 - 使用 IP 地址的自定义身份验证流,如仅为外部请求显示 OTP
- 动态客户端注册
当您在 Red Hat Single Sign-On 身份验证服务器前面有反向代理或负载均衡器时,这可能会有问题。通常的设置是,您有一个前端代理位于公共网络上,该网络可负载平衡并将请求转发给位于专用网络中的后端红帽单点登录服务器实例。在这种场景中,您必须进行一些额外的配置,以便红帽单点登录服务器实例将实际客户端 IP 地址转发到和处理。具体来说:
-
配置反向代理或负载均衡器以正确设置
X-Forwarded-For
和X-Forwarded-Proto
HTTP 标头。 - 配置反向代理或负载均衡器以保留原始的 'Host' HTTP 标头。
-
配置身份验证服务器,从
X-Forwarded-For
标头读取客户端的 IP 地址。
将您的代理配置为生成 X-Forwarded-For
和 X-Forwarded-Proto
HTTP 标头,并保留原始主机 HTTP 标头超出了本指南的范围。采取额外的预防措施以确保代理设置了
X-Forwarded-For
标头。如果您的代理没有正确配置,那么 恶意 客户端可以自行设置这个标头,并欺骗 Red Hat Single Sign-On 认为客户端正在与实际 IP 地址不同的 IP 地址连接。如果您正在执行任何黑色或白名单 IP 地址,这将变得非常重要。
除代理本身外,您需要在红帽单点登录端配置一些事项。如果您的代理通过 HTTP 协议转发请求,那么您需要配置 Red Hat Single Sign-On,以从 X-Forwarded-For
标头而不是从网络数据包拉取客户端的 IP 地址。要做到这一点,请打开配置文件配置文件(standalone.xml、standalone-ha.xml 或 domain.xml,具体取决于您的 操作模式),并查找 urn:jboss:domain:undertow:12.0
XML 块。
x-Forwarded-For
HTTP 配置
<subsystem xmlns="urn:jboss:domain:undertow:12.0"> <buffer-cache name="default"/> <server name="default-server"> <ajp-listener name="ajp" socket-binding="ajp"/> <http-listener name="default" socket-binding="http" redirect-socket="https" proxy-address-forwarding="true"/> ... </server> ... </subsystem>
将 proxy-address-forwarding
属性添加到 http-listener
元素。将值设为 true
。
如果您的代理使用 AJP 协议而非 HTTP 来转发请求(如 Apache HTTPD + mod-cluster),则必须配置其他不同。您不需要修改 http-listener
,而是需要添加过滤器来从 AJP 数据包中提取此信息。
X-Forwarded-For
AJP 配置
<subsystem xmlns="urn:jboss:domain:undertow:12.0"> <buffer-cache name="default"/> <server name="default-server"> <ajp-listener name="ajp" socket-binding="ajp"/> <http-listener name="default" socket-binding="http" redirect-socket="https"/> <host name="default-host" alias="localhost"> ... <filter-ref name="proxy-peer"/> </host> </server> ... <filters> ... <filter name="proxy-peer" class-name="io.undertow.server.handlers.ProxyPeerAddressHandler" module="io.undertow.core" /> </filters> </subsystem>
9.3.2. 使用反向代理启用 HTTPS/SSL
假设您的反向代理不使用 SSL 端口 8443,您还需要配置 HTTPS 流量重定向的端口。
<subsystem xmlns="urn:jboss:domain:undertow:12.0"> ... <http-listener name="default" socket-binding="http" proxy-address-forwarding="true" redirect-socket="proxy-https"/> ... </subsystem>
流程
-
将
redirect-socket
属性添加到http-listener
元素。该值应该是proxy-https
,它指向您还需要定义的套接字绑定。 在
socket-binding
-group 元素中添加新的 socket-binding
元素:<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}"> ... <socket-binding name="proxy-https" port="443"/> ... </socket-binding-group>
9.3.3. 验证配置
您可以验证反向代理或负载均衡器配置
流程
通过反向代理打开路径
/auth/realms/master/.well-known/openid-configuration
。例如,如果反向代理地址是
https://acme.com/
,打开 URLhttps://acme.com/auth/realms/master/.well-known/openid-configuration
。这将显示 JSON 文档,其中列出了红帽单点登录的多个端点。- 确保端点以反向代理或负载均衡器的地址(scheme、domain 和 port)开头。这样做后,请确保您的 Red Hat Single Sign-On 使用正确的端点。
验证 Red Hat Single Sign-On 是否看到请求的正确源 IP 地址。
要检查这一点,您可以尝试使用无效的用户名和/或密码登录到管理控制台。这应该在服务器日志中显示如下警告:
08:14:21,287 WARN XNIO-1 task-45 [org.keycloak.events] type=LOGIN_ERROR, realmId=master, clientId=security-admin-console, userId=8f20d7ba-4974-4811-a695-242c8fbd1bf8, ipAddress=X.X.X.X, error=invalid_user_credentials, auth_method=openid-connect, auth_type=code, redirect_uri=http://localhost:8080/auth/admin/master/console/?redirect_fragment=%2Frealms%2Fmaster%2Fevents-settings, code_id=a3d48b67-a439-4546-b992-e93311d6493e, username=admin
-
检查
ipAddress
的值是您试图使用 登录的机器的 IP 地址,而不是反向代理或负载均衡器的 IP 地址。
9.3.4. 使用内置负载均衡器
本节介绍配置在 集群域示例 中讨论的内置负载均衡器。
集群域示例 仅用于在一个计算机上运行。要在另一台主机上启动从设备,您需要:
- 编辑 domain.xml 文件以指向您的新主机从设备
- 复制服务器分发。您不需要 domain.xml、host.xml 或 host-master.xml 文件。您不需要 standalone/ 目录。
- 编辑 host-slave.xml 文件,以更改所用的绑定地址或在命令行中覆盖它们
流程
- 打开 domain.xml,以便您可以使用负载均衡器配置注册新主机从设备。
转到
load-balancer
配置集中的 undertow 配置。在reverse-proxy
XML 块中添加名为remote-
的新主机定义。host
3domain.xml reverse-proxy 配置
<subsystem xmlns="urn:jboss:domain:undertow:12.0"> ... <handlers> <reverse-proxy name="lb-handler"> <host name="host1" outbound-socket-binding="remote-host1" scheme="ajp" path="/" instance-id="myroute1"/> <host name="host2" outbound-socket-binding="remote-host2" scheme="ajp" path="/" instance-id="myroute2"/> <host name="remote-host3" outbound-socket-binding="remote-host3" scheme="ajp" path="/" instance-id="myroute3"/> </reverse-proxy> </handlers> ... </subsystem>
output-socket-binding
是指向稍后在 domain.xml 文件中配置的socket-binding
的逻辑名称。instance-id
属性还必须对新主机是唯一的,因为此值由 Cookie 使用,以便在负载平衡时启用粘性会话。转到
load-balancer-sockets
socket-binding-group
,再为remote-host3
添加outbound-socket-binding
:这个新绑定需要指向新主机的主机和端口。
domain.xml outbound-socket-binding
<socket-binding-group name="load-balancer-sockets" default-interface="public"> ... <outbound-socket-binding name="remote-host1"> <remote-destination host="localhost" port="8159"/> </outbound-socket-binding> <outbound-socket-binding name="remote-host2"> <remote-destination host="localhost" port="8259"/> </outbound-socket-binding> <outbound-socket-binding name="remote-host3"> <remote-destination host="192.168.0.5" port="8259"/> </outbound-socket-binding> </socket-binding-group>
9.3.4.1. Master 绑定地址
接下来,您需要做的是更改 master 主机的公共
和管理
绑定地址。按照 绑定地址 章节中所述编辑 domain.xml 文件,或者在命令行中指定这些绑定地址,如下所示:
$ domain.sh --host-config=host-master.xml -Djboss.bind.address=192.168.0.2 -Djboss.bind.address.management=192.168.0.2
9.3.4.2. 主机从属绑定地址
接下来,您必须更改 公共
、管理和
域控制器绑定地址(jboss.domain.master-address
)。编辑 host-slave.xml 文件,或者在命令行中指定它们,如下所示:
$ domain.sh --host-config=host-slave.xml -Djboss.bind.address=192.168.0.5 -Djboss.bind.address.management=192.168.0.5 -Djboss.domain.master.address=192.168.0.2
与主机的从设备 IP 地址相关的
的值。jboss.bind.address
.address.managementjboss.domain.master.address
的值需要是域控制器的 IP 地址,即 master 主机的管理地址。
其他资源
- 有关如何使用其他基于软件的 负载均衡器的信息,请参阅 JBoss EAP 配置指南中的 负载平衡 部分。