feat(haproxy,service-registry): Auto-open firewall when publishing
Automatically creates firewall rules for HAProxy when: - Requesting a certificate (haproxyctl cert add) - Publishing a service with a domain (service-registry) Added firewall rules: - HAProxy-HTTP: Allow port 80 from WAN (ACME challenges) - HAProxy-HTTPS: Allow port 443 from WAN (HTTPS traffic) Rules are only created if they don't exist, preventing duplicates. Firewall reloads automatically after rule creation. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
a96899c520
commit
b762bffa44
@ -41,6 +41,59 @@ get_process_for_port() {
|
||||
netstat -tlnp 2>/dev/null | grep ":${port} " | awk '{print $7}' | cut -d'/' -f2 | head -1
|
||||
}
|
||||
|
||||
# Helper: Ensure firewall rules for HAProxy (HTTP/HTTPS from WAN)
|
||||
ensure_haproxy_firewall_rules() {
|
||||
local http_port="${1:-80}"
|
||||
local https_port="${2:-443}"
|
||||
local changed=0
|
||||
|
||||
# Check and create HTTP rule
|
||||
local http_exists=0
|
||||
local i=0
|
||||
while uci -q get firewall.@rule[$i] >/dev/null 2>&1; do
|
||||
local name=$(uci -q get firewall.@rule[$i].name)
|
||||
[ "$name" = "HAProxy-HTTP" ] && http_exists=1 && break
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
if [ "$http_exists" = "0" ]; then
|
||||
uci add firewall rule >/dev/null
|
||||
uci set firewall.@rule[-1].name='HAProxy-HTTP'
|
||||
uci set firewall.@rule[-1].src='wan'
|
||||
uci set firewall.@rule[-1].dest_port="$http_port"
|
||||
uci set firewall.@rule[-1].proto='tcp'
|
||||
uci set firewall.@rule[-1].target='ACCEPT'
|
||||
uci set firewall.@rule[-1].enabled='1'
|
||||
changed=1
|
||||
fi
|
||||
|
||||
# Check and create HTTPS rule
|
||||
local https_exists=0
|
||||
i=0
|
||||
while uci -q get firewall.@rule[$i] >/dev/null 2>&1; do
|
||||
local name=$(uci -q get firewall.@rule[$i].name)
|
||||
[ "$name" = "HAProxy-HTTPS" ] && https_exists=1 && break
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
if [ "$https_exists" = "0" ]; then
|
||||
uci add firewall rule >/dev/null
|
||||
uci set firewall.@rule[-1].name='HAProxy-HTTPS'
|
||||
uci set firewall.@rule[-1].src='wan'
|
||||
uci set firewall.@rule[-1].dest_port="$https_port"
|
||||
uci set firewall.@rule[-1].proto='tcp'
|
||||
uci set firewall.@rule[-1].target='ACCEPT'
|
||||
uci set firewall.@rule[-1].enabled='1'
|
||||
changed=1
|
||||
fi
|
||||
|
||||
# Apply firewall changes
|
||||
if [ "$changed" = "1" ]; then
|
||||
uci commit firewall
|
||||
/etc/init.d/firewall reload >/dev/null 2>&1 &
|
||||
fi
|
||||
}
|
||||
|
||||
# List all services aggregated from providers
|
||||
method_list_services() {
|
||||
local lan_ip
|
||||
@ -542,6 +595,9 @@ method_publish_service() {
|
||||
|
||||
# Create HAProxy vhost if domain specified
|
||||
if [ -n "$domain" ]; then
|
||||
# Ensure firewall allows HTTP/HTTPS from WAN (for public access + ACME)
|
||||
ensure_haproxy_firewall_rules
|
||||
|
||||
# Create backend
|
||||
ubus call luci.haproxy create_backend "{\"name\":\"$section_id\",\"mode\":\"http\"}" 2>/dev/null
|
||||
|
||||
@ -551,6 +607,10 @@ method_publish_service() {
|
||||
# Create vhost with SSL
|
||||
ubus call luci.haproxy create_vhost "{\"domain\":\"$domain\",\"backend\":\"$section_id\",\"ssl\":1,\"ssl_redirect\":1,\"acme\":1,\"enabled\":1}" 2>/dev/null
|
||||
|
||||
# Regenerate HAProxy config to include the new vhost
|
||||
ubus call luci.haproxy generate 2>/dev/null
|
||||
ubus call luci.haproxy reload 2>/dev/null
|
||||
|
||||
uci set "$UCI_CONFIG.$section_id.haproxy_enabled=1"
|
||||
uci set "$UCI_CONFIG.$section_id.haproxy_domain=$domain"
|
||||
uci set "$UCI_CONFIG.$section_id.haproxy_ssl=1"
|
||||
|
||||
@ -33,6 +33,83 @@ ensure_dir() { [ -d "$1" ] || mkdir -p "$1"; }
|
||||
uci_get() { uci -q get ${CONFIG}.$1; }
|
||||
uci_set() { uci set ${CONFIG}.$1="$2" && uci commit ${CONFIG}; }
|
||||
|
||||
# Firewall management - auto-open ports when publishing
|
||||
firewall_ensure_haproxy_rules() {
|
||||
local http_port="${1:-80}"
|
||||
local https_port="${2:-443}"
|
||||
local changed=0
|
||||
|
||||
# Check if HTTP rule exists
|
||||
local http_rule_exists=0
|
||||
local i=0
|
||||
while uci -q get firewall.@rule[$i] >/dev/null 2>&1; do
|
||||
local name=$(uci -q get firewall.@rule[$i].name)
|
||||
if [ "$name" = "HAProxy-HTTP" ]; then
|
||||
http_rule_exists=1
|
||||
break
|
||||
fi
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
# Create HTTP rule if missing
|
||||
if [ "$http_rule_exists" = "0" ]; then
|
||||
log_info "Creating firewall rule for HTTP (port $http_port)..."
|
||||
uci add firewall rule
|
||||
uci set firewall.@rule[-1].name='HAProxy-HTTP'
|
||||
uci set firewall.@rule[-1].src='wan'
|
||||
uci set firewall.@rule[-1].dest_port="$http_port"
|
||||
uci set firewall.@rule[-1].proto='tcp'
|
||||
uci set firewall.@rule[-1].target='ACCEPT'
|
||||
uci set firewall.@rule[-1].enabled='1'
|
||||
changed=1
|
||||
fi
|
||||
|
||||
# Check if HTTPS rule exists
|
||||
local https_rule_exists=0
|
||||
i=0
|
||||
while uci -q get firewall.@rule[$i] >/dev/null 2>&1; do
|
||||
local name=$(uci -q get firewall.@rule[$i].name)
|
||||
if [ "$name" = "HAProxy-HTTPS" ]; then
|
||||
https_rule_exists=1
|
||||
break
|
||||
fi
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
# Create HTTPS rule if missing
|
||||
if [ "$https_rule_exists" = "0" ]; then
|
||||
log_info "Creating firewall rule for HTTPS (port $https_port)..."
|
||||
uci add firewall rule
|
||||
uci set firewall.@rule[-1].name='HAProxy-HTTPS'
|
||||
uci set firewall.@rule[-1].src='wan'
|
||||
uci set firewall.@rule[-1].dest_port="$https_port"
|
||||
uci set firewall.@rule[-1].proto='tcp'
|
||||
uci set firewall.@rule[-1].target='ACCEPT'
|
||||
uci set firewall.@rule[-1].enabled='1'
|
||||
changed=1
|
||||
fi
|
||||
|
||||
# Apply changes
|
||||
if [ "$changed" = "1" ]; then
|
||||
uci commit firewall
|
||||
/etc/init.d/firewall reload 2>/dev/null || true
|
||||
log_info "Firewall rules updated - ports $http_port and $https_port open on WAN"
|
||||
fi
|
||||
}
|
||||
|
||||
firewall_check_haproxy_rules() {
|
||||
local http_ok=0 https_ok=0
|
||||
local i=0
|
||||
while uci -q get firewall.@rule[$i] >/dev/null 2>&1; do
|
||||
local name=$(uci -q get firewall.@rule[$i].name)
|
||||
local enabled=$(uci -q get firewall.@rule[$i].enabled)
|
||||
[ "$name" = "HAProxy-HTTP" ] && [ "$enabled" != "0" ] && http_ok=1
|
||||
[ "$name" = "HAProxy-HTTPS" ] && [ "$enabled" != "0" ] && https_ok=1
|
||||
i=$((i + 1))
|
||||
done
|
||||
[ "$http_ok" = "1" ] && [ "$https_ok" = "1" ]
|
||||
}
|
||||
|
||||
# Load configuration
|
||||
load_config() {
|
||||
http_port="$(uci_get main.http_port)" || http_port="80"
|
||||
@ -789,6 +866,10 @@ cmd_cert_add() {
|
||||
log_info "Ensuring HAProxy config is up to date..."
|
||||
generate_config
|
||||
|
||||
# Ensure firewall allows HTTP/HTTPS from WAN (required for ACME)
|
||||
log_info "Checking firewall rules..."
|
||||
firewall_ensure_haproxy_rules "$http_port" "$https_port"
|
||||
|
||||
local email=$(uci_get acme.email)
|
||||
local staging=$(uci_get acme.staging)
|
||||
local key_type_raw=$(uci_get acme.key_type) || key_type_raw="ec-256"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user