简介
HAProxy,全称高可用代理,是一款流行的开源软件 TCP/HTTP 负载均衡器和代理解决方案,可在 Linux、Solaris 和 FreeBSD 上运行。它最常见的用途是通过将工作负载分布到多台服务器(例如 Web、应用、数据库)上来提高服务器环境的性能和可靠性。它被广泛应用于许多知名环境,包括 GitHub、Imgur、Instagram 和 Twitter。
在本教程中,我们将介绍如何使用 HAProxy 进行 SSL 终止,进行流量加密以及负载均衡您的 Web 服务器。我们还将向您展示如何使用 HAProxy 将 HTTP 流量重定向到 HTTPS。
HAProxy 1.5.x 中实现了原生的 SSL 支持,该版本于 2014 年 6 月发布为稳定版本。
先决条件
要完成本教程,您必须具备或获取以下内容:
- 至少一台 Web 服务器,具有私有网络,监听 HTTP(端口 80)
- 在另一个 VPS 上具有 root 访问权限,我们将在其中安装 HAProxy。设置 root 访问权限的说明可以在此处找到(步骤 3 和 4):使用 Ubuntu 14.04 进行初始服务器设置。
- 具有与您的域名或 IP 地址匹配的“通用名称”的 SSL 证书和私钥对
如果您还没有 SSL 证书和私钥对,请在继续之前获取。以下是一些包含创建 SSL 证书步骤的教程:
- 创建 StartSSL 证书(private.key 和 ssl.crt)
- 在 Ubuntu 14.04 上创建自签名 SSL 证书(第 2 步–apache.key 和 apache.crt)
创建组合的 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/
这将创建名为 example.com.pem
的组合 PEM 文件,并将其复制到 /etc/ssl/private
。请务必确保保护您的私钥文件的任何副本,包括 PEM 文件(其中包含私钥)。
在某些情况下,您可能需要将您的 CA 根证书和 CA 中间证书复制到您的 PEM 文件中。
我们的起始环境
以下是我们要开始的环境:
!Web 服务器上的 HTTP
如果您的环境与示例不同,例如如果您已经在 Web 服务器上使用 SSL,或者您有一个单独的数据库服务器,您应该能够调整本教程以适应您的环境。
如果您对基本的负载均衡概念或术语不熟悉,例如第 7 层负载均衡、后端或 ACL,这里有一篇解释基础知识的文章:HAProxy 和负载均衡概念简介。
我们的目标
在本教程结束时,我们希望拥有以下环境:
!HAProxy SSL 终止
也就是说,您的用户将通过 HTTPS 连接到您的 HAProxy 服务器访问您的网站,该服务器将解密 SSL 会话并将未加密的请求转发到您的 Web 服务器(即 www-backend 中的服务器)通过它们的私有网络接口上的端口 80。然后,您的 Web 服务器将向 HAProxy 服务器发送其响应,后者将加密响应并将其发送回发起原始请求的用户。
您可以根据需要设置 www-backend,使用尽可能多的 Web 服务器,只要它们提供相同的内容。换句话说,您可以使用单个服务器设置,然后通过添加尽可能多的服务器来扩展它。请记住,随着流量的增加,如果 HAProxy 服务器没有足够的系统资源来处理用户流量,它可能会成为性能瓶颈。
注意: 本教程不涵盖如何确保您的 Web/应用服务器提供相同的内容,因为这通常取决于应用程序或 Web 服务器。
安装 HAProxy 1.6.x
创建一个具有私有网络的新 VPS。在本教程中,我们将其称为 haproxy-www,但您可以自行命名。
在我们的 haproxy-www VPS 上,添加专用 PPA 到 apt-get:
sudo add-apt-repository ppa:vbernat/haproxy-1.6
然后更新您的 apt 缓存:
sudo apt-get update
然后使用以下命令安装 HAProxy 1.6:
sudo apt-get install haproxy
现在 HAProxy 1.6 已安装,让我们来配置它!
HAProxy 配置
HAProxy 的配置文件位于 /etc/haproxy/haproxy.cfg
,分为两个主要部分:
- 全局(Global):设置全局参数
- 代理(Proxies):包括 defaults、listen、frontend 和 backend 部分
如果您对 HAProxy 或基本的负载均衡概念和术语不熟悉,请参考以下链接:HAProxy 和负载均衡概念简介
HAProxy 配置:全局(Global)
所有 HAProxy 配置都应在您的 HAProxy VPS 上进行,即 haproxy-www。
在编辑器中打开 haproxy.cfg:
sudo vi /etc/haproxy/haproxy.cfg
您会看到已经定义了两个部分:global 和 defaults。
首先,您需要设置 maxconn 为一个合理的数字。此设置会影响 HAProxy 允许的并发连接数,这可能会影响 QoS 并防止您的 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 选项通过关闭连接但保持 keep-alive 来减少 HAProxy 与用户之间的延迟。
HAProxy 配置:统计信息
使用 HAProxy 统计信息可以帮助确定 HAProxy 如何处理传入流量。如果您想要启用 HAProxy 统计页面,在 defaults 部分添加以下行(用安全值替换用户和密码):
stats enable stats uri /stats stats realm Haproxy\ Statistics stats auth user:password
这将允许您通过在您的域名后加上 /stats
(例如 https://example.com/stats)来查看 HAProxy 统计页面。
不要关闭配置文件!接下来我们将添加代理配置。
HAProxy 配置:代理
前端配置
首先,我们要添加一个前端来处理传入的 HTTP 连接。在文件末尾,让我们添加一个名为 www-http 的前端。确保用您的 haproxy-www VPS 的公共 IP替换 haproxy_www_public_IP
:
frontend www-http bind haproxy_www_public_IP:80 reqadd X-Forwarded-Proto:\ http default_backend www-backend
以下是上述前端配置片段中每行的解释:
- frontend www-http:指定名为 “www-http” 的前端
- bind haproxy_www_public_IP:80:用 haproxy-www 的公共 IP 地址替换
haproxy_www_public_IP
。这告诉 HAProxy 此前端将处理此 IP 地址和端口 80(HTTP)上的传入网络流量 - reqadd X-Forwarded-Proto:\ http:在 HTTP 请求末尾添加 http 头
- default_backend www-backend:指定此前端接收到的任何流量将被转发到 www-backend,我们将在下一步中定义
接下来,我们将添加一个前端来处理传入的 HTTPS 连接。在文件末尾,让我们添加一个名为 www-https 的前端。确保用您的 haproxy-www VPS 的公共 IP替换 haproxy_www_public_IP
:
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” 的前端
- bind haproxy_www_public_IP:443 ssl crt …:用 haproxy-www 的公共 IP 地址替换
haproxy_www_public_IP
,用 pem 格式的 SSL 证书和密钥对中的example.com.pem
替换。这告诉 HAProxy 此前端将处理此 IP 地址和端口 443(HTTPS)上的传入网络流量 - reqadd X-Forwarded-Proto:\ https:在 HTTPS 请求末尾添加 https 头
- default_backend www-backend:指定此前端接收到的任何流量将被转发到 www-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 的后端
- redirect scheme https if !{ ssl_fc }:此行将 HTTP 请求重定向到 HTTPS,使您的站点仅支持 HTTPS。如果要允许 HTTP 和 HTTPS,删除此行
- server www-1 …:指定名为 www-1 的后端服务器,私有 IP(您必须替换)和它正在监听的端口 80。check 选项使负载均衡器定期对此服务器执行健康检查
- server www-2 …:类似于前一行。添加类似的额外行,使用适当的名称和 IP 地址来向负载均衡器添加更多服务器
现在保存并退出 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 服务器!您的负载平衡服务器现在可以通过负载均衡器 haproxy-www 的公共 IP 地址或域名访问。有一些事情您需要检查,以确保一切设置正确。
检查事项
- 如果尚未这样做,请更新您的域名服务器,将您的域指向 haproxy-www 服务器的公共 IP 地址
- 如果您希望服务器仅使用 HTTPS,您需要确保您的 Web 服务器(例如 www-1、www-2 等)仅在它们的私有 IP 地址上监听端口 80。否则,用户将能够通过它们的公共 IP 地址在 HTTP(未加密)上访问您的 Web 服务器
- 通过 HTTPS 访问 haproxy-www 并确保它正常工作
- 通过 HTTP 访问 haproxy-www 并确保它重定向到 HTTPS(除非您配置为允许 HTTP 和 HTTPS)
注意: 如果您使用需要知道自己 URL 的应用程序,比如 WordPress,您需要将 URL 设置从 “http” 更改为 “https”。以 WordPress 为例,您需要转到 WordPress 的常规设置,然后将 WordPress 地址(URL)和站点地址(URL)从 “http” 更改为 “https”。
结论
现在您拥有一个处理 SSL 连接并可用于水平扩展服务器环境的负载均衡器解决方案。请随意将本指南中学到的内容与其他 HAProxy 指南结合使用,以进一步改进您的环境!