8d9a76c751
Rewrites the compiler from ~440 to ~1700 lines covering all major shorewall firewall features: loopback, conntrack fast-path, anti-spoof, DHCP, intra-zone, blacklist/whitelist, conntrack notrack, tunnels (13 types), rules with sections, DNAT/redirect, SNAT/masquerade, static NAT, policies with zone exclusions, MSS clamping, rate limiting, connection limiting, negated addresses, ICMP type matching, TCP RST reject, user/UID matching, mark match/set, NFQUEUE, NONAT, and policy-level rate/conn limiting. Adds full config types for all shorewall subsystems (mangle, accounting, maclist, netmap, providers, tunnels, conntrack, blrules, proxyarp/ndp, routes, tc, secmarks), shorewall migration tooling, expanded CLI commands, expression-level diff engine, and 49 unit tests.
98 lines
3.0 KiB
Go
98 lines
3.0 KiB
Go
package config
|
|
|
|
import "fmt"
|
|
|
|
type SNATAction string
|
|
|
|
const (
|
|
SNATMasquerade SNATAction = "masquerade"
|
|
SNATAddress SNATAction = "snat"
|
|
SNATContinue SNATAction = "continue"
|
|
SNATLog SNATAction = "log"
|
|
)
|
|
|
|
// SNATRule defines a source NAT or masquerade rule.
|
|
// Rules are evaluated in order — first match wins.
|
|
type SNATRule struct {
|
|
Action SNATAction `yaml:"action"`
|
|
|
|
// For SNAT: the source address (or address range first-last) to rewrite to.
|
|
// Supports: single IP, IP range (1.2.3.4-1.2.3.7), or "detect" (use interface addresses).
|
|
Address string `yaml:"address,omitempty"`
|
|
|
|
// Port remapping for SNAT/MASQUERADE. Format: lowport-highport or single port.
|
|
// Requires proto to be tcp, udp, dccp, or sctp.
|
|
PortRange string `yaml:"port_range,omitempty"`
|
|
|
|
// Randomize port mapping.
|
|
Random bool `yaml:"random,omitempty"`
|
|
|
|
// Give a client the same source/destination IP pair (only with address ranges).
|
|
Persistent bool `yaml:"persistent,omitempty"`
|
|
|
|
// Source addresses/networks to match for masquerading.
|
|
// Supports: CIDR, host address, comma-separated list, ipset (+name).
|
|
Source string `yaml:"source,omitempty"`
|
|
|
|
// Outgoing interface(s) and optional destination address qualification.
|
|
// Format: interface, interface:dest-address, or comma-separated interfaces.
|
|
// Use "$FW" for SNAT in the INPUT chain.
|
|
Dest string `yaml:"dest"`
|
|
|
|
// Protocol restriction. Comma-separated list allowed.
|
|
Proto string `yaml:"proto,omitempty"`
|
|
|
|
// Destination port(s).
|
|
DPort PortSpec `yaml:"dport,omitempty"`
|
|
|
|
// Source port(s).
|
|
SPort PortSpec `yaml:"sport,omitempty"`
|
|
|
|
// Packet/connection mark test. Format: [!]value[/mask][:C]
|
|
Mark string `yaml:"mark,omitempty"`
|
|
|
|
// Original destination address filter — match only connections that were
|
|
// previously DNAT'd to these addresses.
|
|
OrigDest string `yaml:"origdest,omitempty"`
|
|
|
|
// Random matching probability (0 < p <= 1) for load-balancing across
|
|
// multiple SNAT addresses.
|
|
Probability float64 `yaml:"probability,omitempty"`
|
|
|
|
// Log level (for log action, or appended to other actions).
|
|
Log string `yaml:"log,omitempty"`
|
|
|
|
Comment string `yaml:"comment,omitempty"`
|
|
}
|
|
|
|
func (c *Config) validateSNAT() error {
|
|
for i, s := range c.SNAT {
|
|
switch s.Action {
|
|
case SNATMasquerade, SNATAddress, SNATContinue, SNATLog:
|
|
default:
|
|
return fmt.Errorf("snat[%d]: unknown action %q", i, s.Action)
|
|
}
|
|
|
|
if s.Action == SNATAddress && s.Address == "" {
|
|
return fmt.Errorf("snat[%d]: address required for snat action", i)
|
|
}
|
|
|
|
if s.Dest == "" {
|
|
return fmt.Errorf("snat[%d]: dest required", i)
|
|
}
|
|
|
|
if s.PortRange != "" && s.Proto == "" {
|
|
return fmt.Errorf("snat[%d]: port_range requires proto (tcp, udp, dccp, or sctp)", i)
|
|
}
|
|
|
|
if s.Persistent && s.Address == "" {
|
|
return fmt.Errorf("snat[%d]: persistent requires an address or address range", i)
|
|
}
|
|
|
|
if s.Probability != 0 && (s.Probability <= 0 || s.Probability > 1) {
|
|
return fmt.Errorf("snat[%d]: probability must be between 0 (exclusive) and 1 (inclusive)", i)
|
|
}
|
|
}
|
|
return nil
|
|
}
|