use 0.0.0.0/0 ::/0 as egress range for internet gateways

This commit is contained in:
Matthew R. Kasun 2022-08-09 13:51:28 -04:00
parent 61553d70ab
commit 85cb88f0ad
5 changed files with 55 additions and 22 deletions

View file

@ -16,6 +16,7 @@ import (
"github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/ncutils" "github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/servercfg" "github.com/gravitl/netmaker/servercfg"
"golang.org/x/exp/slices"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
@ -494,6 +495,11 @@ func GetPeerUpdateForRelayedNode(node *models.Node, udppeers map[string]string)
} }
func getEgressIPs(node, peer *models.Node) []net.IPNet { func getEgressIPs(node, peer *models.Node) []net.IPNet {
//check for internet gateway
internetGateway := false
if slices.Contains(peer.EgressGatewayRanges, "0.0.0.0/0") || slices.Contains(peer.EgressGatewayRanges, "::0") {
internetGateway = true
}
allowedips := []net.IPNet{} allowedips := []net.IPNet{}
for _, iprange := range peer.EgressGatewayRanges { // go through each cidr for egress gateway for _, iprange := range peer.EgressGatewayRanges { // go through each cidr for egress gateway
_, ipnet, err := net.ParseCIDR(iprange) // confirming it's valid cidr _, ipnet, err := net.ParseCIDR(iprange) // confirming it's valid cidr
@ -501,13 +507,13 @@ func getEgressIPs(node, peer *models.Node) []net.IPNet {
logger.Log(1, "could not parse gateway IP range. Not adding ", iprange) logger.Log(1, "could not parse gateway IP range. Not adding ", iprange)
continue // if can't parse CIDR continue // if can't parse CIDR
} }
nodeEndpointArr := strings.Split(peer.Endpoint, ":") // getting the public ip of node nodeEndpointArr := strings.Split(peer.Endpoint, ":") // getting the public ip of node
if ipnet.Contains(net.ParseIP(nodeEndpointArr[0])) { // ensuring egress gateway range does not contain endpoint of node if ipnet.Contains(net.ParseIP(nodeEndpointArr[0])) && !internetGateway { // ensuring egress gateway range does not contain endpoint of node
logger.Log(2, "egress IP range of ", iprange, " overlaps with ", node.Endpoint, ", omitting") logger.Log(2, "egress IP range of ", iprange, " overlaps with ", node.Endpoint, ", omitting")
continue // skip adding egress range if overlaps with node's ip continue // skip adding egress range if overlaps with node's ip
} }
// TODO: Could put in a lot of great logic to avoid conflicts / bad routes // TODO: Could put in a lot of great logic to avoid conflicts / bad routes
if ipnet.Contains(net.ParseIP(node.LocalAddress)) { // ensuring egress gateway range does not contain public ip of node if ipnet.Contains(net.ParseIP(node.LocalAddress)) && !internetGateway { // ensuring egress gateway range does not contain public ip of node
logger.Log(2, "egress IP range of ", iprange, " overlaps with ", node.LocalAddress, ", omitting") logger.Log(2, "egress IP range of ", iprange, " overlaps with ", node.LocalAddress, ", omitting")
continue // skip adding egress range if overlaps with node's local ip continue // skip adding egress range if overlaps with node's local ip
} }

View file

@ -12,6 +12,7 @@ import (
"github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/ncutils" "github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/servercfg" "github.com/gravitl/netmaker/servercfg"
"golang.org/x/exp/slices"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
@ -206,6 +207,11 @@ func GetServerPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, bool, []stri
nodes, err := GetNetworkNodes(serverNode.Network) nodes, err := GetNetworkNodes(serverNode.Network)
if err == nil { if err == nil {
for _, node := range nodes { for _, node := range nodes {
//if egress ranges is internet (0.0.0.0/0 or ::/0) remove as don't want server to use internet gateway
if node.IsEgressGateway == "yes" && (slices.Contains(node.EgressGatewayRanges, "0.0.0.0/0") || slices.Contains(node.EgressGatewayRanges, "::/0")) {
logger.Log(0, "skipping internet gateway for server")
continue
}
if node.IsEgressGateway == "yes" && !IsLocalServer(&node) { if node.IsEgressGateway == "yes" && !IsLocalServer(&node) {
gateways = append(gateways, node.EgressGatewayRanges...) gateways = append(gateways, node.EgressGatewayRanges...)
} }

View file

@ -71,19 +71,20 @@ type Node struct {
RelayAddrs []string `json:"relayaddrs" bson:"relayaddrs" yaml:"relayaddrs"` RelayAddrs []string `json:"relayaddrs" bson:"relayaddrs" yaml:"relayaddrs"`
IngressGatewayRange string `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"` IngressGatewayRange string `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"`
// IsStatic - refers to if the Endpoint is set manually or dynamically // IsStatic - refers to if the Endpoint is set manually or dynamically
IsStatic string `json:"isstatic" bson:"isstatic" yaml:"isstatic" validate:"checkyesorno"` IsStatic string `json:"isstatic" bson:"isstatic" yaml:"isstatic" validate:"checkyesorno"`
UDPHolePunch string `json:"udpholepunch" bson:"udpholepunch" yaml:"udpholepunch" validate:"checkyesorno"` UDPHolePunch string `json:"udpholepunch" bson:"udpholepunch" yaml:"udpholepunch" validate:"checkyesorno"`
DNSOn string `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"` DNSOn string `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"`
IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"` IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
Action string `json:"action" bson:"action" yaml:"action"` Action string `json:"action" bson:"action" yaml:"action"`
IsLocal string `json:"islocal" bson:"islocal" yaml:"islocal" validate:"checkyesorno"` IsLocal string `json:"islocal" bson:"islocal" yaml:"islocal" validate:"checkyesorno"`
LocalRange string `json:"localrange" bson:"localrange" yaml:"localrange"` LocalRange string `json:"localrange" bson:"localrange" yaml:"localrange"`
IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"` IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"`
OS string `json:"os" bson:"os" yaml:"os"` OS string `json:"os" bson:"os" yaml:"os"`
MTU int32 `json:"mtu" bson:"mtu" yaml:"mtu"` MTU int32 `json:"mtu" bson:"mtu" yaml:"mtu"`
Version string `json:"version" bson:"version" yaml:"version"` Version string `json:"version" bson:"version" yaml:"version"`
Server string `json:"server" bson:"server" yaml:"server"` Server string `json:"server" bson:"server" yaml:"server"`
TrafficKeys TrafficKeys `json:"traffickeys" bson:"traffickeys" yaml:"traffickeys"` TrafficKeys TrafficKeys `json:"traffickeys" bson:"traffickeys" yaml:"traffickeys"`
InternetGateway string `json:"internetgateway" bson:"internetgateway" yaml:"internetgateway"`
} }
// NodesArray - used for node sorting // NodesArray - used for node sorting

View file

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"net"
"os" "os"
"runtime" "runtime"
"strings" "strings"
@ -208,11 +209,27 @@ func UpdatePeers(client mqtt.Client, msg mqtt.Message) {
} }
file := ncutils.GetNetclientPathSpecific() + cfg.Node.Interface + ".conf" file := ncutils.GetNetclientPathSpecific() + cfg.Node.Interface + ".conf"
err = wireguard.UpdateWgPeers(file, peerUpdate.Peers) internetGateway, err := wireguard.UpdateWgPeers(file, peerUpdate.Peers)
if err != nil { if err != nil {
logger.Log(0, "error updating wireguard peers"+err.Error()) logger.Log(0, "error updating wireguard peers"+err.Error())
return return
} }
//check if internet gateway has changed
oldGateway, err := net.ResolveUDPAddr("udp", cfg.Node.InternetGateway)
if err != nil || (oldGateway == &net.UDPAddr{}) {
oldGateway = nil
}
if (internetGateway == nil && oldGateway != nil) || (internetGateway != nil && internetGateway != oldGateway) {
cfg.Node.InternetGateway = internetGateway.String()
if err := config.ModNodeConfig(&cfg.Node); err != nil {
logger.Log(0, "failed to save internet gateway", err.Error())
}
if err := wireguard.ApplyConf(&cfg.Node, cfg.Node.Interface, file); err != nil {
logger.Log(0, "error applying internet gateway", err.Error())
}
UpdateLocalListenPort(&cfg)
return
}
queryAddr := cfg.Node.PrimaryAddress() queryAddr := cfg.Node.PrimaryAddress()
//err = wireguard.SyncWGQuickConf(cfg.Node.Interface, file) //err = wireguard.SyncWGQuickConf(cfg.Node.Interface, file)

View file

@ -319,7 +319,6 @@ func ApplyConf(node *models.Node, ifacename string, confPath string) error {
} }
// WriteWgConfig - creates a wireguard config file // WriteWgConfig - creates a wireguard config file
//func WriteWgConfig(cfg *config.ClientConfig, privateKey string, peers []wgtypes.PeerConfig) error {
func WriteWgConfig(node *models.Node, privateKey string, peers []wgtypes.PeerConfig) error { func WriteWgConfig(node *models.Node, privateKey string, peers []wgtypes.PeerConfig) error {
options := ini.LoadOptions{ options := ini.LoadOptions{
AllowNonUniqueSections: true, AllowNonUniqueSections: true,
@ -382,14 +381,15 @@ func WriteWgConfig(node *models.Node, privateKey string, peers []wgtypes.PeerCon
} }
// UpdateWgPeers - updates the peers of a network // UpdateWgPeers - updates the peers of a network
func UpdateWgPeers(file string, peers []wgtypes.PeerConfig) error { func UpdateWgPeers(file string, peers []wgtypes.PeerConfig) (*net.UDPAddr, error) {
var internetGateway *net.UDPAddr
options := ini.LoadOptions{ options := ini.LoadOptions{
AllowNonUniqueSections: true, AllowNonUniqueSections: true,
AllowShadows: true, AllowShadows: true,
} }
wireguard, err := ini.LoadSources(options, file) wireguard, err := ini.LoadSources(options, file)
if err != nil { if err != nil {
return err return internetGateway, err
} }
//delete the peers sections as they are going to be replaced //delete the peers sections as they are going to be replaced
wireguard.DeleteSection(section_peers) wireguard.DeleteSection(section_peers)
@ -408,6 +408,9 @@ func UpdateWgPeers(file string, peers []wgtypes.PeerConfig) error {
} }
} }
wireguard.SectionWithIndex(section_peers, i).Key("AllowedIps").SetValue(allowedIPs) wireguard.SectionWithIndex(section_peers, i).Key("AllowedIps").SetValue(allowedIPs)
if strings.Contains(allowedIPs, "0.0.0.0/0") || strings.Contains(allowedIPs, "::/0") {
internetGateway = peer.Endpoint
}
} }
if peer.Endpoint != nil { if peer.Endpoint != nil {
wireguard.SectionWithIndex(section_peers, i).Key("Endpoint").SetValue(peer.Endpoint.String()) wireguard.SectionWithIndex(section_peers, i).Key("Endpoint").SetValue(peer.Endpoint.String())
@ -417,9 +420,9 @@ func UpdateWgPeers(file string, peers []wgtypes.PeerConfig) error {
} }
} }
if err := wireguard.SaveTo(file); err != nil { if err := wireguard.SaveTo(file); err != nil {
return err return internetGateway, err
} }
return nil return internetGateway, nil
} }
// UpdateWgInterface - updates the interface section of a wireguard config file // UpdateWgInterface - updates the interface section of a wireguard config file