阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

把Web集群由HTTP转换为HTTPS(LVS+HAProxy+SSL)

128次阅读
没有评论

共计 8027 个字符,预计需要花费 21 分钟才能阅读完成。

一、环境介绍

    接到通知,要求网站由 http 改为使用 https,目前我的网站前端架构如下图所示:

把 Web 集群由 HTTP 转换为 HTTPS(LVS+HAProxy+SSL)

    假设我们有两台物理机,每台物理机上面有很多的 tomcat 容器,前端使用的是 haproxy 进行的 http 层负载均衡,再前端我们使用了 LVS 负载均衡,整个 LVS 使用的是 DR 模型。

    刚开始我打算把 tomcat 改成 https,设置成之后再设置 haproxy 的时候,发现 haproxy 不能再使用负载均衡了,因为 SSL 是在第四层的,所以这个方案就结束了,下面我就尝试在 haproxy 层设定 SSL,到后端还使用普通的连接。

 

二、设置步骤

1、概述

    如果你的应用使用 SSL 证书,则需要决定如何在负载均衡器上使用它们。

    单服务器的简单配置通常是考虑客户端 SSL 连接如何被接收请求的服务器解码。由于负载均衡器处在客户端和更多服务器之间,SSL 连接解码就成了需要关注的焦点。

2、有两种主要的策略

把 Web 集群由 HTTP 转换为 HTTPS(LVS+HAProxy+SSL)

  •     第一种是我们选择的模式,在 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

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-21发表,共计8027字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中