使用 nginx 的 docker certbot 容器检索证书时的用户权限问题



我意识到这个问题写得有多糟糕,所以我重写了整个问题和一个解决方案。

TLDR:我想要一个关于如何让 docker certbot/certbot 容器检索到的 letsencrypt 证书和密钥被 nginx:latest 容器读取的解决方案或建议。

它不可读的原因是证书存储在文件夹中,通常是/etc/letsencrypt/archive/domain/certificate,文件夹存档的所有者设置为 root,组设置为 root,模式为 0700。此外,密钥还将所有者设置为根,组设置为根,模式为 0600。

nginx容器将pid 0设置为nginx主进程并由root运行,但它生成了一个需要读取证书和密钥的工作进程。此工作进程由非特权用户拥有。

DOCKER-COMPOSE 配置

---
version: '3'
services:
nginx:
container_name: nginx
image: nginx:latest
ports:
- 80:80
- 443:443
volumes:
- ./data/nginx/conf:/etc/nginx/conf.d
# The volume under is to provide the DHPARAM file.
- ./data/nginx/tls:/etc/pki/tls
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
# This reloads the certificates every 24h as long as the container is running
command: "/bin/sh -c 'while :; do sleep 24h & wait $${!}; nginx -s reload; done & nginx -g "daemon off;"'"
#  certbot:
#    container_name: certbot
#    image: certbot/certbot
#    volumes:
#      - ./data/certbot/conf:/etc/letsencrypt
#      - ./data/certbot/www:/var/www/certbot
#    depends_on:
#      - nginx
#    # This checks if the certificates need to be renewed every 12 hours.
#    entrypoint: "/bin/sh -c "trap exit TERM; while :; do certbot renew; #sleep 12h & wait $${!}; done;""

NGINX配置

server {
listen 80 default_server;
server_name _;
location /.well-known/acme-challenge/ {
allow all;
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}

我已经排除了配置中不必要的行。在对证书进行初始重新竞争后,我将删除 yaml 文件中的注释,以便 certbot 容器在下次我执行 docker-compose up -d 时自动检索新证书。

启动nginx容器后运行的命令。

docker run -it --rm 
-v /FQPN/certbot/conf:/etc/letsencrypt 
-v /FQPN/certbot/www:/var/www/certbot 
certbot/certbot certonly 
-m EMAILADDRESS 
--webroot 
--agree-tos 
--webroot-path=/var/www/certbot 
-d DOMAIN

通过您在上面看到的内容,我获得了有效的证书,但它们只能由 root 读取。

我希望此设置在需要时检索新证书,但是如果我手动更改将其限制为仅root的文件夹/文件的所有权和模式,那么在检索新证书时,这些更改将被撤消。

我想要一个解决方案,以便非特权nginx用户可以读取这些证书和密钥,而无需在检索新证书时进行手动工作。

我检查了certbot中是否有有用的选项。在做完certbot --help之后,我看到有一个certbot -h all选项,它为您提供了certbot的每一个选项。

在那里,我发现了一个后钩子选项,该选项仅在成功检索新证书时运行。

解决方案是更改 docker-compose yaml 文件中的以下行。

entrypoint: "/bin/sh -c "trap exit TERM; while :; do certbot renew; #sleep 12h & wait $${!}; done;""

我将其更改为以下内容。

entrypoint: "/bin/sh -c "trap exit TERM; while :; do certbot renew --post-hook 'chown root:NGINXUID /etc/letsencrypt/live /etc/letsencrypt/archive && chmod 750 /etc/letsencrypt/live /etc/letsencrypt/archive && chown root:NGINXUID /etc/letsencrypt/archive/DOMAIN/privkey*.pem && chmod 640 /etc/letsencrypt/archive/DOMAIN/privkey*.pem'; sleep 12h & wait $${!}; done;""

最新更新