Files
edgeguard-native/cmd/edgeguard-ctl/render.go
Debian 72269f5b7c feat: Squid Forward-Proxy — vollständig (Renderer + Handler + UI)
Stub raus, vollständig implementiert:

* internal/services/forwardproxy: CRUD-Repo gegen forward_proxy_acls
  (priority desc, action allow|deny).
* internal/handlers/forwardproxy.go: REST /api/v1/forward-proxy/acls
  mit Validation (acl_type-Whitelist verhindert Squid-Reload-Crash
  bei Tippfehlern). Auto-Reload nach jeder Mutation.
* internal/squid/squid.cfg.tpl + squid.go: Renderer schreibt
  /etc/edgeguard/squid/squid.conf, atomic + Symlink von
  /etc/squid/squid.conf (Squid liest Distro-Pfad — gleicher
  Pattern-Fix wie wg-quick). cache_dir 100MB, cache_mem 64MB,
  http_port 3128. Default-Policy: nur localnet (10/8, 172.16/12,
  192.168/16) — verhindert Open-Relay, falls Operator keine ACLs
  anlegt.
* main.go: forwardproxy-Repo + squid-Reloader instanziiert + Handler
  registriert.
* render.go: squid.New() bekommt Pool (war () vorher, Stub-Signatur).
* postinst sudoers: edgeguard darf systemctl reload squid.service.
* Frontend /forward-proxy: PageHeader + DataTable + ACL-Modal mit
  acl_type-Dropdown (13 Squid-Vokabular-Typen), action-Select,
  Priority. Sidebar-Eintrag unter Security.
* i18n DE/EN für fwd.* Block + nav.forwardProxy.

Verified end-to-end: ACL-Insert via SQL, render → squid reload →
curl -x http://127.0.0.1:3128 http://example.com/ → 200.

Version 1.0.26.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 00:27:05 +02:00

75 lines
2.1 KiB
Go

package main
import (
"context"
"fmt"
"os"
"strings"
"time"
"git.netcell-it.de/projekte/edgeguard-native/internal/configgen"
"git.netcell-it.de/projekte/edgeguard-native/internal/database"
"git.netcell-it.de/projekte/edgeguard-native/internal/firewall"
"git.netcell-it.de/projekte/edgeguard-native/internal/haproxy"
"git.netcell-it.de/projekte/edgeguard-native/internal/services/configorch"
"git.netcell-it.de/projekte/edgeguard-native/internal/services/secrets"
"git.netcell-it.de/projekte/edgeguard-native/internal/squid"
"git.netcell-it.de/projekte/edgeguard-native/internal/unbound"
"git.netcell-it.de/projekte/edgeguard-native/internal/wireguard"
)
// cmdRenderConfig regenerates every per-service config file from PG
// state. Used after package install (postinst), after admin
// mutations (UI button), or as a manual recovery action.
//
// Flags:
//
// --no-reload Write configs but skip systemctl reload.
// --only=svc1,svc2 Run only the named generators.
func cmdRenderConfig(args []string) int {
skipReload := false
var only []string
for i := 0; i < len(args); i++ {
switch {
case args[i] == "--no-reload":
skipReload = true
case strings.HasPrefix(args[i], "--only="):
val := strings.TrimPrefix(args[i], "--only=")
only = strings.Split(val, ",")
case args[i] == "-h" || args[i] == "--help":
fmt.Println("Usage: edgeguard-ctl render-config [--no-reload] [--only=svc1,svc2]")
return 0
}
}
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
pool, err := database.Open(ctx, database.ConnStringFromEnv())
if err != nil {
fmt.Fprintln(os.Stderr, "render-config: open db:", err)
return 1
}
defer pool.Close()
hap := haproxy.New(pool)
fw := firewall.New(pool)
sq := squid.New(pool)
wg := wireguard.New(pool, secrets.New(""))
ub := unbound.New()
if skipReload {
hap.SkipReload = true
fw.SkipReload = true
}
gens := []configgen.Generator{hap, fw, sq, wg, ub}
results, runErr := configorch.Run(ctx, gens, only)
fmt.Print(configorch.Summarise(results))
if runErr != nil {
fmt.Fprintln(os.Stderr, "render-config aborted:", runErr)
return 1
}
return 0
}