fix: use DNS validation for managed TLS certificate
This commit is contained in:
parent
584e0b4612
commit
5689671312
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user