如何在 Ubuntu 14.04 上使用 HAProxy 实现 SSL 终止
介绍
HAProxy 代表高可用性代理,是一种流行的开源软件 TCP/HTTP 负载平衡器和代理解决方案,可以在 Linux、Solaris 和 FreeBSD 上运行。它最常见的用途是通过在多个服务器(例如 Web、应用程序、数据库)之间分配工作负载来提高服务器环境的性能和可靠性。它用于许多备受瞩目的环境,包括:GitHub、Imgur、Instagram 和 Twitter。
在本教程中,我们将介绍如何使用 HAProxy 进行 SSL 终止、流量加密和负载均衡您的 Web 服务器。我们还将向您展示如何使用 HAProxy 将 HTTP 流量重定向到 HTTPS。
本机 SSL 支持在 HAProxy 1.5.x 中实现,该版本于 2014 年 6 月作为稳定版本发布。
先决条件
要完成本教程,您必须拥有或获得以下内容:
- 至少一台 Web 服务器,具有私有网络,侦听 HTTP(端口 80)
- 对我们将在其上安装 HAProxy 的附加 VPS 的根访问权限。可以在此处找到设置根访问权限的说明(第 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 服务器上使用 SSL 或者您有一个单独的数据库服务器,您应该能够调整本教程以适应您的环境。
如果您不熟悉基本的负载平衡概念或术语,例如第 7 层负载平衡或后端或 ACL,这里有一篇解释基础知识的文章:HAProxy 和负载平衡概念简介。
我们的目标
在本教程结束时,我们希望拥有一个如下所示的环境:

也就是说,您的用户将通过 HTTPS 连接到您的 HAProxy 服务器来访问您的网站,这将解密 SSL 会话并将未加密的请求通过端口 80 上的专用网络接口转发到您的 Web 服务器(即 www-backend 中的服务器) . 然后,您的 Web 服务器会将其响应发送到您的 HAProxy 服务器,HAProxy 服务器将对响应进行加密并将其发送回发出原始请求的用户。
您可以根据需要使用任意数量的 Web 服务器设置您的 www-backend,只要它们提供相同的内容即可。换句话说,您可以使用单个服务器进行设置,然后通过添加任意数量的服务器来扩展它。请记住,随着您的流量增加,如果您的 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
然后使用以下命令使用 apt-get 安装 HAProxy 1.6:
sudo apt-get install haproxy
现在 HAProxy 1.6 已安装,让我们配置它!
HAProxy 配置
HAProxy的配置文件位于/etc/haproxy/haproxy.cfg
,分为两大块:
- 全局:设置进程范围的参数
- 代理:由默认、监听、前端和后端部分组成
同样,如果您不熟悉 HAProxy 或基本的负载均衡概念和术语,请参阅此链接:HAProxy 和负载均衡概念简介。
HAProxy 配置:全局
所有 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 选项通过关闭连接减少 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_public_IP
替换为您的 haproxy-www 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”的前端
- 绑定 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
接下来,我们将添加一个前端来处理传入的 HTTPS 连接。在文件末尾,让我们添加一个名为 www-https 的前端。请务必将 haproxy_www_public_IP
替换为您的 haproxy-www VPS 的公共 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_public_IP
替换为 haproxy-www 的公共 IP 地址,将example.com.pem
替换为您的 SSL 证书和密钥对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 服务器!您的用户现在可以通过负载均衡器的公共 IP 地址或域名 haproxy-www 访问您的负载均衡服务器!您需要检查一些事项,以确保一切设置正确。
检查事项
- 如果您还没有更新您的名称服务器,将您的域指向您的 haproxy-www 服务器的公共 IP 地址
- 如果您希望您的服务器仅使用 HTTPS,您需要确保您的网络服务器(例如 www-1、www-2 等)仅在端口 80 上侦听其私有 IP 地址。否则,用户将能够通过其公共 IP 地址上的 HTTP(未加密)访问您的网络服务器。
- 通过 HTTPS 访问 haproxy-www 并确保其正常工作
- 通过 HTTP 访问 haproxy-www 并确保它重定向到 HTTPS(除非您将其配置为同时允许 HTTP 和 HTTPS)
注意:如果您使用的应用程序需要知道自己的 URL,例如 WordPress,您需要将 URL 设置从“http”更改为 https。以 WordPress 为例,您可以转到 WordPress 常规设置,然后将 WordPress 地址 (URL) 和站点地址 (URL) 从“http”更改为“https”。
结论
现在您有了一个负载均衡器解决方案来处理您的 SSL 连接,并可用于水平扩展您的服务器环境。随意将您在本指南中学到的知识与其他 HAProxy 指南结合起来,以进一步改善您的环境!