专注于WEB前端开发, 追求更好的用户体验, 更好的开发体验 [长沙前端QQ群:234746733]

使用letsencrypt自动生成和续期HTTPS证书

相信一些同学注意到了, 本站启用了https, 域名改成了xhl.me, 服务也早就全都改用docker了.
顺带介绍下之前搞的两个个docker项目: alpine-tengine, docker-backup.

*本文主要介绍letsencrypt证书的创建和通配符HTTPS证书生成, 还有基于letsencrypt docker镜像实现证书自动续期.

Let's Encrypt 是一个自动签发免费HTTPS证书的非营利机构, 生成的证书有3个月有效期, 到期可以免费续期.
Certbot 是 Let's Encrypt 官方推荐的生成证书的客户端工具, 文档.

使用dnsrobocert生成证书(支持通配符域名证书), 并自动续期

这个项目, 集成了certbot(证书生成命令行工具), Lexicon(DNS记录修改工具, 主流DNS服务商都支持).
另外还自带了crontab 定时任务, 只要服务启动, 就会自动续期域名了.

1. 创建, /etc/dnsrobocert/config.yml, 内容类似这样:
# https://git.io/JL1cD
draft: false
acme:
  email_account: <youremail>
  staging: false
profiles:
- name: cloudflare
  provider: cloudflare
  provider_options:
    auth_username: <cloudflare_email>
    auth_token: <cloudflare_token>
- name: dnspod
  provider: dnspod
  provider_options:
    auth_username: <dnspod_id>
    auth_token: <dnspod_token>
certificates:
- domains:
  - "*.xhl.me"
  -  xhl.me
  profile: cloudflare
  # autorestart:
  #   - containers:
  #     - nginx
  autocmd: # 自动重启
    - cmd: nginx -s reload
      containers:
      - nginx
# - domains:
#   - "*.test.com"
#   profile: dnspod
#   ...
2. 根据DNS PROVIDER信息验证, 并自动创建和续期证书
docker run -it --rm --name letsencrypt2 \
  -v /etc/dnsrobocert:/etc/dnsrobocert \
  -v /etc/letsencrypt:/etc/letsencrypt \
  -v /var/run/docker.sock:/var/run/docker.sock \
  adferrand/dnsrobocert

LEXICON_PROVIDER 主流的DNS服务都支持, 比如:

3. 进阶: 使用docker-compose

创建 /compose/letsencrypt/docker-compose.yml:

version: '3'
services:
  letsencrypt:
    container_name: letsencrypt
    image: adferrand/dnsrobocert
    # network_mode: "host"
    volumes:
      - /etc/dnsrobocert/:/etc/dnsrobocert
      - /etc/letsencrypt/:/etc/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock

启动服务执行: cd /compose/letsencrypt; docker-compose up -d --force-recreate -V;

5. 进阶: 开机自启服务

创建 /etc/systemd/system/letsencrypt.service, 内容:

[Unit]
Description=Letsencrypt Container
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutStartSec=0
ExecStart=/usr/local/bin/docker-compose up -d --force-recreate
ExecReload=/usr/local/bin/docker-compose up -d --force-recreate
ExecStop=/usr/local/bin/docker-compose stop
WorkingDirectory=/composes/letsencrypt

[Install]
WantedBy=multi-user.target

执行下, 下面的命令就可以成为自启的服务了:

systemctl daemon-reload;
systemctl enable letsencrypt; systemctl restart letsencrypt;

同理, 也可以把其他docker服务做成自启, 比如Nginx.

证书生成后 nginx 的配置

server {
  listen 80;
  listen 443 ssl;
  server_name xhl.me www.xhl.me;
  ssl_certificate /etc/letsencrypt/live/xhl.me/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/xhl.me/privkey.pem;
  ssl_session_cache shared:SSL:50m;
  ssl_session_timeout 5m;
  ssl_stapling on;
  ssl_stapling_verify on;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
  ssl_prefer_server_ciphers on;
  ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
  ...
}

可能用到的debug命令

telnet xhl.me 443
openssl s_client -connect xhl.me:443
curl -vv -k https://xhl.me # 测试https
docker exec -it letsencrypt sh # 进入容器执行shell命令
docker logs letsencrypt -f # 查看letsencrypt输出的日志信息

tools

另外, 也可以使用certbot 生成证书, 但是没有dnsrobocert方便, 就不介绍了.

如果letsencrypt提示了lexicon执行错误, 看不到具体的错误, 比如: 422 Client Error: Unprocessable Entity for url: xxx, 这时可以看域名对应DNS服务商的API文档, 用curl直接调用接口来debug, 比如:

// godaddy 获取域名的所有记录
curl -X GET -H"Authorization: sso-key KEY:SECRET" https://api.godaddy.com/v1/domains/yourdomain.com/records
// godaddy 批量修改域名记录
curl -X PUT https://api.godaddy.com/v1/domains/yourdomain.com/records -H "Authorization: sso-key KEY:SECRET" \
-H "Content-Type: application/json" -d '[....., {"data": "test", "type": "TXT", "name": "_acme-challenge", "ttl": 3600}]'

/ 分类: 工具,实践 / TrackBackhttps://xhl.me/archives/letsencrypt-ssl/trackback标签: docker, https

添加新评论 »