http://www.linuxidc.com/Linux/2016-08/134233.htm
一、環境介紹
接到通知,要求網站由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