docker 下使用 certbot 申请泛域名证书与续期。

配置文件

# /opt/docker/data/certbot/cloudflare.ini
# chmod 700 /opt/docker/data/certbot
# touch /opt/docker/data/certbot/cloudflare.ini
# chmod 600 /opt/docker/data/certbot/cloudflare.ini

# Cloudflare API credentials used by Certbot
# How to generate API token:
# https://developers.cloudflare.com/api/tokens/create
# https://dash.cloudflare.com/profile/api-tokens
dns_cloudflare_api_token = XXXXXXXXXXXXXXXXXXXX

执行后删除容器

# 申请
docker run -it --rm --name cf \
  -v "/opt/docker/data/certbot/cloudflare.ini:/opt/cloudflare.ini:ro" \
  -v "/opt/docker/data/certbot/etc:/etc/letsencrypt" \
  -v "/opt/docker/data/certbot/lib:/var/lib/letsencrypt" \
  -v "/opt/docker/data/certbot/log:/var/log/letsencrypt" \
  certbot/dns-cloudflare:latest certonly --agree-tos --email [email protected] --non-interactive --dns-cloudflare --dns-cloudflare-credentials /opt/cloudflare.ini --agree-tos -d 196000.xyz,*.196000.xyz --server https://acme-v02.api.letsencrypt.org/directory --dry-run

# 续期
docker run -it --rm --name cf \
  -v "/opt/docker/data/certbot/cloudflare.ini:/opt/cloudflare.ini:ro" \
  -v "/opt/docker/data/certbot/etc:/etc/letsencrypt" \
  -v "/opt/docker/data/certbot/lib:/var/lib/letsencrypt" \
  -v "/opt/docker/data/certbot/log:/var/log/letsencrypt" \
  certbot/dns-cloudflare:latest renew --non-interactive --dns-cloudflare --dns-cloudflare-credentials /opt/cloudflare.ini --agree-tos --server https://acme-v02.api.letsencrypt.org/directory --dry-run

使用 certbot/certbot 添加 TXT 记录认证方式申请证书

version: "3.8"
services:
  certbot:
    image: certbot/certbot:latest
    container_name: certbot
    restart: always
    volumes:
      - ${APP_CONF}/certbot/etc:/etc/letsencrypt
      - ${APP_CONF}/certbot/log:/var/log/letsencrypt
    entrypoint: /bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'
# 进入容器申请证书
docker exec -it certbot /bin/sh
certbot certonly -d xxx.196000.xyz --manual --preferred-challenges dns --email [email protected] --agree-tos --dry-run 
# Saving debug log to /var/log/letsencrypt/letsencrypt.log
# Account registered.
# Simulating renewal of an existing certificate for xxx.196000.xyz
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Please deploy a DNS TXT record under the name:
# _acme-challenge.xxx.196000.xyz.
# with the following value:
# sDzWMyO0jUCBxd0ZlgqLRgsm44TKVwp6RT62NpKyD-w

根据提示增加 TXT 记录后

可以按照提示查看是否已经生效

https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.xxx.196000.xyz

注:此方式需要手动验证域名的所有权,所以 Certbot 无法自动完成续订,后面改下面的 api 方式认证

使用 certbot/dns-cloudflare cloudflare api 方式申请证书

version: "3.8"
services:
  certbot:
    image: certbot/dns-cloudflare:latest
    container_name: certbot
    #entrypoint: /bin/sh -c "sleep infinity"
    #command: certonly --agree-tos --email [email protected] --non-interactive --dns-cloudflare --dns-cloudflare-credentials /opt/cloudflare.ini --agree-tos -d 196000.xyz,*.196000.xyz --server https://acme-v02.api.letsencrypt.org/directory --dry-run
    # Renew
    # Certbot 以非交互方式自动续期证书,并每隔 240 小时(10天)执行一次,检查现有证书是否即将到期,并在需要时自动续期
    # 只有在30天内到期的证书才会被真正更新。这个特性非常有利于自动化,我们不需要关心每个证书的到期时间,只要经常运行certbot renew,就可以自动更新即将到期的证书。
    # 如果想立刻看到更新证书的效果,也可以跳过到期检查,强制更新证书,使用 --force-renewal 选项。
    # 需要注意,证书颁发机构对申请证书的频率有限制,如果频繁强制更新证书,会导致账号被暂时冻结。
    # 速率限制 https://letsencrypt.org/zh-cn/docs/rate-limits/
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew --non-interactive --no-self-upgrade --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare/cloudflare.ini --agree-tos --server https://acme-v02.api.letsencrypt.org/directory; sleep 240h & wait; done;'"
    # command: renew --non-interactive --no-self-upgrade --dns-cloudflare --dns-cloudflare-credentials /opt/cloudflare/cloudflare.ini --agree-tos --server https://acme-v02.api.letsencrypt.org/directory
    volumes:
      - ${APP_CONF}/certbot/cloudflare.ini:/opt/cloudflare.ini:ro # Cloudflare API key
      - ${APP_CONF}/certbot/etc:/etc/letsencrypt     # 证书目录
      - ${APP_CONF}/certbot/log:/var/log/letsencrypt # 日志 debug 级别
      - ${APP_CONF}/certbot/lib:/var/lib/letsencrypt
    environment: 
      - DNS_CLOUDFLARE_API_TOKEN="qAzAHcVga4MjyqZ6rSrV-0mSejfCjnW_sE5PTYbG"
    # 开启以下两个选项可以出现一个交互式的 tty
    # 如果会修改上面的 command 为需要交互式操作的话可以开启
    # stdin_open: true
    # tty: true

环境变量

# VARIABLE=value #comment
WEB_ROOT=/var/www/html
APP_CONF=/opt/docker/data
APP_DATA=/opt/appdata

查看证书期限

# 查看证书期限
docker exec -it certbot certbot certificates
openssl x509 -in /opt/docker/data/certbot/etc/live/196000.xyz/cert.pem -noout -startdate | cut -d= -f2
openssl x509 -in /opt/docker/data/certbot/etc/live/196000.xyz/cert.pem -noout -enddate | cut -d= -f2