certbot 是用来申请 Let's Encrypt 免费 SSL 证书
一般的免费 SSL 证书,好像都是使用 Let's Encrypt 颁发的证书。官网地址:
https://letsencrypt.org/
Let's Encrypt 使用 ACME 协议来认证我们域名,并颁发证书。要获取 Let's Encrypt 证书,我们需要选择一个 ACME 客户端软件。官方推荐的是 Certbot。
Certbot 官网地址:
https://certbot.eff.org
安装 certbot,我们可以查看官方文档:
https://certbot.eff.org/docs/install.html
简述下安装步骤:
最好的方式是:
使用官方给我们提供的 Certbot 包,在官网首页可以下载,选择对应的 web 服务和系统。例如,我的是:
Nginx + CentOS 7
然后下方就会给出我们详细的安装步骤:
/*
下面主要是官网的一些翻译
*/
安装
Certbot 是打包在 EPEL(Extra Packages for Enterprise Linux)。要使用 Certbot,我们必须首先启用 EPEL 仓库。在 RHEL 或 Oracle Linux,我们还必须开启可选的通道。
注意:
如果我们正在 EC2 上使用 EHEL,我们可以通过运行下面的命令来启用可选通道:
$ yum -y install yum-utils
$ yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
之后,我们可以运行下面的命令来安装 Certbot:
$ sudo yum install certbot python2-certbot-nginx
安装 DNS 插件
Certbot 的 DNS 插件可用于我们的系统。这些插件可用于自动从 Let's Encrypt 的 ACMEv2 服务器获取通配符证书。要使用其中一个插件,我们必须为要获取证书的域名配置 DNS,该证书适用于 Certbot 具有插件的 DNS 提供程序。可以在链接('https://certbot.eff.org/docs/using.html#dns-plugins')找到插件列表,以及关于使用它们的更多信息。要安装插件,运行上面的安装命令,但需要将命令中 certbot python2-certbot-nginx 替换为 python2-certbot-dns-PLUGIN,其中 PLUGIN 是要安装的插件的名称。例如,对于 RFC2136 插件,命令应该是 python2-certbot-dns-rfc2136。
开始使用
Certbot 有一个 Nginx 插件, 在许多平台上都支持, 并自动进行证书安装。
$ sudo certbot --nginx
运行该命令,可以让我们获得一个证书, 而且 Certbot 会自动编辑我们的 Nginx 配置来提供服务。如果我们希望自己手动来配置 Nginx,可以使用 certonly 子命令:
$ sudo certbot --nginx certonly
如果我们想要使用 Let's Encrypt 新的 ACMEv2 服务,来获取一个 '通配符' 证书,我们还需要安装 Certbot 的 DNS 插件。确保我们已经通过上面的 '安装 DNS 插件' 说明,安装了 DNS 服务,并运行下面的命令:
$ sudo certbot -a DNS插件名 -i nginx -d "*.example.com" -d example.com --server https://acme-v02.api.letsencrypt.org/directory
自动续订
Certbot 可以配置为,在证书过期之前自动续订。因为 Let's Encrypt 证书的有效期是 90 天,因此我们需要在过期前,重新续订。可以运行下面的命令来测试证书的自动续订:
$ sudo certbot renew --dry-run
如果上面命令没有报错,我们可以通过添加一个 cron job 或 systemd timer 运行下面的命令,来支持自动续订:
certbot renew
注意:
如果我们配置了一个 cron 或 systemd job,建议每天运行2次(在我们的证书续订或撤销之前,它不会执行任何操作。但定期运行,将使我们的网站有机会保持在线状态,以防 Let's Encrypt 由于某种原因异常触发了撤销)。
下面是一个 cron job 示例,每天的中午和半夜运行:
0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew
DNS 插件
如果想要从 Let's Encrypt 上获取通配符证书,或在目标 Web 服务器以外的计算机上运行 certbot,可以使用 Certbot 的 DNS 插件之一。
这些插件不包含在默认的 Certbot 安装中,必须单独安装。虽然 DNS 插件当前不能与 certbot-auto 一起使用,但它们在许多 OS 包管理器和 Docker 镜像中都可以使用。访问 https://certbot.eff.org,了解我们系统上使用 DNS 插件的最佳方法。
安装完成后,我们可以在下方的链接中,找到关于如何使用每个插件的文档:
...
文档列表
...
手动插件(manual)
如果想要在目标 web 服务器以外的机器上运行 certbot 来获取证书,或者自己执行域名验证步骤,我们可以使用 'manual' 插件。没有图形化界面,我们可以通过在命令行上指定 certbot 和 --manual,使用该插件来获取证书。这要求我们复制和粘贴命令到另一个终端会话,该会话可能在另一台机器上。
manual 插件可以使用 http 或 dns challenge(挑战)。我们可以使用 --preferred-challenges 选项来指定我们想要的 challenge
http challenge 要求我们,将包含指定名称和指定内容的文件,直接放到顶级目录(web 根目录)下的 '/.well-known/acme-challenge/' 目录。本质上,同 webroot 插件一样,但是不是自动的。
当使用 dns challenge 时,certbot 将要求我们在域名下,放置一条包含了指定内容的 TXT DNS 记录。包含我们希望颁发证书的主机名,由 '_acme-challenge' 预先设置。
例如,对于 example.com 域名,文件条目如下所示:
_acme-challenge.example.com. 300 IN TXT "gfj9Xq...Rg85nM"
此外,我们可以通过使用 --manual-auth-hook 和 --manual-cleanup-hook 标志,指定脚本,用于准备验证&执行身份认证程序,和(/或)在其后进行清理。这在钩子部分中有更深入的描述。
结合插件
有时候我们可能想要将不同的身份认证程序和安装器程序结合起来。为此,我们可以使用 --authenticator 或 -a 来指定身份认证插件,使用 --installer 或 -i 来指定安装器插件
例如,我们可以使用,用于身份认证的 webroot 插件,和用于安装的 apache 插件,来生成证书。
certbot run -a webroot -i apache -w /var/www/html -d example.com
或者,我们可以使用,用于身份认证的 manual 插件,和用于安装的 nginx 插件,来生成证书。
certbot run -a manual -i nginx -d example.com
第三方插件
其他开发人员也提供了许多针对客户端的第三方插件。许多是测试/实验版本,但有些已经广泛使用
...
第三方插件列表
...
certbot-auto(简单了解下)
安装 certbot-auto
https://certbot.eff.org/docs/install.html#id6
如果上面安装 certbot 的方法不可用,才使用 certbot-auto,它会在我们的系统上自动安装 Certbot:
系统要求:
Python 2.7 或 3.4+,运行在类 unix 系统
默认需要 root 权限,因为要写入到 /etc/letsencrypt, /var/log/letsencrypt, /var/lib/letsencrypt。绑定到 80 和 443 端口(如果使用 standalone 插件),读取并修改 web 服务器配置(如果使用 apache 或 nginx 插件)。
如果避免用 root 用户来运行 ACME 客户端,可以选择 letsencrypt-nosudo(https://github.com/diafygi/letsencrypt-nosudo) 或 simp_le(https://github.com/zenhack/simp_le)
Apache 插件当前需要 augeas 1.0 版本的操作系统;当前支持基于 Debian, Fedora, SUSE, Gentoo 和 Darwin 的现代操作系统.
此外,可以通过验证 certbot-auto 脚本的数字签名来验证它是否完整。这需要安装 gpg2,在许多 Linux 分发版中存在,以 gnupg 或 gnupg2 命名。
使用 certbot-auto 安装,需要 512MB 的 RAM,来构建依赖。通过预构建的系统包来安装,可以避免该问题。我们也可以临时设置一个交换文件(swap file)。查看下面的 'Python 虚拟环境问题' 获取更多信息。
安装 certbot-auto:
wget https://dl.eff.org/certbot-auto
sudo mv certbot-auto /usr/local/bin/certbot-auto
sudo chown root /usr/local/bin/certbot-auto
chmod 0755 /usr/local/bin/certbot-auto
/usr/local/bin/certbot-auto --help
检查脚本完整性:
wget -N https://dl.eff.org/certbot-auto.asc
gpg2 --keyserver pool.sks-keyservers.net --recv-key A2CFB51FA275A7286234E7B24D17C995CD9775F2
gpg2 --trusted-key 4D17C995CD9775F2 --verify certbot-auto.asc /usr/local/bin/certbot-auto
certbot-auto 命令自动更新到最新的客户端版本。由于 certbot-auto 是 certbot 的包装器,它接受与 certbot 完全一样的标志和参数。更多信息,查看 certbot 命令行选项(https://certbot.eff.org/docs/using.html#command-line-options)
要获得完整的命令行帮助,可以输入:
./certbot-auto --help all
看文档,外加查找资料,最终配置成功。这里记录下每一个步骤,以后按照这个步骤安装、配置即可:
1.安装 certbot
访问首页:https://certbot.eff.org,选择我们使用的 web 服务和操作系统,然后会给出默认的安装命令
这里以 'nginx' 和 'centos7' 为例:
yum -y install yum-utils
在 RHEL 或 Oracle Linux 上,还需要执行(我们使用的 centos 不需要):
yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
yum install certbot python2-certbot-nginx
// 注意,这里安装的是 nginx 插件
yum install certbot python2-certbot-nginx
2.通过 certbot 生成证书
certbot --nginx certonly [-d 域名1,域名2]
1>参数解析,很重要:
--nginx - 表示我们之前选择的 nginx 服务
certonly - 默认 certbot 会自动修改我们 nginx 的配置,添加上 ssl 配置,我们想要手动配置 ssl,就需要设置该选项
-d - 指定域名,可以同时指定多个,以 ',' 分隔
2>此外,直接运行上述命令,可能会报错:
Error while running nginx -c /usr/local/nginx/nginx.conf -t
原因:
找不到 nginx 配置文件,默认 certbot 会找 /etc/nginx/nginx.conf 配置文件
我们配置的 nginx 位置可能不同,需要改成自己的 nginx 路径
解决方法:
查看 certbot 帮助,应该提供了修改路径的选项
certbot -h // certbot 命令帮助
certbot -h nginx // nginx 插件帮助
提供了2个选项:
--nginx-server-root
nginx 服务根目录,默认是 '/etc/nginx'
/*
这里还是个坑,因为 certbot 好像只是找 nginx.conf,所以,当我们的配置文件,不是放在 nginx 的根目录,仍然找不到
所以,这里应该是 'nginx 配置文件所在的目录'
例如,我的 nginx 配置路径是:
/usr/local/nginx/conf/
*/
--nginx-ctl
nginx 命令二进制文件名,默认是 'nginx'
所以,我们最终的命令是:
certbot --nginx certbot --nginx-server-root /usr/local/nginx/conf/
3>执行可能还会报错:
ImportError: No module named 'requests.packages.urllib3'
原因:
requests库版本问题
解决方法:
sudo pip install requests urllib3 pyOpenSSL --force --upgrade
sudo pip install --upgrade --force-reinstall 'requests==2.6.0'
4>期间可能还会发生报错:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 1: ordinal not in range(128)
原因:
nginx.conf 出现特殊字符
解决方法:
参考:https://github.com/certbot/certbot/issues/5236
grep -r -P '[^\x00-\x7f]' /usr/local/nginx/conf/nginx.conf
或
grep -r -P '[^\x00-\x7f]' /usr/local/nginx/conf/vhosts/xxx.conf(虚拟主机配置)
上面的命令是,查看有没有 \x00-\x7f 的特殊字符,有的话,将特殊字符删除(中文就是一种特殊字符)
3.续订证书
certbot renew // 续订所有证书
certbot renew --cert-name 证书名 // 续订 '指定证书'
// 查看 renew 子命令
certbot -h renew
4.自动续订证书
因为 Let's Encrypt 证书有效期为 3 个月,我们不可能实时查看,需要配置一个计划任务,在过期前,自动续订:
0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew
5.申请 '通配符' 证书
上面的流程,只能申请指定域名的证书。如果我们想要申请 '通配符' 证书,还需要安装额外的 ' DNS 插件'。
插件列表在 'https://certbot.eff.org/docs/using.html#dns-plugins' 可以查看到
里面列出的插件基本都是国外的,我们可能都不适用。
官方也提供了一个 'manual - 手动认证插件'(这个我没自己测试)
certbot certonly --nginx -d 通配符域名(*.xxx.com) --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
但是手动的方式,有问题,就是自动续订,过期了,还需要 '手动认证'...,没法做到自动生成
但是,官方提供了 '--manual-auth-hook' 和 '--manual-cleanup-hook' 2个钩子,我们可以写脚本来实现自动生成(参考下方笔记 6)
6.在网上找了个文章,写的非常好,推荐下:
https://www.cnblogs.com/redirect/p/10140248.html
它里面提到了一个 'manual' dns 插件脚本,可以帮我们自动订阅 '通配符' 证书,地址:
https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au
里面需要注意的是
1>文档使用的是 certbot-auto,我们安装的是 certbot,两者命令是一致的。certbot-auto 是对 certbot 的封装。
2>au.sh 脚本,我们需要配置下
1>我服务器是 '腾讯云',需要配置 '腾讯云' 的 APP_KEY(key) 和 APP_SECRET(token)
2>我使用的是 php 脚本,配置下 php 命令路径
列出所有命令:
1>安装
cd ~ && mkdir src && cd src
git clone https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au
cd certbot-letencrypt-wildcardcertificates-alydns-au
chmod 0777 au.sh
2.配置 DNS API 秘钥
需要在不同的云平台申请(见文档)
3.配置 au.sh
key
token
php_cmd
4.测试申请证书(有 --dry-run 选项)
certbot certonly -d *.xxx.com --manual --preferred-challenges dns --dry-run --manual-auth-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy add" --manual-cleanup-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy clean"
5.测试无误,正式申请证书(去除 --dry-run 选项)
certbot certonly -d *.xxx.com --manual --preferred-challenges dns --manual-auth-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy add" --manual-cleanup-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy clean"
6.配置自动续订,加入命令到 crontab
# 注意只有成功renew证书,才会重新启动nginx
1 1 */1 * * root certbot renew --manual --preferred-challenges dns --deploy-hook "service nginx restart" --manual-auth-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy add" --manual-cleanup-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy clean"
参考文章:
https://www.cnblogs.com/redirect/p/10140248.html(非常不错)
https://www.seanzhao.me/2018/06/21/certbot-manual.html#%E4%BF%AE%E6%94%B9%E6%9B%B4%E6%96%B0%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6
https://blog.csdn.net/diyiday/article/details/82791663
https://www.seanzhao.me/2018/06/21/certbot-manual.html#%E4%BF%AE%E6%94%B9%E6%9B%B4%E6%96%B0%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6