Add nftables firewall ruleset preview per server (review-only)
New firewall package generates an nftables snippet (INPUT accept for the listen port, FORWARD rules for the WireGuard interface, optional LAN forwarding via a new ServerSetting.LanInterface field). Text only - nothing is applied to the live firewall. Exposed as GET /servers/:id/firewall-preview and a "Firewall Preview" button in the All Servers page. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
0000643187
commit
28eb08df41
@@ -0,0 +1,56 @@
|
||||
// Package firewall generates an nftables ruleset preview for a WireGuard
|
||||
// server. It never touches the live firewall - the output is text only,
|
||||
// meant to be reviewed and applied manually (nft -f <file>) or copied into
|
||||
// an existing ruleset.
|
||||
package firewall
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/ngoduykhanh/wireguard-ui/model"
|
||||
)
|
||||
|
||||
// GeneratePreview renders an nftables ruleset snippet for the given server.
|
||||
// If settings.LanInterface is empty, only WireGuard-interface-local traffic
|
||||
// rules are emitted; forwarding to a LAN interface is added when set.
|
||||
func GeneratePreview(server model.Server, settings model.ServerSetting) string {
|
||||
ifaceName := "wgX"
|
||||
listenPort := 0
|
||||
if server.Interface != nil {
|
||||
if server.Interface.Name != "" {
|
||||
ifaceName = server.Interface.Name
|
||||
}
|
||||
listenPort = server.Interface.ListenPort
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
fmt.Fprintf(&b, "# nftables ruleset preview for server %q (%s)\n", server.Name, server.ID)
|
||||
fmt.Fprintf(&b, "# Generated by wireguard-ui-multi - review before applying, e.g.:\n")
|
||||
fmt.Fprintf(&b, "# nft -f this-file.nft\n")
|
||||
fmt.Fprintf(&b, "# Not applied automatically.\n\n")
|
||||
|
||||
fmt.Fprintf(&b, "table inet wireguard_ui_%s {\n", server.ID)
|
||||
fmt.Fprintf(&b, " chain input {\n")
|
||||
fmt.Fprintf(&b, " type filter hook input priority 0; policy accept;\n")
|
||||
fmt.Fprintf(&b, " udp dport %d accept comment \"wg-ui-multi: %s\"\n", listenPort, server.ID)
|
||||
fmt.Fprintf(&b, " }\n\n")
|
||||
|
||||
fmt.Fprintf(&b, " chain forward {\n")
|
||||
fmt.Fprintf(&b, " type filter hook forward priority 0; policy accept;\n")
|
||||
fmt.Fprintf(&b, " iifname \"%s\" accept comment \"wg-ui-multi: %s inbound\"\n", ifaceName, server.ID)
|
||||
fmt.Fprintf(&b, " oifname \"%s\" accept comment \"wg-ui-multi: %s outbound\"\n", ifaceName, server.ID)
|
||||
if settings.LanInterface != "" {
|
||||
fmt.Fprintf(&b, " iifname \"%s\" oifname \"%s\" accept comment \"wg-ui-multi: %s -> lan\"\n", ifaceName, settings.LanInterface, server.ID)
|
||||
fmt.Fprintf(&b, " iifname \"%s\" oifname \"%s\" accept comment \"wg-ui-multi: lan -> %s\"\n", settings.LanInterface, ifaceName, server.ID)
|
||||
}
|
||||
fmt.Fprintf(&b, " }\n")
|
||||
fmt.Fprintf(&b, "}\n")
|
||||
|
||||
if settings.LanInterface == "" {
|
||||
fmt.Fprintf(&b, "\n# No LAN interface configured for this server - peers can only reach\n")
|
||||
fmt.Fprintf(&b, "# each other, not your LAN. Set one in Server Settings to add forwarding.\n")
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
Reference in New Issue
Block a user