在 CentOS 7 系统上使用免费的 Let’s Encrypt 证书部署 HTTPS 服务(Nginx)


2018 年 12 月 1 日更新

推荐使用更好用证书的部署工具 —— acme.sh,具体的使用方法可查看我的另一篇文章

2018 年 3 月 15 日更新

自 2018 年 3 月 14 日起,Let’s Encrypt 已经支持免费签发通配符证书!但暂时只能通过 DNS 进行验证。文末我将简要地介绍一下操作方法。


一、Let’s Encrypt 简介

Let’s Encrypt 是一个 X.509 数字证书颁发机构。

在 Let’s Encrypt 成立之前,为网站签发证书基本上都是收费的(至少在那个时候我还没看到过免费的),而且价格不菲。这使得很多网站(特别是小网站)玩不起 HTTPS。

2015 年 Let’s Encrypt 成立之后,它就为全世界提供了免费的 DV 证书签发服务。

虽然 Let’s Encrypt 每张免费证书的有效期只有短短 90 天,比收费的证书的有效期短了一大截,但是 Let’s Encrypt 有一个自动化工具,可以实现证书的全自动签发与更新,所以基本上可以忽略这个问题。同时短有效期的证书也能快速适应加密方式的发展与变迁,对增强安全性有很大的帮助。

总之,Let’s Encrypt 为互联网安全作出了巨大的贡献!

Let’s Encrypt 签发证书的过程支持 DNS 以及 Web 验证方式。鉴于一些 DNS 解析商并不提供域名操作的 API,使得自动化部署的难度大大增加。所以可以的话还是尽量选择 Web 验证。

Let’s Encrypt 官方网站


二、示例环境

  • 操作系统:CentOS 7.4.1708
  • 网站域名:example.com
  • 网站目录:/usr/share/nginx/html
  • Web 服务器:Nginx(只有 HTTP 服务)

三、操作步骤

3.1 安装 EPEL 软件源

yum -y install epel-release && yum -y update

3.2 安装 Let’s Encrypt 自动化工具

yum -y install certbot

3.3 配置 Web 服务器

说明
需要配置网站的 /.well-known/acme-challenge/ 目录允许以 HTTP(不是 HTTPS)协议访问。

请使用 vim 之类的文本编辑器打开您的站点配置文件,然后按照下面的格式以及提示修改文件。

 # 下面是网站的 HTTP(不是 HTTPS)服务配置段
server { 
    listen       80 ;
    server_name  example.com;  # example.com 改为您的域名

    ### 加入的内容 ###
    location /.well-known/acme-challenge/ {
        root /usr/share/nginx/html;   # /usr/share/nginx/html 改为您网站所在的目录
    }
    #################

    其它配置项……
}

修改完成后记得保存。

然后执行以下命令让 Nginx 使用新的配置。

systemctl reload nginx

3.4 配置 DNS 服务

请确保要申请证书域名的 A 记录或 AAAA 记录指向该 Web 服务器的公网 IP。

如果使用了 Cloudflare 之类的 CDN 服务,可能需要暂时关闭 CDN,或者使用 DNS 的方式验证(本文不讲)。

3.5 申请证书

命令用法

/usr/bin/certbot certonly --webroot --webroot-path <网站目录> -d <网站域名> --agree-tos --email <您的邮箱地址>

举例

example.com 申请证书。

/usr/bin/certbot certonly --webroot --webroot-path /usr/share/nginx/html -d example.com --agree-tos --email [email protected]

运行结果

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o:     #第一次申请证书的时候会问是否需要订阅邮件,我们不要,输入 n 回车。

Performing the following challenges:
http-01 challenge for example.com
Using the webroot path /usr/share/nginx/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem

   #如果出现以上信息,说明证书签发成功。如果有错误,请根据提示自行解决错误。

   Your cert will expire on 2018-05-14. 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"
 - 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

3.6 证书存放的位置

证书(包含完整的证书链)的存放位置为:

/etc/letsencrypt/live/<您的域名>/fullchain.pem

证书密钥的存放位置为:

/etc/letsencrypt/live/<您的域名>/privkey.pem

说明
上面这两个文件其实是符号链接,在证书更新之后会自动指向最新的证书,无需手动干预。

3.7 使用证书

请使用 vim 之类的文本编辑器打开您的站点配置文件,然后按照下面的格式以及提示修改文件。

# 下面是网站的 HTTPS 服务配置段(建议在原 HTTP 配置的基础上做修改)
server {
  listen 443    ssl http2;
  server_name    example.com;  # example.com 改为您的域名

  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # 证书文件位置,example.com 改为您的域名
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # 证书密钥位置,example.com 改为您的域名



    #(可以不用设置 .well-known 目录的访问)

    其它配置项……
}

#----------------------------------------------------------#

# 下面是网站的 HTTP 服务配置段
server { 
    listen       80 ;
    server_name  example.com;  # example.com 改为您的域名

    location /.well-known/acme-challenge/ {
        root /usr/share/nginx/html;   # /usr/share/nginx/html 改为您网站所在的目录
    }

    location / {
        return 301 https://$server_name$request_uri;  # 将 HTTP 访问全部重定向至 HTTPS
    }
}

修改完成后记得保存。

然后执行以下命令让 Nginx 使用新的配置。

systemctl reload nginx

3.8 设置自动更新证书

说明
1. 由于每一张证书的有效期为 90 天,所以每隔 2 个月更新一次证书就够了。
2. 如果计划任务出现问题而导致证书得不到更新,Let’s Encrypt 会发邮件提醒您。

下面我们设定每隔 2 个月的 10 日 0 点整更新证书。更新成功之后让 Nginx 使用它。

执行以下命令:

crontab -e

然后请在命令行窗口中按下 O(大写),将以下内容直接粘贴到命令行窗口中,再按下 ESC ,最后输入 :wq 按回车。

0 10 1 */2 * /usr/bin/certbot renew --agree-tos && /usr/bin/systemctl reload nginx

四、注意事项

  1. 请不要频繁地申请证书。同一个域名一周最多只能申请 5 次。
  2. 请妥善保护好 /etc/letsencrypt/ 这个目录,里面包含有证书以及密钥。
  3. 如果不慎泄露证书私钥,请及时按照官网上的提示吊销证书。
  4. 由于证书签署的规则随时都有可能发生变化,所以本文具有时效性(最初发表于 2018 年 2 月 13 日),仅供参考。

【更新】五、签发通配符证书

说明
1. 由于我的 DNS 解析商不支持 API 自动化操作,所以到期自动更新证书这一块我就没办法测试了。
2. 裸域名不能使用通配符证书。如果裸域名需要使用证书的话,还要另外签发一张裸域名的证书。
3. 这里需要用到一个使用 Shell 脚本编写的工具,证书存放的路径和上面的有所不同,请注意辨别。

5.1 下载 acme.sh 脚本

curl -O /usr/local/bin/acme.sh https://raw.githubusercontent.com/Neilpang/acme.sh/master/acme.sh

5.2 添加执行权限

chmod +x /usr/local/bin/acme.sh

5.3 提交证书请求 & 获取域名设置信息

命令用法

acme.sh --issue -d <您的域名> -d *.<您的域名> --dns dns_cf

运行命令之后请根据提示在 DNS 解析商的控制面板上设置好 TXT 记录。然后等待大约 2 分钟让记录生效。

5.4 申请证书

命令用法

acme.sh --renew -d <您的域名> -d *.<您的域名>

如果没有错误提示,那么证书就签发成功了。

5.5 证书存放的位置

证书(包含完整的证书链)的存放位置为:

~/.acme.sh/<您的域名>/fullchain.cer

证书密钥的存放位置为:

~/.acme.sh/<您的域名>/<您的域名>.key
分享到:

发表评论

电子邮件地址不会被公开。