Files
AriWeb-Suite/modules/arimail/deploy/tls-when-ready.sh

30 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# 인증서 자동 발급(0.8.18~) — root 로 실행(보통 <APP_NAME>-tls.timer 가 15분마다 부름): bash deploy/tls-when-ready.sh <site.env>
#
# 새 서버에 설치할 때 DNS(MAIL_HOST → 이 서버)가 아직 바뀌지 않았으면 Let's Encrypt HTTP-01 검증이 실패하므로 setup.sh 는
# 80 포트만 여는 임시 nginx 설정으로 끝납니다. 이 스크립트는 MAIL_HOST 의 A 레코드가 이 서버의 IP 와 같아지는 순간을 기다렸다가
# certbot 으로 인증서를 받고 setup.sh 를 다시 실행해 443 설정·인증서 사본·메일 포트 TLS 를 켠 뒤 타이머를 멈춥니다.
# 이미 인증서가 있으면 아무 일도 하지 않고 타이머만 끕니다(갱신은 certbot 의 자체 타이머가 합니다).
set -euo pipefail
[ "$(id -u)" = 0 ] || { echo 'root 로 실행하세요' >&2; exit 1; }
. "$(dirname "$0")/lib.sh"
load_site "${1:?site.env 경로}"
TIMER="$APP_NAME-tls.timer"
stop_timer() { systemctl disable --now "$TIMER" >/dev/null 2>&1 || true; }
if [ -d "/etc/letsencrypt/live/$MAIL_HOST" ]; then echo "이미 인증서가 있습니다: $MAIL_HOST"; stop_timer; exit 0; fi
# DNS 확인: 권위 DNS 가 아니라 이 서버의 해석기 기준입니다(certbot 검증 서버가 보는 값과 보통 같습니다).
RESOLVED="$(getent ahostsv4 "$MAIL_HOST" 2>/dev/null | awk '{print $1}' | sort -u || true)"
MINE="$(ip -4 -o addr show scope global | awk '{print $4}' | cut -d/ -f1 | sort -u)"
MATCH=""; for a in $RESOLVED; do for b in $MINE; do [ "$a" = "$b" ] && MATCH="$a"; done; done
if [ -z "$MATCH" ]; then echo "$MAIL_HOST 가 아직 이 서버를 가리키지 않습니다 (DNS: ${RESOLVED:-없음} / 서버: $MINE) — 다음에 다시 확인"; exit 0; fi
echo "DNS 확인됨($MAIL_HOST → $MATCH). 인증서를 발급합니다"
mkdir -p "$ACME_WEBROOT"
# 등록된 certbot 계정이 없으면 이메일 없이 등록합니다(만료 안내 메일을 받으려면 나중에 certbot register/update_account 로 바꾸세요).
ACCOUNT_FLAG=""; ls /etc/letsencrypt/accounts/*/directory/*/regr.json >/dev/null 2>&1 || ACCOUNT_FLAG="--register-unsafely-without-email"
certbot certonly --webroot -w "$ACME_WEBROOT" -d "$MAIL_HOST" --non-interactive --agree-tos --keep-until-expiring $ACCOUNT_FLAG
echo "발급 완료. setup.sh 를 다시 실행해 443 설정과 메일 포트 TLS 를 켭니다"
SITE="$SITE" bash "$APP_DIR/repo/deploy/setup.sh"
stop_timer
echo "✔ TLS 준비 완료: https://$MAIL_HOST/"