diff --git a/package/secubox/secubox-app-haproxy/Makefile b/package/secubox/secubox-app-haproxy/Makefile index 6c3b204..78a6559 100644 --- a/package/secubox/secubox-app-haproxy/Makefile +++ b/package/secubox/secubox-app-haproxy/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=secubox-app-haproxy PKG_VERSION:=1.0.0 -PKG_RELEASE:=13 +PKG_RELEASE:=14 PKG_MAINTAINER:=CyberMind PKG_LICENSE:=MIT @@ -50,11 +50,28 @@ define Package/secubox-app-haproxy/install $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_BIN) ./files/usr/sbin/haproxyctl $(1)/usr/sbin/haproxyctl + $(INSTALL_BIN) ./files/usr/sbin/haproxy-sync-certs $(1)/usr/sbin/haproxy-sync-certs + + $(INSTALL_DIR) $(1)/usr/lib/acme/deploy + $(INSTALL_BIN) ./files/usr/lib/acme/deploy/haproxy.sh $(1)/usr/lib/acme/deploy/haproxy.sh $(INSTALL_DIR) $(1)/usr/share/haproxy/templates $(INSTALL_DATA) ./files/usr/share/haproxy/templates/* $(1)/usr/share/haproxy/templates/ $(INSTALL_DIR) $(1)/usr/share/haproxy/certs + + # Add cron job for certificate sync after ACME renewals + $(INSTALL_DIR) $(1)/etc/cron.d + echo "# Sync ACME certs to HAProxy after renewals" > $(1)/etc/cron.d/haproxy-certs + echo "15 3 * * * root /usr/sbin/haproxy-sync-certs >/dev/null 2>&1" >> $(1)/etc/cron.d/haproxy-certs +endef + +define Package/secubox-app-haproxy/postinst +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] && exit 0 +# Sync existing ACME certificates on install +/usr/sbin/haproxy-sync-certs 2>/dev/null || true +exit 0 endef $(eval $(call BuildPackage,secubox-app-haproxy)) diff --git a/package/secubox/secubox-app-haproxy/files/etc/init.d/haproxy b/package/secubox/secubox-app-haproxy/files/etc/init.d/haproxy index 94cd476..6bed2b3 100644 --- a/package/secubox/secubox-app-haproxy/files/etc/init.d/haproxy +++ b/package/secubox/secubox-app-haproxy/files/etc/init.d/haproxy @@ -16,6 +16,9 @@ start_service() { [ "$enabled" = "1" ] || return 0 + # Sync ACME certificates to HAProxy format before starting + /usr/sbin/haproxy-sync-certs 2>/dev/null || true + procd_open_instance procd_set_param command "$PROG" service-run procd_set_param respawn 3600 5 0 diff --git a/package/secubox/secubox-app-haproxy/files/usr/lib/acme/deploy/haproxy.sh b/package/secubox/secubox-app-haproxy/files/usr/lib/acme/deploy/haproxy.sh new file mode 100644 index 0000000..eba5b5b --- /dev/null +++ b/package/secubox/secubox-app-haproxy/files/usr/lib/acme/deploy/haproxy.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# ACME deploy hook for HAProxy +# Combines fullchain + private key into single .pem file +# Usage: Called by acme.sh after certificate issuance/renewal + +HAPROXY_CERTS_DIR="/srv/haproxy/certs" + +# acme.sh passes these environment variables: +# DOMAIN - the domain name +# CERT_PATH - path to the domain certificate +# KEY_PATH - path to the domain private key +# CA_PATH - path to the intermediate CA certificate +# FULLCHAIN_PATH - path to the full chain certificate +# CERT_KEY_PATH - same as KEY_PATH + +deploy() { + local domain="$1" + local key_path="$2" + local cert_path="$3" + local ca_path="$4" + local fullchain_path="$5" + + [ -z "$domain" ] && { echo "Error: domain required"; return 1; } + + mkdir -p "$HAPROXY_CERTS_DIR" + + # Use fullchain if available, otherwise use cert + ca + local combined_cert="" + if [ -n "$fullchain_path" ] && [ -f "$fullchain_path" ]; then + combined_cert="$fullchain_path" + elif [ -n "$cert_path" ] && [ -f "$cert_path" ]; then + combined_cert="$cert_path" + else + echo "Error: No certificate file found for $domain" + return 1 + fi + + if [ -z "$key_path" ] || [ ! -f "$key_path" ]; then + echo "Error: No key file found for $domain" + return 1 + fi + + # Combine fullchain + private key for HAProxy + echo "Deploying certificate for $domain to HAProxy..." + cat "$combined_cert" "$key_path" > "$HAPROXY_CERTS_DIR/$domain.pem" + chmod 600 "$HAPROXY_CERTS_DIR/$domain.pem" + + echo "Certificate deployed: $HAPROXY_CERTS_DIR/$domain.pem" + + # Reload HAProxy if running + if [ -x /etc/init.d/haproxy ]; then + /etc/init.d/haproxy reload 2>/dev/null || true + fi + + return 0 +} + +# Entry point for acme.sh deploy hook +deploy "$Le_Domain" "$CERT_KEY_PATH" "$CERT_PATH" "$CA_CERT_PATH" "$CERT_FULLCHAIN_PATH" diff --git a/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxy-sync-certs b/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxy-sync-certs new file mode 100644 index 0000000..994321a --- /dev/null +++ b/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxy-sync-certs @@ -0,0 +1,47 @@ +#!/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" + +# Reload HAProxy if running +if pgrep -x haproxy >/dev/null 2>&1 || lxc-info -n haproxy -s 2>/dev/null | grep -q RUNNING; then + log_info "Reloading HAProxy..." + /etc/init.d/haproxy reload 2>/dev/null || true +fi diff --git a/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl b/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl index c72ce7d..a94ee7b 100644 --- a/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl +++ b/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl @@ -630,8 +630,13 @@ cmd_cert_add() { --home "$LE_WORKING_DIR" \ --cert-file "$CERTS_PATH/$domain.crt" \ --key-file "$CERTS_PATH/$domain.key" \ - --fullchain-file "$CERTS_PATH/$domain.pem" \ + --fullchain-file "$CERTS_PATH/$domain.fullchain.pem" \ --reloadcmd "/etc/init.d/haproxy reload" 2>/dev/null || true + + # HAProxy needs combined file: fullchain + private key + log_info "Creating combined PEM for HAProxy..." + cat "$CERTS_PATH/$domain.fullchain.pem" "$CERTS_PATH/$domain.key" > "$CERTS_PATH/$domain.pem" + chmod 600 "$CERTS_PATH/$domain.pem" fi # Restart HAProxy if it was running