本文通过分析Certbot的程序目录和配置文件目录,解析其是如何实现证书获取、存放、更新的。
要了解另一款流行的证书获取、更新、管理软件,请看前文acme.sh的介绍和安装,附插件列表和中文文档。
Certbot是一个python程序,其主程序目录位于/usr/lib/python3/dist-packages/certbot
,配置文件目录位于/etc/letsencrypt
。
查看certbot的bin文件,其实是一个python文件:less /usr/bin/certbot
,用__requires__
引入了certbot的python包。
#!/usr/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'certbot==0.31.0','console_scripts','certbot'
__requires__ = 'certbot==0.31.0'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('certbot==0.31.0', 'console_scripts', 'certbot')()
)
查看certbot获取的证书,默认存放在/etc/letsencrypt/live/证书ID
路径下,而这个路径下的证书其实是/etc/letsencrypt/archive/证书ID
路径下多个版本证书的软链接,始终指向最新那个版本,这保证了证书路径是固定、确定的,配置证书时可以不用担心证书更新导致路径变更而带来麻烦。
qiushan@topvps:~$ sudo certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
Certificate Name: vps123.top-0001
Domains: *.vps123.top
Expiry Date: 2019-06-22 10:43:59+00:00 (VALID: 30 days)
Certificate Path: /etc/letsencrypt/live/vps123.top-0001/fullchain.pem
Private Key Path: /etc/letsencrypt/live/vps123.top-0001/privkey.pem
Certificate Name: vps123.top
Domains: vps123.top
Expiry Date: 2019-06-22 10:41:31+00:00 (VALID: 30 days)
Certificate Path: /etc/letsencrypt/live/vps123.top/fullchain.pem
Private Key Path: /etc/letsencrypt/live/vps123.top/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
renew
命令会读取/etc/letsencrypt/renewal
路径下所有的证书ID.conf
文件,证书配置文件是有版本的,如果certbot认为它不能handle以实现成功的自动更新,会提示。如果证书还不到期,也会提示。
qiushan@topvps:~$ sudo certbot renew
[sudo] password for qi:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/vps123.top-0001.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attempting to parse the version 0.34.2 renewal configuration file found at /etc/letsencrypt/renewal/zimuxt.com-0001.conf with version 0.31.0 of Certbot. This might not work.
Cert not yet due for renewal
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/vps123.top.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certs are not due for renewal yet:
/etc/letsencrypt/live/vps123.top-0001/fullchain.pem expires on 2019-06-22 (skipped)
/etc/letsencrypt/live/vps123.top/fullchain.pem expires on 2019-06-22 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
证书配置文件是自动生成的,会记住你上次获取/更新某证书时的配置。下面来看两个版本的renew配置文件,分别是主域名和通配符域名的。熟悉了以后,我们可以手动编辑它。
一个主域名证书的配置文件,用webroot
方式验证,即 authenticator=webroot, installer=none
:
qiushan@topvps:~$ less /etc/letsencrypt/renewal/vps123.top.conf
# renew_before_expiry = 30 days
version = 0.31.0
archive_dir = /etc/letsencrypt/archive/vps123.top
cert = /etc/letsencrypt/live/vps123.top/cert.pem
privkey = /etc/letsencrypt/live/vps123.top/privkey.pem
chain = /etc/letsencrypt/live/vps123.top/chain.pem
fullchain = /etc/letsencrypt/live/vps123.top/fullchain.pem
# Options used in the renewal process
[renewalparams]
authenticator = webroot
account = 65b14deb3d403c39e0ea13af1a54031f
server = https://acme-v02.api.letsencrypt.org/directory
webroot_path = /var/www/html/vps123,
[[webroot_map]]
vps123.top = /var/www/html/vps123
一个通配符域名证书的配置文件,用dns-01
方式验证,即 authenticator=manual, installer=none
。dns-01
的自动验证是通过certbot-letencrypt-wildcardcertificates-alydns-au实现的,这个插件提供了auth
和cleanup
两个钩子,分别用于添加/删除txt记录。manual_public_ip_logging_ok = True
这个配置项保证自动更新时不会被提示是否允许此IP登陆,从而避免被输入提示卡住。
qiushan@topvps:~$ less /etc/letsencrypt/renewal/vps123.top-0001.conf
# renew_before_expiry = 30 days
version = 0.34.2
archive_dir = /etc/letsencrypt/archive/vps123.top-0001
cert = /etc/letsencrypt/live/vps123.top-0001/cert.pem
privkey = /etc/letsencrypt/live/vps123.top-0001/privkey.pem
chain = /etc/letsencrypt/live/vps123.top-0001/chain.pem
fullchain = /etc/letsencrypt/live/vps123.top-0001/fullchain.pem
# Options used in the renewal process
[renewalparams]
authenticator = manual
server = https://acme-v02.api.letsencrypt.org/directory
manual_public_ip_logging_ok = True
account = 65b14deb3d403c39e0ea13af1a54031f
manual_auth_hook = /home/centos/app/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php aly add
manual_cleanup_hook = /home/centos/app/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php aly clean
pref_challs = dns-01,
结合以上介绍,和前文用Certbot删除多余的Let’s Encrypt账户关于Let’s Encrypt账户的论述,回顾梳理一下certbot的配置目录。
qiushan@topvps:~$ sudo tree /etc/letsencrypt
/etc/letsencrypt
├── accounts # 账户文件,分不同的版本/type,如有staging、非staging、v01、v02等
│ ├── acme-staging.api.letsencrypt.org
│ ├── acme-staging-v02.api.letsencrypt.org
│ ├── acme-v01.api.letsencrypt.org
│ │ └── directory
│ └── acme-v02.api.letsencrypt.org
│ └── directory
│ └── 65b14deb3d403c39e0ea13af1a54031f
│ ├── meta.json
│ ├── private_key.json
│ └── regr.json
├── archive # 实际的证书文件,分cert、chain、fullchain、privkey四类,从1开始依次编号,后来获取的证书编号+1,即序号最大的是有效的,其它的通常已过期
│ ├── vps123.top # 这个名字是证书ID
│ │ ├── cert1.pem
│ │ ├── ... ...
│ │ ├── cert5.pem
│ │ ├── chain1.pem
│ │ ├── ... ...
│ │ ├── chain5.pem
│ │ ├── fullchain1.pem
│ │ ├── ... ...
│ │ ├── fullchain5.pem
│ │ ├── privkey1.pem
│ │ ├── ... ...
│ │ └── privkey5.pem
│ ├── vps123.top-0001 # 证书ID,同一个域名的不同证书,从第二个开始,后缀附【-[\d]4】,从0001开始
│ ├── cert1.pem
│ ├── ... ...
│ ├── cert5.pem
│ ├── chain1.pem
│ ├── ... ...
│ ├── chain5.pem
│ ├── fullchain1.pem
│ ├── ... ...
│ ├── fullchain5.pem
│ ├── privkey1.pem
│ ├── ... ...
│ └── privkey5.pem
├── cli.ini # 命令行配置文件
├── csr # csr(证书签发请求),于key(private key)是成对出现的,数量非常多,每一个pair对对应一次成功或失败的证书签发请求。
│ ├── 0000_csr-certbot.pem
│ ├── 0001_csr-certbot.pem
│ ├── ... ...
│ └── 0347_csr-certbot.pem
├── keys # key(private key),与csr(证书签发请求)是成对出现的,数量非常多,每一个pair对对应一次成功或失败的证书签发请求。
│ ├── 0000_key-certbot.pem
│ ├── 0001_key-certbot.pem
│ └── ... ...
│ └── 0347_key-certbot.pem
├── live # 为方便证书部署,保证固定的证书路径,提供的alias目录,始终指向最新的有效证书。
│ ├── vps123.top
│ │ ├── cert.pem -> ../../archive/vps123.top/cert5.pem
│ │ ├── chain.pem -> ../../archive/vps123.top/chain5.pem
│ │ ├── fullchain.pem -> ../../archive/vps123.top/fullchain5.pem
│ │ ├── privkey.pem -> ../../archive/vps123.top/privkey5.pem
│ │ └── README
│ ├── vps123.top-0001
│ ├── cert.pem -> ../../archive/vps123.top-0001/cert5.pem
│ ├── chain.pem -> ../../archive/vps123.top-0001/chain5.pem
│ ├── fullchain.pem -> ../../archive/vps123.top-0001/fullchain5.pem
│ ├── privkey.pem -> ../../archive/vps123.top-0001/privkey5.pem
│ └── README
├── options-ssl-apache.conf # apache部署的配置文件
├── renewal # renew配置文件,命名为【证书ID.conf】,分版本,可以手动编辑
│ ├── vps123.top-0001.conf
│ ├── vps123.top.conf
└── renewal-hooks # 一些用于renew的钩子,默认为空
├── deploy
├── post
└── pre
最后附上certbot的package包的目录(已删除大部分__pycache__目录行、tests目录),从文件名大致可以看出其角色、作用。
qiushan@topvps:~$ tree /usr/lib/python3/dist-packages/certbot
/usr/lib/python3/dist-packages/certbot
├── account.py # account.py
├── achallenges.py
├── auth_handler.py
├── cert_manager.py # cert_manager.py
├── client.py
├── cli.py
├── compat.py
├── configuration.py
├── constants.py
├── crypto_util.py
├── display
│ ├── completer.py
│ ├── dummy_readline.py
│ ├── enhancements.py
│ ├── __init__.py
│ ├── ops.py
│ ├── __pycache__
│ │ ├── completer.cpython-35.pyc
│ │ ├── ... ...
│ │ └── util.cpython-35.pyc
│ └── util.py
├── eff.py
├── error_handler.py
├── errors.py
├── hooks.py # hooks.py
├── __init__.py
├── interfaces.py
├── lock.py
├── log.py
├── main.py
├── notify.py # notify.py
├── ocsp.py
├── plugins # 插件,即authenticator,installer在certbot_apache包实现,详后
│ ├── common.py # common.py
│ ├── common_test.py
│ ├── disco.py
│ ├── disco_test.py
│ ├── dns_common_lexicon.py
│ ├── dns_common_lexicon_test.py
│ ├── dns_common.py # dns_common.py
│ ├── dns_common_test.py
│ ├── dns_test_common_lexicon.py
│ ├── dns_test_common.py
│ ├── enhancements.py
│ ├── enhancements_test.py
│ ├── __init__.py
│ ├── manual.py # manual.py
│ ├── manual_test.py
│ ├── null.py
│ ├── null_test.py
│ ├── __pycache__
│ │ ├── common.cpython-35.pyc
│ │ ├── ... ...
│ │ └── webroot_test.cpython-35.pyc
│ ├── selection.py
│ ├── selection_test.py
│ ├── standalone.py # standalone.py
│ ├── standalone_test.py
│ ├── storage.py # storage.py
│ ├── storage_test.py
│ ├── util.py
│ ├── util_test.py
│ ├── webroot.py # webroot.py
│ └── webroot_test.py
├── __pycache__
│ ├── account.cpython-35.pyc
│ ├── ... ...
│ └── util.cpython-35.pyc
├── renewal.py
├── reporter.py
├── reverter.py
├── ssl-dhparams.pem
├── storage.py
├── tests
│ │ ... ...
│ ├── util.py
│ └── util_test.py
├── updater.py
└── util.py
自动为apache安装证书的插件certbot_apache
包:
qiushan@topvps:~$ tree /usr/lib/python3/dist-packages/certbot_apache
/usr/lib/python3/dist-packages/certbot_apache
├── apache_util.py
├── augeas_configurator.py
├── augeas_lens
│ └── httpd.aug
├── centos-options-ssl-apache.conf
├── configurator.py
├── constants.py
├── display_ops.py
├── entrypoint.py
├── http_01.py
├── __init__.py
├── obj.py
├── options-ssl-apache.conf
# 以下是几个面向几个系统平台的
├── override_arch.py
├── override_centos.py
├── override_darwin.py
├── override_debian.py
├── override_gentoo.py
├── override_suse.py
├── parser.py
├── __pycache__
│ ├── apache_util.cpython-35.pyc
│ ├── ... ...
│ └── tls_sni_01.cpython-35.pyc
├── tests
│ └── ... ...
│ └── util.py
└── tls_sni_01.py
4 directories, 67 files
-- EOF --
本文最后修改于6年前 (2019-05-23)