如何在 Ubuntu 14.04 上用 Let's Encrypt 加密 HAProxy

介绍

Let's Encrypt是一个新的证书授权机构(CA),它提供了一个简单的方法来获取和安装免费的TLS/SSL证书,从而在Web服务器上启用加密的HTTPS。它通过提供软件客户端Certbot来简化这个过程,它试图自动化大多数所需的步骤。目前,获取和安装证书的整个过程仅在ApacheWeb服务器上完全自动化。然而,Certbot可以用来轻松获得免费的SSL证书,无论您选择的Web服务器软件如何,都可以手动安装。

在本教程中,我们将向您展示如何使用Certbot获得免费的SSL证书,并在Ubuntu 14.04上使用HAProxy。

HAProxy with Let's Encrypt TLS/SSL Certificate and Auto-renewal

前提条件

在遵循本教程之前,您将需要一些东西。

您应该有一个 Ubuntu 14.04 服务器,有一个具有sudo特权的非根用户,您可以通过遵循我们 Ubuntu 14.04 初始服务器设置中的步骤 1-3 来学习如何设置这样的用户帐户。

您必须拥有或控制您希望使用证书的注册域名;如果您还没有注册域名,您可以与许多域名注册商之一(例如 Namecheap、GoDaddy 等)注册域名。

如果您还没有,请确保创建一个 A 记录,将您的域名指向您的服务器的公共 IP 地址。 这是由于 Let's Encrypt 验证您拥有它正在发行证书的域名的方式所必需的。 例如,如果您想为 example.com 获得证书,那么该域必须解决到您的服务器,以便验证过程工作。 我们的设置将使用 example.comwww.example.com 作为域名,因此 ** 都需要 DNS 记录**。

一旦你已经完成了所有前提条件,让我们继续安装certbot,即Let’s Encrypt客户端软件。

步骤 1 – 安装 Let’s Encrypt 客户端

使用 Let's Encrypt 获取 SSL 证书的第一步是将certbot软件安装到您的服务器上。 Certbot 开发人员提供具有最新版本的软件存储库。

1sudo add-apt-repository ppa:certbot/certbot

您将被要求确认添加。 按ENTER来继续。 然后更新包缓存以获取新包列表:

1sudo apt-get update

最后,安装certbot包:

1sudo apt-get install certbot

现在我们已经安装了certbot,我们已经准备好获得我们的SSL证书。

步骤二:获得证书

Let's Encrypt 提供了通过各种插件获取 SSL 证书的各种方式. 与 Apache 插件不同,该插件被涵盖在 不同的教程,大多数插件只会帮助您获得证书,您必须手动配置您的 Web 服务器来使用。

我们将向您展示如何使用 Standalone插件获得SSL证书。

检查端口 80 已打开

Standalone 插件提供了一个非常简单的方法来获得 SSL 证书。它通过在您的服务器上暂时运行一个小型 Web 服务器(默认的端口为 80),让 Let’s Encrypt CA 能够在发行证书之前连接并验证您的服务器的身份。因此,这种方法要求端口为 80 未使用。

例如,如果您正在使用 HAProxy,您可以通过运行此命令来阻止它:

1sudo service haproxy stop

如果您不確定「80」端口是否正在使用,您可以執行以下命令:

1netstat -na | grep ':80.*LISTEN'

如果在运行此命令时没有输出,则可以使用独立插件。

运行Certbot

现在使用独立插件运行此命令:

1sudo certbot certonly --standalone --preferred-challenges http --http-01-port 80 -d example.com -d www.example.com

您将被要求输入您的电子邮件地址并同意让我们加密服务条款。之后,http挑战将运行。如果一切顺利,certbot将打印这样的输出信息:

 1[secondary_label Output:]
 2IMPORTANT NOTES:
 3 - Congratulations! Your certificate and chain have been saved at
 4   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert
 5   will expire on 2017-09-06. To obtain a new or tweaked version of
 6   this certificate in the future, simply run certbot again. To
 7   non-interactively renew *all* of your certificates, run "certbot
 8   renew"
 9 - Your account credentials have been saved in your Certbot
10   configuration directory at /etc/letsencrypt. You should make a
11   secure backup of this folder now. This configuration directory will
12   also contain certificates and private keys obtained by Certbot so
13   making regular backups of this folder is ideal.
14 - If you like Certbot, please consider supporting our work by:
15
16   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
17   Donating to EFF:                    https://eff.org/donate-le

您将需要记住证书的路径和到期日期,这在上面的示例输出中被突出。

<$>[注] 注: 如果您的域名正在通过 CloudFlare 等 DNS 服务进行路由,您需要暂时禁用它,直到您获得证书。

证书档案

获取 cert 后,您将拥有以下 PEM 加密文件:

  • cert.pem: 您的域名证书 chain.pem: 让我们加密链证书 fullchain.pem: cert.pemchain.pem 结合 privkey.pem: 您的证书的私钥

重要的是,您知道刚刚创建的证书文件的位置,所以您可以在您的 Web 服务器配置中使用它们. 这些文件本身被放置在 `/etc/letsencrypt/archive 中的子目录中。

您可以通过运行此命令来检查文件是否存在(在您的域名中代替):

1sudo ls /etc/letsencrypt/live/your_domain_name

输出应该是前面提到的四个证书文件。

连接 fullchain.pem 和 privkey.pem

在配置 HAProxy 以执行 SSL 终止,以便将其与最终用户之间的流量加密,您必须将fullchain.pemprivkey.pem合并到一个文件中。

首先,创建将组合文件放置的目录, /etc/haproxy/certs:

1sudo mkdir -p /etc/haproxy/certs

接下来,使用这个cat命令创建组合文件(用您的域名取代突出标示的example.com):

1DOMAIN='example.com' sudo -E bash -c 'cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/haproxy/certs/$DOMAIN.pem'

使用此命令安全访问包含私钥的组合文件:

1sudo chmod -R go-rwx /etc/haproxy/certs

现在我们已经准备好使用SSL cert和私钥与HAProxy。

步骤 3 – 安装 HAProxy

此步骤涵盖了安装 HAProxy. 如果它已经安装在您的服务器上,请跳过此步骤。

我们将安装HAProxy 1.6,这不是在默认的Ubuntu存储库中。然而,我们仍然可以使用包管理器来安装HAProxy 1.6,如果我们使用PPA,使用这个命令:

1sudo add-apt-repository ppa:vbernat/haproxy-1.6

更新负载平衡器上的本地包索引并通过键入安装 HAProxy:

1sudo apt-get update
2sudo apt-get install haproxy

HAProxy现在已安装,但需要配置。

步骤 4 – 配置 HAProxy

本节将向您展示如何配置基本的 HAProxy 与 SSL 设置. 它还涵盖如何配置 HAProxy 以使我们能够自动更新我们的 Let's Encrypt 证书。

在文本编辑器中打开haproxy.cfg:

1sudo nano /etc/haproxy/haproxy.cfg

保持这个文件打开,我们在接下来的几个部分中编辑它。

全球部分

让我们在全球部分中添加一些基本设置。

您要做的第一件事是将 maxconn 设置为合理数量,这会影响 HAProxy 允许的同时连接数量,这可能会影响 QoS,并防止您的 Web 服务器试图满足太多请求。

1[label haproxy.cfg — 1 of 7]
2   maxconn 2048

接下来,添加此行,以配置生成的临时 DHE 密钥的最大大小:

1[label haproxy.cfg — 2 of 7]
2   tune.ssl.default-dh-param 2048

缺陷部分

defaults 部分中添加以下行:

1[label haproxy.cfg — 3 of 7]
2   option forwardfor
3   option http-server-close

forwardfor 选项将 HAProxy 设置为每个请求添加X-Forwarded-For标题,而http-server-close选项会通过关闭连接而减少 HAProxy 和您的用户之间的延迟。

前线部分

现在我们已经准备好定义我们的前端部分。

首先我们要添加的是一个前端来处理接入的HTTP连接,并将其发送到默认的后端(我们将在稍后定义)。

1[label haproxy.cfg — 4 of 7]
2frontend www-http
3   bind haproxy_www_public_IP:80
4   reqadd X-Forwarded-Proto:\ http
5   default_backend www-backend

接下来,我们将添加一个前端来处理接入的 HTTPS 连接。 文件的末尾,添加一个前端,名为 www-https. 请确保用您的 HAProxy 服务器的公共 IP 代替 haproxy_www_public_IP。 此外,您还需要用您的域名代替 example.com’(这应该与您之前创建的证书文件相符):

1[label haproxy.cfg — 5 of 7]
2frontend www-https
3   bind haproxy_www_public_IP:443 ssl crt /etc/haproxy/certs/example.com.pem
4   reqadd X-Forwarded-Proto:\ https
5   acl letsencrypt-acl path_beg /.well-known/acme-challenge/
6   use_backend letsencrypt-backend if letsencrypt-acl
7   default_backend www-backend

此前端使用ACL(letsencrypt-acl)发送Let’s Encrypt验证请求(为/.已知/acme-challenge)到letsencrypt-backend后端,这将使我们能够在不停止HAProxy服务的情况下更新证书。

背后部分

完成配置前端后,请通过添加以下行添加www-backend后端. 请确保用您的 Web 服务器的相应私有 IP 地址替换突出的单词(调整服务器行数以匹配您拥有的后端服务器数量):

1[label haproxy.cfg — 6 of 7]
2backend www-backend
3   redirect scheme https if !{ ssl_fc }
4   server www-1 www_1_private_IP:80 check
5   server www-2 www_2_private_IP:80 check

此后端接收的任何流量都将通过其服务器条目进行平衡,通过HTTP(端口80)。

最后,添加letsencrypt-backend后端,通过添加这些行

1[label haproxy.cfg — 7 of 7]
2backend letsencrypt-backend
3   server letsencrypt 127.0.0.1:54321

此后端仅处理用于证书请求和更新的 Let's Encrypt ACME 挑战,将流量发送到 localhost 在端口 54321. 当我们更新我们的 Let's Encrypt SSL 证书时,我们将使用此端口而不是 80443

现在我们已经准备好开始HAProxy:

1sudo service haproxy restart

<$>[注] 注: 如果您在「haproxy.cfg」配置文件中遇到问题,请参阅 This GitHub Gist 以获取一个示例。

让我们加密 TLS/SSL 证书现在已经到位,我们已经准备好设置自动更新脚本,在此时,您应该通过访问您的域名在 Web 浏览器中测试 TLS/SSL 证书是否有效。

步骤5:设置自动更新

Let’s Encrypt 证书仅有效 90 天,因此重要的是自动更新过程。

确保您的证书不会过时的一种实用方法是创建一个 cron 工作,为您自动处理更新过程。Cronjob 将每天运行certbot并在 30 天内更新证书。

让我们现在创建这个脚本,然后测试它。

创建一个更新脚本

/usr/local/bin 中打开一个新的文件作为 root:

1sudo nano /usr/local/bin/renew.sh

這將是一個新的空白文本檔案. 插入以下簡短脚本,確保以自己的方式更新突出的網域名稱:

 1#!/bin/sh
 2
 3SITE=example.com
 4
 5# move to the correct let's encrypt directory
 6cd /etc/letsencrypt/live/$SITE
 7
 8# cat files to make combined .pem for haproxy
 9cat fullchain.pem privkey.pem > /etc/haproxy/certs/$SITE.pem
10
11# reload haproxy
12service haproxy reload

保存和关闭文件. 此脚本移动到正确的 Let's Encrypt 目录,运行cat命令将两个.pem 文件连接到一个,然后重新加载 haproxy。

接下来,使脚本可执行:

1sudo chmod u+x /usr/local/bin/renew.sh

然后运行剧本:

1sudo /usr/local/bin/renew.sh

它应该运行没有错误. 你会看到一些关于重新加载 haproxy的输出。接下来,我们将更新Certbot并配置它来运行这个更新脚本。

更新 certbot 配置

我们将使用的certbot renew命令来更新我们的证书,读取我们第一次运行certbot时创建的配置文件。我们需要打开该文件并更新certbot用于运行其独立的HTTP服务器的端口,以便它不会与 haproxy(已经在端口80和443上聆听)冲突。

1sudo nano /etc/letsencrypt/renewal/example.com.conf

我们需要更改http01_port行,所以它读起来像这样:

1[label example.com.conf]
2http01_port = 54321

现在测试更新过程,指定--dry-run,所以我们实际上不会更新任何东西:

1sudo certbot renew --dry-run

Certbot 會在端口 54321 上聽取更新挑戰,而 haproxy 會從端口 80 到端口 54321 進行代理。

创建一个Cron工作

接下来,我们将编辑 crontab 来创建一个新的任务,每天都会运行certbot renew 命令。

1sudo crontab -e

将下列内容添加到文件的底部:

1[label crontab entry]
230 2 * * * /usr/bin/certbot renew --renew-hook "/usr/local/bin/renew.sh" >> /var/log/le-renewal.log

这将创建一个新的 cron 任务,每天下午 2:30 执行certbot renew命令.该命令产生的输出将被导向位于 `/var/log/le-renewal.log 的日志文件。

结论

HAProxy 现在使用免费的 Let's Encrypt TLS/SSL 证书,以安全地服务 HTTPS 流量。

Published At
Categories with 技术
comments powered by Disqus