|
@@ -7,6 +7,7 @@ import (
|
|
|
"net"
|
|
|
"net/netip"
|
|
|
|
|
|
+ "github.com/google/uuid"
|
|
|
"github.com/gravitl/netmaker/database"
|
|
|
"github.com/gravitl/netmaker/logger"
|
|
|
"github.com/gravitl/netmaker/logic/acls/nodeacls"
|
|
@@ -193,7 +194,11 @@ func GetPeerUpdateForHost(ctx context.Context, network string, host *models.Host
|
|
|
}
|
|
|
}
|
|
|
if peer.IsEgressGateway {
|
|
|
- allowedips = append(allowedips, getEgressIPs(&node, &peer)...)
|
|
|
+ allowedips = append(allowedips, getEgressIPs(
|
|
|
+ &models.Client{
|
|
|
+ Host: *GetHostByNodeID(peer.ID.String()),
|
|
|
+ Node: peer,
|
|
|
+ })...)
|
|
|
}
|
|
|
if peer.Action != models.NODE_DELETE &&
|
|
|
!peer.PendingDelete &&
|
|
@@ -570,42 +575,36 @@ func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet
|
|
|
return allowedips
|
|
|
}
|
|
|
|
|
|
-func getEgressIPs(node, peer *models.Node) []net.IPNet {
|
|
|
- host, err := GetHost(node.HostID.String())
|
|
|
- if err != nil {
|
|
|
- logger.Log(0, "error retrieving host for node", node.ID.String(), err.Error())
|
|
|
- }
|
|
|
- peerHost, err := GetHost(peer.HostID.String())
|
|
|
- if err != nil {
|
|
|
- logger.Log(0, "error retrieving host for peer", peer.ID.String(), err.Error())
|
|
|
- }
|
|
|
+// getEgressIPs - gets the egress IPs for a client
|
|
|
+func getEgressIPs(client *models.Client) []net.IPNet {
|
|
|
|
|
|
//check for internet gateway
|
|
|
internetGateway := false
|
|
|
- if slices.Contains(peer.EgressGatewayRanges, "0.0.0.0/0") || slices.Contains(peer.EgressGatewayRanges, "::/0") {
|
|
|
+ if slices.Contains(client.Node.EgressGatewayRanges, "0.0.0.0/0") || slices.Contains(client.Node.EgressGatewayRanges, "::/0") {
|
|
|
internetGateway = true
|
|
|
}
|
|
|
allowedips := []net.IPNet{}
|
|
|
- for _, iprange := range peer.EgressGatewayRanges { // go through each cidr for egress gateway
|
|
|
- _, ipnet, err := net.ParseCIDR(iprange) // confirming it's valid cidr
|
|
|
+ for _, iprange := range client.Node.EgressGatewayRanges { // go through each cidr for egress gateway
|
|
|
+ ip, cidr, err := net.ParseCIDR(iprange) // confirming it's valid cidr
|
|
|
if err != nil {
|
|
|
logger.Log(1, "could not parse gateway IP range. Not adding ", iprange)
|
|
|
continue // if can't parse CIDR
|
|
|
}
|
|
|
+ cidr.IP = ip
|
|
|
// getting the public ip of node
|
|
|
- if ipnet.Contains(peerHost.EndpointIP) && !internetGateway { // ensuring egress gateway range does not contain endpoint of node
|
|
|
- logger.Log(2, "egress IP range of ", iprange, " overlaps with ", host.EndpointIP.String(), ", omitting")
|
|
|
+ if cidr.Contains(client.Host.EndpointIP) && !internetGateway { // ensuring egress gateway range does not contain endpoint of node
|
|
|
+ logger.Log(2, "egress IP range of ", iprange, " overlaps with ", client.Host.EndpointIP.String(), ", omitting")
|
|
|
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
|
|
|
- if ipnet.Contains(node.LocalAddress.IP) && !internetGateway { // ensuring egress gateway range does not contain public ip of node
|
|
|
- logger.Log(2, "egress IP range of ", iprange, " overlaps with ", node.LocalAddress.String(), ", omitting")
|
|
|
+ if cidr.Contains(client.Node.LocalAddress.IP) && !internetGateway { // ensuring egress gateway range does not contain public ip of node
|
|
|
+ logger.Log(2, "egress IP range of ", iprange, " overlaps with ", client.Node.LocalAddress.String(), ", omitting")
|
|
|
continue // skip adding egress range if overlaps with node's local ip
|
|
|
}
|
|
|
if err != nil {
|
|
|
logger.Log(1, "error encountered when setting egress range", err.Error())
|
|
|
} else {
|
|
|
- allowedips = append(allowedips, *ipnet)
|
|
|
+ allowedips = append(allowedips, *cidr)
|
|
|
}
|
|
|
}
|
|
|
return allowedips
|
|
@@ -630,7 +629,11 @@ func getNodeAllowedIPs(peer, node *models.Node) []net.IPNet {
|
|
|
// handle egress gateway peers
|
|
|
if peer.IsEgressGateway {
|
|
|
//hasGateway = true
|
|
|
- egressIPs := getEgressIPs(node, peer)
|
|
|
+ egressIPs := getEgressIPs(
|
|
|
+ &models.Client{
|
|
|
+ Host: *GetHostByNodeID(peer.ID.String()),
|
|
|
+ Node: *peer,
|
|
|
+ })
|
|
|
allowedips = append(allowedips, egressIPs...)
|
|
|
}
|
|
|
if peer.IsRelay {
|
|
@@ -679,3 +682,191 @@ func filterNodeMapForClientACLs(publicKey, network string, nodePeerMap map[strin
|
|
|
}
|
|
|
return nodePeerMap
|
|
|
}
|
|
|
+
|
|
|
+func GetPeerUpdate(host *models.Host) []wgtypes.PeerConfig {
|
|
|
+ peerUpdate := []wgtypes.PeerConfig{}
|
|
|
+ for _, nodeStr := range host.Nodes {
|
|
|
+ node, err := GetNodeByID(uuid.MustParse(nodeStr).String())
|
|
|
+ if err != nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ client := models.Client{Host: *host, Node: node}
|
|
|
+ peers, err := GetNetworkClients(node.Network)
|
|
|
+ if err != nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if node.IsRelayed {
|
|
|
+ peerUpdate = append(peerUpdate, peerUpdateForRelayed(&client, &peers)...)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if node.IsRelay {
|
|
|
+ peerUpdate = append(peerUpdate, peerUpdateForRelay(&client, &peers)...)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ for _, peer := range peers {
|
|
|
+ if peer.Host.ID == client.Host.ID {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ // if peer is relayed by some other node, remove it from the peer list, it
|
|
|
+ // will be added to allowedips of relay peer
|
|
|
+ if peer.Node.IsRelayed {
|
|
|
+ update := wgtypes.PeerConfig{
|
|
|
+ PublicKey: peer.Host.PublicKey,
|
|
|
+ Remove: true,
|
|
|
+ }
|
|
|
+ peerUpdate = append(peerUpdate, update)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ update := wgtypes.PeerConfig{
|
|
|
+ PublicKey: peer.Host.PublicKey,
|
|
|
+ ReplaceAllowedIPs: true,
|
|
|
+ Endpoint: &net.UDPAddr{
|
|
|
+ IP: peer.Host.EndpointIP,
|
|
|
+ Port: peer.Host.ListenPort,
|
|
|
+ },
|
|
|
+ PersistentKeepaliveInterval: &peer.Node.PersistentKeepalive,
|
|
|
+ }
|
|
|
+ // if peer is a relay that relays us, don't do anything
|
|
|
+ if peer.Node.IsRelay && client.Node.RelayedBy == peer.Node.ID.String() {
|
|
|
+ continue
|
|
|
+ } else {
|
|
|
+ update.AllowedIPs = append(update.AllowedIPs, getRelayAllowedIPs(&peer)...)
|
|
|
+ }
|
|
|
+ //normal peer
|
|
|
+ update.AllowedIPs = append(update.AllowedIPs, AddAllowedIPs(&peer)...)
|
|
|
+ peerUpdate = append(peerUpdate, update)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return peerUpdate
|
|
|
+}
|
|
|
+
|
|
|
+func AddAllowedIPs(peer *models.Client) []net.IPNet {
|
|
|
+ allowedIPs := []net.IPNet{}
|
|
|
+ if peer.Node.Address.IP != nil {
|
|
|
+ peer.Node.Address.Mask = net.CIDRMask(32, 32)
|
|
|
+ allowedIPs = append(allowedIPs, peer.Node.Address)
|
|
|
+ }
|
|
|
+ if peer.Node.Address6.IP != nil {
|
|
|
+ peer.Node.Address6.Mask = net.CIDRMask(128, 128)
|
|
|
+ allowedIPs = append(allowedIPs, peer.Node.Address6)
|
|
|
+ }
|
|
|
+ if peer.Node.IsEgressGateway {
|
|
|
+ allowedIPs = append(allowedIPs, getEgressIPs(peer)...)
|
|
|
+ }
|
|
|
+ if peer.Node.IsIngressGateway {
|
|
|
+ allowedIPs = append(allowedIPs, getIngressIPs(peer)...)
|
|
|
+ }
|
|
|
+ return allowedIPs
|
|
|
+}
|
|
|
+
|
|
|
+// getRelayAllowedIPs returns the list of allowedips for a peer that is a relay
|
|
|
+func getRelayAllowedIPs(peer *models.Client) []net.IPNet {
|
|
|
+ var relayIPs []net.IPNet
|
|
|
+ if !peer.Node.IsRelay {
|
|
|
+ logger.Log(0, "getRelayAllowedIPs called for a non-relay node", peer.Host.Name)
|
|
|
+ return relayIPs
|
|
|
+ }
|
|
|
+ //if !client.Node.IsRelayed || client.Node.RelayedBy != peer.Node.ID.String() {
|
|
|
+ //logger.Log(0, "getRelayAllowedIPs called for non-relayed node", client.Host.Name, peer.Host.Name)
|
|
|
+ //return relayIPs
|
|
|
+ //}
|
|
|
+ fmt.Println("relayednodes", peer.Node.RelayedNodes)
|
|
|
+ for _, relayed := range peer.Node.RelayedNodes {
|
|
|
+ relayedNode, err := GetNodeByID(relayed)
|
|
|
+ fmt.Println("process relayed node", relayed, GetHostByNodeID(relayedNode.ID.String()).Name)
|
|
|
+ if err != nil {
|
|
|
+ logger.Log(0, "retrieve relayed node", err.Error())
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if relayedNode.Address.IP != nil {
|
|
|
+ relayedNode.Address.Mask = net.CIDRMask(32, 32)
|
|
|
+ fmt.Println("adding address", relayedNode.Address.String())
|
|
|
+ relayIPs = append(relayIPs, relayedNode.Address)
|
|
|
+ }
|
|
|
+ if relayedNode.Address6.IP != nil {
|
|
|
+ relayedNode.Address.Mask = net.CIDRMask(128, 128)
|
|
|
+ fmt.Println("adding address6", relayedNode.Address6.String())
|
|
|
+ relayIPs = append(relayIPs, relayedNode.Address6)
|
|
|
+ }
|
|
|
+ if relayedNode.IsRelay {
|
|
|
+ relayIPs = append(relayIPs, getRelayAllowedIPs(
|
|
|
+ &models.Client{
|
|
|
+ Host: *GetHostByNodeID(relayedNode.ID.String()),
|
|
|
+ Node: relayedNode,
|
|
|
+ })...)
|
|
|
+ }
|
|
|
+ if relayedNode.IsEgressGateway {
|
|
|
+ relayIPs = append(relayIPs, getEgressIPs(
|
|
|
+ &models.Client{
|
|
|
+ Host: *GetHostByNodeID(relayedNode.ID.String()),
|
|
|
+ Node: relayedNode,
|
|
|
+ })...)
|
|
|
+ }
|
|
|
+ if relayedNode.IsIngressGateway {
|
|
|
+ relayIPs = append(relayIPs, getIngressIPs(
|
|
|
+ &models.Client{
|
|
|
+ Host: *GetHostByNodeID(relayedNode.ID.String()),
|
|
|
+ Node: relayedNode,
|
|
|
+ })...)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return relayIPs
|
|
|
+}
|
|
|
+
|
|
|
+// getIngressIPs returns the additional allowedips (ext client addresses) that need
|
|
|
+// to be included for an ingress gateway peer
|
|
|
+// TODO: add ExtraAllowedIPs
|
|
|
+func getIngressIPs(peer *models.Client) []net.IPNet {
|
|
|
+ var ingressIPs []net.IPNet
|
|
|
+ extclients, err := GetNetworkExtClients(peer.Node.Network)
|
|
|
+ if err != nil {
|
|
|
+ return ingressIPs
|
|
|
+ }
|
|
|
+ for _, ec := range extclients {
|
|
|
+ if ec.IngressGatewayID == peer.Node.ID.String() {
|
|
|
+ if ec.Address != "" {
|
|
|
+ ip, cidr, err := net.ParseCIDR(ec.Address)
|
|
|
+ if err != nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ cidr.IP = ip
|
|
|
+ ingressIPs = append(ingressIPs, *cidr)
|
|
|
+ }
|
|
|
+ if ec.Address6 != "" {
|
|
|
+ ip, cidr, err := net.ParseCIDR(ec.Address6)
|
|
|
+ if err != nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ cidr.IP = ip
|
|
|
+ ingressIPs = append(ingressIPs, *cidr)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ingressIPs
|
|
|
+}
|
|
|
+
|
|
|
+// GetPeerUpdateForRelay - returns the peer update for a relay node
|
|
|
+func GetPeerUpdateForRelay(client *models.Client, peers *[]models.Client) []wgtypes.PeerConfig {
|
|
|
+ peerConfig := []wgtypes.PeerConfig{}
|
|
|
+ if !client.Node.IsRelay {
|
|
|
+ return []wgtypes.PeerConfig{}
|
|
|
+ }
|
|
|
+ for _, peer := range *peers {
|
|
|
+ if peer.Host.ID == client.Host.ID {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ update := wgtypes.PeerConfig{
|
|
|
+ PublicKey: peer.Host.PublicKey,
|
|
|
+ ReplaceAllowedIPs: true,
|
|
|
+ Remove: false,
|
|
|
+ Endpoint: &net.UDPAddr{
|
|
|
+ IP: peer.Host.EndpointIP,
|
|
|
+ Port: peer.Host.ListenPort,
|
|
|
+ },
|
|
|
+ PersistentKeepaliveInterval: &peer.Node.PersistentKeepalive,
|
|
|
+ }
|
|
|
+ update.AllowedIPs = append(update.AllowedIPs, AddAllowedIPs(&peer)...)
|
|
|
+ peerConfig = append(peerConfig, update)
|
|
|
+ }
|
|
|
+ return peerConfig
|
|
|
+}
|