package config import "fmt" type TunnelType string const ( TunnelIPSec TunnelType = "ipsec" TunnelIPSecNAT TunnelType = "ipsecnat" TunnelIPIP TunnelType = "ipip" TunnelGRE TunnelType = "gre" TunnelL2TP TunnelType = "l2tp" TunnelPPTPClient TunnelType = "pptpclient" TunnelPPTPServer TunnelType = "pptpserver" TunnelOpenVPN TunnelType = "openvpn" TunnelOpenVPNClient TunnelType = "openvpnclient" TunnelOpenVPNServer TunnelType = "openvpnserver" TunnelTinc TunnelType = "tinc" Tunnel6to4 TunnelType = "6to4" TunnelGeneric TunnelType = "generic" ) // Tunnel defines VPN tunnel rules that allow encapsulated traffic to pass // between the firewall and remote gateways. The actual traffic flowing // through the tunnel is handled by normal zone/policy/rules. type Tunnel struct { // Tunnel type. For ipsec, append ":ah" to use Authentication Headers (default: no AH). // For openvpn variants, append ":tcp" or ":udp" (default: udp). // For generic, append ":protocol" or ":protocol:port". Type string `yaml:"type"` // Zone of the physical interface through which tunnel traffic passes. Zone string `yaml:"zone"` // Remote tunnel gateway address(es). Use 0.0.0.0/0 or ::/0 for road warriors. Gateways []string `yaml:"gateways"` // Zones that the remote gateway host belongs to (for IPSEC ISAKMP traffic). GatewayZones []string `yaml:"gateway_zones,omitempty"` // Port override for openvpn/generic types (default: type-specific). Port int `yaml:"port,omitempty"` Comment string `yaml:"comment,omitempty"` } var validTunnelTypes = map[TunnelType]bool{ TunnelIPSec: true, TunnelIPSecNAT: true, TunnelIPIP: true, TunnelGRE: true, TunnelL2TP: true, TunnelPPTPClient: true, TunnelPPTPServer: true, TunnelOpenVPN: true, TunnelOpenVPNClient: true, TunnelOpenVPNServer: true, TunnelTinc: true, Tunnel6to4: true, TunnelGeneric: true, } func ParseTunnelType(s string) (TunnelType, string, bool) { for i, c := range s { if c == ':' { return TunnelType(s[:i]), s[i+1:], true } } return TunnelType(s), "", false } func (c *Config) validateTunnels() error { for i, t := range c.Tunnels { baseType, _, _ := ParseTunnelType(t.Type) if !validTunnelTypes[baseType] { return fmt.Errorf("tunnels[%d]: unknown tunnel type %q", i, baseType) } if t.Zone == "" { return fmt.Errorf("tunnels[%d]: zone required", i) } if _, ok := c.Zones[t.Zone]; !ok { return fmt.Errorf("tunnels[%d]: zone %q not defined", i, t.Zone) } if len(t.Gateways) == 0 { return fmt.Errorf("tunnels[%d]: at least one gateway required", i) } for _, gz := range t.GatewayZones { if _, ok := c.Zones[gz]; !ok { return fmt.Errorf("tunnels[%d]: gateway zone %q not defined", i, gz) } } } return nil }