我有一个带有Nginx docker容器的应用程序,它的TLS证书是在部署应用程序的主机(具有Ubuntu OS)中使用以下命令手动生成的:
certbot certonly --manual --manual-public-ip-logging-ok --preferred-challenges dns -d my.app.com
当证书过期时,我必须续订它们。
但是我不能使用下面的certbot renew
命令来达到这个目的,因为它会给出一个错误:
$ sudo certbot renew
Failed to renew certificate my.app.com with error: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.')
因此,我现在要做的是再次创建证书(使用之前使用的相同certbot certonly
命令),而不是续订它们。
如何使用certbot renew
命令修复此错误?
如何自动执行此设置?
发布于 2021-03-15 21:28:08
这是我的设置。它涉及在nginx和certbot之间共享的docker卷中的LE秘密,以及nginx将续订请求代理到certbot,因此在certbot进行验证时,您不必停止nginx。
nginx设置
对certbot后端的代理验证
端口80上的letsencrypt验证请求被转发到certbot,其他任何请求都被重定向到https。(如果您想知道为什么我将代理传递后端定义为变量,请参阅this SO answer)
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location /.well-known/acme-challenge {
resolver 127.0.0.11 valid=30s;
set $upstream letsencrypt;
proxy_pass http://$upstream:80;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto https;
}
location / {
return 301 https://$host$request_uri;
}
}
SSL设置
这里有很多标准的东西:
server {
listen 443 ssl;
server_name ${DOMAINNAME};
ssl_certificate /etc/letsencrypt/live/${DOMAINNAME}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${DOMAINNAME}/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2;
ssl_ciphers 'EECDH+AESGCM: EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_dhparam dhparam.pem;
... your lcoation block goes here ...
}
docker-compose magic
certbot
对单次运行certbot有一个特殊的"docker-compose-LE.yml“:
version: '3.4'
services:
letsencrypt:
image: certbot/certbot:latest
command: sh -c "certbot certonly --standalone -d ${DOMAINNAME} --text --agree-tos --email you@example.com --server https://acme-v02.api.letsencrypt.org/directory --rsa-key-size 4096 --verbose --keep-until-expiring --preferred-challenges=http"
entrypoint: ""
volumes:
- "letsencrypt:/etc/letsencrypt"
environment:
- TERM=xterm
volumes:
letsencrypt:
name: letsencrypt_keys
通过运行"docker-compose -f docker-compose-LE.yml up“,您将创建并验证证书。您可以使用相同的命令来续订证书,certbot非常智能。您可以随心所欲地运行此命令(每天),因为它只会在证书即将到期时续订。
在第一次运行此命令之前,请参阅下面的“警告”。
nginx
在docker-compose.yml中,从一个卷挂载证书。该卷已由letsencrypt创建,因此将其声明为外部卷。
services:
nginx:
image: nginx:1.18
restart: always
volumes:
- letsencrypt:/etc/letsencrypt:ro
volumes:
letsencrypt:
external:
name: letsencrypt_keys
注意事项
这种方法在第一次创建证书时会导致鸡蛋问题:如果没有证书文件,nginx将无法启动,也无法代理LE验证。没有nginx意味着没有证书,没有证书意味着没有nginx。
为了解决这个问题,你必须在没有nginx的情况下第一次调用certbot,并使用certbots内部暴露的http服务器。因此,第一次运行certbot时,将以下行添加到docker-compose-LE.yml:
letsencrypt:
ports:
- "80:80"
证书续订
只需在每日cronjob中运行这两个命令:
docker-compose -f docker-compose-LE.yml up
将检查证书并在证书到期后开始续订过程。现在运行的nginx将代理certbot的认证验证。
docker-compose exec nginx nginx -s reload
一旦证书在docker卷certbot和nginx共享中就地更新,只需向nginx发送一个SIGHUP,这样它就可以在不中断服务的情况下重新加载证书文件。
https://stackoverflow.com/questions/66638368
复制相似问题