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.
58 lines
1.5 KiB
Go
58 lines
1.5 KiB
Go
package config
|
|
|
|
import "fmt"
|
|
|
|
type Host struct {
|
|
Zone string `yaml:"zone"`
|
|
Interface string `yaml:"interface"`
|
|
Addresses []string `yaml:"addresses"`
|
|
Exclusions []string `yaml:"exclusions,omitempty"`
|
|
Dynamic bool `yaml:"dynamic,omitempty"`
|
|
Options HostOptions `yaml:"options,omitempty"`
|
|
}
|
|
|
|
type HostOptions struct {
|
|
Broadcast bool `yaml:"broadcast,omitempty"`
|
|
DestOnly bool `yaml:"destonly,omitempty"`
|
|
IPSec bool `yaml:"ipsec,omitempty"`
|
|
MSS int `yaml:"mss,omitempty"`
|
|
NoSmurfs bool `yaml:"nosmurfs,omitempty"`
|
|
RouteBack bool `yaml:"routeback,omitempty"`
|
|
TCPFlags bool `yaml:"tcpflags,omitempty"`
|
|
}
|
|
|
|
func (c *Config) validateHosts() error {
|
|
fwZone := c.FirewallZone()
|
|
|
|
for i, h := range c.Hosts {
|
|
if h.Zone == "" {
|
|
return fmt.Errorf("host[%d]: zone required", i)
|
|
}
|
|
if h.Zone == fwZone {
|
|
return fmt.Errorf("host[%d]: firewall zone must not be listed in hosts", i)
|
|
}
|
|
if _, ok := c.Zones[h.Zone]; !ok {
|
|
return fmt.Errorf("host[%d]: zone %q not defined", i, h.Zone)
|
|
}
|
|
if h.Interface == "" {
|
|
return fmt.Errorf("host[%d]: interface required", i)
|
|
}
|
|
|
|
ifaceFound := false
|
|
for _, iface := range c.Interfaces {
|
|
if iface.Interface == h.Interface || iface.PhysicalName() == h.Interface {
|
|
ifaceFound = true
|
|
break
|
|
}
|
|
}
|
|
if !ifaceFound {
|
|
return fmt.Errorf("host[%d]: interface %q not defined in interfaces", i, h.Interface)
|
|
}
|
|
|
|
if !h.Dynamic && len(h.Addresses) == 0 {
|
|
return fmt.Errorf("host[%d]: at least one address required (or set dynamic: true)", i)
|
|
}
|
|
}
|
|
return nil
|
|
}
|