Fix jwt-token

This commit is contained in:
2025-09-13 08:54:16 +02:00
parent a2403ab5cd
commit 22d925d14a
11 changed files with 585 additions and 0 deletions

View File

@@ -0,0 +1,173 @@
#!/bin/bash
# Main certificate renewal script
set -e
DOMAIN="${DOMAIN:-dev.uggla.uamils.com}"
EMAIL="${EMAIL:-admin@uggla.uamils.com}"
RENEWAL_DAYS="${RENEWAL_DAYS:-10}"
LOG_FILE="/var/log/certbot/renewal.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
check_certificate_expiry() {
local cert_path="/etc/letsencrypt/live/$DOMAIN/cert.pem"
if [[ ! -f "$cert_path" ]]; then
log "Certificate not found at $cert_path - will attempt to obtain new certificate"
return 1
fi
# Get certificate expiry date
local expiry_date=$(openssl x509 -in "$cert_path" -noout -enddate | cut -d= -f2)
local expiry_epoch=$(date -d "$expiry_date" +%s)
local current_epoch=$(date +%s)
local days_until_expiry=$(( (expiry_epoch - current_epoch) / 86400 ))
log "Certificate expires in $days_until_expiry days"
if [[ $days_until_expiry -le $RENEWAL_DAYS ]]; then
log "Certificate expires in $days_until_expiry days - renewal needed"
return 1
else
log "Certificate is valid for $days_until_expiry more days - no renewal needed"
return 0
fi
}
attempt_dns_challenge() {
log "Attempting DNS challenge with Loopia API..."
if [[ -z "$LOOPIA_USER" || -z "$LOOPIA_PASSWORD" ]]; then
log "LOOPIA_USER or LOOPIA_PASSWORD not set - skipping DNS challenge"
return 1
fi
# Try with dns-lexicon
if command -v lexicon >/dev/null 2>&1; then
log "Using dns-lexicon for DNS challenge..."
certbot certonly \
--dns-lexicon \
--dns-lexicon-provider loopia \
--dns-lexicon-loopia-username="$LOOPIA_USER" \
--dns-lexicon-loopia-password="$LOOPIA_PASSWORD" \
--email "$EMAIL" \
--agree-tos \
--non-interactive \
--expand \
-d "$DOMAIN" \
-d "*.$DOMAIN"
return $?
fi
# Fallback: Manual DNS with custom hook
if [[ -f "/app/scripts/loopia-hook.sh" ]]; then
log "Using custom Loopia hook for DNS challenge..."
certbot certonly \
--manual \
--preferred-challenges dns \
--manual-auth-hook "/app/scripts/loopia-hook.sh auth" \
--manual-cleanup-hook "/app/scripts/loopia-hook.sh cleanup" \
--email "$EMAIL" \
--agree-tos \
--non-interactive \
--expand \
-d "$DOMAIN" \
-d "*.$DOMAIN"
return $?
fi
return 1
}
attempt_http_challenge() {
log "Attempting HTTP challenge..."
# Start nginx for HTTP challenge
nginx -t && nginx
certbot certonly \
--webroot \
--webroot-path=/var/www/html \
--email "$EMAIL" \
--agree-tos \
--non-interactive \
--expand \
-d "$DOMAIN"
local result=$?
# Stop nginx
nginx -s quit || true
return $result
}
reload_nginx() {
log "Copying certificates to shared directory..."
# Copy certificates to shared SSL directory
if [[ -d "/etc/letsencrypt/live/$DOMAIN" ]]; then
mkdir -p /shared/ssl
cp "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" "/shared/ssl/fullchain.pem" || log "Could not copy fullchain.pem"
cp "/etc/letsencrypt/live/$DOMAIN/privkey.pem" "/shared/ssl/privkey.pem" || log "Could not copy privkey.pem"
chmod 644 /shared/ssl/fullchain.pem
chmod 600 /shared/ssl/privkey.pem
log "Certificates copied to /shared/ssl/"
fi
log "Reloading nginx configuration..."
# Check if nginx container exists and reload it
if command -v docker >/dev/null 2>&1; then
if docker ps --format "table {{.Names}}" | grep -q "nginx\|proxy"; then
log "Reloading nginx container..."
docker exec nginx nginx -s reload 2>/dev/null || \
docker exec drone-detection-nginx nginx -s reload 2>/dev/null || \
log "Could not reload nginx container - manual reload may be required"
fi
fi
# Also try to reload host nginx if running
if pgrep nginx >/dev/null; then
log "Reloading host nginx..."
nginx -s reload || log "Could not reload host nginx"
fi
}
main() {
log "Starting certificate renewal check for $DOMAIN"
# Check if renewal is needed
if check_certificate_expiry; then
log "Certificate is still valid - no action needed"
exit 0
fi
log "Certificate renewal required - attempting to renew..."
# Try DNS challenge first (for wildcard support)
if attempt_dns_challenge; then
log "DNS challenge successful!"
reload_nginx
log "Certificate renewal completed successfully"
exit 0
fi
# Fallback to HTTP challenge (for main domain only)
log "DNS challenge failed - falling back to HTTP challenge"
if attempt_http_challenge; then
log "HTTP challenge successful!"
reload_nginx
log "Certificate renewal completed successfully"
exit 0
fi
log "ERROR: All certificate renewal attempts failed"
exit 1
}
# Run main function
main "$@"

View File

@@ -0,0 +1,158 @@
#!/bin/bash
# Loopia DNS API hook for certbot
# This script handles DNS TXT record creation and cleanup for Let's Encrypt challenges
set -e
LOOPIA_USER="${LOOPIA_USER:-}"
LOOPIA_PASSWORD="${LOOPIA_PASSWORD:-}"
LOOPIA_API_URL="https://api.loopia.se/RPCSERV"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Loopia Hook: $1" >&2
}
# Extract domain and subdomain parts
extract_domain_parts() {
local full_domain="$1"
# For *.dev.uggla.uamils.com -> domain=uamils.com, subdomain=_acme-challenge.dev
# For dev.uggla.uamils.com -> domain=uamils.com, subdomain=_acme-challenge.dev
if [[ "$full_domain" == *.uamils.com ]]; then
DOMAIN="uamils.com"
local prefix="${full_domain%.uamils.com}"
if [[ "$prefix" == *"*"* ]]; then
# Wildcard domain *.dev.uggla.uamils.com
SUBDOMAIN="_acme-challenge.${prefix#*.}"
else
# Regular domain dev.uggla.uamils.com
SUBDOMAIN="_acme-challenge.$prefix"
fi
else
log "ERROR: Unsupported domain format: $full_domain"
exit 1
fi
}
# Call Loopia API
call_loopia_api() {
local method="$1"
shift
local params="$@"
curl -s -X POST "$LOOPIA_API_URL" \
-H "Content-Type: text/xml" \
-d "<?xml version=\"1.0\"?>
<methodCall>
<methodName>$method</methodName>
<params>
<param><value><string>$LOOPIA_USER</string></value></param>
<param><value><string>$LOOPIA_PASSWORD</string></value></param>
$params
</params>
</methodCall>"
}
# Add DNS TXT record
add_txt_record() {
local domain="$1"
local subdomain="$2"
local txt_value="$3"
log "Adding TXT record: $subdomain.$domain = $txt_value"
local response=$(call_loopia_api "addZoneRecord" \
"<param><value><string>$domain</string></value></param>
<param><value><string>$subdomain</string></value></param>
<param><value><struct>
<member>
<name>type</name>
<value><string>TXT</string></value>
</member>
<member>
<name>rdata</name>
<value><string>$txt_value</string></value>
</member>
<member>
<name>ttl</name>
<value><int>300</int></value>
</member>
</struct></value></param>")
if echo "$response" | grep -q "OK"; then
log "Successfully added TXT record"
else
log "ERROR adding TXT record: $response"
exit 1
fi
}
# Remove DNS TXT record
remove_txt_record() {
local domain="$1"
local subdomain="$2"
log "Removing TXT records for: $subdomain.$domain"
# Get existing records
local records=$(call_loopia_api "getZoneRecords" \
"<param><value><string>$domain</string></value></param>
<param><value><string>$subdomain</string></value></param>")
# Extract record IDs for TXT records
local record_ids=$(echo "$records" | grep -A5 "<name>type</name>" | grep -B5 "<string>TXT</string>" | grep "record_id" | sed 's/.*<int>\([0-9]*\)<\/int>.*/\1/')
for record_id in $record_ids; do
if [[ -n "$record_id" ]]; then
log "Removing TXT record ID: $record_id"
call_loopia_api "removeZoneRecord" \
"<param><value><string>$domain</string></value></param>
<param><value><string>$subdomain</string></value></param>
<param><value><int>$record_id</int></value></param>"
fi
done
}
# Main script logic
case "$1" in
"auth")
if [[ -z "$CERTBOT_DOMAIN" || -z "$CERTBOT_VALIDATION" ]]; then
log "ERROR: CERTBOT_DOMAIN or CERTBOT_VALIDATION not set"
exit 1
fi
if [[ -z "$LOOPIA_USER" || -z "$LOOPIA_PASSWORD" ]]; then
log "ERROR: LOOPIA_USER or LOOPIA_PASSWORD not set"
exit 1
fi
extract_domain_parts "$CERTBOT_DOMAIN"
add_txt_record "$DOMAIN" "$SUBDOMAIN" "$CERTBOT_VALIDATION"
# Wait for DNS propagation
log "Waiting 60 seconds for DNS propagation..."
sleep 60
;;
"cleanup")
if [[ -z "$CERTBOT_DOMAIN" ]]; then
log "ERROR: CERTBOT_DOMAIN not set"
exit 1
fi
if [[ -z "$LOOPIA_USER" || -z "$LOOPIA_PASSWORD" ]]; then
log "WARNING: LOOPIA_USER or LOOPIA_PASSWORD not set - skipping cleanup"
exit 0
fi
extract_domain_parts "$CERTBOT_DOMAIN"
remove_txt_record "$DOMAIN" "$SUBDOMAIN"
;;
*)
log "Usage: $0 {auth|cleanup}"
exit 1
;;
esac

View File

@@ -0,0 +1,45 @@
#!/bin/bash
# Status check script for monitoring
set -e
DOMAIN="${DOMAIN:-dev.uggla.uamils.com}"
LOG_FILE="/var/log/certbot/status.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
check_certificate_status() {
local cert_path="/etc/letsencrypt/live/$DOMAIN/cert.pem"
if [[ ! -f "$cert_path" ]]; then
log "STATUS: No certificate found for $DOMAIN"
return 1
fi
# Get certificate details
local expiry_date=$(openssl x509 -in "$cert_path" -noout -enddate | cut -d= -f2)
local expiry_epoch=$(date -d "$expiry_date" +%s)
local current_epoch=$(date +%s)
local days_until_expiry=$(( (expiry_epoch - current_epoch) / 86400 ))
# Get certificate subject
local subject=$(openssl x509 -in "$cert_path" -noout -subject | sed 's/subject=//')
log "STATUS: Certificate for $DOMAIN"
log " Subject: $subject"
log " Expires: $expiry_date"
log " Days until expiry: $days_until_expiry"
if [[ $days_until_expiry -le 10 ]]; then
log " WARNING: Certificate expires soon!"
elif [[ $days_until_expiry -le 30 ]]; then
log " NOTICE: Certificate expires in less than 30 days"
else
log " OK: Certificate is valid"
fi
}
# Check certificate status
check_certificate_status