fix(haproxy+unbound): http_to_https per Domain + leere Forward-Zones überspringen

haproxy: http_to_https=false Domains bekommen jetzt eigene use_backend-Regeln
im public_http-Frontend statt dem globalen HTTPS-Redirect. Das Feld war bisher
in DB + UI vorhanden aber vom Config-Generator komplett ignoriert.

unbound: Forward-Zones ohne forward-addr (ForwardTo=nil oder leer) werden jetzt
übersprungen. Unbound lehnt solche Blöcke beim Start ab.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-05-24 12:36:53 +02:00
parent 519522b8ee
commit 92eece936d
7 changed files with 33 additions and 9 deletions

View File

@@ -1 +1 @@
1.1.81 1.1.82

View File

@@ -60,7 +60,7 @@ import (
usersvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/users" usersvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/users"
) )
var version = "1.1.81" var version = "1.1.82"
func main() { func main() {
addr := os.Getenv("EDGEGUARD_API_ADDR") addr := os.Getenv("EDGEGUARD_API_ADDR")

View File

@@ -11,7 +11,7 @@ import (
"git.netcell-it.de/projekte/edgeguard-native/internal/services/setup" "git.netcell-it.de/projekte/edgeguard-native/internal/services/setup"
) )
var version = "1.1.81" var version = "1.1.82"
const usage = `edgeguard-ctl — EdgeGuard CLI const usage = `edgeguard-ctl — EdgeGuard CLI

View File

@@ -35,7 +35,7 @@ import (
"git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts" "git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts"
) )
var version = "1.1.81" var version = "1.1.82"
const ( const (
// renewTickInterval — how often we re-evaluate expiring certs. // renewTickInterval — how often we re-evaluate expiring certs.

View File

@@ -32,7 +32,8 @@ defaults
# ── Public :80 ───────────────────────────────────────────────────────── # ── Public :80 ─────────────────────────────────────────────────────────
# ACME-01 challenges proxy to edgeguard-api which serves the webroot. # ACME-01 challenges proxy to edgeguard-api which serves the webroot.
# Everything else redirects to HTTPS. # Domains with http_to_https=false bypass the redirect and are proxied
# directly. Everything else redirects to HTTPS.
frontend public_http frontend public_http
bind :80 bind :80
{{- if .IPv6Enabled}} {{- if .IPv6Enabled}}
@@ -40,11 +41,21 @@ frontend public_http
{{- end}} {{- end}}
acl is_acme path_beg /.well-known/acme-challenge/ acl is_acme path_beg /.well-known/acme-challenge/
{{- range $d := .HTTPDomains}}
acl is_http_only hdr(host) -i {{$d.Name}}
{{- end}}
# Redirect to HTTPS first (skipped for ACME paths) — must come # Redirect to HTTPS (skipped for ACME and http-only domains).
# before use_backend so HAProxy doesn't warn about ordering. http-request redirect scheme https code 301 unless is_acme{{if .HTTPDomains}} or is_http_only{{end}}
http-request redirect scheme https code 301 unless is_acme
{{- range $d := .HTTPDomains}}
{{- range $r := $d.Routes}}
use_backend eg_backend_{{$r.BackendID}} if { hdr(host) -i {{$d.Name}} } { path_beg {{$r.PathPrefix}} }
{{- end}}
{{- if $d.PrimaryBackendID}}
use_backend eg_backend_{{$d.PrimaryBackendID}} if { hdr(host) -i {{$d.Name}} }
{{- end}}
{{- end}}
use_backend api_backend if is_acme use_backend api_backend if is_acme
# ── Public :443 (Customer-Backends only) ────────────────────────────── # ── Public :443 (Customer-Backends only) ──────────────────────────────

View File

@@ -133,6 +133,10 @@ type View struct {
Domains []DomainView Domains []DomainView
Backends []BackendView Backends []BackendView
// HTTPDomains: aktive Domains mit HTTPToHTTPS=false. Diese bekommen
// in public_http eigene use_backend-Regeln statt dem globalen Redirect.
HTTPDomains []DomainView
// GlobalMaintenance: wenn true emittiert public_https einen // GlobalMaintenance: wenn true emittiert public_https einen
// 503-Block ganz am Anfang (vor allen anderen ACLs), der // 503-Block ganz am Anfang (vor allen anderen ACLs), der
// alle Customer-Domains gleichzeitig stilllegt. mgmt_https // alle Customer-Domains gleichzeitig stilllegt. mgmt_https
@@ -278,7 +282,13 @@ func (g *Generator) loadView(ctx context.Context) (*View, error) {
domViews = append(domViews, dv) domViews = append(domViews, dv)
} }
v := &View{Domains: domViews, Backends: activeBackends} httpDomains := make([]DomainView, 0)
for _, dv := range domViews {
if !dv.HTTPToHTTPS && (dv.PrimaryBackendID != nil || len(dv.Routes) > 0) {
httpDomains = append(httpDomains, dv)
}
}
v := &View{Domains: domViews, Backends: activeBackends, HTTPDomains: httpDomains}
if g.SetupStore != nil { if g.SetupStore != nil {
if st, err := g.SetupStore.Load(); err == nil && st != nil { if st, err := g.SetupStore.Load(); err == nil && st != nil {
v.GlobalMaintenance = st.MaintenanceMode v.GlobalMaintenance = st.MaintenanceMode

View File

@@ -136,6 +136,9 @@ func (g *Generator) buildView(ctx context.Context) (*View, error) {
if z.ForwardTo != nil { if z.ForwardTo != nil {
fwd = splitCSV(*z.ForwardTo) fwd = splitCSV(*z.ForwardTo)
} }
if len(fwd) == 0 {
continue // skip — Unbound rejects a forward-zone without forward-addr
}
view.ForwardZones = append(view.ForwardZones, forwardZoneView{ view.ForwardZones = append(view.ForwardZones, forwardZoneView{
Name: z.Name, Forwarders: fwd, Name: z.Name, Forwarders: fwd,
}) })