本文最后更新于 2022年03月21日
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 acme nginx
这里推荐一下我基于官方docker nginx编译添加模块的NGINX,可以直接开启brotli压缩。
具体如何操作我写在了注释里,非常简单,唯一需要注意的一点就是,在还未生成证书之前,不要修改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
初撰本文时,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; }
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
Docker 下,a container to another container 的部署方式结果与配置不一致
原文链接:https://sleele.com/2021/04/15/docker-acme-with-docker-nginx/