76933d21c1
- Replace Bazarr with NZBGet in Caddyfile routes - Add global DNS provider configuration for ACME DNS-01 challenges - Implement dynamic DNS updater with Bunny.net provider - Add comprehensive security headers and authentication - Update documentation with new requirements and setup instructions - Add .env.example, Dockerfile, cron jobs, and scripts - Modify compose.yml to use local build and add environment variables BREAKING CHANGE: Requires Bunny.net API key and updated Caddyfile configuration
123 lines
3.0 KiB
Bash
123 lines
3.0 KiB
Bash
#!/bin/bash
|
|
# Script: ddns-cert-sync.sh
|
|
# Purpose: Monitor public IP changes and ensure Caddy DNS/TLS is synchronized
|
|
# Usage: Run via cron (e.g., every 5 minutes)
|
|
|
|
set -euo pipefail
|
|
|
|
# Configuration
|
|
LOCK_FILE="/tmp/caddy-ddns-cert-sync.lock"
|
|
STATE_FILE="/var/lib/caddy/last_ip.txt"
|
|
LOG_FILE="/var/log/caddy-ddns-cert-sync.log"
|
|
CADDY_BIN="/usr/bin/caddy"
|
|
IP_CHECK_URL="https://api.ipify.org?format=txt"
|
|
|
|
# Logging function
|
|
log() {
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
# Check if script is already running
|
|
if [ -f "$LOCK_FILE" ]; then
|
|
log "Lock file exists. Another instance is running. Exiting."
|
|
exit 0
|
|
fi
|
|
|
|
# Create lock file
|
|
trap "rm -f '$LOCK_FILE'; exit" INT TERM EXIT
|
|
touch "$LOCK_FILE"
|
|
|
|
# Get current public IP
|
|
get_current_ip() {
|
|
curl -s --max-time 10 "$IP_CHECK_URL" || echo ""
|
|
}
|
|
|
|
# Read last known IP from state file
|
|
read_last_ip() {
|
|
if [ -f "$STATE_FILE" ]; then
|
|
cat "$STATE_FILE" 2>/dev/null || echo ""
|
|
else
|
|
echo ""
|
|
fi
|
|
}
|
|
|
|
# Write current IP to state file
|
|
write_current_ip() {
|
|
echo "$1" > "$STATE_FILE"
|
|
}
|
|
|
|
# Test HTTPS connectivity
|
|
test_https() {
|
|
local domain="$1"
|
|
if curl -s --max-time 10 -o /dev/null -w "%{http_code}" "https://$domain/" | grep -q "^200$"; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Main execution
|
|
log "Starting IP check and Caddy sync"
|
|
|
|
CURRENT_IP=$(get_current_ip)
|
|
if [ -z "$CURRENT_IP" ]; then
|
|
log "ERROR: Could not determine current public IP. Retrying in next cycle."
|
|
rm -f "$LOCK_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
log "Current public IP: $CURRENT_IP"
|
|
|
|
LAST_IP=$(read_last_ip)
|
|
if [ -z "$LAST_IP" ]; then
|
|
log "No previous IP found. Writing current IP to state file."
|
|
write_current_ip "$CURRENT_IP"
|
|
rm -f "$LOCK_FILE"
|
|
exit 0
|
|
fi
|
|
|
|
log "Last known IP: $LAST_IP"
|
|
|
|
if [ "$CURRENT_IP" = "$LAST_IP" ]; then
|
|
log "IP unchanged. No action needed."
|
|
rm -f "$LOCK_FILE"
|
|
exit 0
|
|
fi
|
|
|
|
# IP has changed
|
|
log "IP changed from $LAST_IP to $CURRENT_IP. Triggering Caddy reload and TLS verification."
|
|
|
|
# Update state file
|
|
write_current_ip "$CURRENT_IP"
|
|
|
|
# Reload Caddy to ensure DNS and TLS are synchronized
|
|
if [ -x "$CADDY_BIN" ]; then
|
|
log "Reloading Caddy..."
|
|
if "$CADDY_BIN" reload --config /etc/caddy/Caddyfile; then
|
|
log "Caddy reloaded successfully."
|
|
else
|
|
log "ERROR: Failed to reload Caddy. Attempting restart."
|
|
"$CADDY_BIN" stop || true
|
|
sleep 2
|
|
"$CADDY_BIN" start --config /etc/caddy/Caddyfile --adapter caddyfile || log "ERROR: Failed to restart Caddy."
|
|
fi
|
|
else
|
|
log "ERROR: Caddy binary not found at $CADDY_BIN"
|
|
fi
|
|
|
|
# Verify HTTPS for critical domains
|
|
log "Running HTTPS verification for critical domains..."
|
|
CRITICAL_DOMAINS=("recept.gynther.se" "jellyfin.gynther.se" "wetty.gynther.se")
|
|
for domain in "${CRITICAL_DOMAINS[@]}"; do
|
|
if test_https "$domain"; then
|
|
log "HTTPS test PASSED for $domain"
|
|
else
|
|
log "WARNING: HTTPS test FAILED for $domain (may be due to DNS propagation)"
|
|
fi
|
|
done
|
|
|
|
log "IP change handling completed."
|
|
|
|
# Cleanup
|
|
rm -f "$LOCK_FILE"
|
|
exit 0 |