使用docker acme申请、续订泛域名证书,并自动重载docker nginx

admin

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,查看效果

XJuG6B
4uSOJi

之后就就不用再理会了,证书快到期后会自动续订,并重载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

1.296890s