在 CentOS 7 上为网站安装使用 Let’s Encrypt SSL 证书

Let’s Encrypt 免费 SSL 证书早已经脱离测试开始正式开放申请了。其自动化部署工具也已经比较成熟。下面是水景一页在自己的 VPS 上部署 Let’s Encrypt SSL 证书的经验记录。

水景一页两年前已经部署了 SSL 证书,开始提供 HTTPS 加密访问。只是因为感觉国内 HTTPS 访问外部站点的时候速度会受到比较大的影响就没有强制全站开启,所以估计很多访客都不知道。不过现在 Google 已经默认只索引水景一页上 HTTPS 版本的链接了。之前两年使用的是 StartSSL 的免费证书。用起来挺方便,每年续一次就可以一直免费使用。可是我弄丢了该网站颁发的登录证书,所以就得重新注册申请新的证书。这个也是比较头疼。

NOTE @ 2016-11-27:

偶然发现 Let’s Encrypt 现在与 EFF 合作使用 Certbot,一个基于 Automatic Certificate Management Environment (ACME)(自动化证书管理环境)标准的客户端来获取、部署和更新证书。

NOTE @ 2017-07-16:

更新下面的内容以使用上面提到的 Certbot 来获取和更新证书。certbot 跟最开始介绍的 ./letsencrypt 方式可以并行使用。它们实际上是同一服务的不同客户端,所以获取的证书的配置和存放路径是一样的,甚至可以混用(当然肯定是没必要的,安装了 Certbot 之后就可以删除之前从 git 安装的 letsencrypt 客户端了;但是之前设定的自动更新脚本里面的指令也需要更新)。

言归正传,下面开始部署 Let’s Encrypt 的 SSL 证书。

安装 Let’s Encrypt 客户端

对于 CentOS 发行版来说目前有两种安装 Let’s Encrypt 客户端的方式,一种是从上游的 EPEL 源直接 yum 安装,一种是从 Let’s Encrypt 的 GitHub 源下载。水景一页使用的是下面的第二种方法,从 GitHub 下载;并于 2017.07.16 改为 Certbot 方式(第一种方法的后续升级版本)。

两种安装方式

简单比较:

  • YUM 安装可跟随系统更新一起更新该安装包,但是没有 apache 自动安装证书的这个组件(已升级整合),安装过程非常简单。
  • git 安装也很简单,有 apache 插件,但是需要另行升级更新。并且需要该虚拟主机已经配置了 SSL 证书(自己签发的也行)。

目前 EPEL 源中已经有了 letsencrypt 安装包,但是这个安装包还没有整合 Apache 组件。这就意味着该客户端只能获取证书,还不能自动为网站安装证书(其实安装证书也就是修改虚拟主机配置文件,将其中的指向安全证书的路径替换为当前获取的 Let’s Encrypt CA 证书)。后来改用统一的 Certbot,并且 Certbot 已经整合到 EPEL 源中了。

但是这个 Apache 插件在 Let’s Encrypt 的 GitHub 源里面已经是有了的。所以我们有两种方案来操作:一是获取 GitHub 上的 Let’s Encrypt 客户端,然后自动获取和安装证书;二是从 EPEL 源上直接安装 letsencrypt 包,仅获取证书,手工安装证书。

使用不包含 apache 插件的 letsencrypt 是不太方便的。因为这里的 letsencrypt 没有 Apache 插件,只能使用 certonly 或者 standalone 模式获取证书。而因为获取的证书需要立即进行验证,也就是验证所申请的证书与对应域名的一致性,可是因为不能自动安装证书,所以需要把 certonly 模式获取的证书放在对应虚拟主机的网站根目录让 Let’s Encrypt 验证服务器可以访问到。该目录在 Linux 上还是个以 . 开头的隐藏目录,需要设置 Apache 服务器以允许访问隐藏目录内的内容。看起来似乎也是挺麻烦的。standalone 模式似乎更麻烦,可能还需要让虚拟主机暂停一下服务。由于当前存在这些问题,所以水景一页选择的是使用 GitHub 上的 Let’s Encrypt 客户端以减少麻烦(自带可执行文件,无须编译安装)。

注意:使用客户端获取和安装证书后其会自动极短暂地重启 Apache 服务以使证书生效!

从 EPEL 安装 Let’s Encrypt

Certbot 支持大多数主流 Linux 服务器发行版(具体可查阅这里),至少 CentOS 是没问题的 :-)

  1. 参考官方文档:https://certbot.eff.org/#centosrhel7-apache
  2. 这里安装的是 Apache 版本。

目前 EPEL (Extra Packages for Enterprise Linux) 官方源里面已经整合了 Let’s Encrypt 的 Certbot 的安装包了。如果系统里使用了 EPEL 的源的话,直接 YUM 安装即可。不过再安装一次 EPEL 源也不麻烦。

# yum -y install yum-utils
# yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional

然后安装 certbot(这里假设是水景一页这样用的 Apache 服务器),

# yum install certbot-apache

运行,

# certbot -h

可以查看帮助。Certbot 不但能获取证书,还能自动为网站安装证书(根据已有的 virtualhost 配置文件)。

可以尝试使用 apache 组件获取证书并安装,

# certbot --apache certonly --dry-run

--dry-run 表示模拟执行(不对服务器产生实际的配置操作),但是它只能用于模拟更新证书(renew)或者仅获取证书(certonly)的操作而不能模拟获取并安装的操作。

执行,

# certbot --apache -d cnzhx.net -d www.cnzhx.net -d test.cnzhx.net

这样就会针对三个域名 cnzhx.net, www.cnzhx.net, test.cnzhx.net 来获取并安装证书。

还可以简单的运行,

# certbot --apache

来给服务器上所有满足条件的域名获取并安装证书。

当然也可以只是获取证书而不自动安装(但是为了测试获取的证书,还是会锻造重新加载虚拟主机服务),

# certbot --apache certonly

git 安装

安装服务器依赖组件,因为要用 git 嘛,

# yum install epel-release
# yum install git

然后下载 Let’s Encrypt 客户端,也就是从 GitHub 上复制该源的所有文件,

# git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

上面的指令中最后的目录表示将程序保存到本地的 /opt/letsencrypt 文件夹。

如果需要更新客户端,可以通过下面的指令更新之,

# cd /opt/letsencrypt
# sudo git pull

当然也可以把这个指令加到下面要介绍的自动更新证书的脚本里面自动执行。

调整虚拟主机配置文件

先不慌着运行客户端来获取证书,还有些准备工作要做。使用 apache 自动安装证书插件有以下前提需要满足才能成功,(2017-07-16 更新时未测试新程序是否有次限制。)

  • 需要该虚拟主机已经配置了 SSL 证书(自己签发的也行)。如果需要安装一个自己签发的证书,可以参考水景一页上的这篇文章
  • 需要一个虚拟主机单独一个 Apache 配置文件(.conf 文件)。

如果像水景一页一样没有使用分离的配置文件,可以按照下面的思路修改配置文件。因为如果服务器的 SSL 配置文件中有几个虚拟主机,letsencryptcertbot 运行时会提示错误,

“We were unable to find a vhost with ServerName or Address of cnzhx.net

然后让你选择有效的配置文件。

假设原来的服务器上虚拟主机的配置文件在 vhostssl.conf 文件中。

新建文件夹,

mkdir /etc/httpd/sites-available
mkdir /etc/httpd/sites-enabled

将 vhostssl.conf 文件中每个虚拟主机单独用一个针对 SSL 的配置文件,例如 cnzhx.net-ssl.conftest.cnzhx.net-ssl.conf,保存在 sites-available 文件夹中。同时删除 vhostssl.conf 文件中的对应内容

然后针对要启用的主机的配置文件建立软连接到 sites-enabled 文件夹中,比如这里的 cnzhx.net

ln -s /etc/httpd/sites-available/cnzhx.net-ssl.conf /etc/httpd/sites-enabled/cnzhx.net-ssl.conf

这样的好处是,如果不需要 cnzhx.net-ssl.conf 了,直接删除 sites-enabled 文件夹中的该项,而 sites-available 中还保留着原始配置文件作为备份。

然后在 vhostssl.conf 中添加下面的一行指令以让 Apache 启动时加载 sites-enabled 文件夹中的所有虚拟主机配置文件,

IncludeOptional sites-enabled/*.conf

嗯,如果是 Apache 2.4 之前的版本,应该用,

Include sites-enabled/*.conf

准备好之后就可以进入 letsencrypt 安装目录执行证书的获取和启用了。

获取及安装证书

certbot

这里以 certbot 为例。

 

letsencrypt

这里以 git 安装的 letsencrypt 为例。指令为,

# ./letsencrypt-auto

进入 letsencrypt 文件夹,比如这里的,

# cd /opt/letsencrypt

运行以下指令,

# ./letsencrypt-auto --apache -d cnzhx.net -d www.cnzhx.net -d test.cnzhx.net

其中 --apache 表示使用 apache 插件安装证书;每个需要安装证书的域名都跟在一个 -d 后面。一般对于主域名,如这里的 cnzhx.net,通常我们会将 www.cnzhx.net 作为其别名同时申请证书。也就是说,至少包含类似于上面的三个域名中的前两个。当然也可以分开申请证书,比如,

先进行,

# ./letsencrypt-auto --apache -d cnzhx.net -d www.cnzhx.net

完成后再执行,

# ./letsencrypt-auto --apache -d test.cnzhx.net

第一次运行会自动安装一些必须的软件包,包括 python 相关的内容。下载量大约是 20-30MB。之后就会自动获取证书并安装。

前面说过,apache 插件目前只能处理一个虚拟主机单独一个配置文件的配置方式。比如这里提到的三个域名对应两个虚拟主机,cnzhx.net 和 www.cnzhx.net 对应主站;test.cnzhx.net 是另一个独立的网站。那么就需要将这两个虚拟主机的 vhost 配置文件分别写成两个独立的文件,比如 cnzhx.net-ssl.conftest.cnzhx.net-ssl.conf。否则会触发错误而导致失败。错误类似于,

The apache plugin is not working; there may be problems with your existing configuration.
The error was: PluginError(('There has been an error in parsing the file (%s): %s', u'/etc/httpd/conf.d/vhost.conf', u'Syntax error'),)

当然,修改虚拟主机配置文件后重新运行就可以了。下面接着说正确的路子。

然后紧接着就会提示输入管理帐号的 email 地址。再就是同意协议。很简单,除了 email 地址要输入,剩下的就是一路 Enter 就可以了。

1. email for recovery of account credentials
2. Agrement

申请下来的证书会被保存在 /etc/letsencrypt/live/ 文件夹。

定时更新证书

注意:下面是按照 git 安装的情况来说明的,如果是 yum 安装,则需要根据情况调整 letsencrypt 指令为 certbot,其它不变。

Let’s Encrypt 证书的有效期是 90 天。但是因为流程是全自动的,所以也不会造成多大麻烦。官方说明中强调所有证书只要过了 60 天就可以换发新的证书,以留出一些时间用于应付突发情况。

对于自动更新脚本,官方则建议最好每天运行一次,并且是在一天中随机的某个时刻,这样可以避免每次更新时都遇到特定的网络状况、服务器拥堵等问题,也就尽可能避免了连续多天无法获取新证书的情况出现。

自动续期的命令为,

# certbot renew

或者,

# ./letsencrypt-auto renew

该指令会自动更新服务器上所有通过该方法获取的证书。

官方给了一个自动更新脚本作为例子,下面是针对使用 apache 插件的自动续约脚本。按照前面的情况,假设安装位置为 /opt/letsencrypt。

#!/bin/sh
if ! /opt/letsencrypt/letsencrypt-auto renew > /var/log/letsencrypt/renew.log 2>&1 ; then
 echo Automated renewal failed:
 cat /var/log/letsencrypt/renew.log
 exit 1
fi

或者 certbot 版本,

#!/bin/sh
if ! certbot renew > /var/log/letsencrypt/renew.log 2>&1 ; then
 echo Automated renewal failed:
 cat /var/log/letsencrypt/renew.log
 exit 1
fi

将其保存为 le-renew.sh 文件,然后可以通过 cron 定时运行该文件。

下面是水景一页使用的自动化脚本,前面添加了一个自动延迟几分钟的指令以避免总在某一个特定时刻更新,并ie如果更新失败则会自动向指定的邮件地址发送邮件提醒。

#!/bin/sh
# https://cnzhx.net/
# 自动更新 letsencrypt 客户端
cd /opt/letsencrypt
git pull

# 延时随机的分钟数
sleep $[ ( $RANDOM % 10 ) + 1 ]m
# 自动续签 Let's Encrypt 证书
cd /opt/letsencrypt
if ! ./letsencrypt-auto renew > /var/log/letsencrypt/renew.log 2>&1 ; then
 echo Automated renewal failed: | mail -s "LE renew failed" your@email.com
 cat /var/log/letsencrypt/renew.log
 exit 1
fi

设置脚本自动执行前要自己先直接运行试试看有没有错误,是否达到预期效果。

要设置该脚本自动运行,比如每天凌晨 5 点钟执行,则直接以 root 身份修改 crontab 文件即可,在其最后添加如下一行并保存即可,

0 5 * * * root sh /path/to/le-renew.sh > /dev/null 2>&1

注意修改到 le-renew.sh 的路径 :D

参考链接

欢迎留言讨论与 Let’s Encrypt 相关的问题。©

本文发表于水景一页。永久链接:<https://cnzhx.net/blog/implement-letsencrypt-ca-on-centos-7/>。转载请保留此信息及相应链接。

20 条关于 “在 CentOS 7 上为网站安装使用 Let’s Encrypt SSL 证书” 的评论

    • 哈,我不知道 StartSSL 可以重新验证,当时就直接新注册了一个,然后就发现 CNAME 不能是主域名了。
      Let’s Encrypt 也还好,虽然 2 个月续一次,可是能够自动完成,无所谓换的频率了。
      P.S. 你又开始露脸了啊 :D

  1. 二、安装证书

    /etc/httpd/conf.modules.d/00-base.conf 里 也没有
    ssl 官方 给的文档下面的,可第一步 就没有 走通 ,所以博主 还是 写个教程吧。

    1.修改apache下的httpd.conf文件。
    (1)打开apache安装目录下conf目录中的httpd.conf文件,找到
    #LoadModule ssl_module modules/mod_ssl.so
    #Include conf/extra/httpd-ssl.conf
    (2)删除行首的配置语句注释符号“#”,保存退出。

    • 先运行

      # apachectl -M | grep ssl_module

      看看返回结果是否是 ssl_module (shared)
      如果是,则该模块已经加载;否则,查看 /etc/httpd/conf.modules.d/00-ssl.conf 里面是不是有 #LoadModule ssl_module modules/mod_ssl.so
      之所以没法再写一篇,是因为所有的步骤和操作都是一样的,跟你用的哪家的证书没有关系。Let’s Encrypt 的证书的安装之所以重写了,是因为它引入了证书自动安装和更新的方法。

  2. 荣我多句话啊,如果是为访客着想,最好不要用国内的证书发布商提供的证书。

    这里没有明白
    另外评论无法上传图片 博主的 网址 现在弹出提示框,内容如下:
    完全警报
    该站点安全证书的吊销信息不可用。是否继续?
    是 否 查看证书

雁过留声,人过留名

电子邮件地址不会被公开。 必填项已用*标注

特别提示:与当前文章主题无关的讨论相关但需要较多讨论求助信息请发布到水景一页讨论区的相应版块,谢谢您的理解与合作!请参考本站互助指南
您可以在评论中使用如下的 HTML 标记来辅助表达: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>