secubox-openwrt/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxy-sync-certs
CyberMind-FR 2335578203 fix(haproxy): Permanent container-only architecture
- Add lxc_start_bg() and lxc_reload() functions for container management
- Replace all /etc/init.d/haproxy calls with container-aware functions
- Fix haproxy-sync-certs to use haproxyctl reload
- Host HAProxy init script disabled, container is sole handler

Resolves intermittent 404 errors caused by dual HAProxy instances.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-25 10:40:56 +01:00

94 lines
2.9 KiB
Bash

#!/bin/sh
# Sync ACME certificates to HAProxy format
# Combines fullchain + private key into .pem files
# Called by ACME renewal or manually via haproxyctl
ACME_DIR="/etc/acme"
HAPROXY_CERTS_DIR="/srv/haproxy/certs"
log_info() { echo "[haproxy-sync-certs] $*"; logger -t haproxy-sync-certs "$*"; }
log_error() { echo "[haproxy-sync-certs] ERROR: $*" >&2; logger -t haproxy-sync-certs -p err "$*"; }
mkdir -p "$HAPROXY_CERTS_DIR"
# Find all ACME certificates and deploy them
for domain_dir in "$ACME_DIR"/*/; do
[ -d "$domain_dir" ] || continue
# Skip non-domain directories
case "$(basename "$domain_dir")" in
ca|*.ecc) continue ;;
esac
domain=$(basename "$domain_dir")
fullchain="$domain_dir/fullchain.cer"
key="$domain_dir/${domain}.key"
# Try alternate paths
[ -f "$fullchain" ] || fullchain="$domain_dir/fullchain.pem"
[ -f "$key" ] || key="$domain_dir/privkey.pem"
[ -f "$key" ] || key="$domain_dir/${domain}.key"
if [ -f "$fullchain" ] && [ -f "$key" ]; then
log_info "Syncing certificate for $domain"
cat "$fullchain" "$key" > "$HAPROXY_CERTS_DIR/$domain.pem"
chmod 600 "$HAPROXY_CERTS_DIR/$domain.pem"
else
log_error "Missing cert or key for $domain (fullchain=$fullchain, key=$key)"
fi
done
log_info "Certificate sync complete"
# Generate certs.list for multi-certificate SNI support
CERTS_LIST="$HAPROXY_CERTS_DIR/certs.list"
CONTAINER_CERTS_PATH="/opt/haproxy/certs"
log_info "Generating certificate list file..."
> "$CERTS_LIST"
for cert_file in "$HAPROXY_CERTS_DIR"/*.pem; do
[ -f "$cert_file" ] || continue
filename=$(basename "$cert_file")
container_cert_path="$CONTAINER_CERTS_PATH/$filename"
# Extract domain names from certificate SANs
domains=$(openssl x509 -in "$cert_file" -noout -text 2>/dev/null | \
grep -A1 "Subject Alternative Name" | \
tail -n1 | \
sed 's/DNS://g' | \
tr ',' '\n' | \
tr -d ' ')
# If no SANs, try to get CN
if [ -z "$domains" ]; then
domains=$(openssl x509 -in "$cert_file" -noout -subject 2>/dev/null | \
sed -n 's/.*CN *= *\([^,/]*\).*/\1/p')
fi
if [ -n "$domains" ]; then
echo "$domains" | while read -r domain; do
[ -n "$domain" ] || continue
echo "$container_cert_path $domain" >> "$CERTS_LIST"
done
else
log_info "No domain found in certificate: $filename, adding without SNI filter"
echo "$container_cert_path" >> "$CERTS_LIST"
fi
done
# Deduplicate entries
if [ -f "$CERTS_LIST" ]; then
sort -u "$CERTS_LIST" > "$CERTS_LIST.tmp"
mv "$CERTS_LIST.tmp" "$CERTS_LIST"
count=$(wc -l < "$CERTS_LIST")
log_info "Generated certs.list with $count entries"
fi
# Reload HAProxy container if running
if lxc-info -n haproxy -s 2>/dev/null | grep -q RUNNING; then
log_info "Reloading HAProxy container..."
/usr/sbin/haproxyctl reload 2>/dev/null || true
fi