← back to Domain Landings

batch_nginx.sh

75 lines

#!/usr/bin/env bash
# Install nginx vhost + Let's Encrypt SAN cert for a batch of landing domains.
# Usage: batch_nginx.sh <batch-id> <domain1> <domain2> ...
# Idempotent + resilient: only certs domains that have actually propagated to this box;
# unpropagated ones are reported so they can be retried on a re-run.
set -u
BATCH="$1"; shift
DOMS="$*"
IP="45.61.58.125"
APP_PORT="$(cat /root/Projects/domain-landings/.port 2>/dev/null || echo 9794)"
CONF="/etc/nginx/sites-available/dl-batch-${BATCH}.conf"
WEBROOT="/var/www/certbot"

# 1) HTTP-only block first (acme challenge + proxy) so nothing 404s during cert issuance
{
  echo "server {"
  echo "    listen 80;"
  echo "    server_name ${DOMS};"
  echo "    location ^~ /.well-known/acme-challenge/ { root ${WEBROOT}; default_type \"text/plain\"; }"
  echo "    location / {"
  echo "        proxy_pass http://127.0.0.1:${APP_PORT};"
  echo "        proxy_set_header Host \$host;"
  echo "        proxy_set_header X-Forwarded-Host \$host;"
  echo "        proxy_set_header X-Forwarded-Proto \$scheme;"
  echo "    }"
  echo "}"
} > "$CONF"
ln -sf "$CONF" "/etc/nginx/sites-enabled/dl-batch-${BATCH}.conf"
nginx -t >/dev/null 2>&1 && systemctl reload nginx || { echo "NGINX_TEST_FAIL(http)"; exit 1; }

# 2) keep only domains that resolve to this box (propagated) — avoids SAN-cert-wide failure
RES=""
for d in $DOMS; do
  ip="$(dig +short A "$d" @1.1.1.1 2>/dev/null | tail -1)"
  [ "$ip" = "$IP" ] && RES="$RES $d" || echo "  UNPROPAGATED $d (got '${ip:-none}')"
done
RES="$(echo "$RES" | xargs)"
[ -z "$RES" ] && { echo "NO_PROPAGATED_DOMAINS"; exit 0; }

# 3) SAN cert for propagated domains (apex only)
CARGS=""; for d in $RES; do CARGS="$CARGS -d $d"; done
certbot certonly --webroot -w "$WEBROOT" $CARGS --cert-name "dl-batch-${BATCH}" \
  --non-interactive --agree-tos -m steve@designerwallcoverings.com --keep-until-expiring \
  >/tmp/certbot-${BATCH}.log 2>&1
if [ ! -f "/etc/letsencrypt/live/dl-batch-${BATCH}/fullchain.pem" ]; then
  echo "CERT_FAILED — see tail:"; tail -6 /tmp/certbot-${BATCH}.log; exit 1
fi

# 4) final conf: 80 (acme + redirect) + 443 (proxy) for the certed domains
{
  echo "server {"
  echo "    listen 80;"
  echo "    server_name ${RES};"
  echo "    location ^~ /.well-known/acme-challenge/ { root ${WEBROOT}; default_type \"text/plain\"; }"
  echo "    location / { return 301 https://\$host\$request_uri; }"
  echo "}"
  echo "server {"
  echo "    listen ${IP}:443 ssl http2;"
  echo "    server_name ${RES};"
  echo "    ssl_certificate /etc/letsencrypt/live/dl-batch-${BATCH}/fullchain.pem;"
  echo "    ssl_certificate_key /etc/letsencrypt/live/dl-batch-${BATCH}/privkey.pem;"
  echo "    ssl_protocols TLSv1.2 TLSv1.3;"
  echo "    add_header X-Content-Type-Options \"nosniff\" always;"
  echo "    location / {"
  echo "        proxy_pass http://127.0.0.1:${APP_PORT};"
  echo "        proxy_set_header Host \$host;"
  echo "        proxy_set_header X-Forwarded-Host \$host;"
  echo "        proxy_set_header X-Forwarded-Proto \$scheme;"
  echo "    }"
  echo "}"
} > "$CONF"
nginx -t >/dev/null 2>&1 && systemctl reload nginx || { echo "NGINX_TEST_FAIL(ssl)"; exit 1; }
echo "BATCH_${BATCH}_DONE certed:$(echo $RES | wc -w)"
echo "CERTED_LIST:${RES}"