2022.03.21更新 ACME ECC RSA双证书
本站在迁移服务器后,决定在新环境中把所有服务都使用docker部署。这不难,甚至可以说是很方便,因为之前除了NGINX外,基本所有服务都是通过docker部署的。为啥之前没有用docker nginx?因为一直用certbot,certbot太方便了。
目录
借着这次迁移站点,正好研究一下docker acme
之前一直不知道acme怎么能够操作docker nginx,因为容器是互相隔离的,谁也看不见谁的进程,觉得可能需要写一个脚本,通过宿主机来定时重启NGINX容器,但是在偶然间,搜索到了一个issue,发现原来docker acme是可以操作docker nginx的。
Docker 下,a container to another container 的部署方式结果与配置不一致 https://github.com/acmesh-official/acme.sh/issues/2400
于是乎按照这位老哥的配置,简单修改了一下,便成功了。
快速部署docker acme nginx
这里推荐一下我基于官方docker nginx编译添加模块的NGINX,可以直接开启brotli压缩。
https://github.com/SuperNG6/docker-nginx
具体如何操作我写在了注释里,非常简单,唯一需要注意的一点就是,在还未生成证书之前,不要修改NGINX配置文件,以免NGINX不停报错重启。
这里推荐使用dns验证,可以不占用80端口
version: '3.1'
services:
nginx:
image: superng6/nginx:debian-stable-1.18.0
container_name: docker_nginx
restart: unless-stopped
network_mode: host
labels:
- 'docker_nginx'
volumes:
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
- /var/www/html:/var/www/html
- /root/nginx/nginx.conf:/etc/nginx/nginx.conf
- /root/nginx/conf.d:/etc/nginx/conf.d
- /root/nginx/ssl:/etc/nginx/ssl
- /root/nginx/logs:/var/log/nginx
acme:
image: neilpang/acme.sh
container_name: acme
restart: unless-stopped
environment:
DP_Id: '这里填dnspod id'
DP_Key: '这里填dnspod key'
DEPLOY_DOCKER_CONTAINER_LABEL: 'docker_nginx'
DEPLOY_DOCKER_CONTAINER_KEY_FILE: '/etc/nginx/ssl/all.sleele.com/sleele.com.key'
DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE: '/etc/nginx/ssl/all.sleele.com/fullchain.cer'
DEPLOY_DOCKER_CONTAINER_RELOAD_CMD: 'nginx -s reload'
volumes:
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /root/nginx/acme.sh:/acme.sh
- /root/nginx/ssl:/etc/nginx/ssl
command: daemon
# 首次运行先进入容器生成证书
# acme.sh --issue --dns dns_dp -d sleele.com -d *.sleele.com
# docker exec -i acme acme.sh --issue --dns dns_dp -d sleele.com -d *.sleele.com
# 然后部署证书到指定文件夹
# acme.sh --deploy -d sleele.com --deploy-hook docker
# docker exec -i acme acme.sh --deploy -d sleele.com --deploy-hook docker
2022.03.21更新 acme换用zero ssl 首次使用需注册邮箱
初撰本文时,acme还没有使用zero ssl,随着版本迭代,acme.sh换用了zero ssl,首次使用必须要注册邮箱才可以
docker exec -i acme-rsa acme.sh --register-account -m my@example.com
首次运行先生成泛域名证书,然后再部署证书
docker exec -i acme acme.sh --issue --dns dns_dp -d 你的域名.com -d *.你的域名.com
docker exec -i acme acme.sh --deploy -d 你的域名.com --deploy-hook docker
所有二级域名都可以使用这个证书,所以NGINX里每个站点的配置文件都指向这个证书就可以了
NGINX HTTPS CONF
这里给两个,一个反向代理,一个正向代理。
反向代理
# generated 2021-03-27, Mozilla Guideline v5.6, nginx 1.18.0, OpenSSL 1.1.1d, intermediate configuration
# https://ssl-config.mozilla.org/#server=nginx&version=1.18.0&config=intermediate&openssl=1.1.1d&guideline=5.6
server {
listen 80;
listen [::]:80;
server_name 你到域名;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name 你到域名;
location / {
proxy_pass http://你要反代的ip:端口;
proxy_redirect off;
# 保证获取到真实IP
proxy_set_header X-Real-IP $remote_addr;
# 真实端口号
proxy_set_header X-Real-Port $remote_port;
# X-Forwarded-For 是一个 HTTP 扩展头部。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 在多级代理的情况下,记录每次代理之前的客户端真实ip
proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr;
# 获取到真实协议
proxy_set_header X-Forwarded-Proto $scheme;
# 真实主机名
proxy_set_header Host $host;
# 设置变量
proxy_set_header X-NginX-Proxy true;
# 开启 brotli
proxy_set_header Accept-Encoding "";
}
# 日志
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# 证书
ssl_certificate /etc/nginx/ssl/all.sleele.com/fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/all.sleele.com/sleele.com.key;
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
ssl_dhparam /etc/nginx/ssl/dhparam;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/nginx/ssl/all.sleele.com/fullchain.cer;
# replace with the IP address of your resolver
resolver 223.5.5.5;
resolver_timeout 5s;
}
正向代理
# generated 2021-03-27, Mozilla Guideline v5.6, nginx 1.18.0, OpenSSL 1.1.1d, intermediate configuration
# https://ssl-config.mozilla.org/#server=nginx&version=1.18.0&config=intermediate&openssl=1.1.1d&guideline=5.6
server {
listen 80;
listen [::]:80;
server_name tk.sleele.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name tk.sleele.com;
location / {
root /var/www/html/aria2-trackers;
index index.html;
}
# 日志
access_log /var/log/nginx/tk-access.log;
error_log /var/log/nginx/tk-error.log;
# 证书
ssl_certificate /etc/nginx/ssl/all.sleele.com/fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/all.sleele.com/sleele.com.key;
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
ssl_dhparam /etc/nginx/ssl/dhparam;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/nginx/ssl/all.sleele.com/fullchain.cer;
# replace with the IP address of your resolver
resolver 223.5.5.5;
resolver_timeout 5s;
}
nginx.conf
load_module /usr/local/nginx/modules/ngx_http_brotli_filter_module.so;
load_module /usr/local/nginx/modules/ngx_http_brotli_static_module.so;
load_module /usr/local/nginx/modules/ngx_http_cache_purge_module.so;
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_session_cache shared:SSL:50m; # speed up first time. 1m ~= 4000 connections
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv1, ref: POODLE
ssl_prefer_server_ciphers on;
ssl_ciphers 'TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5'; ssl_prefer_server_ciphers on;
ssl_buffer_size 4k;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
client_max_body_size 2048M;
proxy_max_temp_file_size 2048M;
# Enable Gzip compression
gzip on;
# Compression level (1-9)
gzip_comp_level 5;
gzip_static on;
# Don't compress anything under 256 bytes
gzip_min_length 256;
# Compress output of these MIME-types
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-font-opentype
application/x-font-truetype
application/x-javascript
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/eot
font/opentype
font/otf
image/svg+xml
image/x-icon
image/vnd.microsoft.icon
text/css
text/plain
text/javascript
text/x-component;
# Disable gzip for bad browsers
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
brotli on;
brotli_comp_level 5;
brotli_static on;
brotli_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-font-opentype
application/x-font-truetype
application/x-javascript
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/eot
font/opentype
font/otf
image/svg+xml
image/x-icon
image/vnd.microsoft.icon
text/css
text/plain
text/javascript
text/x-component;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
推荐设置
为了让NGINX的使用体验更接近宿主机上的nginx,建议设置别名,这样就和本机安装的NGINX使用起来无异了
sudo vim ~/.bashrc
# 添加如下内容,保存
alias nginx='docker exec -i docker_nginx nginx'
查看效果
部署完证书后,就可以修改NGINX配置文件了,之后nginx -s reload
,查看效果
之后就就不用再理会了,证书快到期后会自动续订,并重载NGINX
2022.03.21更新 ACME ECC RSA双证书
介绍就不多说了,ECC更快更节能,兼容性方面,在2022这个节点,已经没有任何问题了,不过为了保险还是双证书吧
注意:第一次需要用,需要用自己的邮箱注册 zero ssl
docker exec -i acme-ecc acme.sh --register-account -m my@example.com
docker exec -i acme-rsa acme.sh --register-account -m my@example.com
先部署acme容器后,再执行上面👆🏻的操作
version: "3.4"
services:
nginx:
image: superng6/nginx:stable-1.20.2
container_name: docker_nginx
restart: unless-stopped
network_mode: host
labels:
- "docker_nginx"
volumes:
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
- /root/nginx/www/html:/var/www/html
- /root/nginx/nginx.conf:/etc/nginx/nginx.conf
- /root/nginx/conf.d:/etc/nginx/conf.d
- /root/nginx/ssl:/etc/nginx/ssl
- /root/nginx/logs:/var/log/nginx
acme-rsa:
image: neilpang/acme.sh
container_name: acme-rsa
restart: unless-stopped
environment:
DP_Id: "*"
DP_Key: "*"
DEPLOY_DOCKER_CONTAINER_LABEL: "docker_nginx"
DEPLOY_DOCKER_CONTAINER_KEY_FILE: "/etc/nginx/ssl/all.sleele.com/sleele.com.key"
DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE: "/etc/nginx/ssl/all.sleele.com/fullchain.cer"
DEPLOY_DOCKER_CONTAINER_RELOAD_CMD: "nginx -s reload"
volumes:
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /root/nginx/acme.sh:/acme.sh
- /root/nginx/ssl:/etc/nginx/ssl
command: daemon
# 首次运行先进入容器生成证书
# docker exec -i acme-rsa acme.sh --issue --dns dns_dp -d sleele.com -d *.sleele.com
# 然后部署证书到制定文件夹
# acme.sh --deploy -d sleele.com --deploy-hook docker
# docker exec -i acme-rsa acme.sh --deploy -d sleele.com --deploy-hook docker
acme-ecc:
image: neilpang/acme.sh
container_name: acme-ecc
restart: unless-stopped
environment:
DP_Id: "*"
DP_Key: "*"
DEPLOY_DOCKER_CONTAINER_LABEL: "docker_nginx"
DEPLOY_DOCKER_CONTAINER_KEY_FILE: "/etc/nginx/ssl/all.sleele.com.ecc/sleele.com.key"
DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE: "/etc/nginx/ssl/all.sleele.com.ecc/fullchain.cer"
DEPLOY_DOCKER_CONTAINER_RELOAD_CMD: "nginx -s reload"
volumes:
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /root/nginx/acme.sh.ecc:/acme.sh
- /root/nginx/ssl:/etc/nginx/ssl
command: daemon
# 首次运行先进入容器生成证书
# acme.sh --issue --dns dns_dp -d sleele.com -d *.sleele.com
# 第一次需要用自己的邮箱注册 docker exec -i acme-ecc acme.sh --register-account -m my@example.com
# docker exec -i acme-ecc acme.sh --issue --dns dns_dp -d sleele.com -d *.sleele.com --keylength ec-256
# 然后部署证书到指定文件夹
# acme.sh --deploy -d sleele.com --deploy-hook docker
# docker exec -i acme-ecc acme.sh --deploy -d sleele.com --ecc --deploy-hook docker
参考资料
acme deploy-to-docker-containers
https://github.com/acmesh-official/acme.sh/wiki/deploy-to-docker-containers
Docker 下,a container to another container 的部署方式结果与配置不一致
https://github.com/acmesh-official/acme.sh/issues/2400
本文由 NG6 于2021年04月15日发表在 sleele的博客
如未特殊声明,本站所有文章均为原创;你可以在保留作者及原文地址的情况下转载
转载请注明:使用docker acme申请、续订泛域名证书,并自动重载docker nginx | sleele的博客
优质文章!
大佬你好!
文章开头提到:“发现原来docker acme是可以操作docker nginx的”
请问acme在什么时候会操作docker nginx呀?是在续签新证书的时候自动reload了nginx嘛?
一个 acme.sh docker 容器只能绑定一个域名是吧?
希望博主能在docker-compose文件中把acme相关的设置加上
network mode: host
,因为docker容器默认的网络是隔离的,这样docker容器时无法访问外网的,自然而然证书也就没法生成了,不知道有没有其他用户也遇到过这样的问题@zayac 没有遇到这个问题,默认情况下,docker创建的桥接网络是可以连接外网的,none模式没有网络
以前一直用Nginx Proxy Manager这个图形化的docker来搞定Nginx+证书的事,后来越用越觉得有不足,但是搞成宿主机直接用Nginx和acme,又觉得迁移资料的时候不方便,而且没有隔离。楼主的这个很不错,我去学习学习!
大佬,两年前第一次用ARIA2就是用的您的前端,现在想转成docker+ HTTPS,可是按您帖子没成功,您可以录屏做个教程吗。非常感谢。
@大神好 这个教程的难度太高了,对docker和nginx没有一个比较全面的认知还是不要搞了
换其他的方法吧,比如freessl弄一个一年的免费证书,然后修改一下我那个反代的配置文件就好了
大佬,我没安装成功,请教下这是什么问题。
Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: rootfs_linux.go:76: mounting “/root/nginx/nginx.conf” to rootfs at “/etc/nginx/nginx.conf” caused: mount through procfd: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type
@大神好 挂载路径错了,没有这个文件或路径
赞,注释很详细。 能转载么?
@bloodking 可以,注明出处和链接即可