- 更新:2021-08-25 14:04:29
- 首发:2020-03-07 23:39:33
- 教程
- 7534
在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 或已经支持泛域名。
解决思路:
- 参考另外一篇博文配置自动续期的免费通配符SSL证书。
- 未测试的方案:https://github.com/adferrand/docker-letsencrypt-dns
- 推荐搭配acme.sh实现该需求。
思路3具体操作如下:
- 按照acme.sh说明安装acme.sh。通常只需要执行curl https://get.acme.sh | sh命令。
- 根据https://github.com/acmesh-official/acme.sh/wiki/dnsapi 寻找你的域名DNS提供商,参照说明配置API账号。例如腾讯云则参考DNSPod配置方式,阿里云则参考第十一条Aliyun的配置方式。如果您使用的DNS解析提供商不在该列表,可以在github搜搜看。
- 生成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
- 下载此代码https://gist.github.com/yi-ge/6c13dfddabd128a630bea9481ac8fb98 到nginx.tmpl文件或参考jtegtmeier提供的配置方法:https://github.com/nginx-proxy/nginx-proxy/commit/07655df85884b4ee7937a422ccd33b413b584a02 。
感谢jtegtmeier提供的方案!
- 以类似下述命令的方式启动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在执行文件的目录下。
- 增加环境变量配置并启动容器。
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个月后检查一下自己的网站是否正常运行。
暂无内容




 
 
老师你好,我希望能用一个openwrt路由器实现IPv4和IPv6的桥接,请问我该如何实现?我尝试了直接新增dhcpv6的接口,但是效果不甚理想(无法成功获取公网的ipv6,但是直连上级路由的其他设备是可以获取公网的ipv6地)
你好
,为什么我这里是0039 813C 0600 0075 16xx xx xx,只有前6组是相同的,博客中要前8位相同,这个不同能不能照着修改呢?我系统版本是Win1124H2
大神你好,win11专业版24h2最新版26100.2033,文件如何修改?谢谢
win11专业版24h2最新版26100.2033,Windows Feature Experience Pack 1000.26100.23.0。C:\Windows\System32\termsrv.dll系统自带的这个文件,39 81 3C 06 00 00 0F 85 XX XX XX XX 替换为 B8 00 01 00 00 89 81 38 06 00 00 90。仍然无法远程连接。原来是win11 21h2系统,是可以远程链接的。共享1个主机,2个显示器,2套键鼠,各自独立操作 各自不同的账号,不同的桌面环境。
博主,win11专业版24h2最新版,C:\Windows\System32\termsrv.dll系统自带的这个文件,找不到应该修改哪个字段。我的微信:一三五73二五九五00,谢谢