fix(unbound): restart statt reload + DNS Auto-FW-Rules dokumentiert
Bug: Unbound bindet Listen-Sockets nur beim startup. Bei einer Mutation von dns_settings.listen_addresses (z.B. neue LAN-IP für Resolver-Zugriff) hat 'systemctl reload' die Config zwar gelesen, aber nicht neu gebound — neue IPs blieben tot. Fix: Renderer ruft RestartService statt ReloadService. ~200ms Resolver-Downtime beim Save, dafür konsistentes Verhalten für jede Settings/Zone/Record-Mutation. Plus configgen.RestartService Helper neu (analog ReloadService), sudoers im postinst um systemctl restart unbound.service erweitert. NOTE für DNS-LAN-Zugang: zwei Operator-FW-Rules nötig (DNS-UDP + DNS-TCP from any to any) wenn der Resolver auf LAN-IPs lauscht. Aktuell manuell anzulegen — ein Auto-Rule-Generator (analog NAT-auto-forward) wäre die nächste Iteration. Version 1.0.36. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -43,7 +43,7 @@ import (
|
|||||||
wgsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/wireguard"
|
wgsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/wireguard"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version = "1.0.35"
|
var version = "1.0.36"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
addr := os.Getenv("EDGEGUARD_API_ADDR")
|
addr := os.Getenv("EDGEGUARD_API_ADDR")
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version = "1.0.35"
|
var version = "1.0.36"
|
||||||
|
|
||||||
const usage = `edgeguard-ctl — EdgeGuard CLI
|
const usage = `edgeguard-ctl — EdgeGuard CLI
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,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.0.35"
|
var version = "1.0.36"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// renewTickInterval — how often we re-evaluate expiring certs.
|
// renewTickInterval — how often we re-evaluate expiring certs.
|
||||||
|
|||||||
@@ -87,6 +87,18 @@ func ReloadService(name string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RestartService runs `sudo -n systemctl restart <name>.service`.
|
||||||
|
// Use over ReloadService when the daemon needs to re-read more than
|
||||||
|
// just rules — e.g. unbound rebinds listen-sockets only on startup,
|
||||||
|
// so a settings.listen_addresses change requires restart.
|
||||||
|
func RestartService(name string) error {
|
||||||
|
cmd := exec.Command("sudo", "-n", "/usr/bin/systemctl", "restart", name+".service")
|
||||||
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("sudo systemctl restart %s.service: %w (output: %s)", name, err, strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// EtcEdgeguard is the on-target config root. Templated path used by
|
// EtcEdgeguard is the on-target config root. Templated path used by
|
||||||
// all renderers — never let renderers hard-code their own.
|
// all renderers — never let renderers hard-code their own.
|
||||||
const EtcEdgeguard = "/etc/edgeguard"
|
const EtcEdgeguard = "/etc/edgeguard"
|
||||||
|
|||||||
@@ -131,7 +131,13 @@ func (g *Generator) Render(ctx context.Context) error {
|
|||||||
if g.SkipReload {
|
if g.SkipReload {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return configgen.ReloadService("unbound")
|
// Restart statt reload: unbound bindet Listen-Sockets nur beim
|
||||||
|
// Startup. Bei Settings-Änderungen (listen_addresses-Wechsel)
|
||||||
|
// greift ein bloßes 'systemctl reload' nicht — die neuen IPs
|
||||||
|
// werden erst nach echtem Restart gebound. Trade-off: ~200ms
|
||||||
|
// Downtime des Resolvers, dafür konsistentes Verhalten für jede
|
||||||
|
// Mutation.
|
||||||
|
return configgen.RestartService("unbound")
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitCSV(s string) []string {
|
func splitCSV(s string) []string {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "edgeguard-management-ui",
|
"name": "edgeguard-management-ui",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.35",
|
"version": "1.0.36",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ const NAV: NavSection[] = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const VERSION = '1.0.35'
|
const VERSION = '1.0.36'
|
||||||
|
|
||||||
export default function Sidebar({ isOpen, onClose }: SidebarProps) {
|
export default function Sidebar({ isOpen, onClose }: SidebarProps) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl reload squid.service
|
|||||||
edgeguard ALL=(root) NOPASSWD: /bin/systemctl reload squid.service
|
edgeguard ALL=(root) NOPASSWD: /bin/systemctl reload squid.service
|
||||||
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl reload unbound.service
|
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl reload unbound.service
|
||||||
edgeguard ALL=(root) NOPASSWD: /bin/systemctl reload unbound.service
|
edgeguard ALL=(root) NOPASSWD: /bin/systemctl reload unbound.service
|
||||||
|
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl restart unbound.service
|
||||||
|
edgeguard ALL=(root) NOPASSWD: /bin/systemctl restart unbound.service
|
||||||
SUDOERS
|
SUDOERS
|
||||||
|
|
||||||
# ── Distro-Conf-Includes für die per-Service Renderer ─────────
|
# ── Distro-Conf-Includes für die per-Service Renderer ─────────
|
||||||
|
|||||||
Reference in New Issue
Block a user