代理服务器充当寻求从其他服务器获取资源的客户端请求的中介。 客户端连接到代理服务器,请求来自不同服务器的某些服务或可用资源,代理服务器会评估请求以简化和控制其复杂性。
注意
支持使用 SSL 卸载或使用为 Tower 处理 SSL 的代理。 代理/负载均衡器需要配置为传递远程主机信息。
将 SSL 卸载到负载均衡器或代理时,将 nginx_disable_https=true
设置为传递到设置剧本的额外变量。 有关将额外变量应用于设置剧本的信息,请参阅 剧本设置。
Tower 中的会话在创建时会关联一个 IP 地址。 Tower 策略要求任何会话使用都必须与最初关联的 IP 地址匹配。
为了提供代理服务器支持,Tower 通过 Tower 设置中的 REMOTE_HOST_HEADERS
列表变量(/etc/tower/conf.d/remote_host_headers.py
)处理代理请求(例如,Tower 前面的 ALB、NLB、HAProxy、Squid、Nginx 和 tinyproxy)。 默认情况下,REMOTE_HOST_HEADERS
设置为 ['REMOTE_ADDR', 'REMOTE_HOST']
。
要启用代理服务器支持,请像下面这样设置 REMOTE_HOST_HEADERS
:REMOTE_HOST_HEADERS = ['HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR', 'REMOTE_HOST']
注意
Ansible Tower 的新安装将不包含 remote_host_headers.py
文件。 但是,您仍然可以在“配置 Tower”用户界面的“系统”设置中设置这些值。
Tower 通过搜索 REMOTE_HOST_HEADERS
中的标头列表,直到找到第一个 IP 地址,来确定远程主机的 IP 地址。
注意
标头名称是使用以下逻辑构建的
除了 CONTENT_LENGTH
和 CONTENT_TYPE
外,请求中的任何 HTTP 标头都会通过将所有字符转换为大写、将所有连字符替换为下划线以及在名称前添加 HTTP_
前缀来转换为 META 键。 例如,名为 X-Barkley
的标头将映射到 META 键 HTTP_X_Barkley
。
有关 HTTP 请求和响应对象的更多信息,请参阅:https://docs.django.ac.cn/en/1.8/ref/request-response/#django.http.HttpRequest.META
注意
如果在负载均衡器处使用 SSL 终止并将流量转发到 Tower 节点上的不同端口(443 -> 80),请在 /etc/tower/conf.d/custom.py
文件中相应地设置以下值
USE_X_FORWARDED_PORT = True
USE_X_FORWARDED_HOST = True
当 Tower 配置为 REMOTE_HOST_HEADERS = ['HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR', 'REMOTE_HOST']
时,它假定 X-Forwarded-For
的值来自位于 Tower 前面的代理/负载均衡器。 在 Tower 仍然可以通过不使用代理/负载均衡器或代理不验证标头的情况下访问的情况下,X-Forwarded-For
可以相当容易地被伪造以伪造源 IP 地址。 在 REMOTE_HOST_HEADERS
设置中使用 HTTP_X_FORWARDED_FOR
会带来漏洞,实质上允许用户访问他们不应该拥有的某些资源。
为了避免这种情况,您可以配置允许的“已知代理”列表,即通过设置 API 进行的 PROXY_IP_ALLOWED_LIST
设置。 不在列表中的负载均衡器和主机将导致请求被拒绝。
PROXY_IP_ALLOWED_LIST
仅在列表中的代理适当地清理标头输入并正确设置等于客户端真实源 IP 的 X-Forwarded-For
值时才有效; 此设置的关键在于 Tower 可以依靠 PROXY_IP_ALLOWED_LIST
中的 IP/主机名来为 X-Forwarded-For
字段提供非伪造的值。
HTTP_X_FORWARDED_FOR
不应配置为 REMOTE_HOST_HEADERS
中的项目,除非满足以下所有条件
您正在使用带有 SSL 终止的代理环境
代理提供
X-Forwarded-For
标头的清理/验证以防止客户端伪造
/etc/tower/conf.d/remote_host_headers.py
定义PROXY_IP_ALLOWED_LIST
,其中仅包含受信任的代理/负载均衡器的源 IP。
注意
如果您不需要将所有流量都通过代理,那么您可以在 no_proxy
字段中指定要排除的 IP 方案。 该列表可以是 IP 范围或单个 IP,用逗号分隔。 此示例显示了以 JSON 格式指定的 IP 范围
"https_proxy": "example.proxy.com:8080",
"http_proxy": "example.proxy.com:8080",
"no_proxy": "10.0.0.0/8"
此外,具有 no_proxy
配置和 CIDR 表示法的 SCM 更新可能不适用于特定的 SCM。 对 http_proxy
和 no_proxy
的支持取决于应用程序(git|hg|svn)中的实现。 例如,git 不支持 no_proxy
的 CIDR 表示法,因为 git 受其 C 库限制:https://curl.haxx.se/libcurl/c/CURLOPT_NOPROXY.html。
如果您位于反向代理后面,您可能需要为 HTTP_X_FORWARDED_FOR
设置标头字段。 X-Forwarded-For
(XFF) HTTP 标头字段标识通过 HTTP 代理或负载均衡器连接到 Web 服务器的客户端的源 IP 地址。
REMOTE_HOST_HEADERS = ['HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR', 'REMOTE_HOST']
您应该考虑的一个关键配置是 websocket 设置,以便将 websocket 配置与您的 nginx/负载均衡器配置对齐。
Tower 节点通过 websocket 连接到所有其他 Tower 节点。 此互连用于将所有 websocket 发出的消息分发到所有其他 Tower 节点。 这是必需的,因为任何浏览器客户端 websocket 都可以订阅可能在任何 Tower 节点上运行的任何作业。 换句话说,websocket 客户端不会路由到特定的 Tower 节点。 任何 Tower 节点都可以处理任何 websocket 请求。 因此,每个 Tower 节点必须了解发往所有客户端的所有 websocket 消息。
Tower 将自动通过数据库中的实例记录来处理其他 Tower 节点的发现。 Tower 必须被告知端口、协议以及在建立 websocket 连接时是否验证证书。 这是使用以下三个设置配置的
BROADCAST_WEBSOCKET_PROTOCOL = 'http'
BROADCAST_WEBSOCKET_PORT = 80
BROADCAST_WEBSOCKET_VERIFY_CERT = False
例如,在负载均衡器级别为 Tower 前面进行 SSL 终止的拓扑结构将具有以下设置
BROADCAST_WEBSOCKET_PROTOCOL = 'http'
BROADCAST_WEBSOCKET_PORT = 80
通过 nginx 在每个单独的 Tower 节点执行 SSL 的拓扑结构将具有以下设置
BROADCAST_WEBSOCKET_PROTOCOL = 'https'
BROADCAST_WEBSOCKET_PORT = 443
BROADCAST_WEBSOCKET_VERIFY_CERT = True
注意
您的节点将 websocket 流量广播到私有、受信任的子网(而不是公开的互联网)上。 因此,如果您关闭 websocket 广播的 HTTPS,则 websocket 流量(主要由 Ansible 剧本 stdout 组成)将在 Tower 节点之间未加密地发送。