共计 4665 个字符,预计需要花费 12 分钟才能阅读完成。
概述
如果你的应用使用 SSL 证书,则需要决定如何在负载均衡器上使用它们。
单 服务器的简单配置通常是考虑客户端 SSL 连接如何被接收请求的服务器解码。由于负载均衡器处在客户端和更多服务器之间,SSL 连接解码就成了需要关注的焦点。
有两种主要的策略。
SSL 终端 是在负载均衡器终止 / 解码 SSL 连接并发送非加密连接到后台服务器的做法
这意味着负载均衡器负责解码 SSL 连接 – 涉及非 SSL 请求的缓慢的 CPU 密集型处理。
这与 SSL 穿透 相反,它是直接向代理服务器发送 SSL 连接的。
使用 SSL 穿透,SSL 连接在每个代理服务器终止,将 CPU 负载都分散到那些服务器。然而,这样做会让你失去增加或修改 HTTP 报头的能力,因为连接只是简单地从负载均衡器路由到代理服务器。
这意味着应用服务器会失去获取 X-Forwarded-* 报头的能力,这个报头包含了客户端 IP 地址、端口和使用的协议。
选择哪个策略 取决于你及应用的需求。SSL 终端为我所见过最典型的策略,但 SSL 穿透可能会更安全。
有两种策略的组合做法,就是 SSL 连接在负载均衡器处终止,按需求调整,然后作为 新的SSL 连接代理到后台服务器。这可能会提供最大的安全性和发送客户端信息的能力。这样做的代价是更多的 CPU 能耗和稍复杂一点的配置。
我的一篇关于负载均衡器的效果与性能及哥伸缩性的老文章也有讨论过这些问题。
使用 HAProxy 作为 SSL 终端
首先,我们将介绍最典型的解决方案 – SSL 终端。正如前面提到的,我们需要让负载均衡器处理 SSL 连接。这就意味着要将 SSL 证书放在负载均衡服务器上。
在之前的 SFH 中,我们已经介绍过如何创建自签名证书。我们将重用那些信息来创建一份给 HAProxy 使用的 SSL 证书。
记住,在生产环境里使用 (而不是自签名) 的 SSL 证书,是不会需要你自己来生成或签名 – 你只需要创建证书签名请求 (csr) 并把它交给那个你向它购买证书的机构即可。
首先,我们创建一份自签名的证书给 *.xip.io 作为示范,并在本地使用同一份证书,因为本地测试时我们服务器的 IP 地址可能会有所不同。例如,我们本地服务器 IP 是 192.168.33.10,但之后我们虚拟机的 IP 会变成 192.168.33.11, 这样我就不用重要创建自签名证书了。
我使用 xip.io 服务是因为它允许我们使用主机名而非直接通过 IP 访问服务器,这就不需要悠我电脑的 Host 文件了。
虽然这个操作过程需要一份合格的 SSL 证书,但我会在这里简单地演示生成自签名证书的步骤:
$
sudo
mkdir
/etc/ssl/xip
.io
$
sudo
openssl genrsa -out
/etc/ssl/xip
.io
/xip
.io.key 1024
$
sudo
openssl req -new -key
/etc/ssl/xip
.io
/xip
.io.key -out
/etc/ssl/xip
.io
/xip
.io.csr
> Country Name (2 letter code) [AU]:US
> State or Province Name (full name) [Some-State]:Connecticut
> Locality Name (eg, city) []:New Haven
> Organization Name (eg, company) [Internet Widgits Pty Ltd]:SFH
> Organizational Unit Name (eg, section) []:
> Common Name (e.g. server FQDN or YOUR name) []:*.xip.io
> Email Address []:
> Please enter the following
'extra'
attributes to be sent with your certificate request
> A challenge password []:
> An optional company name []:
$
sudo
openssl x509 -req -days 365 -
in
/etc/ssl/xip
.io
/xip
.io.csr -signkey
/etc/ssl/xip
.io
/xip
.io.key -out
/etc/ssl/xip
.io
/xip
.io.crt
这就生成了 axip.io.csr,xip.io.key 和 xip.io.crt 文件了。
接着,在创建了证书之后,我们需要创建 pem 文件。pem 文件本质上只是将证书、密钥及证书认证中心证书(可有可无)拼接成一个文件。在我们的例子中,我们只是简单地将证书及密钥文件并以这个顺序拼接在一样来创建 xip.io.pem 文件。这是 HAProxy 读取 SSL 证书首选的方式。
$ sudo cat /etc/ssl/xip.io/xip.io.crt /etc/ssl/xip.io/xip.io.key | sudo tee /etc/ssl/xip.io/xip.io.pem
当购买真正的证书 时,你不一定会获取拼接后的文件。你可以要自己拼接它们。然而,很多机构也会提供一份拼接好的文件给你。如果你没有获取到拼接后的文件,则它可能不是一个 pem 文件,而是 bundle、cert、cert、key 文件或一些相同概念但名称类似的文件。这个 Stack Overflow 答案对问题解释得很好。
无论如何,只要我们得到了 HAProxy 使用的 pem 文件,我们只需经过简单配置就是可以处理 SSL 连接了。
我们将配置我们的应用以同时接受 http 和 https 连接。在最新版的 HAProxy 中,我们配置这样的前端:
frontend localnodes
bind *:80
mode http
default_backend nodes
要在 HAProxy 里终止 SSL 连接,我们现在就可以添加校准 SSL 端 口 443 的绑定,并让 HAProxy 知道 SSL 证书的位置:
frontend localhost
bind *:80
bind *:443 ssl crt /etc/ssl/xip.io/xip.io.pem
mode http
default_backend nodes
在上面的例子中,我们使用了后台 ”nodes”。幸运的是,后台不需要特别配置。在之前的 HAProxy 版本中,我们要这样配置后台:
backend nodes
mode http
balance roundrobin
option forwardfor
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
server web01 172.17.0.3:9000 check
server web02 172.17.0.3:9001 check
server web03 172.17.0.3:9002 check
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if {ssl_fc}
因为 SSL 连接在负载均衡器上终止了,我们依然来发送正常的 HTTP 请求到后台服务器。我们不需要更改配置就可以得到同样的效果了!
只接受 SSL 连接
如果你想让网站只接受 SSL 连接,你可以添加向前端配置加上 redirect 导向:
frontend localhost
bind *:80
bind *:443 ssl crt /etc/ssl/xip.io/xip.io.pem
redirect scheme https if !{ssl_fc}
mode http
default_backend nodes
上面,我们添加了 redirect 导向,如果连接不是通过 SSL 连接的,它将 http 重定向到 https。更多信息参见 ssl_fcis available here。
使用 HAProxy 实现 SSL 穿透
使用SSL 穿透,我们将让后台服务器处理 SSL 连接,而非负载均衡器来处理。
负载均衡器的工作就只是简单地将请求转发到配置好的后台服务器。因为连接还保持加密状态,HAProxy 只能将它转发给其他服务器,其他事情就没法做了。
在这个配置中,我们需要在前端和后台配置中同时使用 TCP 模式而不是 HTTP 模式。HAProxy 只会把连接当作信息流来转发到其他服务器,而不会使用在 HTTP 请求上才能使用的功能。
首先 ,我们调整一下 前端 配置:
frontend localhost
bind *:80
bind *:443
option tcplog
mode tcp
default_backend nodes
这里依然同时绑定 80 和 443 端口,以保证正常的 HTTP 连接和 SSL 连接都能工作。
正如上述提到的,转发一个安全连接事台服务器而不作任何解码,我们需要使用 TCP 模式(mode tcp)。这也意味着我们需要设置 tcp 日志而不是默认的 http 日志(option tcplog)。阅读这个可以了解日志格式并搞清楚 tcplog 和 httplog 的区别。
接着 ,我们要调整 后台 end配置。注意,我们还要将这个更改成 TCP 模式,并删除一些 directives 以避免因为修改 / 增加 HTTP 报头功能所带来的冲突:
backend nodes
mode tcp
balance roundrobin
option ssl-hello-chk
server web01 172.17.0.3:443 check
server web02 172.17.0.4:443 check
正如你所看到的,这里设置成了 mode tcp – 前端和后台配置都需要设置成这个模式。
我们还删除了 option forwardfor 和 http-request 选项 – 这些不能用于 TCP 模式,而且我们也不能向已加密的请求添加报头。
为了检查正确与否,我们可以使用 ssl-hello-chk 来检查连接及它处理 SSL(特别是 SSLv3)连接的能力。
在这个例子中,我虚构了两个接受 SSL 证书的后台服务器。如果你有阅读过 edition SSL certificates,你会看到如何将它们集成到 Apache 或 Nginx 来创建一个网络服务器后台,以处理 SSL 通信。使用 SSL 穿越,不需要给 HAProxy 创建或使用 SSL 证书。后台服务器都能够处理 SSL 连接,如同只有一如服务器且没有使用负载均衡器那样。
资源
-
HAProxy 官方 博客关于 SSL 终端的文章
-
SO 问题: “ 什么是 PEM 文件?”
-
在 Nginx 中读取自定义报头 – 没有特别在这个版本中提到,但对于理解发送给 Nginx 的 X -Forwarded-* 报头有用
-
所以你使用了负载均衡器,一篇关于在你的应用中使用负载均衡器注意事项的文章。.
Haproxy+Keepalived 搭建 Weblogic 高可用负载均衡集群 http://www.linuxidc.com/Linux/2013-09/89732.htm
Keepalived+HAProxy 配置高可用负载均衡 http://www.linuxidc.com/Linux/2012-03/56748.htm
CentOS 6.3 下 Haproxy+Keepalived+Apache 配置笔记 http://www.linuxidc.com/Linux/2013-06/85598.htm
Haproxy + KeepAlived 实现 WEB 群集 on CentOS 6 http://www.linuxidc.com/Linux/2012-03/55672.htm
Haproxy+Keepalived 构建高可用负载均衡 http://www.linuxidc.com/Linux/2012-03/55880.htm
HAproxy 的详细介绍:请点这里
HAproxy 的下载地址:请点这里