惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
Security Archives - TechRepublic
Security Archives - TechRepublic
V
Vulnerabilities – Threatpost
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Proofpoint News Feed
G
GRAHAM CLULEY
P
Privacy International News Feed
The Hacker News
The Hacker News
Forbes - Security
Forbes - Security
U
Unit 42
N
News and Events Feed by Topic
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Cisco Blogs
A
About on SuperTechFans
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
D
Docker
I
Intezer
Spread Privacy
Spread Privacy
The Last Watchdog
The Last Watchdog
V2EX - 技术
V2EX - 技术
S
Security @ Cisco Blogs
F
Full Disclosure
S
Secure Thoughts
M
MIT News - Artificial intelligence
Microsoft Security Blog
Microsoft Security Blog
G
Google Developers Blog
aimingoo的专栏
aimingoo的专栏
W
WeLiveSecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Project Zero
Project Zero
Recorded Future
Recorded Future
Cyberwarzone
Cyberwarzone
S
Security Affairs
AWS News Blog
AWS News Blog
H
Help Net Security
The GitHub Blog
The GitHub Blog
Hacker News: Ask HN
Hacker News: Ask HN
Vercel News
Vercel News
P
Proofpoint News Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The Register - Security
The Register - Security
S
Schneier on Security
F
Fortinet All Blogs
C
CERT Recently Published Vulnerability Notes
L
LINUX DO - 最新话题
T
Tor Project blog
T
The Exploit Database - CXSecurity.com
MongoDB | Blog
MongoDB | Blog
Webroot Blog
Webroot Blog

轶哥博客

blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog
blog
2020-03-07 · via 轶哥博客

MySQL定时备份程序中我有提到一个基于Docker快速生成SSL证书的方式。该文章整理了该方案的详细教程。

基于Let's Encrypt免费SSL证书。

官方介绍

docker-letsencrypt-nginx-proxy-companion

官方示例

使用方法

非docker-compose模式下。

第一步:执行下述两条命令

docker run --detach \
    --name nginx-proxy \
    --publish 80:80 \
    --publish 443:443 \
    -e ENABLE_IPV6=true \
    --volume /etc/nginx/certs \
    --volume /etc/nginx/vhost.d \
    --volume /usr/share/nginx/html \
    --volume /var/run/docker.sock:/tmp/docker.sock:ro \
    jwilder/nginx-proxy

docker run --detach \
    --name nginx-proxy-acme \
    --volumes-from nginx-proxy \
    --volume /var/run/docker.sock:/var/run/docker.sock:ro \
    --volume acme:/etc/acme.sh \
    --env "DEFAULT_EMAIL=mail@yourdomain.tld" \
    nginxproxy/acme-companion

第二步:启动项目时加上相关环境变量

以Nginx静态资源站点为例:

docker run -itd --restart always \
      -v 你的静态资源文件:/usr/share/nginx/html \
    --env "VIRTUAL_PORT=80" \
    --env "VIRTUAL_HOST=你的域名" \
    --env "LETSENCRYPT_HOST=你的域名" \
    nginx

此时,直接访问LETSENCRYPT_HOST中的域名,显示证书正常即可(可能有一分钟左右延迟)。

第三步:重复第二步

是不是很简单,几乎零配置,连修改nginx配置的工夫都省了。

环境变量说明

VIRTUAL_PORT:您的项目监听的端口。这里有个坑,某些情况下监听端口不一定成功。建议每次暴露内部端口,例如增加-p 80参数,确保监听一定成功。详见Node.js示例。

VIRTUAL_HOST:站点域名,可多个,以英文逗号分割。

LETSENCRYPT_HOST:申请SSL证书的域名,可多个,以英文逗号分割。

LETSENCRYPT_EMAIL:通知邮箱,选填。(很多情况下填了也没用)

docker-compose示例参考:https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/blob/master/docs/Docker-Compose.md

更多示例用法

Node.js 项目

docker run -itd --name appointment-service --restart always \
    -m 1024m \
    --link mysql:mysql \
    -p 80 \
    --env "VIRTUAL_PORT=80" \
    --env "VIRTUAL_HOST=appointment.api.ykfz.pw" \
    --env "LETSENCRYPT_HOST=appointment.api.ykfz.pw" \
    -v /etc/localtime:/etc/localtime:ro \
    -v /root/site/appointment-service:/root \
    -w /root \
    --restart=always node:13.7.0 npm start

说明:-p 80参数将明确暴露容器内80端口,随机转发到宿主机某一端口。缺少该参数将可能导致监听失败出现502报错

泛解析用法

由于申请免费通配符证书需要ACMEv2支持,以上方法暂不适用于通配符域名(原因 2021年08月25日14:03:29更新:nginxproxy/acme-companion 或已经支持泛域名。

解决思路:

  1. 参考另外一篇博文配置自动续期的免费通配符SSL证书
  2. 未测试的方案:https://github.com/adferrand/docker-letsencrypt-dns
  3. 推荐搭配acme.sh实现该需求。

思路3具体操作如下:

  1. 按照acme.sh说明安装acme.sh。通常只需要执行curl https://get.acme.sh | sh命令。
  2. 根据https://github.com/acmesh-official/acme.sh/wiki/dnsapi 寻找你的域名DNS提供商,参照说明配置API账号。例如腾讯云则参考DNSPod配置方式,阿里云则参考第十一条Aliyun的配置方式。如果您使用的DNS解析提供商不在该列表,可以在github搜搜看。
  3. 生成SSL证书。例如acme.sh --issue --dns dns_dp -d *.app.ykfz.pw

将得到:

[2020年 03月 07日 星期六 21:40:19 CST] Your cert is in  /root/.acme.sh/*.app.ykfz.pw/*.app.ykfz.pw.cer
[2020年 03月 07日 星期六 21:40:19 CST] Your cert key is in  /root/.acme.sh/*.app.ykfz.pw/*.app.ykfz.pw.key
[2020年 03月 07日 星期六 21:40:19 CST] The intermediate CA cert is in  /root/.acme.sh/*.app.ykfz.pw/ca.cer
[2020年 03月 07日 星期六 21:40:19 CST] And the full chain certs is there:  /root/.acme.sh/*.app.ykfz.pw/fullchain.cer
  1. 下载此代码https://gist.github.com/yi-ge/6c13dfddabd128a630bea9481ac8fb98nginx.tmpl文件或参考jtegtmeier提供的配置方法:https://github.com/nginx-proxy/nginx-proxy/commit/07655df85884b4ee7937a422ccd33b413b584a02

感谢jtegtmeier提供的方案!

  1. 以类似下述命令的方式启动nginx-proxy
docker run --detach \
    --name nginx-proxy \
    --publish 80:80 \
    --publish 443:443 \
    --volume /etc/nginx/certs \
    --volume /etc/nginx/vhost.d \
    --volume /usr/share/nginx/html \
    --volume /var/run/docker.sock:/tmp/docker.sock:ro \
    -v `pwd`/nginx.tmpl:/app/nginx.tmpl \
    -v /root/.acme.sh:/root/.acme.sh \
    jwilder/nginx-proxy

增加了acme路径映射,请确保nginx.tmpl在执行文件的目录下。

  1. 增加环境变量配置并启动容器。
docker run -itd -m 1024m \
  --restart=always \
  --name appointment-ui \
  -v /root/site/appointment-ui:/usr/share/nginx/html \
  --env "VIRTUAL_HOST=*.app.ykfz.pw" \
  --env "CERT_PATHNAME=/root/.acme.sh/*.app.ykfz.pw/*.app.ykfz.pw.cer" \
  --env "PRIVATE_KEY_PATHNAME=/root/.acme.sh/*.app.ykfz.pw/*.app.ykfz.pw.key" \
  --env "CHAIN_PATHNAME=/root/.acme.sh/*.app.ykfz.pw/fullchain.cer" \
  nginx 

请参考第二步得到的证书,对应设置证书路径。

Custom pathnames are set on the virtual hosts using these environment variables:

  • CERT_PATHNAME=/path/to/cert
  • PRIVATE_KEY_PATHNAME=/path/to/key
  • CHAIN_PATHNAME=/path/to/chain

注意,此处有个坑。请检查crontab配置,在自动更新SSL证书的配置下方增加nginx重启指令。

例如:

49 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
55 0 * * * /usr/bin/docker restart nginx-proxy

如果未使用nginx-proxy(即使用的是本地nginx),则参考添加如下命令:

17 0 1 * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
22 0 1 * * /use/sbin/nginx -s reload

配置完毕。

总结: 免费泛解析SSL证书必须修改DNS进行验证,每个季度一次。无论是手工修改DNS还是通过DNS API,都请做一个TODO List,在3个月后检查一下自己的网站是否正常运行。