共计 8027 个字符,预计需要花费 21 分钟才能阅读完成。
一、环境介绍
接到通知,要求网站由 http 改为使用 https,目前我的网站前端架构如下图所示:
假设我们有两台物理机,每台物理机上面有很多的 tomcat 容器,前端使用的是 haproxy 进行的 http 层负载均衡,再前端我们使用了 LVS 负载均衡,整个 LVS 使用的是 DR 模型。
刚开始我打算把 tomcat 改成 https,设置成之后再设置 haproxy 的时候,发现 haproxy 不能再使用负载均衡了,因为 SSL 是在第四层的,所以这个方案就结束了,下面我就尝试在 haproxy 层设定 SSL,到后端还使用普通的连接。
二、设置步骤
1、概述
如果你的应用使用 SSL 证书,则需要决定如何在负载均衡器上使用它们。
单服务器的简单配置通常是考虑客户端 SSL 连接如何被接收请求的服务器解码。由于负载均衡器处在客户端和更多服务器之间,SSL 连接解码就成了需要关注的焦点。
2、有两种主要的策略
第一种是我们选择的模式,在 haproxy 这里设定 SSL,这样我们可以继续使用七层负载均衡。SSL 连接终止在负载均衡器 haproxy —–> 解码 SSL 连接并发送非加密连接到后端应用 tomcat,这意味着负载均衡器负责解码 SSL 连接,这与 SSL 穿透相反,它是直接向代理服务器发送 SSL 连接的。
第二种使用 SSL 穿透,SSL 连接在每个 tomcat 服务器终止,将 CPU 负载都分散到 tomcat 服务器。然而,这样做会让你失去增加或修改 HTTP 报头的能力,因为连接只是简单地从负载均衡器路由到 tomcat 服务器,这意味着应用服务器会失去获取 X-Forwarded-* 报头的能力,这个报头包含了客户端 IP 地址、端口和使用的协议。
有两种策略的组合做法,那就是第三种,SSL 连接在负载均衡器处终止,按需求调整,然后作为新的 SSL 连接代理到后台服务器。这可能会提供最大的安全性和发送客户端信息的能力。这样做的代价是更多的 CPU 能耗和稍复杂一点的配置。
选择哪个策略取决于你及应用的需求。SSL 终端为我所见过最典型的策略,但 SSL 穿透可能会更安全。
3、使用 HAProxy 作为 SSL 终端
首先,我们将介绍最典型的解决方案 – SSL 终端。正如前面提到的,我们需要让负载均衡器处理 SSL 连接。这就意味着要将 SSL 证书放在负载均衡服务器上。
记住,在生产环境里使用(而不是自签名)的 SSL 证书,是不会需要你自己来生成或签名 – 你只需要创建证书签名请求 (csr) 并把它交给那个你向它购买证书的机构即可。
首先,我们创建一份自签名的证书作为示范,并在本地使用同一份证书。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | openssl genrsa -out /etc/haproxy/wzlinux .key 2048 openssl req -new -key /etc/haproxy/wzlinux .key -out /etc/haproxy/wzlinux .csr > Country Name (2 letter code) [AU]:CN > State or Province Name (full name) [Some-State]:Shanghai > Locality Name (eg, city) []:Shanghai > Organization Name (eg, company) [Internet Widgits Pty Ltd]:wzlinux > Organizational Unit Name (eg, section) []: > Common Name (e.g. server FQDN or YOUR name) []:www.wzlinux.com > Email Address []: > Please enter the following 'extra' attributes to be sent with your certificate request > A challenge password []: > An optional company name []: cd /etc/haproxy openssl x509 -req -days 3655 - in wzlinux.csr -signkey wzlinux.key -out wzlinux.crt |
这就生成了 wzlinux.csr,wzlinux.key 和 wzlinux.crt 文件了。
接着,在创建了证书之后,我们需要创建 pem 文件。pem 文件本质上只是将证书、密钥及证书认证中心证书(可有可无)拼接成一个文件。在我们的例子中,我们只是简单地将证书及密钥文件并以这个顺序拼接在一样来创建 wzlinux.pem 文件。这是 HAProxy 读取 SSL 证书首选的方式。
1 | cat wzlinux.crt wzlinux.key | tee wzlinux.pem |
当购买真正的证书 时,你不一定会获取拼接后的文件。你可以要自己拼接它们。然而,很多机构也会提供一份拼接好的文件给你。如果你没有获取到拼接后的文件,则它可能不是一个 pem 文件,而是 bundle、cert、cert、key 文件或一些相同概念但名称类似的文件。
无论如何,只要我们得到了 HAProxy 使用的 pem 文件,我们只需经过简单配置就是可以处理 SSL 连接了。
下面我们将要配置 haproxy 来安装 SSL 证书,配置文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | #--------------------------------------------------------------------- # Example configuration for a possible web application. See the # full configuration options online. # # http://haproxy.1wt.eu/download/1.4/doc/configuration.txt # #--------------------------------------------------------------------- #--------------------------------------------------------------------- # Global settings #--------------------------------------------------------------------- global # to have these messages end up in /var/log/haproxy.log you will # need to: # # 1) configure syslog to accept network log events. This is done # by adding the '-r' option to the SYSLOGD_OPTIONS in # /etc/sysconfig/syslog # # 2) configure local2 events to go to the /var/log/haproxy.log # file. A line like the following can be added to # /etc/sysconfig/syslog # # local2.* /var/log/haproxy.log # log 127.0.0.1 local2 warning chroot /var/lib/haproxy pidfile /var/run/haproxy .pid maxconn 400000 user haproxy group haproxy daemon tune.ssl.default-dh-param 2048 # nbproc 3 # turn on stats unix socket stats socket /var/lib/haproxy/stats #--------------------------------------------------------------------- # common defaults that all the 'listen' and 'backend' sections will # use if not designated in their block #--------------------------------------------------------------------- defaults mode http log global option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0 /8 option redispatch option httpclose retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s stats enable stats hide-version stats uri /haproxy ?status stats realm Haproxy\ Statistics stats auth admin:asd870719 # stats admin if TRUE #--------------------------------------------------------------------- # main frontend which proxys to the backends #--------------------------------------------------------------------- #frontend main *:5000 # acl url_static path_beg -i /static /images /javascript /stylesheets # acl url_static path_end -i .jpg .gif .png .css .js # use_backend static if url_static # default_backend app frontend wzlinux_ssl bind *:80 bind *:443 ssl crt /etc/haproxy/wzlinux .pem mode http default_backend wzlinux #--------------------------------------------------------------------- # static backend for serving up images, stylesheets and such #--------------------------------------------------------------------- #backend static # balance roundrobin # server static 127.0.0.1:4331 check backend wzlinux mode http balance roundrobin option forwardfor # option httpchk HEAD / HTTP/1.1\r\nHost:localhost server wzlinux01 10.0.0.9:8080 check inter 15000 rise 2 fall 4 server wzlinux02 10.0.0.9:8081 check inter 15000 rise 2 fall 4 server wzlinux03 10.0.0.9:8082 check inter 15000 rise 2 fall 4 server wzlinux04 10.0.0.9:8083 check inter 15000 rise 2 fall 4 server wzlinux05 10.0.0.9:8084 check inter 15000 rise 2 fall 4 server wzlinux06 10.0.0.9:8085 check inter 15000 rise 2 fall 4 server wzlinux07 10.0.0.9:8086 check inter 15000 rise 2 fall 4 # 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 导向:
1 2 3 4 5 6 | frontend wzlinux_ssl bind *:80 bind *:443 ssl crt /etc/haproxy/wzlinux .pem redirect scheme https if !{ssl_fc} mode http default_backend wzlinux |
上面,我们添加了 redirect 导向,如果连接不是通过 SSL 连接的,它将 http 重定向到 https。
4、使用 HAProxy 实现 SSL 穿透
使用 SSL 穿透,我们将让后台服务器处理 SSL 连接,而非负载均衡器来处理。
负载均衡器的工作就只是简单地将请求转发到配置好的后台服务器。因为连接还保持加密状态,HAProxy 只能将它转发给其他服务器,其他事情就没法做了。
在这个配置中,我们需要在前端和后台配置中同时使用 TCP 模式而不是 HTTP 模式。HAProxy 只会把连接当作信息流来转发到其他服务器,而不会使用在 HTTP 请求上才能使用的功能。
首先,我们调整一下前端配置:
1 2 3 4 5 6 | frontend wzlinux_ssl bind *:80 bind *:443 option tcplog mode tcp default_backend wzlinux |
这里依然同时绑定 80 和 443 端口,以保证正常的 HTTP 连接和 SSL 连接都能工作。
正如上述提到的,转发一个安全连接而服务器而不作任何解码,我们需要使用 TCP 模式 (mode tcp)。这也意味着我们需要设置 tcp 日志而不是默认的 http 日志(option tcplog)。
接着,我们要调整后台 end 配置。注意,我们还要将这个更改成 TCP 模式,并删除一些 directives 以避免因为修改 / 增加 HTTP 报头功能所带来的冲突:
1 2 3 4 5 6 7 8 9 10 11 | backend wzlinux mode tcp balance roundrobin option ssl-hello-chk server wzlinux01 10.0.0.9:8080 check inter 15000 rise 2 fall 4 server wzlinux02 10.0.0.9:8081 check inter 15000 rise 2 fall 4 server wzlinux03 10.0.0.9:8082 check inter 15000 rise 2 fall 4 server wzlinux04 10.0.0.9:8083 check inter 15000 rise 2 fall 4 server wzlinux05 10.0.0.9:8084 check inter 15000 rise 2 fall 4 server wzlinux06 10.0.0.9:8085 check inter 15000 rise 2 fall 4 server wzlinux07 10.0.0.9:8086 check inter 15000 rise 2 fall 4 |
正如你所看到的,这里设置成了 mode tcp – 前端和后台配置都需要设置成这个模式。
我们还删除了 option forwardfor 和 http-request 选项 – 这些不能用于 TCP 模式,而且我们也不能向已加密的请求添加报头,还有一些前面的默认配置也删去关于 http 的配置,这里不再演示。
为了检查正确与否,我们可以使用 ssl-hello-chk 来检查连接及它处理 SSL(特别是 SSLv3)连接的能力。
在这个例子中,我虚构了两个接受 SSL 证书的后台服务器。如果你有阅读过 edition SSL certificates,你会看到如何将它们集成到 Apache 或 Nginx 来创建一个网络服务器后台,以处理 SSL 通信。使用 SSL 穿越,不需要给 HAProxy 创建或使用 SSL 证书。后台服务器都能够处理 SSL 连接,如同只有一台服务器且没有使用负载均衡器那样。
在关于如何设定 lvs 分发这里不再进行设定演示,大家可以查看我有关 LVS 的文章。
相关阅读:
通过 LVS 实现 WEB 站点的 MySQL 高可用 http://www.linuxidc.com/Linux/2013-06/86390.htm
LVS+Apache+PHP+MySQL 读写分离 http://www.linuxidc.com/Linux/2012-12/77027.htm
MySQL LVS 负载均衡 http://www.linuxidc.com/Linux/2012-09/69862.htm
企业 Web 高可用集群实战之 LVS+Keepalived+MySQL HA http://www.linuxidc.com/Linux/2012-09/70097.htm
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2016-08/134233.htm