chore: initial skeleton
- docs/architecture.md: native rewrite plan (5 services + control plane,
Active-Active cluster like nmg, Floating-IP for HTTP ingress)
- cmd/edgeguard-{api,scheduler,ctl}: minimal Gin + CLI stubs
- packaging/debian/edgeguard-{api,ui,meta}: control + maintainer scripts
- deploy/systemd/edgeguard-api.service + edgeguard-scheduler.service
with hardening defaults
- Makefile: build / cross-compile (amd64+arm64) / deb / publish targets
- scripts/install.sh + scripts/apt-repo/build-package.sh stubs
This commit is contained in:
44
.gitignore
vendored
Normal file
44
.gitignore
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
# ── Go ────────────────────────────────────────────────────────────────────
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
*.test
|
||||
*.out
|
||||
go.work
|
||||
go.work.sum
|
||||
|
||||
# ── Build artifacts ───────────────────────────────────────────────────────
|
||||
/build/
|
||||
/dist/
|
||||
/edgeguard-api
|
||||
/edgeguard-scheduler
|
||||
/edgeguard-ctl
|
||||
|
||||
# ── Env / secrets ─────────────────────────────────────────────────────────
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# ── Claude Code ───────────────────────────────────────────────────────────
|
||||
.claude/
|
||||
|
||||
# ── Editor / OS ───────────────────────────────────────────────────────────
|
||||
.DS_Store
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# ── Debian packaging intermediates ────────────────────────────────────────
|
||||
*.deb
|
||||
*.buildinfo
|
||||
*.changes
|
||||
|
||||
# ── mkdocs build output ───────────────────────────────────────────────────
|
||||
docs-site/site/
|
||||
|
||||
# ── UI build output ───────────────────────────────────────────────────────
|
||||
management-ui/dist/
|
||||
management-ui/node_modules/
|
||||
104
Makefile
Normal file
104
Makefile
Normal file
@@ -0,0 +1,104 @@
|
||||
# EdgeGuard — Build-System.
|
||||
# Cross-Compile für Debian 13 + Ubuntu 24.04 auf amd64 und arm64.
|
||||
# CGO_ENABLED=0 (statische Binaries, keine libre2-/CGO-Abhängigkeit in v1).
|
||||
|
||||
GO ?= $(shell which go || echo /usr/local/go/bin/go)
|
||||
MODULE := git.netcell-it.de/projekte/edgeguard-native
|
||||
BINARIES := edgeguard-api edgeguard-scheduler edgeguard-ctl
|
||||
VERSION := $(shell cat VERSION 2>/dev/null || echo 0.0.1-dev)
|
||||
LDFLAGS := -s -w -X main.version=$(VERSION)
|
||||
GOFLAGS := -trimpath -mod=readonly
|
||||
export CGO_ENABLED ?= 0
|
||||
|
||||
.PHONY: all help build test lint tidy clean ui \
|
||||
build-linux-amd64 build-linux-arm64 \
|
||||
deb deb-amd64 deb-arm64 \
|
||||
publish publish-amd64 publish-arm64
|
||||
|
||||
all: build
|
||||
|
||||
help:
|
||||
@echo "EdgeGuard build targets:"
|
||||
@echo " build Build all binaries for the host architecture (build/host/)"
|
||||
@echo " build-linux-amd64 Cross-compile all binaries for linux/amd64 (build/amd64/)"
|
||||
@echo " build-linux-arm64 Cross-compile all binaries for linux/arm64 (build/arm64/)"
|
||||
@echo " test go test ./..."
|
||||
@echo " lint go vet + staticcheck (if installed)"
|
||||
@echo " tidy go mod tidy"
|
||||
@echo " ui Build management-ui (vite)"
|
||||
@echo " deb-amd64 Cross-compile + build edgeguard_<ver>_amd64.deb"
|
||||
@echo " deb-arm64 Cross-compile + build edgeguard_<ver>_arm64.deb"
|
||||
@echo " deb Build both amd64 and arm64 .deb packages"
|
||||
@echo " publish-amd64 Build amd64 deb AND upload to Gitea"
|
||||
@echo " publish-arm64 Same for arm64"
|
||||
@echo " publish publish-amd64 + publish-arm64"
|
||||
@echo " clean Remove build artifacts"
|
||||
|
||||
build:
|
||||
@mkdir -p build/host
|
||||
@for bin in $(BINARIES); do \
|
||||
echo " -> build/host/$$bin"; \
|
||||
$(GO) build $(GOFLAGS) -ldflags '$(LDFLAGS)' \
|
||||
-o build/host/$$bin ./cmd/$$bin || exit 1; \
|
||||
done
|
||||
|
||||
build-linux-amd64:
|
||||
@mkdir -p build/amd64
|
||||
@for bin in $(BINARIES); do \
|
||||
echo " -> build/amd64/$$bin"; \
|
||||
GOOS=linux GOARCH=amd64 $(GO) build $(GOFLAGS) -ldflags '$(LDFLAGS)' \
|
||||
-o build/amd64/$$bin ./cmd/$$bin || exit 1; \
|
||||
done
|
||||
|
||||
build-linux-arm64:
|
||||
@mkdir -p build/arm64
|
||||
@for bin in $(BINARIES); do \
|
||||
echo " -> build/arm64/$$bin"; \
|
||||
GOOS=linux GOARCH=arm64 $(GO) build $(GOFLAGS) -ldflags '$(LDFLAGS)' \
|
||||
-o build/arm64/$$bin ./cmd/$$bin || exit 1; \
|
||||
done
|
||||
|
||||
test:
|
||||
$(GO) test $(GOFLAGS) ./...
|
||||
|
||||
lint:
|
||||
$(GO) vet ./...
|
||||
@command -v staticcheck >/dev/null && staticcheck ./... || echo "staticcheck not installed, skipping"
|
||||
|
||||
tidy:
|
||||
$(GO) mod tidy
|
||||
|
||||
ui:
|
||||
@echo " -> management-ui (vite build, version $(VERSION))"
|
||||
@cd management-ui && npm run build
|
||||
|
||||
deb-amd64: build-linux-amd64
|
||||
@./scripts/apt-repo/build-package.sh amd64 $(VERSION)
|
||||
|
||||
deb-arm64: build-linux-arm64
|
||||
@./scripts/apt-repo/build-package.sh arm64 $(VERSION)
|
||||
|
||||
deb: deb-amd64 deb-arm64
|
||||
|
||||
GITEA_DEB_URL := https://git.netcell-it.de/api/packages/projekte/debian/pool/trixie/main/upload
|
||||
|
||||
publish-amd64: deb-amd64
|
||||
@TOK="$$(cat $$HOME/.gitea-token | tr -d '\n')"; \
|
||||
if [ -z "$$TOK" ]; then echo "publish: ~/.gitea-token is empty"; exit 1; fi; \
|
||||
echo " -> publish edgeguard-api_$(VERSION)_amd64.deb"; \
|
||||
curl -sS -H "Authorization: token $$TOK" \
|
||||
--upload-file build/deb/edgeguard-api_$(VERSION)_amd64.deb \
|
||||
$(GITEA_DEB_URL)
|
||||
|
||||
publish-arm64: deb-arm64
|
||||
@TOK="$$(cat $$HOME/.gitea-token | tr -d '\n')"; \
|
||||
if [ -z "$$TOK" ]; then echo "publish: ~/.gitea-token is empty"; exit 1; fi; \
|
||||
echo " -> publish edgeguard-api_$(VERSION)_arm64.deb"; \
|
||||
curl -sS -H "Authorization: token $$TOK" \
|
||||
--upload-file build/deb/edgeguard-api_$(VERSION)_arm64.deb \
|
||||
$(GITEA_DEB_URL)
|
||||
|
||||
publish: publish-amd64 publish-arm64
|
||||
|
||||
clean:
|
||||
rm -rf build/
|
||||
35
README.md
Normal file
35
README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# EdgeGuard
|
||||
|
||||
Native Reverse-Proxy / Loadbalancer / Forward-Proxy / VPN / Firewall — als signiertes `.deb` für Debian 13 + Ubuntu 24.04, amd64 + arm64.
|
||||
|
||||
> Status: **v0.x — Neufassung des bisherigen Docker-Stacks**, parallel zum Bestand `proxy-lb-waf`.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
curl -fsSL https://get.edgeguard.netcell-it.de | sudo bash
|
||||
```
|
||||
|
||||
**Unterstützte Plattformen:** Debian 13 (Trixie), Ubuntu 24.04 LTS (Noble) — amd64 + arm64.
|
||||
|
||||
## Architektur in Kürze
|
||||
|
||||
- **Daten-Services (v1):** HAProxy, Angie, Squid, WireGuard, nftables — alle nativ via APT, Configs aus PostgreSQL generiert.
|
||||
- **Control-Plane:** `edgeguard-api` (Go/Gin), `management-ui` (React/AntD), PostgreSQL 16, KeyDB Active-Active.
|
||||
- **Cluster:** N symmetrische Peers, KeyDB AA für Shared State, PG Streaming Replication, Floating-IP des Hosters statt VRRP.
|
||||
- **Auslieferung:** signierte `.deb`, Update via `apt`. Update-Trigger via UI/API.
|
||||
|
||||
Volle Architektur: [`docs/architecture.md`](docs/architecture.md).
|
||||
|
||||
## Build
|
||||
|
||||
```
|
||||
make build # Host-Architektur
|
||||
make deb # amd64 + arm64 .deb
|
||||
make publish # deb + Upload Gitea Package Registry
|
||||
```
|
||||
|
||||
## Repo
|
||||
|
||||
- **Lokal:** `/var/www/edgeguard-native`
|
||||
- **Gitea:** `https://git.netcell-it.de/projekte/edgeguard-native`
|
||||
31
cmd/edgeguard-api/main.go
Normal file
31
cmd/edgeguard-api/main.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var version = "0.0.1-dev"
|
||||
|
||||
func main() {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
r := gin.New()
|
||||
r.Use(gin.Recovery())
|
||||
|
||||
r.GET("/api/health", func(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"status": "ok", "version": version})
|
||||
})
|
||||
|
||||
addr := os.Getenv("EDGEGUARD_API_ADDR")
|
||||
if addr == "" {
|
||||
addr = "127.0.0.1:9443"
|
||||
}
|
||||
|
||||
log.Printf("edgeguard-api %s listening on %s", version, addr)
|
||||
if err := r.Run(addr); err != nil {
|
||||
log.Fatalf("edgeguard-api: %v", err)
|
||||
}
|
||||
}
|
||||
40
cmd/edgeguard-ctl/main.go
Normal file
40
cmd/edgeguard-ctl/main.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
var version = "0.0.1-dev"
|
||||
|
||||
const usage = `edgeguard-ctl — EdgeGuard CLI
|
||||
|
||||
Usage:
|
||||
edgeguard-ctl <command> [args]
|
||||
|
||||
Commands:
|
||||
version Print version
|
||||
initdb Initialise PostgreSQL database and user (idempotent)
|
||||
migrate up Apply pending migrations
|
||||
migrate down Roll back last migration (dev only)
|
||||
cluster-join Join an existing cluster (--from URL --token TOKEN)
|
||||
cluster-leave Leave the cluster cleanly
|
||||
promote Promote this node's PG to primary
|
||||
dump-config Print effective config to stdout
|
||||
`
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Fprint(os.Stderr, usage)
|
||||
os.Exit(2)
|
||||
}
|
||||
switch os.Args[1] {
|
||||
case "version":
|
||||
fmt.Println(version)
|
||||
case "-h", "--help", "help":
|
||||
fmt.Print(usage)
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "edgeguard-ctl: command %q not yet implemented\n", os.Args[1])
|
||||
os.Exit(2)
|
||||
}
|
||||
}
|
||||
15
cmd/edgeguard-scheduler/main.go
Normal file
15
cmd/edgeguard-scheduler/main.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
var version = "0.0.1-dev"
|
||||
|
||||
func main() {
|
||||
log.Printf("edgeguard-scheduler %s starting", version)
|
||||
for {
|
||||
time.Sleep(60 * time.Second)
|
||||
}
|
||||
}
|
||||
0
deploy/angie/.gitkeep
Normal file
0
deploy/angie/.gitkeep
Normal file
0
deploy/haproxy/.gitkeep
Normal file
0
deploy/haproxy/.gitkeep
Normal file
0
deploy/nftables/.gitkeep
Normal file
0
deploy/nftables/.gitkeep
Normal file
0
deploy/squid/.gitkeep
Normal file
0
deploy/squid/.gitkeep
Normal file
31
deploy/systemd/edgeguard-api.service
Normal file
31
deploy/systemd/edgeguard-api.service
Normal file
@@ -0,0 +1,31 @@
|
||||
[Unit]
|
||||
Description=EdgeGuard Management API
|
||||
Documentation=https://git.netcell-it.de/projekte/edgeguard-native
|
||||
After=network-online.target postgresql.service keydb-server.service
|
||||
Wants=network-online.target keydb-server.service
|
||||
Requires=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=edgeguard
|
||||
Group=edgeguard
|
||||
ExecStart=/usr/bin/edgeguard-api
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
# Hardening — API needs to shell out to `sudo systemctl reload haproxy/angie/squid`
|
||||
# after writing configs. Sandboxing stays strict around fs/net.
|
||||
NoNewPrivileges=false
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectControlGroups=true
|
||||
PrivateTmp=true
|
||||
PrivateDevices=true
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||
SystemCallFilter=@system-service
|
||||
ReadWritePaths=/etc/edgeguard /var/lib/edgeguard /var/log/edgeguard
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
28
deploy/systemd/edgeguard-scheduler.service
Normal file
28
deploy/systemd/edgeguard-scheduler.service
Normal file
@@ -0,0 +1,28 @@
|
||||
[Unit]
|
||||
Description=EdgeGuard Scheduler (cron-like jobs)
|
||||
Documentation=https://git.netcell-it.de/projekte/edgeguard-native
|
||||
After=edgeguard-api.service
|
||||
Requires=edgeguard-api.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=edgeguard
|
||||
Group=edgeguard
|
||||
ExecStart=/usr/bin/edgeguard-scheduler
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectControlGroups=true
|
||||
PrivateTmp=true
|
||||
PrivateDevices=true
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||
SystemCallFilter=@system-service
|
||||
ReadWritePaths=/var/lib/edgeguard /var/log/edgeguard
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
384
docs/architecture.md
Normal file
384
docs/architecture.md
Normal file
@@ -0,0 +1,384 @@
|
||||
# EdgeGuard — Architektur
|
||||
|
||||
> Status: **v0.1 (Entwurf)** · Stand: 2026-05-08 · Ziel-Plattformen: Debian 13 (Trixie) + Ubuntu 24.04 LTS (Noble Numbat), Architekturen amd64 + arm64.
|
||||
|
||||
EdgeGuard ist die native Neufassung des bisherigen Docker-basierten Reverse-Proxy/Loadbalancer/Forward-Proxy/VPN-Stacks. Vorbild für Architektur, Build-System und Cluster-Modell ist [`mail-gateway`](../../mail-gateway/docs/architecture.md) (`nmg`); UI-Pattern und Bootstrap-Onliner stammen aus [`netcell-webpanel`](../../netcell-webpanel/CLAUDE.md) (`enconf`).
|
||||
|
||||
---
|
||||
|
||||
## 0. Leitplanken (nicht verhandelbar)
|
||||
|
||||
- **Kein Docker.** Alle Dienste nativ unter `systemd`, installiert via `apt`. Distro-Pakete für Drittsoftware (HAProxy, Angie, Squid, WireGuard, PostgreSQL, KeyDB, certbot), eigene `.deb`-Pakete für EdgeGuard-Code (api, ui, ctl).
|
||||
- **Plattform-Matrix:** Debian 13 (Trixie) **und** Ubuntu 24.04 LTS (Noble Numbat), je amd64 + arm64. Alle vier Targets gleichberechtigt.
|
||||
- **Auslieferung:** signierte `.deb`-Pakete + Meta-Paket via APT. Bootstrap ist der enconf-analoge curl-Onliner `curl -fsSL https://get.edgeguard.netcell-it.de | sudo bash`.
|
||||
- **HA nativ als Cluster:** N symmetrische Peers, **KeyDB Active-Active** für Shared State + **PostgreSQL Streaming Replication** (single writer, transparenter API-Write-Proxy) + **Floating-IP des Hosters** für HTTP/HTTPS-Ingress (nicht VRRP, nicht DNS-RR).
|
||||
- **Kein WAF, kein IDS, kein DHCP, kein RADIUS, keine Mail-Funktion in v1.** Mail-Gateway ist eigenes Produkt (`nmg`); WAF/CrowdSec/Suricata kommen ggf. in v2.
|
||||
- **Migrations:** `goose` (SQL-Dateien), nicht GORM AutoMigrate.
|
||||
|
||||
**Nicht-Ziele (ausdrücklich):** kein WAF, kein Network-IDS (Suricata), kein IPS (CrowdSec), kein DHCP-Server (Kea), kein RADIUS, keine Mail-Verarbeitung, keine Multi-Tenant-GuardZones in v1, keine ISO-Builds (kein EdgeGuardOS-Klon — nur APT).
|
||||
|
||||
---
|
||||
|
||||
## 1. Scope — fünf Daten-Services + Control-Plane
|
||||
|
||||
| Service | Rolle | Distro-Paket | Config-Quelle |
|
||||
|---|---|---|---|
|
||||
| **HAProxy** | Public-Ingress (80/443), interner LB (8081), TLS-PassThrough | `haproxy` (Debian/Ubuntu) | aus PG generiert, `systemctl reload haproxy` |
|
||||
| **Angie** | Reverse-Proxy, vHost-Routing, ACME-Webroot | eigenes APT-Repo (`angie`) | aus PG generiert, `systemctl reload angie` |
|
||||
| **Squid** | Forward-Proxy mit ACL/Auth | `squid` | aus PG generiert, `systemctl reload squid` |
|
||||
| **WireGuard** | Site-to-Site- + Road-Warrior-VPN | `wireguard-tools` (Kernel-Modul ab Kernel 5.6) | aus PG generiert, `wg syncconf` |
|
||||
| **nftables** | Firewall (Input + Forward + NAT) | `nftables` | aus PG generiert, `nft -f /etc/nftables.conf` |
|
||||
|
||||
**Control-Plane:**
|
||||
|
||||
| Komponente | Rolle |
|
||||
|---|---|
|
||||
| `edgeguard-api` | Go/Gin REST-API, bindet `127.0.0.1:9443`, Reads aus lokaler PG, Writes an Cluster-Primary |
|
||||
| `edgeguard-scheduler` | Cron-artige Jobs (ACME-Renewal-Hook, Backup, Health-Aggregation, License-Heartbeat) |
|
||||
| `edgeguard-ctl` | CLI für Setup/Wartung (`initdb`, `migrate`, `cluster-join`, `promote`, `dump-config`) |
|
||||
| `management-ui` | React 19 + AntD 6 + Vite, statisch unter `/usr/share/edgeguard/ui/`, Angie liefert aus |
|
||||
| **PostgreSQL 16** | Single Source of Truth — Domains, Backends, Routing-Rules, ACLs, Peers, etc. |
|
||||
| **KeyDB** (Redis-kompatibel) | Active-Active-Replication, Cluster-State, Locks, Rate-Counter, Pub/Sub für Config-Reload |
|
||||
|
||||
---
|
||||
|
||||
## 2. Package-Layout (Repo)
|
||||
|
||||
```
|
||||
/var/www/edgeguard-native/
|
||||
├── cmd/ # Go-Binary-Entry-Points
|
||||
│ ├── edgeguard-api/ # Management-API (HTTP, 127.0.0.1:9443)
|
||||
│ ├── edgeguard-scheduler/ # Cron-artige Jobs
|
||||
│ └── edgeguard-ctl/ # CLI für Setup/Wartung
|
||||
├── internal/
|
||||
│ ├── models/ # GORM-Models (domain, backend, routing_rule, acl, peer, …)
|
||||
│ ├── handlers/ # HTTP-Handler (REST)
|
||||
│ ├── services/ # Business-Logik (config-render, health-check, cluster-sync)
|
||||
│ ├── haproxy/ # HAProxy-Config-Generator
|
||||
│ ├── angie/ # Angie-Config-Generator (vHosts, Upstreams, ACME)
|
||||
│ ├── squid/ # Squid-Config-Generator (squid.conf + squid.d/*)
|
||||
│ ├── wireguard/ # WireGuard-Config-Generator (wg-quick + wg syncconf)
|
||||
│ ├── firewall/ # nftables-Ruleset-Generator
|
||||
│ ├── cluster/ # Join/Promote/Peer-Discovery, KeyDB-Replication-Setup, pg_basebackup
|
||||
│ ├── proxy/ # API-Write-Proxy-Middleware (Replica → Primary), mTLS-Calls
|
||||
│ ├── aggregator/ # Cluster-View-APIs (alle Backends, alle Peers, alle Health-States)
|
||||
│ └── license/ # License-Validation, License-Leader-Election (KeyDB-Lock)
|
||||
├── management-ui/ # React 19 + AntD 6 + Vite (Struktur 1:1 wie netcell-webpanel/management-ui/)
|
||||
├── packaging/
|
||||
│ └── debian/
|
||||
│ ├── edgeguard-api/ # control, postinst, postrm, conffiles, systemd-Units
|
||||
│ ├── edgeguard-ui/
|
||||
│ └── edgeguard-meta/ # nur Depends, keine Dateien
|
||||
├── deploy/
|
||||
│ ├── systemd/ # *.service, *.target, *.timer
|
||||
│ ├── haproxy/ # haproxy.cfg.tpl
|
||||
│ ├── angie/ # nginx.conf.tpl, sni-map.tpl
|
||||
│ ├── squid/ # squid.conf.tpl
|
||||
│ └── nftables/ # ruleset.nft.tpl
|
||||
├── scripts/
|
||||
│ ├── apt-repo/ # build-package.sh, publish.sh, setup-repo.sh
|
||||
│ ├── install.sh # Bootstrap-Onliner
|
||||
│ └── release.sh # CI Release-Helper
|
||||
├── migrations/ # SQL-Migrations (goose-Format)
|
||||
├── docs/
|
||||
├── Makefile
|
||||
├── go.mod # module git.netcell-it.de/projekte/edgeguard-native
|
||||
└── go.sum
|
||||
```
|
||||
|
||||
**Go-Module-Name:** `git.netcell-it.de/projekte/edgeguard-native`
|
||||
**Build-System:** `Makefile` (POSIX-kompatibel). Targets: `build`, `test`, `lint`, `deb`, `clean`, `install-local`, `release`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Debian-Pakete
|
||||
|
||||
Drei Pakete + Meta — analog nmg, kein WAF-Paket weil kein WAF in v1.
|
||||
|
||||
| Paket | Arch | Inhalt | Depends |
|
||||
|---|---|---|---|
|
||||
| `edgeguard-api` | amd64, arm64 | `/usr/bin/edgeguard-{api,scheduler,ctl}`, Unit-Files, Migrations, Default-Configs | `postgresql-16`, `keydb-server`, `angie`, `haproxy`, `squid`, `wireguard-tools`, `nftables`, `certbot` |
|
||||
| `edgeguard-ui` | all | `/usr/share/edgeguard/ui/` (statische Build-Artefakte), Angie-Site | `edgeguard-api (= ${binary:Version})`, `angie` |
|
||||
| `edgeguard-meta` | all | keine Dateien, nur `Depends` | `edgeguard-api`, `edgeguard-ui` |
|
||||
|
||||
Pro Release: 1 arch-spezifisch × 2 Dists × 2 Arches = 4 `.deb` + 2 arch-agnostische × 2 Dists = 4 `.deb` → **8 Artefakte je Release**.
|
||||
|
||||
**KeyDB-Herkunft:** KeyDB ist weder in `trixie` noch `noble` in den offiziellen Repos. Wir bauen es aus Source (amd64 + arm64), veröffentlichen es parallel im eigenen APT-Repo. `edgeguard-api` `Depends: keydb-server` löst aus unserem Repo aus.
|
||||
|
||||
**Angie-Herkunft:** Eigenes APT-Repo bei `angie.software` — `edgeguard-api` `Depends: angie`. Im `install.sh` wird das Angie-Repo zusätzlich zu unserem hinzugefügt.
|
||||
|
||||
**Build-Werkzeug:** **direkter `dpkg-deb`-Build** analog WebPanel/EdgeGuardOS-Pattern. **Nicht** `dh_make`/`debhelper`, **nicht** `fpm`. Konsistenz mit existierendem Workflow.
|
||||
|
||||
**postinst (`edgeguard-api`):**
|
||||
1. User `edgeguard` anlegen (`adduser --system --group --home /var/lib/edgeguard`).
|
||||
2. `/etc/edgeguard/`, `/var/lib/edgeguard/`, `/var/log/edgeguard/` mit `0750`, `chown edgeguard:edgeguard`.
|
||||
3. Default-Configs nur anlegen wenn nicht vorhanden (`conffiles` verhindert Überschreiben).
|
||||
4. PostgreSQL: `edgeguard-ctl initdb` (idempotent — prüft DB/User).
|
||||
5. DB-Migration: `edgeguard-ctl migrate up`.
|
||||
6. `systemctl daemon-reload && systemctl enable --now edgeguard-api.service edgeguard-scheduler.service`.
|
||||
|
||||
**postrm (purge):** DB + User nur bei `purge`, *niemals* bei `remove`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Verzeichnis-Layout auf Zielsystem
|
||||
|
||||
```
|
||||
/etc/edgeguard/
|
||||
├── edgeguard.yaml # Hauptconfig (conffile)
|
||||
├── api.env # API-Secrets (mode 0600, edgeguard:edgeguard)
|
||||
├── haproxy/ # haproxy.cfg-Fragmente (von edgeguard-api generiert)
|
||||
├── angie/ # vHosts + sni-map (generiert)
|
||||
├── squid/ # squid.conf-Fragmente
|
||||
├── wireguard/ # wg0.conf etc. (generiert)
|
||||
├── nftables.d/ # Ruleset-Fragmente
|
||||
└── tls/ # ACME-verwaltete Zertifikate (0750, edgeguard:edgeguard)
|
||||
|
||||
/var/lib/edgeguard/
|
||||
├── state/ # Migrations-Marker, Cluster-Cursor
|
||||
├── trial.json # Lizenz-Trial-File
|
||||
├── .jwt_fingerprint # JWT-Secret-Fingerprint (analog enconf — Schutz vor Rotation)
|
||||
└── backups/ # lokale PG-Dumps (vor Migration)
|
||||
|
||||
/var/log/edgeguard/
|
||||
├── api.log
|
||||
├── scheduler.log
|
||||
└── audit.log
|
||||
|
||||
/usr/bin/
|
||||
├── edgeguard-api
|
||||
├── edgeguard-scheduler
|
||||
└── edgeguard-ctl
|
||||
|
||||
/usr/share/edgeguard/
|
||||
├── ui/ # statische React-Build-Artefakte
|
||||
└── templates/ # Config-Templates für haproxy/angie/squid/wireguard/nftables
|
||||
```
|
||||
|
||||
Entspricht FHS — keine Überraschungen für Admins, Lintian-clean.
|
||||
|
||||
---
|
||||
|
||||
## 5. systemd-Units
|
||||
|
||||
| Unit | Typ | Depends-on | User | Restart |
|
||||
|---|---|---|---|---|
|
||||
| `edgeguard-api.service` | `simple` | `postgresql.service`, `keydb-server.service` | `edgeguard` | `on-failure`, `RestartSec=5` |
|
||||
| `edgeguard-scheduler.service` | `simple` | `edgeguard-api.service` | `edgeguard` | `on-failure` |
|
||||
| `edgeguard-cert-deploy.path` | `path` | — | — | — |
|
||||
| `edgeguard-firewall.service` | `oneshot`, `RemainAfterExit=true` | — | root | — |
|
||||
| `edgeguard.target` | `target` | api+scheduler | — | — |
|
||||
|
||||
Hardening-Defaults pro Unit (außer `edgeguard-firewall`, das braucht `CAP_NET_ADMIN`):
|
||||
```
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectControlGroups=true
|
||||
PrivateTmp=true
|
||||
PrivateDevices=true
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||
SystemCallFilter=@system-service
|
||||
ReadWritePaths=/var/lib/edgeguard /var/log/edgeguard /etc/edgeguard
|
||||
```
|
||||
|
||||
Drittsoftware (HAProxy, Angie, Squid, WireGuard via `wg-quick@.service`, nftables) läuft als **Distro-Units**. EdgeGuard generiert deren Config + signalisiert Reload, übernimmt aber die Service-Verwaltung **nicht**.
|
||||
|
||||
API bindet auf `127.0.0.1:9443` (nicht öffentlich). Angie terminiert TLS auf `:443` und proxied an die API.
|
||||
|
||||
---
|
||||
|
||||
## 6. Datenbank-Setup
|
||||
|
||||
- **PostgreSQL 16**, Distro-Paket `postgresql-16`.
|
||||
- **Verbindung:** Unix-Socket (`/var/run/postgresql`) für lokale Reads + Writes der API. TCP/5432 mit TLS-Client-Cert nur zwischen Cluster-Peers für Streaming Replication.
|
||||
- **Topologie:** **ein logischer Primary** zu jedem Zeitpunkt, N Read-Replicas. Lokale API liest immer aus lokaler PG; Writes routet die API-Write-Proxy-Middleware transparent an den aktuellen Primary (KeyDB-Key `cluster:pg-primary-url`).
|
||||
- **Migrations:** `goose` (SQL-Dateien in `migrations/`). **Nicht** GORM AutoMigrate.
|
||||
|
||||
GORM bleibt als ORM für Query-Komfort; nur das Schema-Management wechselt zu `goose`.
|
||||
|
||||
---
|
||||
|
||||
## 7. KeyDB Active-Active
|
||||
|
||||
KeyDB ersetzt Redis. **Active-Active Replication** (Multi-Master, operation-basiert, split-brain-tolerant).
|
||||
|
||||
**Verwendung:**
|
||||
- `cluster:pg-primary-url` — wer ist aktueller PG-Primary?
|
||||
- `cluster:license-leader` — Lock für License-Heartbeat (`SET … NX EX 60`)
|
||||
- `cluster:license-status` — Cache des Lizenz-Validate-Ergebnisses (TTL 24 h)
|
||||
- `cluster:nodes:<node-id>` — Heartbeat-Marker (TTL 2 min)
|
||||
- `ratelimit:<scope>:<key>` — Rate-Counter (HINCRBY-Ops mergen korrekt)
|
||||
- `acme:lock:<domain>` — verhindert Parallel-Issue auf zwei Nodes
|
||||
- Pub/Sub: `edgeguard:config-changed` — alle Nodes regenerieren Config
|
||||
|
||||
KeyDB hört nur auf `127.0.0.1:6379` für lokale Clients und `<node-ip>:16379` (TLS) für Peer-Replication.
|
||||
|
||||
---
|
||||
|
||||
## 8. Cluster-Topologie & HA pro Service
|
||||
|
||||
**N symmetrische Peers** (1 … N Nodes, jeder vollwertig). Keine VRRP, keine Master/Backup-Rollen für Daten-Services. Public-IP: **Floating-IP des Hosters** (siehe §9).
|
||||
|
||||
| Service | HA-Strategie |
|
||||
|---|---|
|
||||
| **HAProxy** | stateless, pro Node identisch. Floating-IP zeigt zum aktuellen aktiven Node; bei Node-Ausfall API-Call zum Hoster (oder manueller Switch) reicht. |
|
||||
| **Angie** | stateless, pro Node identisch. ACME-Issue nur auf License-Leader (KeyDB-Lock); Zerts werden via PG/mTLS an alle verteilt. |
|
||||
| **Squid** | stateless (Cache lokal, kein Sync nötig). Pro Node identische ACL-Config. |
|
||||
| **WireGuard** | siehe §8.1 |
|
||||
| **nftables** | pro Node identisch, Ruleset aus PG generiert. `crowdsec_blocklist`/`threat_intel_blocklist`-Sets entfallen in v1 (kein CrowdSec). |
|
||||
| **edgeguard-api** | pro Node, Reads lokal, Writes via Proxy zu Primary. |
|
||||
| **edgeguard-ui** | statisch, pro Node identisch. |
|
||||
| **PostgreSQL** | Streaming Replication, manueller Promote (siehe nmg §6.2). |
|
||||
| **KeyDB** | Active-Active. |
|
||||
|
||||
### 8.1 WireGuard im Cluster
|
||||
|
||||
Drei Optionen, für v1 wählen wir **Option A**:
|
||||
|
||||
- **A — Geteilte Server-Identität (gewählt):** alle Peers haben **denselben** Server-Privatkey + dasselbe Listen-Port. Floating-IP routet UDP zum aktiven Node. Bei Failover: Floating-IP wandert, Clients schicken Pakete zum neuen Node, neuer Handshake (~1–2s Latenz beim ersten Paket). Replay-Protection-Counter werden nicht repliziert — beim Failover macht der Client neuen Handshake, alte Counter sind irrelevant.
|
||||
- B — Pro Node eigene Identität, Client kennt alle: Client-Configs haben mehrere `[Peer]`-Blöcke. Aufwendiger zu provisionieren, kein Failover-Vorteil.
|
||||
- C — Aktiv/Standby per License-Leader-Pattern: nur ein Node hat WireGuard aktiv, andere idle. Verschwendet Kapazität.
|
||||
|
||||
**Begründung A:** Privatkey ist in PG (verschlüsselt mit `edgeguard.key`), wird beim Cluster-Join an neue Peers verteilt. WireGuard handelt selbständig neue Sessions aus, kein State-Sync nötig. Operation-Tools (Peer hinzufügen/entfernen) wirken auf alle Nodes via `edgeguard:config-changed` Pub/Sub + lokales `wg syncconf`.
|
||||
|
||||
### 8.2 Manual Promote (PG-Primary-Failover)
|
||||
|
||||
1:1 nmg-Pattern (siehe `mail-gateway/docs/architecture.md` §6.2). Bei Ausfall des Primary antworten Config-Writes mit `503 + actionable Error`. Admin promotet via UI/CLI. Datenebene (HAProxy/Angie/Squid/WireGuard) läuft unbeeinträchtigt weiter, weil jeder Node eine lokale PG-Replica hat.
|
||||
|
||||
### 8.3 License-Leader-Election
|
||||
|
||||
Ein einziger Node kontaktiert `license.netcell-it.com` (KeyDB-Lock, 60-s-TTL). Ergebnis cluster-weit in `cluster:license-status` (TTL 24 h). `active_servers`-Verbrauchswert = Count der Peers mit Heartbeat < 2 min.
|
||||
|
||||
---
|
||||
|
||||
## 9. Public-Ingress — Floating-IP statt VRRP
|
||||
|
||||
**Problem:** HTTP-Clients machen kein automatisches Failover bei DNS-RR (anders als MTAs). Ein toter A-Record = 50% Fehler bis DNS-TTL.
|
||||
|
||||
**Entscheidung:** **Floating-IP des Hosters**. Der Hoster bietet eine API zum Umroute der IP zwischen Servern (z. B. via REST oder DNS-Update bei dynamischer Anycast-Lösung). Failover dauert Sekunden, kein VRRP-Drama, kein "VIP verschwindet"-Problem aus dem alten Setup.
|
||||
|
||||
Optionen pro Hoster:
|
||||
1. **Provider-Floating-IP** (gewünscht): API-Call schaltet IP um. EdgeGuard exponiert `POST /api/v1/cluster/promote-this-node`, das die Hoster-API aufruft.
|
||||
2. **DNS-RR mit kurzer TTL (60s)** als Notlösung wenn keine Floating-IP verfügbar.
|
||||
3. **Anycast/BGP** als Premium-Variante (für Enterprise).
|
||||
|
||||
**v1-Default:** Single-Node mit fest zugewiesener Floating-IP. Cluster-Erweiterung kommt mit Phase 2.
|
||||
|
||||
⚑ **OFFEN:** Welcher Hoster ist Standard? API-Spec dokumentieren sobald geklärt.
|
||||
|
||||
---
|
||||
|
||||
## 10. Erst-Einrichtung — curl-Onliner
|
||||
|
||||
```
|
||||
curl -fsSL https://get.edgeguard.netcell-it.de | sudo bash
|
||||
```
|
||||
|
||||
Schritte (idempotent, analog `netcell-webpanel/install.sh`):
|
||||
|
||||
1. **OS-Detection** (`/etc/os-release`): nur Trixie *oder* Noble, sonst Abbruch.
|
||||
2. **Arch-Detection**: nur amd64 *oder* arm64.
|
||||
3. **Base-Deps:** `curl gnupg ca-certificates apt-transport-https`.
|
||||
4. **APT-Keyrings:**
|
||||
- `https://apt.netcell-it.de/edgeguard/repository.key` → `/etc/apt/keyrings/netcell-edgeguard.gpg`
|
||||
- Angie-Repo-Key (für `angie`-Paket)
|
||||
5. **APT-Sources:** `/etc/apt/sources.list.d/netcell-edgeguard.list` + Angie-List.
|
||||
6. **Install:** `apt-get install -y edgeguard` (Meta-Paket).
|
||||
7. **Auto-Security-Updates:** `unattended-upgrades` + `apt-listchanges` (nach enconf-Muster).
|
||||
8. **Setup-Modus:** `edgeguard-api` läuft im Setup-Modus bis Admin-User existiert. UI leitet alle Anfragen auf `/setup` um. Wizard: Admin-Account, FQDN, ACME-Email, Lizenz oder Trial.
|
||||
|
||||
**Cluster-Join (zusätzlicher Peer):**
|
||||
```
|
||||
curl -fsSL https://get.edgeguard.netcell-it.de | sudo bash -s -- \
|
||||
--join https://<existing-node-fqdn> \
|
||||
--token <cluster-join-token>
|
||||
```
|
||||
|
||||
`edgeguard-ctl cluster-join` führt aus: PG-Basebackup vom Primary, KeyDB-Replication-Setup, Node-Registrierung in `ha_nodes`, TLS-Cert-Pull via mTLS, Config-Regeneration, Service-Start.
|
||||
|
||||
---
|
||||
|
||||
## 11. Update-Pfad (apt-Repo)
|
||||
|
||||
- **Primärquelle:** Gitea Package Registry (`https://git.netcell-it.de/api/packages/projekte/debian`).
|
||||
- **Kunden-Mirror:** `https://apt.netcell-it.de/edgeguard/` (rsync von Gitea).
|
||||
- **Suiten:** `stable` · `testing` · `security` — pro Codename (`trixie`, `noble`).
|
||||
- **Signatur:** GPG-Key `netcell-edgeguard-signing`, ausgeliefert in `/etc/apt/keyrings/`.
|
||||
- **Update-Check-API:** `GET /api/v1/system/package-versions` → pro `edgeguard-*`-Paket `{name, installed, available, reboot_required}`.
|
||||
- **Upgrade-Trigger:** `POST /api/v1/system/upgrade` startet `systemd-run --unit=edgeguard-upgrade.service --collect …` (HTTP-Response geht VOR dem Upgrade raus, weil API beim Self-Update stirbt — Pattern aus `netcell-webpanel/management-agent/internal/handlers/update.go:105`).
|
||||
|
||||
Build-/Release-Scripts identisch zu `mail-gateway/scripts/apt-repo/`.
|
||||
|
||||
---
|
||||
|
||||
## 12. Lizenz & ACME
|
||||
|
||||
### 12.1 Lizenz
|
||||
|
||||
1:1 nach `netcell-webpanel/docs/licensing-integration.md`. Verbrauchswert: `active_domains` (Anzahl konfigurierter EdgeGuard-Domains).
|
||||
|
||||
- **Lizenzserver:** `https://license.netcell-it.com` (öffentlich, kein API-Key).
|
||||
- **Verify-Endpoint:** `GET /api/v1/licenses/{key}/verify?system_id={fp}&system_name={host}&active_domains={n}`.
|
||||
- **Fingerprint:** `SHA256(/etc/machine-id + erste-aktive-MAC + hostname)`.
|
||||
- **Caching:** Live → KeyDB `cluster:license-status` (TTL 24h) → `/var/lib/edgeguard/trial.json` (30 Tage) → `expired`.
|
||||
- **Leader-Election** wie nmg §6.3.
|
||||
|
||||
### 12.2 ACME
|
||||
|
||||
- **certbot** (Distro-Paket) mit `--webroot`-Plugin für Angie-vHosts.
|
||||
- **Lock vor Issue:** `acme:lock:<domain>` in KeyDB verhindert Parallel-Issue auf zwei Nodes.
|
||||
- **Deploy-Hook:** schreibt Sentinel-Datei → `edgeguard-cert-deploy.path`-Unit triggert Angie-/HAProxy-Reload.
|
||||
- **Cert-Verteilung im Cluster:** Issuing-Node pushed via mTLS-API an alle Peers, Zerts landen in `/etc/edgeguard/tls/`.
|
||||
|
||||
---
|
||||
|
||||
## 13. UI — 100% enconf-WebPanel-Pattern
|
||||
|
||||
Komponentenbibliothek, Theme, Layouts, Navigations-Struktur, Form-Patterns, i18n-Setup vollständig 1:1 aus `netcell-webpanel/management-ui/`. Keine eigenen Design-Entscheidungen.
|
||||
|
||||
**Pflichtlektüre:**
|
||||
- `netcell-webpanel/docs/design-system.md`
|
||||
- `netcell-webpanel/docs/design.md`
|
||||
- `netcell-webpanel/docs/frontend-reference.md`
|
||||
|
||||
**Stack:** React 19 + TypeScript strict, Vite, Ant Design 6.x, TanStack Query 5, axios, i18next (de/en), `@uiw/react-codemirror`, `recharts`, ESLint flat config.
|
||||
|
||||
**Seiten v1:** Dashboard · Domains · Backends · Routing-Rules · SSL · ForwardProxy (Squid) · VPN (WireGuard) · Firewall · Cluster · Logs · Settings · Setup-Wizard.
|
||||
|
||||
---
|
||||
|
||||
## 14. Plattform-Matrix
|
||||
|
||||
| Distribution | Codename | Arch | Status v1 |
|
||||
|---|---|---|---|
|
||||
| Debian 13 | trixie | amd64 | Tier 1 |
|
||||
| Debian 13 | trixie | arm64 | Tier 1 |
|
||||
| Ubuntu 24.04 LTS | noble | amd64 | Tier 1 |
|
||||
| Ubuntu 24.04 LTS | noble | arm64 | Tier 1 |
|
||||
|
||||
Andere Distributionen (Debian 12, Ubuntu 22.04, RHEL/Rocky) sind **nicht unterstützt**. Installer bricht hart ab.
|
||||
|
||||
---
|
||||
|
||||
## 15. Migration vom Docker-Stand
|
||||
|
||||
EdgeGuard-Native ist eigenes Repo (`git.netcell-it.de/projekte/edgeguard-native`), parallel zum bestehenden `proxy-lb-waf`. Migration:
|
||||
|
||||
1. **Frische Installation** auf Test-VM via `install.sh`.
|
||||
2. **Config-Export** aus altem Stack (`edgeguard-ctl export --from-docker`) — liest aus alter PG, schreibt in neues Format.
|
||||
3. **Validierung** Side-by-Side (alter Stack auf einem Server, neuer Stack auf anderem, Traffic vergleichen).
|
||||
4. **Cutover** via Floating-IP-Switch.
|
||||
|
||||
Der alte `proxy-lb-waf`-Code bleibt für Bestandskunden im Wartungsmodus, keine neuen Features.
|
||||
|
||||
---
|
||||
|
||||
## Offene Punkte
|
||||
|
||||
- **Hoster + Floating-IP-API** (§9): Spec dokumentieren.
|
||||
- **Angie-Repo-Verfügbarkeit** für arm64 prüfen.
|
||||
- **WireGuard-State-Replication** in der Praxis testen (Handshake-Latenz nach Floating-IP-Switch messen).
|
||||
- **`get.edgeguard.netcell-it.de`** anlegen oder Übergangs-URL auf `apt.netcell-it.de/edgeguard/install.sh` nutzen.
|
||||
37
go.mod
Normal file
37
go.mod
Normal file
@@ -0,0 +1,37 @@
|
||||
module git.netcell-it.de/projekte/edgeguard-native
|
||||
|
||||
go 1.25.0
|
||||
|
||||
require github.com/gin-gonic/gin v1.10.0
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.11.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/stretchr/testify v1.11.1 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.48.0 // indirect
|
||||
golang.org/x/net v0.50.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
100
go.sum
Normal file
100
go.sum
Normal file
@@ -0,0 +1,100 @@
|
||||
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
||||
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
|
||||
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
0
internal/aggregator/.gitkeep
Normal file
0
internal/aggregator/.gitkeep
Normal file
0
internal/angie/.gitkeep
Normal file
0
internal/angie/.gitkeep
Normal file
0
internal/cluster/.gitkeep
Normal file
0
internal/cluster/.gitkeep
Normal file
0
internal/config/.gitkeep
Normal file
0
internal/config/.gitkeep
Normal file
0
internal/database/.gitkeep
Normal file
0
internal/database/.gitkeep
Normal file
0
internal/firewall/.gitkeep
Normal file
0
internal/firewall/.gitkeep
Normal file
0
internal/handlers/.gitkeep
Normal file
0
internal/handlers/.gitkeep
Normal file
0
internal/haproxy/.gitkeep
Normal file
0
internal/haproxy/.gitkeep
Normal file
0
internal/license/.gitkeep
Normal file
0
internal/license/.gitkeep
Normal file
0
internal/models/.gitkeep
Normal file
0
internal/models/.gitkeep
Normal file
0
internal/proxy/.gitkeep
Normal file
0
internal/proxy/.gitkeep
Normal file
0
internal/services/.gitkeep
Normal file
0
internal/services/.gitkeep
Normal file
0
internal/squid/.gitkeep
Normal file
0
internal/squid/.gitkeep
Normal file
0
internal/wireguard/.gitkeep
Normal file
0
internal/wireguard/.gitkeep
Normal file
0
management-ui/src/.gitkeep
Normal file
0
management-ui/src/.gitkeep
Normal file
0
migrations/.gitkeep
Normal file
0
migrations/.gitkeep
Normal file
1
packaging/debian/edgeguard-api/DEBIAN/conffiles
Normal file
1
packaging/debian/edgeguard-api/DEBIAN/conffiles
Normal file
@@ -0,0 +1 @@
|
||||
/etc/edgeguard/edgeguard.yaml
|
||||
18
packaging/debian/edgeguard-api/DEBIAN/control
Normal file
18
packaging/debian/edgeguard-api/DEBIAN/control
Normal file
@@ -0,0 +1,18 @@
|
||||
Package: edgeguard-api
|
||||
Version: __VERSION__
|
||||
Architecture: __ARCH__
|
||||
Maintainer: NetCell IT <support@netcell-it.de>
|
||||
Homepage: https://edgeguard.netcell-it.de
|
||||
Description: EdgeGuard — native Reverse-Proxy / LB / Forward-Proxy / VPN / Firewall
|
||||
EdgeGuard is a native Debian/Ubuntu edge gateway combining HAProxy,
|
||||
Angie (nginx-fork), Squid, WireGuard and nftables, configured from
|
||||
a PostgreSQL single-source-of-truth via a Go management API.
|
||||
Deployable as a cluster of symmetric peers (KeyDB Active-Active +
|
||||
PG Streaming Replication + provider Floating-IP for HTTP ingress).
|
||||
.
|
||||
This package ships the management API, scheduler and CLI.
|
||||
Depends: postgresql-16 | postgresql-17, edgeguard-keydb (>= 6.3.4-edgeguard1), angie, haproxy (>= 2.8), squid, wireguard-tools, nftables, certbot, sudo, adduser, systemd, ca-certificates
|
||||
Recommends: apparmor, fail2ban
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Installed-Size: 0
|
||||
46
packaging/debian/edgeguard-api/DEBIAN/postinst
Executable file
46
packaging/debian/edgeguard-api/DEBIAN/postinst
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
# postinst for edgeguard-api — creates system user, filesystem layout,
|
||||
# enables systemd units. DB init + migrations run lazily on first start
|
||||
# of edgeguard-api.
|
||||
set -e
|
||||
|
||||
export LC_ALL=C
|
||||
export LANG=C
|
||||
|
||||
EG_USER="edgeguard"
|
||||
EG_HOME="/var/lib/edgeguard"
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
# ── System user ──────────────────────────────────────────────
|
||||
if ! getent passwd "$EG_USER" >/dev/null; then
|
||||
adduser --system --group --home "$EG_HOME" \
|
||||
--shell /usr/sbin/nologin --no-create-home \
|
||||
--gecos "EdgeGuard daemon" "$EG_USER"
|
||||
fi
|
||||
|
||||
# ── Directories ──────────────────────────────────────────────
|
||||
for d in /etc/edgeguard /var/lib/edgeguard /var/log/edgeguard \
|
||||
/etc/edgeguard/haproxy /etc/edgeguard/angie \
|
||||
/etc/edgeguard/squid /etc/edgeguard/wireguard \
|
||||
/etc/edgeguard/nftables.d /etc/edgeguard/tls; do
|
||||
install -d -m 0750 -o "$EG_USER" -g "$EG_USER" "$d"
|
||||
done
|
||||
|
||||
# ── systemd ──────────────────────────────────────────────────
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now edgeguard-api.service edgeguard-scheduler.service || true
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
24
packaging/debian/edgeguard-api/DEBIAN/postrm
Executable file
24
packaging/debian/edgeguard-api/DEBIAN/postrm
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
purge)
|
||||
# Only on purge: remove user, configs, state.
|
||||
if getent passwd edgeguard >/dev/null; then
|
||||
deluser --quiet edgeguard >/dev/null 2>&1 || true
|
||||
fi
|
||||
rm -rf /etc/edgeguard /var/lib/edgeguard /var/log/edgeguard
|
||||
;;
|
||||
|
||||
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postrm called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
21
packaging/debian/edgeguard-api/DEBIAN/prerm
Executable file
21
packaging/debian/edgeguard-api/DEBIAN/prerm
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
remove|upgrade|deconfigure)
|
||||
systemctl stop edgeguard-api.service edgeguard-scheduler.service || true
|
||||
systemctl disable edgeguard-api.service edgeguard-scheduler.service || true
|
||||
;;
|
||||
|
||||
failed-upgrade)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "prerm called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
14
packaging/debian/edgeguard-meta/DEBIAN/control
Normal file
14
packaging/debian/edgeguard-meta/DEBIAN/control
Normal file
@@ -0,0 +1,14 @@
|
||||
Package: edgeguard
|
||||
Version: __VERSION__
|
||||
Architecture: all
|
||||
Maintainer: NetCell IT <support@netcell-it.de>
|
||||
Homepage: https://edgeguard.netcell-it.de
|
||||
Description: EdgeGuard — meta package
|
||||
Pulls the full EdgeGuard stack: management API, UI, configured
|
||||
third-party services (HAProxy, Angie, Squid, WireGuard, nftables).
|
||||
.
|
||||
Install this package to get a complete EdgeGuard node.
|
||||
Depends: edgeguard-api (= ${binary:Version}), edgeguard-ui (= ${binary:Version})
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Installed-Size: 0
|
||||
12
packaging/debian/edgeguard-ui/DEBIAN/control
Normal file
12
packaging/debian/edgeguard-ui/DEBIAN/control
Normal file
@@ -0,0 +1,12 @@
|
||||
Package: edgeguard-ui
|
||||
Version: __VERSION__
|
||||
Architecture: all
|
||||
Maintainer: NetCell IT <support@netcell-it.de>
|
||||
Homepage: https://edgeguard.netcell-it.de
|
||||
Description: EdgeGuard — management UI (static React build)
|
||||
React 19 + Ant Design 6 single-page admin UI for EdgeGuard.
|
||||
Served by the Angie reverse proxy bundled in edgeguard-api.
|
||||
Depends: edgeguard-api (= ${binary:Version}), angie
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Installed-Size: 0
|
||||
10
scripts/apt-repo/build-package.sh
Executable file
10
scripts/apt-repo/build-package.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build .deb packages for EdgeGuard.
|
||||
# Usage: build-package.sh <amd64|arm64> <version>
|
||||
# Output: build/deb/edgeguard-{api,ui,meta}_<version>_<arch>.deb
|
||||
#
|
||||
# TODO — Stub. Wird mit Task #3 (Spike-Build) implementiert.
|
||||
set -euo pipefail
|
||||
ARCH="${1:?arch required}"
|
||||
VERSION="${2:?version required}"
|
||||
echo "build-package.sh stub — would build edgeguard-{api,ui,meta}_${VERSION}_${ARCH}.deb"
|
||||
17
scripts/install.sh
Executable file
17
scripts/install.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
# ============================================================================
|
||||
# EdgeGuard — Bootstrap Installer (One-Liner)
|
||||
# ============================================================================
|
||||
# Usage:
|
||||
# curl -fsSL https://get.edgeguard.netcell-it.de | sudo bash
|
||||
# curl -fsSL https://get.edgeguard.netcell-it.de | sudo bash -s -- \
|
||||
# --join https://<existing-node-fqdn> --token <cluster-join-token>
|
||||
#
|
||||
# Platform: Debian 13 (Trixie) or Ubuntu 24.04 LTS (Noble), amd64 + arm64.
|
||||
# Idempotent — safe to re-run.
|
||||
# ============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
# ─── TODO — Stub. Wird in Task #4 implementiert. ────────────────────────────
|
||||
echo "EdgeGuard installer stub — full install.sh follows in Task #4."
|
||||
exit 0
|
||||
Reference in New Issue
Block a user