fix: use DNS validation for managed TLS certificate

This commit is contained in:
lunanting 2026-09-12 16:08:57 +08:00
parent 584e0b4612
commit 5689671312
3 changed files with 16 additions and 39 deletions

View File

@ -45,6 +45,14 @@ npm run remote:start
## 服务器管理
首次配置 `ck.yydd.ai` 的正式证书时,管理员需在服务器创建 `/etc/cangku-tls/cloudflare.ini`,内容为 Cloudflare 最小权限 API Token:
```ini
dns_cloudflare_api_token = <仅 DNS 编辑权限的 Token>
```
文件权限必须为 `0600`、所有者为 root。然后以 root 依次运行 `provision-certificate.sh` 和 `install.sh`;Certbot 会使用 DNS-01 验证并由系统定时器自动续期。该文件绝不能提交到 Git。
服务器使用 `cangku-bootstrap` systemd 服务、独立的受限 MySQL 发号账号和 SSH 用户证书 CA。常用命令:
```bash

View File

@ -14,7 +14,7 @@ test -f "${MYSQL_ENV}"
test -f "${SOURCE_DIR}/bootstrap_service.py"
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq python3-venv openssl certbot >/dev/null
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq python3-venv openssl certbot python3-certbot-dns-cloudflare >/dev/null
if ! getent passwd cangku-bootstrap >/dev/null; then
useradd --system --home-dir /var/lib/cangku-bootstrap --create-home --shell /usr/sbin/nologin cangku-bootstrap

View File

@ -7,51 +7,20 @@ if [[ ${EUID} -ne 0 ]]; then
fi
DOMAIN=ck.yydd.ai
WEBROOT=/var/www/cangku-bootstrap-acme
TEMP_SITE=/etc/nginx/sites-available/cangku-bootstrap-acme
TLS_ROOT=/etc/cangku-tls
EAB_FILE=${TLS_ROOT}/eab.json
ACME_SERVER=https://acme.zerossl.com/v2/DV90
CF_CREDENTIALS=${TLS_ROOT}/cloudflare.ini
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq certbot >/dev/null
install -d -m 0755 "${WEBROOT}/.well-known/acme-challenge"
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq certbot python3-certbot-dns-cloudflare >/dev/null
install -d -m 0700 "${TLS_ROOT}"
if [[ ! -f "/etc/letsencrypt/live/${DOMAIN}/fullchain.pem" ]]; then
if [[ ! -f "${EAB_FILE}" ]]; then
echo "Missing ${EAB_FILE}; create ZeroSSL EAB credentials and store them there with mode 0600" >&2
if [[ ! -f "${CF_CREDENTIALS}" ]]; then
echo "Missing ${CF_CREDENTIALS}; store a scoped Cloudflare API token there with mode 0600" >&2
exit 1
fi
umask 0022
{
printf 'server {\n'
printf ' listen 80;\n'
printf ' listen [::]:80;\n'
printf ' server_name %s;\n' "${DOMAIN}"
printf ' location /.well-known/acme-challenge/ { root %s; }\n' "${WEBROOT}"
printf ' location / { return 404; }\n'
printf '}\n'
} > "${TEMP_SITE}"
ln -sfn "${TEMP_SITE}" /etc/nginx/sites-enabled/cangku-bootstrap-acme
nginx -t
systemctl reload nginx
readarray -t eab < <(python3 - "${EAB_FILE}" <<'PY'
import json
import sys
with open(sys.argv[1], encoding='utf-8') as handle:
value = json.load(handle)
print(value['eab_kid'])
print(value['eab_hmac_key'])
PY
)
certbot certonly --server "${ACME_SERVER}" \
--eab-kid "${eab[0]}" --eab-hmac-key "${eab[1]}" \
--webroot -w "${WEBROOT}" -d "${DOMAIN}" \
--email certs@yydd.ai --agree-tos --non-interactive --no-eff-email
unlink "${EAB_FILE}"
unlink /etc/nginx/sites-enabled/cangku-bootstrap-acme
unlink "${TEMP_SITE}"
chmod 0600 "${CF_CREDENTIALS}"
certbot certonly --dns-cloudflare --dns-cloudflare-credentials "${CF_CREDENTIALS}" \
-d "${DOMAIN}" --email certs@yydd.ai --agree-tos --non-interactive --no-eff-email
fi
systemctl enable --now certbot.timer