#!/bin/bash # FE Gentoo (monstro): certbot renew + TLS smoke for Android Cast vhosts. # Install: fe/ac-certbot-renew-smoke.sh (executable) # Cron example: 0 4 * * * root /etc/nginx/ac-certbot-renew-smoke.sh --quiet set -euo pipefail QUIET=0 DRY_RUN=0 while [ $# -gt 0 ]; do case "$1" in --quiet|-q) QUIET=1 ;; --dry-run) DRY_RUN=1 ;; -h|--help) echo "Usage: $0 [--dry-run] [--quiet]" exit 0 ;; *) echo "unknown arg: $1" >&2; exit 2 ;; esac shift done log() { [ "$QUIET" -eq 0 ] && echo "[ac-certbot-renew] $*"; } warn() { echo "[ac-certbot-renew] WARN: $*" >&2; } RELOAD=0 if [ "$DRY_RUN" -eq 1 ]; then log "certbot renew --dry-run" certbot renew --dry-run else log "certbot renew" if certbot renew --quiet --deploy-hook "touch /run/nginx-reload-needed"; then : fi if [ -f /run/nginx-reload-needed ]; then RELOAD=1 rm -f /run/nginx-reload-needed fi fi if [ "$RELOAD" -eq 1 ]; then log "nginx reload after renew" nginx -t rc-service nginx reload fi # TLS smoke — CN must match host (curl verify); HTTP codes are informational. _smoke() { _host="$1" _path="${2:-/}" _code="$(curl -sS -o /dev/null -w "%{http_code}" --max-time 15 "https://${_host}${_path}" 2>/dev/null || echo 000)" _subj="$(echo | openssl s_client -connect "${_host}:443" -servername "${_host}" 2>/dev/null | openssl x509 -noout -subject 2>/dev/null | sed "s/subject=//")" log "${_host}${_path} -> http=${_code} cert=${_subj:-unknown}" case "$_subj" in *"${_host}"*|*CN=${_host}*) return 0 ;; *) warn "cert CN/SAN mismatch for ${_host}: ${_subj}"; return 1 ;; esac } FAIL=0 _smoke apps.f0xx.org /app/androidcast_project/ || FAIL=$((FAIL+1)) _smoke acl0.f0xx.org /app/androidcast_project/issues/api/diag.php || FAIL=$((FAIL+1)) _smoke s.f0xx.org /api/v1/health || FAIL=$((FAIL+1)) if [ "$FAIL" -gt 0 ]; then warn "smoke failures: $FAIL" exit 1 fi log "ok"