Backend: - Audit-Log: Search-Endpoint mit ILIKE-Filter (actor/action/subject/date) - NTP: /ntp/status via chronyc tracking (Stratum, Offset, Quelle) - System: /service-restart mit Allowlist (haproxy/squid/unbound/chrony/scheduler) - Domain-Response-Headers + Rate-Limit (Migration 0024) - Join-Tokens (Migration 0025), Cluster-mTLS, Aggregator-Fan-Out - apt-Service für Update-Banner (apt-get update + Versionsprüfung) - Backup-Retry mit exponential backoff (retry_apt 3×) - publish.sh fail-fast + cleanup-old.sh (max 10 Versionen) Frontend: - Audit-Log-Page (/audit) mit Filter + Pagination - ErrorBoundary an React-Root + Vite build-target festgenagelt (iOS 15+) - Storage-Schema-Stamp: auto-wipe bei Versions-Mismatch (blank-page-Fix) - EmptyState-Komponente überall ausgerollt - SSL: Aggregate-Karte (total/expiring/expired/errors) - Backups: Aggregate-Karte (letzter Backup/Größe/Fehlschläge 24h) + Backup-Now - NTP: Sync-Status-Karte (chronyc tracking live) - Domains: Backend-UP/DOWN-Chip aus HAProxy-Stats - Backends: HAProxy-Status-Spalte (UP/DEGRADED/DOWN) - Settings: Service-Neustart-Karte (haproxy/squid/unbound/chrony/scheduler) - Settings: Upgrade-Status-Card, Wartungsmodus, Auto-Update, Retention - Dashboard: Recent-Alerts, Cluster-Health, License-Chip, Onboarding-Hint - System-Regeln im Firewall als eigener Tab Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
63 lines
2.0 KiB
Go
63 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
|
|
"git.netcell-it.de/projekte/edgeguard-native/internal/cluster/clustertls"
|
|
)
|
|
|
|
// cmdClusterRenewSelf: re-issued das eigene peer.{crt,key} mit der
|
|
// lokalen Cluster-CA. Nur sinnvoll auf der Founder/Primary-Box wo die
|
|
// CA-Key noch vorhanden ist; auf Joinern fehlt die ca.key (sie haben
|
|
// nur die CA-Cert zum Verify) und der Aufruf scheitert.
|
|
//
|
|
// Usage:
|
|
// edgeguard-ctl cluster-renew-self [--cn <fqdn>] [--tls-dir <path>]
|
|
//
|
|
// Output: schreibt peer.crt + peer.key über das vorhandene peer.{crt,
|
|
// key} hinweg. Restart-Hinweis am Ende.
|
|
func cmdClusterRenewSelf(args []string) int {
|
|
fs := flag.NewFlagSet("cluster-renew-self", flag.ContinueOnError)
|
|
cn := fs.String("cn", "", "subject common name (default: aus dem aktuellen peer.crt geerbt)")
|
|
tlsDir := fs.String("tls-dir", clustertls.DefaultDir, "where peer.{crt,key} live")
|
|
fs.SetOutput(os.Stderr)
|
|
if err := fs.Parse(args); err != nil {
|
|
return 2
|
|
}
|
|
store := clustertls.New(*tlsDir)
|
|
if !store.HasCA() {
|
|
fmt.Fprintln(os.Stderr,
|
|
"edgeguard-ctl cluster-renew-self: no local CA found — this command works only on a founder/primary node.")
|
|
return 1
|
|
}
|
|
commonName := *cn
|
|
if commonName == "" {
|
|
if info, err := store.PeerCertInfo(); err == nil && info.CommonName != "" {
|
|
commonName = info.CommonName
|
|
}
|
|
}
|
|
if commonName == "" {
|
|
h, _ := os.Hostname()
|
|
commonName = h
|
|
}
|
|
if commonName == "" {
|
|
commonName = "edgeguard-node"
|
|
}
|
|
if err := store.RenewSelfSigned(commonName, []string{commonName}, nil, nil); err != nil {
|
|
fmt.Fprintf(os.Stderr, "edgeguard-ctl cluster-renew-self: %v\n", err)
|
|
return 1
|
|
}
|
|
info, _ := store.PeerCertInfo()
|
|
fmt.Printf("Cluster-Peer-Cert erneuert.\n")
|
|
fmt.Printf(" CN: %s\n", commonName)
|
|
fmt.Printf(" Files: %s/peer.{crt,key}\n", *tlsDir)
|
|
if info != nil {
|
|
fmt.Printf(" Gültig bis: %s (%d Tage)\n", info.NotAfter, info.DaysRemaining)
|
|
}
|
|
fmt.Printf("\nDamit der Agent-Listener das neue Cert lädt:\n")
|
|
fmt.Printf(" sudo systemctl restart edgeguard-api\n")
|
|
return 0
|
|
}
|