Certbot
Certbot 是 电子前哨基金会(Electronic Frontier Foundation) 的 ACME 客户端,它使用 Python 编写,并提供诸如自动 Web 服务器配置和用于 HTTP 质询的内置 Web 服务器等便利功能。Certbot 是 Let's Encrypt 推荐的客户端。
安装
插件可用于自动配置和安装在 Web 服务器中颁发的证书
- 可以使用 certbot-nginx 软件包安装 Nginx 插件。
- 可以使用 certbot-apache 软件包安装 Apache HTTP 服务器 插件。
配置
请查阅 Certbot 文档,以获取有关证书创建和使用的更多信息。
插件
Nginx
certbot-nginx 插件为 nginx 提供了自动配置。此插件将尝试检测每个域的配置设置。该插件添加了推荐用于安全性的额外配置、证书使用设置以及 Certbot 证书的路径。请参阅 #管理 Nginx 服务器块 以获取示例。
首次设置 服务器块
# certbot --nginx
续订证书
# certbot renew
更改证书而不修改 nginx 配置文件
# certbot --nginx certonly
有关更多信息,请参阅 Arch Linux 上的 Certbot-Nginx,并参阅 #自动续订 以保持已安装证书的有效性。
管理 Nginx 服务器块
在手动管理这些文件时,以下示例可用于所有 服务器块
/etc/nginx/sites-available/example
server { listen 443 ssl http2; listen [::]:443 ssl http2; # Listen on IPv6 ssl_certificate /etc/letsencrypt/live/domain/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/domain/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; .. }
有关更多信息,请参阅 nginx#TLS。
也可以创建一个单独的配置文件,并将其包含在每个服务器块中
/etc/nginx/conf/001-certbot.conf
ssl_certificate /etc/letsencrypt/live/domain/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/domain/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf;
/etc/nginx/sites-available/example
server { listen 443 ssl http2; listen [::]:443 ssl http2; # Listen on IPv6 include conf/001-certbot.conf; .. }
Apache
certbot-apache 插件为 Apache HTTP 服务器 提供了自动配置。此插件将尝试检测每个域的配置设置。该插件添加了推荐用于安全性的额外配置、证书使用设置以及 Certbot 证书的路径。请参阅 #管理 Apache 虚拟主机 以获取示例。
首次设置 虚拟主机
# certbot --apache
续订证书
# certbot renew
更改证书而不修改 Apache 配置文件
# certbot --apache certonly
有关更多信息,请参阅 Arch Linux 上的 Certbot-Apache,并参阅 #自动续订 以保持已安装证书的有效性。
管理 Apache 虚拟主机
在手动管理这些文件时,以下示例可用于所有 虚拟主机
/etc/httpd/conf/extra/001-certbot.conf
<IfModule mod_ssl.c> <VirtualHost *:443> Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/'domain'/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/'domain'/privkey.pem </VirtualHost> </IfModule>
当 VirtualHost 由 certbot-apache 自动生成时,有时 'Include' 行可能会出现在两个 'SSLCertificate' 行之后。在这种情况下,从浏览器使用 http 访问 virtualHost 将无法工作,并出现 SSL_PROTOCOL_ERROR 错误。如果发生这种情况,只需将 Include 行放在两个 SSLCertificates 行之上并重启 httpd 即可。
/etc/httpd/conf/httpd.conf
<IfModule mod_ssl.c> Listen 443 </IfModule> Include conf/extra/001-certbot.conf ..
有关更多信息,请参阅 Apache HTTP 服务器#TLS。
Webroot
- Webroot 方法需要 端口 80 上的 HTTP 才能进行 Certbot 验证。
- 服务器名称必须与其对应的 DNS 相匹配。
- 可能需要在主机上更改权限,以允许读取访问
http://domain.tld/.well-known
。
使用 webroot 方法时,Certbot 客户端会将质询响应放置在 /path/to/domain.tld/html/.well-known/acme-challenge/
中,该路径用于验证。
建议使用此方法而不是手动安装;它提供自动续订和更轻松的证书管理。但是,由于 #插件 允许自动配置和安装,因此使用插件可能是首选。
映射 ACME-challenge 请求
通过将所有针对 .well-known/acme-challenge
的 HTTP 请求映射到单个文件夹(例如 /var/lib/letsencrypt
),可以更轻松地进行管理。
然后,该路径必须对 Cerbot 和 Web 服务器(例如,以用户 http 身份运行的 nginx 或 Apache HTTP 服务器)可写
# mkdir -p /var/lib/letsencrypt/.well-known # chgrp http /var/lib/letsencrypt # chmod g+s /var/lib/letsencrypt
nginx
创建一个包含 location 块的文件,并将其包含在服务器块内
/etc/nginx/conf.d/letsencrypt.conf
location ^~ /.well-known/acme-challenge/ { allow all; root /var/lib/letsencrypt/; default_type "text/plain"; try_files $uri =404; }
服务器配置示例
/etc/nginx/servers-available/domain.conf
server { server_name domain.tld .. include conf.d/letsencrypt.conf; }
Apache
创建文件 /etc/httpd/conf/extra/httpd-acme.conf
/etc/httpd/conf/extra/httpd-acme.conf
Alias /.well-known/acme-challenge/ "/var/lib/letsencrypt/.well-known/acme-challenge/" <Directory "/var/lib/letsencrypt/"> AllowOverride None Options MultiViews SymLinksIfOwnerMatch IncludesNoExec Require method GET POST OPTIONS </Directory>
将其包含在 /etc/httpd/conf/httpd.conf
中
/etc/httpd/conf/httpd.conf
Include conf/extra/httpd-acme.conf
获取证书
使用 /var/lib/letsencrypt/
作为公共可访问路径,为 domain.tld
请求证书
# certbot certonly --email email@example.com --webroot -w /var/lib/letsencrypt/ -d domain.tld
要添加(子)域名,请包含当前设置中使用的所有已注册域名
# certbot certonly --email email@example.com --webroot -w /var/lib/letsencrypt/ -d domain.tld,sub.domain.tld
续订(所有)当前证书
# certbot renew
请参阅 #自动续订 作为替代方法。
手动
如果您的 Web 服务器没有插件,请使用以下命令
# certbot certonly --manual
当首选使用 DNS 挑战(TXT 记录)时,请使用
# certbot certonly --manual --preferred-challenges dns
这将自动验证您的域名并创建私钥和证书对。它们放置在 /etc/letsencrypt/archive/your.domain/
中,并从 /etc/letsencrypt/live/your.domain/
符号链接。
然后,您可以手动配置您的 Web 服务器以引用符号链接目录中的私钥、证书和完整证书链。
/etc/letsencrypt/archive/your.domain/
中创建带有尾随编号的多组文件。Certbot 会自动更新 /etc/letsencrypt/live/your.domain/
中的符号链接,以指向文件的最新实例,因此无需更新您的 Web 服务器以指向新的密钥材料。DNS 挑战
对于未暴露于公共互联网的服务器,可以使用 DNS-01 挑战 来验证域名所有权
安装 您的 DNS 提供商的 certbot 插件 certbot-dns-*。以下示例展示了使用 certbot-dns-cloudflare 的 cloudflare。
创建凭据文件
/etc/certbot-cloudflare.creds.ini
dns_cloudflare_api_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
获取证书。
# chmod 600 /etc/certbot-cloudflare.creds.ini # certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/certbot-cloudflare.creds.ini -d domain.tld
certbot-renew.service
将使用上述凭据文件自动续订 #自动续订。有关获取 API 令牌和其他选项,请参阅 文档。
高级配置
自动续订
systemd
certbot 附带一个 systemd certbot-renew.service
,它尝试续订在 30 天内过期的证书。如果所有证书都未到期续订,则此服务不执行任何操作。
如果您不使用插件自动管理 Web 服务器配置,则每次续订证书时,都必须手动重新加载 Web 服务器以重新加载证书。这可以通过将 --post-hook "systemctl reload nginx.service"
添加到 ExecStart
命令 [1] 来完成。当然,如果适用,请使用 httpd.service
而不是 nginx.service
。可以根据需要将其他服务添加到 systemctl 命令,例如 systemctl reload httpd dovecot postfix
。
启用 并 启动 certbot-renew.timer
以每天检查两次证书续订,包括随机延迟,以便将每个人的续订请求分散到一天中,以减轻 Let's Encrypt 服务器负载 [2]。
通配符证书的自动续订
该过程相当简单。要颁发通配符证书,您必须通过 DNS 挑战请求,使用 ACMEv2 协议 来完成。
虽然手动颁发证书很容易,但对于自动化来说并不直接。DNS 挑战表示一个 TXT 记录,由 certbot 给出,必须在域区域文件中手动设置。
您需要在每次续订时更新区域文件。为了避免手动执行此操作,您可以使用 RFC 2136,certbot 为其提供了一个打包在 certbot-dns-rfc2136 中的插件。您还需要配置 DNS 服务器以允许对 TXT 记录进行动态更新。
配置 BIND 以使用 rfc2136
生成 TSIG 密钥
$ tsig-keygen -a HMAC-SHA512 example-key
并将其添加到配置文件中
/etc/named.conf
... zone "domain.ltd" IN { ... // this is for certbot update-policy { grant example-key name _acme-challenge.domain.ltd. txt; }; ... }; key "example-key" { algorithm hmac-sha512; secret "a_secret_key"; }; ...
重启 named.service
。
配置 certbot 以使用 rfc2136
安装 certbot-dns-rfc2136,然后为其创建一个配置文件。
/etc/letsencrypt/rfc2136.ini
dns_rfc2136_server = IP.ADD.RE.SS dns_rfc2136_name = example-key dns_rfc2136_secret = INSERT_KEY_WITHOUT_QUOTES dns_rfc2136_algorithm = HMAC-SHA512
由于该文件包含密钥的副本,请使用 chmod 删除组和其他人的权限来保护它。
测试我们所做的
# certbot certonly --dns-rfc2136 --force-renewal --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini --server https://acme-v02.api.letsencrypt.org/directory --email example@domain.ltd --agree-tos --no-eff-email -d 'domain.ltd' -d '*.domain.ltd'
如果您成功通过验证并收到证书,那么您就可以自动化 certbot 了。否则,出现了一些错误,您需要调试您的设置。从现在开始,它基本上归结为运行 certbot renew
,请参阅 #自动续订。
将证书部署到应用程序
certbot 将证书保存在 /etc/letsencrypt/live
下。此目录只能由 root 用户读取。可以使用部署 hook 脚本在证书续订时将证书复制到应用程序目录。
示例脚本,用于将证书复制到应用程序的状态目录,并使用正确的权限重启应用程序服务。使用可执行权限创建以下脚本。
/etc/letsencrypt/renewal-hooks/deploy/myapp_cert_copy.sh
#!/bin/sh set -eu if [ "$RENEWED_DOMAINS" = "myapp.mydomain.com" ] then app=myapp appuser=$app certpath="/var/lib/$app/certs" mkdir -p "$certpath" chmod 750 "$certpath" chown $appuser:$appuser "$certpath" install -o "$appuser" -g "$appuser" -m 444 "$RENEWED_LINEAGE/fullchain.pem" -t "$certpath" install -o "$appuser" -g "$appuser" -m 400 "$RENEWED_LINEAGE/privkey.pem" -t "$certpath" systemctl restart $app.service echo "$(date) Renewed and deployed certificates for $app" >> /var/log/cert-renew.log fi
如果证书已生成,则可以使用此命令运行部署脚本以复制证书,而无需重新生成新证书
$ certbot certonly -d myapp.mydomain.com --run-deploy-hooks --dry-run
参见
- Acme.sh 替代 ACME 客户端,支持 Let's Encrypt
- 传输层安全性#ACME 客户端
- EFF 的 Certbot 文档
- Let's Encrypt – ACME 客户端列表