全称为高可用性Proxy的HAProxy无疑是当前最具人气的开源软件TCP/HTTP负载均衡方案之一,且能够运行在Linux、Solaris以及FreeBSD等多种系统平台之上。其最为常见的使用方式就是将工作负载分布至多台服务器上以提升服务器环境性能与可靠性。目前GitHub、Imgur、Instagram以及Twitter等高知名度环境皆使用HAProxy。
在今天的教程中,我们将了解如何利用HAProxy实现SSL终端,包括流量加密以及Web服务器负载均衡。另外,我们还将探讨如何利用HAProxy将HTTP流量转发至HTTPS。
HAProxy 1.6.x提供原生SSL支持能力,即发布于2014年6月的稳定版本。
先决条件
要完成本教程,大家需要满足以下条件:
至少拥有一套配备专有网络的Web服务器,且监听HTTP(即端口80)。
以root方式访问另一套VPS,我们将在这里安装HAProxy。
一套SSL证书与私钥对,其“常规名称”应与我们的域名或者IP地址相匹配。
创建文件将PEM SSL证书/密钥相结合
要利用HAProxy实现SSL终端,我们必须确保SSL证书与密钥对的格式正确,即PEM。在多数情况下,大家可以轻松将SSL证书(由认证中心提供的.crt或者.cer文件)与及对应私钥(让我们自己生成的.key文件)相结合。假定大家的证书文件为example.com.crt,而私钥文件为example.com.key,则:
cat example.com.crt example.com.key > example.com.pem
sudo cp example.com.pem /etc/ssl/private/
此命令会生成结合后的PEM文件,名为example.com.pem,并将其复制到/etc/ssl/private当中。
在某些情况下,大家可能需要将CA root证书与CA中间证书也复制到PEM文件当中。
起始环境
下面来看本示例中的起始环境:
如果大家的环境与示例有所不同,本教程中的大部分内容仍然同样适用。
教程目标
到教程结束时,我们希望构建起以下环境:
用户将能够通过HTTPS接入HAProxy服务器以实现网站访问,其会对SSL会话进行加密并将指向Web服务器的请求通过专有网络接口转发至端口80.我们的Web服务器随后会将其响应结果发送至HAProxy服务器,并由后者加密响应结果再发送回用户。
大家也可以设置www-backend,换言之,我们可以在单一服务器上进行设置,并在后续规模扩展过程中添加更多服务器。请注意,随着流量的增加,我们的HAProxy服务器可能会出现性能瓶颈。
注意:本教程不涉及Web/应用服务器间的内容一致性议题,因为具体方式在不同应用或Web服务器上可能存在较大差别。
安装HAProxy 1.6.x
创建一套包含有专有网络的新VPS。在本教程中,我们将其命名为haproxy-www,但大家也可以任选其它名称。
在haproxy-www VPS中向apt-get中添加专有PPA:
sudo add-apt-repository ppa:vbernat/haproxy-1.6
而后更新apt缓存:
sudo apt-get update
接下来利用apt-get安装HAProxy 1.6:
sudo apt-get install haproxy
安装完成!
HAProxy配置
HAProxy的配置文件位于/etc/haproxy/haproxy.cfg,且主要分为两部分:
Global: 设置进程范围内参数
Proxies: 包括defaults、listen、frontend与backend四个部分
HAProxy配置: Global
所有HAProxy配置工作都应在HAProxy VPS上进行。
打开haproxy.cfg文件:
sudo vi /etc/haproxy/haproxy.cfg
在这里我们可以看到已经定义完成的两部分,即global与defaults。
这里我们首先将maxconn设定为合理的数字。这一设置会影响到HAProxy所允许的并发连接数量,进而决定服务质量并防止Web服务器因请求数量过多而崩溃。在global部分添加以下行(具体数值视您的运行环境而定):
maxconn 2048
添加此行以配置所生成临时DHE密钥的最大长度:
tune.ssl.default-dh-param 2048
下面在defaults部分的mode http之后添加以下行:
option forwardfor
option http-server-close
其中forwardfor选项设置HAProxy在每条请求中添加X-Forwarded-For标题,而http-server-close选项则会关闭HAProxy与用户间的连接但保持其活动以降低延迟。
HAProxy配置: Stats
使用HAProxy stats能够帮助大家检查HAProxy如何处理输入流量 。如果大家倾向于启用HAProxy stats页面,则可在defaults部分添加以下行(注意将用户与密码部分替换为实际值):
stats enable
stats uri /stats
stats realm Haproxy\ Statistics
stats auth user:password
这样我们就能够通过域名上的/stats(例如https://example.com/stats)查看HAProxy状态页面了。
先别关闭配置文件,我们还要添加其它一些代理配置。
HAProxy配置: Proxies
Frontend配置
首先添加一条frontend来处理接入的HTTP连接。在文件末尾处,我们添加一条名为www-http的frountend。确保将其中的haproxy_www_public_IP替换为您haproxy-ww VPS的实际公共IP:
frontend www-http
bind haproxy_www_public_IP:80
reqadd X-Forwarded-Proto:\ http
default_backend www-backend
下面解释其中各行的含义:
frontend www-http: 指定一个名为”www-http”的frontend
bind haproxy_www_public_IP:80: 将haproxy_www_public_IP替换为haproxy-www的公共IP地址。这部分负责告知HAProxy此前端将处理指向该IP地址及端口80(HTTP)上的输入流量。
reqadd X-Forwarded-Proto:\ http:为每条HTTP请求添加http标题头
default_backend www-backend: 指定前端接收到的任意流量将被转发至www-backend,我们将在后续步骤中对后端进行定义。
接下来,我们添加一条frontend以处理接入的HTTPS连接。在文件末尾处添加名为www-https的frontend,注意替换对应部分:
frontend www-https
bind haproxy_www_public_IP:443 ssl crt /etc/ssl/private/example.com.pem
reqadd X-Forwarded-Proto:\ https
default_backend www-backend
frontend www-https: 指定一个名为”www-https”的frontend
bind haproxy_www_public_IP:443 ssl crt …:将haproxy_www_public_IP替换为haproxy-www的公共IP地址,example.com.pem以pem格式结合SSL证书与密钥对。其告知HAProxy此前端将处理指向其IP地址及端口443(HTTPS)上的输入流量。
reqadd X-Forwarded-Proto:\ https: 为每条HTTPS请求添加https标题头
default_backend www-backend: 指定前端接收到的任意流量将被转发至www-backend,我们将在后续步骤中对后端进行定义。
Backend配置
在完成了前端的配置之后,接下来添加以下行进行后端配置。注意将其中的高亮部分替换为Web服务器的专有IP地址:
backend www-backend
redirect scheme https if !{ ssl_fc }
server www-1 www_1_private_IP:80 check
server www-2 www_2_private_IP:80 check
下面解释各行的具体含义:
backend www-backend: 指定一个名为www-backend的backend
redirect scheme https if !{ ssl_fc }: 此行会将HTTP请求转发至HTTPS,意味着我们的站点将只接收HTTPS请求。如果大家希望同时使用HTTP与HTTPS,请移除此行。
server www-1 …: 指定名为www-a的后端服务器,其专有IP以及所监听的端口80。其中check选项代表负载均衡机制会周期性对此服务器的运行状态进行检查。
server www-2 …: 与上一行类似,大家可以重复此行将更多服务器添加至负载均衡机制中来。
保存并退出haproxy.cfg。现在HAProxy已经做好启动准备,但我们首先需要启用日志记录机制。
启用HAProxy日志记录
启用HAProxy中的日志记录非常简单,首先打开rsyslog.conf文件:
sudo vi /etc/rsyslog.conf
找到以下两行,取消其注释以启用UDP syslog接收功能:
$ModLoad imudp
$UDPServerRun 514
$UDPServerAddress 127.0.0.1
现在重启rsyslog以启用新配置:
sudo service rsyslog restart
HAProxy日志记录功能启用完成,日志文件将在HAProxy启动时于/var/log/haproxy.log位置创建。
启动HAProxy
在haproxy-www上启动HAProxy以应用各配置变更:
sudo service haproxy restart
HAProxy现在开始执行SSL终端并对Web服务器进行负载均衡。负载均衡服务器可通过公共IP地址或者负载均衡域名haproxy-www进行访问。不过我们还需要检查以下几项来确保一切顺利运行。
待检查项
确保更新命名服务器以将域名指向haproxy-www服务器的公共IP地址。
如果希望服务器只使用HTTPS,则需要确保各Web服务器(www-1、www-2等等)只监听端口80上的专有IP地址。否则,用户将能够通过HTTP(未加密)对公共IP地址进行访问。
通过HTTPS访问haproxy-www以确保其正常运行。
通过HTTP访问haproxy-www以确保其被重新定向至HTTPS(除非大家在配置中允许同时使用HTTP与HTTPS)。
注意:如果大家使用的应用需要了解其URL,例如WordPress,则需要将URL由http变更为https。以WordPress为例,大家应当前往WordPress General Settings,而后将WordPress Address(URL)与Site Address(URL)由“http”变更为“https”。
总结
现在大家的负载均衡解决方案已经能够处理SSL连接,并能够在服务器环境横向扩展时继续发挥作用。大家也可以随意探索其它可行途径,思考如何更好地实现环境改进。