如何使用CentOS 7上的Let's Encrypt来保护HAProxy

2018-10-15 17:24:05 浏览数 (1)

介绍

我们的加密是一个新的证书颁发机构(CA),它提供了一种获取和安装免费TLS / SSL证书的简便方法,从而在Web服务器上启用加密的HTTPS。它通过提供软件客户端Certbot来简化流程,该客户端尝试自动执行大多数所需步骤。目前,获取和安装证书的整个过程仅在Apache Web服务器上完全自动化。但是,无论您选择哪种Web服务器软件,都可以使用Certbot轻松获取免费的SSL证书,该证书可以手动安装。

在本教程中,我们将向您展示如何使用Let的加密来获取免费的SSL证书,并将其与CentOS 7上的HAProxy一起使用。我们还将向您展示如何自动续订您的SSL证书。

准备

在学习本教程之前,您需要准备以下内容。

您应该拥有一个具有sudo权限的非root用户的CentOS 7服务器。您可以按照Linux系统下给非root用户添加sudo权限设置此类用户帐户。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。

您必须拥有或控制您希望使用证书的注册域名。

  • 如果你有域名,保护你网站的最简单方法是使用腾讯云SSL证书服务,它提供免费的可信证书。腾讯云SSL证书安装操作指南进行设置。
  • 如果你没有域名,建议您先去这里注册一个域名,如果你只是使用此配置进行测试或个人使用,则可以使用自签名证书,不需要购买域名。自签名证书提供了相同类型的加密,但没有域名验证公告。关于自签名证书,你可以参考为Apache创建自签名SSL证书和如何为Nginx创建自签名SSL证书这两篇文章。

这是必需的,因为Let's Encrypt要验证您拥有为其颁发证书的域。例如,如果要给example.com获取证书,则该域必须解析到您的服务器才能使验证过程正常工作。我们的设置将使用example.comwww.example.com作为域名,因此需要两个DNS记录

一旦你完成了所有的准备条件,让我们继续安装Let's Encrypt客户端软件certbot

第一步 - 安装Certbot,一个Let's Encrypt客户端

使用Let's Encrypt获取SSL证书的第一步是在服务器上安装该certbot软件。目前,安装它的最佳方法是通过EPEL存储库。

通过输入以下内容,可以访问服务器上的EPEL存储库:

代码语言:javascript复制
sudo yum install epel-release

启用存储库后,您可以通过输入certbot内容来获取包:

代码语言:javascript复制
sudo yum install certbot

certbot让我们加密客户端现在应该安装并投入使用。

第二步 - 获得证书

Let's Encrypt提供了各种通过插件获取SSL证书的方法。与Apache插件不同,大多数插件只能帮助您获取必须手动配置Web服务器才能使用的证书。仅获取证书但不安装证书的插件称为“身份验证器”,因为它们用于验证服务器是否应颁发证书。

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

验证端口80是否已打开

Standalone插件提供了一种获取SSL证书的简单方法。它的工作原理是在80服务器端口临时运行一个小型Web服务器,Let's Encrypt 的CA可以连接并在颁发证书之前验证服务器的身份。因此,此方法要求端口80未使用。也就是说,在尝试使用此插件之前,请务必停止正常的Web服务器(如果它正在使用端口80(即http))。

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

代码语言:javascript复制
sudo systemctl stop haproxy

如果您不确定端口80是否正在使用,则可以运行以下命令:

代码语言:javascript复制
netstat -na | grep ':80.*LISTEN'

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

运行Certbot

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

代码语言:javascript复制
sudo certbot certonly --standalone --preferred-challenges http --http-01-port 80 -d example.com -d www.example.com

系统将提示您输入您的电子邮件地址并同意Let's Encrypt服务条款。之后,http挑战将会进行。如果一切都成功,certbot将打印输出消息,如下所示:

代码语言:javascript复制
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert
   will expire on 2017-09-06. To obtain a new or tweaked version of
   this certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:
​
   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

您需要记下证书的路径和到期日期。

注意:如果您的域通过CloudFlare等DNS服务进行路由,则需要暂时禁用它,直到获得证书为止。

证书文件

获得证书后,您将拥有以下PEM编码文件:

  • cert.pem:您的域名证书
  • chain.pem: Let的加密链证书
  • fullchain.pem:合并 cert.pemchain.pem
  • privkey.pem:您的证书的私钥

了解刚刚创建的证书文件的位置非常重要,因此您可以在Web服务器配置中使用它们。文件本身放在一个子目录/etc/letsencrypt/archive中。但是,Certbot会创建指向/etc/letsencrypt/live/your_domain_name目录中最新证书文件的符号链接。

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

代码语言:javascript复制
sudo ls /etc/letsencrypt/live/your_domain_name

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

合并fullchain.pem和privkey.pem

在配置HAProxy的执行SSL终止,所以将加密本身和最终用户之间的流量,你必须将fullchain.pemprivkey.pem合并成一个单一的文件。

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

代码语言:javascript复制
sudo mkdir -p /etc/haproxy/certs

接下来,使用此cat命令创建组合文件(用您的域名替换example.com):

代码语言:javascript复制
DOMAIN='example.com' sudo -E bash -c 'cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/haproxy/certs/$DOMAIN.pem'

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

代码语言:javascript复制
sudo chmod -R go-rwx /etc/haproxy/certs

现在我们已准备好将SSL证书和私钥与HAProxy一起使用。

第三步 - 安装HAProxy

此步骤介绍HAProxy的安装。如果它已安装在您的服务器上,请跳过此步骤。

用yum安装HAProxy:

代码语言:javascript复制
sudo yum install haproxy

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

第四步 - 配置HAProxy

本节将向您展示如何使用SSL设置配置基本HAProxy。它还介绍了如何配置HAProxy以允许我们自动续订Let's Encrypt 证书。

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

代码语言:javascript复制
sudo vi /etc/haproxy/haproxy.cfg

保持此文件打开,我们将在接下来的几个部分中对其进行编辑。

全局部分

将此行添加到全局部分以配置生成的临时DHE密钥的最大大小:

代码语言:javascript复制
   tune.ssl.default-dh-param 2048

前端部分

现在我们准备定义我们的frontend部分。

注意:默认的HAProxy配置包括前端和几个后端。随意删除它们,因为我们不会使用它们。

我们要添加的第一件事是处理传入HTTP连接的前端,并将它们发送到默认后端(稍后我们将定义)。在文件的末尾,让我们添加一个名为www-http的前端。请务必haproxy_public_IP使用HAProxy服务器的公共IP地址替换:

代码语言:javascript复制
frontend www-http
   bind haproxy_www_public_IP:80
   reqadd X-Forwarded-Proto: http
   default_backend www-backend

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

代码语言:javascript复制
frontend www-https
   bind haproxy_www_public_IP:443 ssl crt /etc/haproxy/certs/example.com.pem
   reqadd X-Forwarded-Proto: https
   acl letsencrypt-acl path_beg /.well-known/acme-challenge/
   use_backend letsencrypt-backend if letsencrypt-acl
   default_backend www-backend

此前端使用ACL(letsencrypt-acl)将Let's Encrypt验证请求( /.well-known/acme-challenge)发送到letsencrypt-backend后端,这将使我们能够在不停止HAProxy服务的情况下续订证书。所有其他请求将被转发到www-backend,这是将为我们的Web应用程序或站点提供服务的后端。

后端部分

配置完前端后,通过添加以下行添加www-backend后端。请务必使用Web服务器的相应专用IP地址替换www-1 www_1_private_IP及www_2_private_IP(调整server行以匹配您拥有的后端服务器数量):

代码语言:javascript复制
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

此后端接收的任何流量将server通过HTTP(端口80)在其条目之间进行平衡。

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

代码语言:javascript复制
backend letsencrypt-backend
   server letsencrypt 127.0.0.1:54321

此后端仅处理用于证书请求和续订的Let's Encrypt ACME质询,将流量发送到localhost 的54321端口上。当我们再次让我们加密的SSL证书,我们将使用此端口而不是80443

现在我们准备启动HAProxy了:

代码语言:javascript复制
sudo systemctl start haproxy

注意:如果您在haproxy.cfg配置文件方面遇到问题,请查看此GitHub Gist以获取示例。

Let's Encrypt TLS / SSL证书现已到位,我们已准备好设置自动续订脚本。此时,您应该通过在Web浏览器中访问您的域来测试TLS / SSL证书是否有效。

第五步 - 设置自动续订

Let's Encrypt证书仅在90天内有效,因此自动化续订过程非常重要。

确保证书不会过时的实用方法是创建一个cron作业,该作业将自动为您处理续订过程。cronjob将certbot每天运行并在证书到期后的30天内更新证书。在成功的续订后,certbot也会运行一个特殊的renew-hook脚本。我们将使用此续订脚本来更新我们合并的.pem文件并重新加载haproxy。

我们现在创建该脚本,然后测试它。

创建续订脚本

root身份打开一个新文件/usr/local/bin

代码语言:javascript复制
sudo vi /usr/local/bin/renew.sh

这将是一个新的空白文本文件。粘贴在以下简短脚本中,确保更新使用您自己的域名:

代码语言:javascript复制
#!/bin/sh
​
SITE=example.com
​
# move to the correct let's encrypt directory
cd /etc/letsencrypt/live/$SITE
​
# cat files to make combined .pem for haproxy
cat fullchain.pem privkey.pem > /etc/haproxy/certs/$SITE.pem
​
# reload haproxy
systemctl reload haproxy

保存并关闭文件。这个脚本进入正确的Let's Encrypt目录,运行cat命令将两个.pem文件连接成一个,然后重新加载haproxy。

接下来,使脚本可执行:

代码语言:javascript复制
sudo chmod u x /usr/local/bin/renew.sh

然后运行脚本:

代码语言:javascript复制
sudo /usr/local/bin/renew.sh

它应该运行没有错误。接下来,我们将更新Certbot并将其配置为运行此续订脚本。

更新certbot配置

certbot renew命令是我们用于续订证书的命令会读取我们第一次运行时创建配置文件certbot。我们需要打开这个文件并更新certbot用于运行其独立http服务器的端口,这样它就不会与haproxy(已经在端口80和443上监听)发生冲突。在文本编辑器中打开配置文件:

代码语言:javascript复制
sudo vi /etc/letsencrypt/renewal/example.com.conf

我们需要更改该http01_port行,因此它如下所示:

代码语言:javascript复制
http01_port = 54321

保存并关闭文件。现在测试续订过程,指定--dry-run,所以我们实际上不更新任何东西:

代码语言:javascript复制
sudo certbot renew --dry-run

Certbot将在端口54321上侦听续订挑战,而haproxy将从端口80代理请求到54321。

创建一个Cron作业

接下来,我们将编辑crontab以创建每天运行该certbot renew命令的新作业。要为root用户编辑crontab,请运行:

代码语言:javascript复制
sudo crontab -e

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

代码语言:javascript复制
30 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的日志文件。如果证实实际更新了证书,则--renew-hook脚本将运行以创建组合的PEM文件并重新加载haproxy

结论

HAProxy现在使用免费的Let's Encrypt TLS / SSL证书来安全地提供HTTPS流量。

想要了解更多关于CentOS的开源信息教程,请前往腾讯云 社区学习更多知识。

参考文献:《How To Secure HAProxy with Let's Encrypt on CentOS 7》

0 人点赞