96 lines
3.0 KiB
Bash
96 lines
3.0 KiB
Bash
#!/usr/bin/env bash
|
||
# 在沒有互動 sudo 密碼的情況下,利用 188 既有 docker 群組權限修復 registry.wooo.work 憑證。
|
||
# 需求:ollama 使用者可執行 docker,且 sudoers 允許 NOPASSWD restart nginx。
|
||
|
||
set -euo pipefail
|
||
|
||
DOMAIN="${DOMAIN:-registry.wooo.work}"
|
||
ROOT_IMAGE="${ROOT_IMAGE:-alpine:latest}"
|
||
CERTBOT_IMAGE="${CERTBOT_IMAGE:-certbot/certbot:latest}"
|
||
STAMP="$(date +%Y%m%d%H%M%S)"
|
||
TOKEN="awoooi-certbot-${STAMP}"
|
||
|
||
echo "== Patch nginx HTTP-01 route =="
|
||
docker run --rm \
|
||
-v /etc/nginx/sites-available:/mnt/sites \
|
||
-v /var/www:/mnt/www \
|
||
"$ROOT_IMAGE" sh -eu -c '
|
||
conf=/mnt/sites/internal-tools-https.conf
|
||
marker="AWOOOI internal-tools HTTP-01 managed block"
|
||
test -f "$conf"
|
||
cp "$conf" "$conf.bak-'"$STAMP"'-registry-http01"
|
||
mkdir -p /mnt/www/certbot/.well-known/acme-challenge
|
||
chmod 0755 /mnt/www /mnt/www/certbot /mnt/www/certbot/.well-known /mnt/www/certbot/.well-known/acme-challenge
|
||
if ! grep -q "$marker" "$conf"; then
|
||
tmp="$(mktemp)"
|
||
cat >"$tmp" <<'"'"'EOF'"'"'
|
||
# AWOOOI internal-tools HTTP-01 managed block
|
||
server {
|
||
listen 80;
|
||
server_name
|
||
gitea.wooo.work
|
||
sentry.wooo.work
|
||
langfuse.wooo.work
|
||
harbor.wooo.work
|
||
registry.wooo.work
|
||
stock.wooo.work;
|
||
|
||
location /.well-known/acme-challenge/ {
|
||
root /var/www/certbot;
|
||
}
|
||
|
||
location / {
|
||
return 301 https://$host$request_uri;
|
||
}
|
||
}
|
||
|
||
EOF
|
||
cat "$conf" >>"$tmp"
|
||
cat "$tmp" >"$conf"
|
||
rm -f "$tmp"
|
||
fi
|
||
'
|
||
|
||
echo "== Reload nginx =="
|
||
sudo -n systemctl restart nginx
|
||
|
||
echo "== Verify HTTP-01 webroot =="
|
||
docker run --rm \
|
||
-v /var/www:/mnt/www \
|
||
"$ROOT_IMAGE" sh -eu -c '
|
||
mkdir -p /mnt/www/certbot/.well-known/acme-challenge
|
||
printf "%s\n" "'"$TOKEN"'" > /mnt/www/certbot/.well-known/acme-challenge/'"$TOKEN"'
|
||
'
|
||
trap 'docker run --rm -v /var/www:/mnt/www "$ROOT_IMAGE" sh -c "rm -f /mnt/www/certbot/.well-known/acme-challenge/'"$TOKEN"'" >/dev/null 2>&1 || true' EXIT
|
||
|
||
body="$(curl -fsS --max-time 10 "http://${DOMAIN}/.well-known/acme-challenge/${TOKEN}")"
|
||
if [ "$body" != "$TOKEN" ]; then
|
||
echo "ERROR: HTTP-01 probe failed for ${DOMAIN}" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "== Renew certificate with certbot container =="
|
||
docker run --rm \
|
||
-v /etc/letsencrypt:/etc/letsencrypt \
|
||
-v /var/lib/letsencrypt:/var/lib/letsencrypt \
|
||
-v /var/log/letsencrypt:/var/log/letsencrypt \
|
||
-v /var/www/certbot:/var/www/certbot \
|
||
"$CERTBOT_IMAGE" renew \
|
||
--cert-name "$DOMAIN" \
|
||
--force-renewal \
|
||
--no-random-sleep-on-renew \
|
||
--webroot \
|
||
-w /var/www/certbot \
|
||
--non-interactive
|
||
|
||
echo "== Restart nginx and clear failed certbot units =="
|
||
sudo -n systemctl restart nginx
|
||
sudo -n systemctl reset-failed certbot.service snap.certbot.renew.service 2>/dev/null || true
|
||
|
||
echo "== Verify public TLS =="
|
||
echo | openssl s_client -servername "$DOMAIN" -connect "${DOMAIN}:443" 2>/dev/null \
|
||
| openssl x509 -noout -subject -issuer -dates
|
||
curl -LsS -o /dev/null -w "registry_tls_http=%{http_code}\n" --max-time 12 "https://${DOMAIN}/v2/"
|
||
|
||
echo "REGISTRY_CERTBOT_RENEWAL_OK"
|