Add per-server NAT egress, ip_forward auto-enable, OPNsense import review checklist
- ServerSetting gains WanInterface/EgressSNATIP for optional per-server masquerade/SNAT of client traffic, isolated in each server's own nftables table - wireguard.Start/Restart now ensure net.ipv4.ip_forward and net.ipv6.conf.all.forwarding are enabled before bringing an interface up - OPNsense config.xml import now parses staticroutes/filter/nat rules and surfaces them as a manual-review checklist in the preview UI (never auto-applied) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ATVUwTa4Pqwq26orW5BcDW
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
cf9c136874
commit
83b1da291f
+56
-1
@@ -50,11 +50,24 @@ type PreviewServer struct {
|
||||
Warnings []string `json:"warnings,omitempty"`
|
||||
}
|
||||
|
||||
// ReviewChecklistItem is one manual-review entry surfaced from parts of
|
||||
// config.xml that wireguard-ui-multi does not import or model at all
|
||||
// (static routes, firewall rules, outbound NAT). These are never applied -
|
||||
// they exist purely so the admin knows what else the old OPNsense config
|
||||
// was doing and can recreate the equivalent manually (e.g. via
|
||||
// ServerSetting.WanInterface/EgressSNATIP or a custom FirewallRule) before
|
||||
// cutover, instead of discovering the gap after go-live.
|
||||
type ReviewChecklistItem struct {
|
||||
Kind string `json:"kind"` // "static_route" | "filter_rule" | "nat_rule"
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// PreviewResult is the full response of the preview step: every server
|
||||
// OPNsense defined, mapped and ready for the admin to review/edit before
|
||||
// confirming the import. It is never written to the store by itself.
|
||||
type PreviewResult struct {
|
||||
Servers []PreviewServer `json:"servers"`
|
||||
Servers []PreviewServer `json:"servers"`
|
||||
ReviewChecklist []ReviewChecklistItem `json:"review_checklist,omitempty"`
|
||||
}
|
||||
|
||||
var slugInvalidChars = regexp.MustCompile(`[^a-zA-Z0-9_-]+`)
|
||||
@@ -210,9 +223,51 @@ func ToPreview(cfg *ParsedConfig, existingServerIDs []string) *PreviewResult {
|
||||
result.Servers = append(result.Servers, ps)
|
||||
}
|
||||
|
||||
result.ReviewChecklist = buildReviewChecklist(cfg)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// buildReviewChecklist summarizes static routes, firewall rules, and
|
||||
// outbound NAT rules found in the source config.xml that wireguard-ui-multi
|
||||
// has no equivalent import path for. Purely informational.
|
||||
func buildReviewChecklist(cfg *ParsedConfig) []ReviewChecklistItem {
|
||||
var items []ReviewChecklistItem
|
||||
|
||||
for _, r := range cfg.StaticRoutes {
|
||||
desc := fmt.Sprintf("route %s via %s", r.Network, r.Gateway)
|
||||
if r.Descr != "" {
|
||||
desc += fmt.Sprintf(" (%s)", r.Descr)
|
||||
}
|
||||
items = append(items, ReviewChecklistItem{Kind: "static_route", Description: desc})
|
||||
}
|
||||
|
||||
for _, r := range cfg.FilterRules {
|
||||
desc := fmt.Sprintf("%s rule on %s: %s -> %s", orDefault(r.Type, "pass"), r.Interface, orDefault(r.Source.Network, "any"), orDefault(r.Destination.Network, "any"))
|
||||
if r.Descr != "" {
|
||||
desc += fmt.Sprintf(" (%s)", r.Descr)
|
||||
}
|
||||
items = append(items, ReviewChecklistItem{Kind: "filter_rule", Description: desc})
|
||||
}
|
||||
|
||||
for _, r := range cfg.NatRules {
|
||||
desc := fmt.Sprintf("outbound NAT on %s: %s -> %s", r.Interface, orDefault(r.Source.Network, "any"), orDefault(r.Target, "interface address"))
|
||||
if r.Descr != "" {
|
||||
desc += fmt.Sprintf(" (%s)", r.Descr)
|
||||
}
|
||||
items = append(items, ReviewChecklistItem{Kind: "nat_rule", Description: desc})
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
func orDefault(s, fallback string) string {
|
||||
if strings.TrimSpace(s) == "" {
|
||||
return fallback
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func mapClient(rc rawClient) PreviewClient {
|
||||
pc := PreviewClient{
|
||||
SourceUUID: rc.UUID,
|
||||
|
||||
Reference in New Issue
Block a user