2a3eb3b04d
Spiritual successor to shorewall — manages nftables directly via google/nftables. Reads a single YAML config covering zones, interfaces, hosts, policy, rules, snat, and named portgroups. Computes differential changes against the running nftables state and applies them atomically. Supports detecting and purging rules added outside of tomswall.
54 lines
1.3 KiB
Go
54 lines
1.3 KiB
Go
package config
|
|
|
|
import "fmt"
|
|
|
|
type PolicyAction string
|
|
|
|
const (
|
|
PolicyAccept PolicyAction = "accept"
|
|
PolicyDrop PolicyAction = "drop"
|
|
PolicyReject PolicyAction = "reject"
|
|
PolicyContinue PolicyAction = "continue"
|
|
PolicyNone PolicyAction = "none"
|
|
)
|
|
|
|
type Policy struct {
|
|
Source string `yaml:"source"`
|
|
Dest string `yaml:"dest"`
|
|
Action PolicyAction `yaml:"action"`
|
|
Log string `yaml:"log,omitempty"`
|
|
RateLimit string `yaml:"rate_limit,omitempty"`
|
|
ConnLimit int `yaml:"conn_limit,omitempty"`
|
|
}
|
|
|
|
func (c *Config) validatePolicy() error {
|
|
if len(c.Policy) == 0 {
|
|
return fmt.Errorf("no policies defined")
|
|
}
|
|
|
|
for i, p := range c.Policy {
|
|
if p.Source == "" {
|
|
return fmt.Errorf("policy[%d]: source required", i)
|
|
}
|
|
if p.Dest == "" {
|
|
return fmt.Errorf("policy[%d]: dest required", i)
|
|
}
|
|
if p.Source != "all" {
|
|
if _, ok := c.Zones[p.Source]; !ok {
|
|
return fmt.Errorf("policy[%d]: source zone %q not defined", i, p.Source)
|
|
}
|
|
}
|
|
if p.Dest != "all" {
|
|
if _, ok := c.Zones[p.Dest]; !ok {
|
|
return fmt.Errorf("policy[%d]: dest zone %q not defined", i, p.Dest)
|
|
}
|
|
}
|
|
switch p.Action {
|
|
case PolicyAccept, PolicyDrop, PolicyReject, PolicyContinue, PolicyNone:
|
|
default:
|
|
return fmt.Errorf("policy[%d]: unknown action %q", i, p.Action)
|
|
}
|
|
}
|
|
return nil
|
|
}
|