[mark]First application[/mark]
[h2title]make web directory:[/h2title]
mkdir -p /letsencrypt/site
#这里以静态网页为例,也可以设为反向代理。
[h2title]make docker-compose file:[/h2title]
vim /letsencrypt/docker-compose.yml
docker-compose.yml :
version: '3.1'
services:
demo-site:
container_name: 'demo-site'
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./site:/usr/share/nginx/html
networks:
- docker-network
networks:
docker-network:
driver: bridge
[h2title]make nginx file:[/h2title]
vim /letsencrypt/nginx.conf
nginx.conf :
server {
listen 80;
server_name example.com www.example.com;
location ~ /.well-known/acme-challenge {
allow all;
root /usr/share/nginx/html;
}
root /usr/share/nginx/html;
index index.html;
}
start web server:
cd /letsencrypt && docker-compose up -d
[h2title]run Certbot:[/h2title]
docker run --rm -it \
-v /letsencrypt/certbot/etc/letsencrypt:/etc/letsencrypt \ # 证书申请工作目录
-v /letsencrypt/certbot/var/log/letsencrypt:/var/log/letsencrypt \ # 日志记录
-v /letsencrypt/site:/data/letsencrypt \ # ACME验证token目录,与nginx服务器共享
certbot/certbot \
certonly --webroot \ # 指定ACME验证方式:token文件验证
--email [email protected] --agree-tos --no-eff-email \ # 申请者邮件
--webroot-path=/data/letsencrypt \ # ACME验证token文件放置目录
-d example.com -d www.example.com # 指定要申请证书的域名列表
如果脚本正常运行,可以在/letsencrypt/certbot/etc/letsencrypt/live下找到example.com文件夹,其中包含申请成功的证书文件:fullchain.pem和privkey.pem。
[h2title]stop web server:[/h2title]
cd /letsencrypt && docker-compose down
[h2title]update docker-compose :[/h2title]
version: '3.1'
services:
demo-site:
container_name: 'demo-site'
image: nginx:alpine
ports:
- "80:80" # 保留80端口,用于证书更新
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./site:/usr/share/nginx/html
- ./certbot/etc/letsencrypt/live:/letsencrypt/live # 当前证书目录
- ./certbot/etc/letsencrypt/archive:/letsencrypt/archive # 历史证书目录
- ./dhparam-2048.pem:/letsencrypt/dhparam-2048.pem # 使用2048位DH(Diffie-Hellman)参数,生成方法在下面
networks:
- docker-network
networks:
docker-network:
driver: bridge
生成 2048 位的 DH 参数文件命令如下:
openssl dhparam -out /letsencrypt/dhparam-2048.pem 2048
live 目录的证书会 soft link 到 archive 目录,而 docker 对 soft link 支持不好,因此需要同时映射 live 和 archive 目录。
[h2title]更新 nginx 配置,启用 HTTPS:[/h2title]
server {
listen 80;
server_name example.com www.example.com;
# 重定向到https
location / {
rewrite ^ https://$host$request_uri? permanent;
}
# 高优先级,仅用于更新证书
location ~ /.well-known/acme-challenge {
allow all;
root /usr/share/nginx/html;
}
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
server_tokens off;
ssl on;
ssl_certificate /letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /letsencrypt/live/example.com/privkey.pem;
ssl_buffer_size 8k;
ssl_dhparam /letsencrypt/dhparam-2048.pem; # 使用2048位DH参数,加强安全
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
root /usr/share/nginx/html;
index index.html;
}
DH 以及 OCSP 内容请参考:Strong SSL Security On nginx
[h2title]重新启动 web 服务器:[/h2title]
cd /letsencrypt && docker-compose up -d
[mark]更新证书[/mark]
[h2title]设置更新脚本:[/h2title]
touch /letsencrypt/renew.sh
chmod +x /letsencrypt/renew.sh
vim /letsencrypt/renew.sh
[h2title]renew.sh 脚本内容如下:[/h2title]
#!/bin/bash
docker run -i --rm \
-v /letsencrypt/certbot/etc/letsencrypt:/etc/letsencrypt \
-v /letsencrypt/certbot/var/lib/letsencrypt:/var/lib/letsencrypt \
-v /letsencrypt/certbot/var/log/letsencrypt:/var/log/letsencrypt \
-v /letsencrypt/site:/data/letsencrypt \
certbot/certbot \
renew --webroot -w /data/letsencrypt --quiet && docker kill --signal=HUP demo-site
最后一行脚本说明:在更新完证书后,通知 nginx 重新加载配置。
[h2title]通过 crontab 设置定时任务:[/h2title]
crontab -e
添加一行,每周执行一次更新脚本:
0 1 * * 0 /letsencrypt/renew.sh >> /tmp/renew_cerbot.txt 2>&1