mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-09 21:36:09 +08:00
Merge pull request #2693 from gravitl/NET-800
NET-800: Extclients ExtraAllowed IPs
This commit is contained in:
commit
0874618aac
5 changed files with 150 additions and 75 deletions
|
@ -481,6 +481,9 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
|
||||||
sendPeerUpdate = true
|
sendPeerUpdate = true
|
||||||
logic.SetClientACLs(&oldExtClient, update.DeniedACLs)
|
logic.SetClientACLs(&oldExtClient, update.DeniedACLs)
|
||||||
}
|
}
|
||||||
|
if !logic.IsSlicesEqual(update.ExtraAllowedIPs, oldExtClient.ExtraAllowedIPs) {
|
||||||
|
sendPeerUpdate = true
|
||||||
|
}
|
||||||
|
|
||||||
if update.Enabled != oldExtClient.Enabled {
|
if update.Enabled != oldExtClient.Enabled {
|
||||||
sendPeerUpdate = true
|
sendPeerUpdate = true
|
||||||
|
|
|
@ -3,11 +3,13 @@ package logic
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/database"
|
"github.com/gravitl/netmaker/database"
|
||||||
|
"github.com/gravitl/netmaker/logger"
|
||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/models"
|
||||||
"golang.org/x/exp/slog"
|
"golang.org/x/exp/slog"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
@ -184,6 +186,9 @@ func CreateExtClient(extclient *models.ExtClient) error {
|
||||||
} else if len(extclient.PrivateKey) == 0 && len(extclient.PublicKey) > 0 {
|
} else if len(extclient.PrivateKey) == 0 && len(extclient.PublicKey) > 0 {
|
||||||
extclient.PrivateKey = "[ENTER PRIVATE KEY]"
|
extclient.PrivateKey = "[ENTER PRIVATE KEY]"
|
||||||
}
|
}
|
||||||
|
if extclient.ExtraAllowedIPs == nil {
|
||||||
|
extclient.ExtraAllowedIPs = []string{}
|
||||||
|
}
|
||||||
|
|
||||||
parentNetwork, err := GetNetwork(extclient.Network)
|
parentNetwork, err := GetNetwork(extclient.Network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -247,9 +252,7 @@ func UpdateExtClient(old *models.ExtClient, update *models.CustomExtClient) mode
|
||||||
if update.Enabled != old.Enabled {
|
if update.Enabled != old.Enabled {
|
||||||
new.Enabled = update.Enabled
|
new.Enabled = update.Enabled
|
||||||
}
|
}
|
||||||
if update.ExtraAllowedIPs != nil && StringDifference(old.ExtraAllowedIPs, update.ExtraAllowedIPs) != nil {
|
new.ExtraAllowedIPs = update.ExtraAllowedIPs
|
||||||
new.ExtraAllowedIPs = update.ExtraAllowedIPs
|
|
||||||
}
|
|
||||||
if update.DeniedACLs != nil && !reflect.DeepEqual(old.DeniedACLs, update.DeniedACLs) {
|
if update.DeniedACLs != nil && !reflect.DeepEqual(old.DeniedACLs, update.DeniedACLs) {
|
||||||
new.DeniedACLs = update.DeniedACLs
|
new.DeniedACLs = update.DeniedACLs
|
||||||
}
|
}
|
||||||
|
@ -318,3 +321,107 @@ func ToggleExtClientConnectivity(client *models.ExtClient, enable bool) (models.
|
||||||
|
|
||||||
return newClient, nil
|
return newClient, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, []models.EgressNetworkRoutes, error) {
|
||||||
|
var peers []wgtypes.PeerConfig
|
||||||
|
var idsAndAddr []models.IDandAddr
|
||||||
|
var egressRoutes []models.EgressNetworkRoutes
|
||||||
|
extPeers, err := GetNetworkExtClients(node.Network)
|
||||||
|
if err != nil {
|
||||||
|
return peers, idsAndAddr, egressRoutes, err
|
||||||
|
}
|
||||||
|
host, err := GetHost(node.HostID.String())
|
||||||
|
if err != nil {
|
||||||
|
return peers, idsAndAddr, egressRoutes, err
|
||||||
|
}
|
||||||
|
for _, extPeer := range extPeers {
|
||||||
|
extPeer := extPeer
|
||||||
|
if !IsClientNodeAllowed(&extPeer, peer.ID.String()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pubkey, err := wgtypes.ParseKey(extPeer.PublicKey)
|
||||||
|
if err != nil {
|
||||||
|
logger.Log(1, "error parsing ext pub key:", err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if host.PublicKey.String() == extPeer.PublicKey ||
|
||||||
|
extPeer.IngressGatewayID != node.ID.String() || !extPeer.Enabled {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var allowedips []net.IPNet
|
||||||
|
var peer wgtypes.PeerConfig
|
||||||
|
if extPeer.Address != "" {
|
||||||
|
var peeraddr = net.IPNet{
|
||||||
|
IP: net.ParseIP(extPeer.Address),
|
||||||
|
Mask: net.CIDRMask(32, 32),
|
||||||
|
}
|
||||||
|
if peeraddr.IP != nil && peeraddr.Mask != nil {
|
||||||
|
allowedips = append(allowedips, peeraddr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if extPeer.Address6 != "" {
|
||||||
|
var addr6 = net.IPNet{
|
||||||
|
IP: net.ParseIP(extPeer.Address6),
|
||||||
|
Mask: net.CIDRMask(128, 128),
|
||||||
|
}
|
||||||
|
if addr6.IP != nil && addr6.Mask != nil {
|
||||||
|
allowedips = append(allowedips, addr6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, extraAllowedIP := range extPeer.ExtraAllowedIPs {
|
||||||
|
_, cidr, err := net.ParseCIDR(extraAllowedIP)
|
||||||
|
if err == nil {
|
||||||
|
allowedips = append(allowedips, *cidr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
egressRoutes = append(egressRoutes, getExtPeerEgressRoute(extPeer)...)
|
||||||
|
primaryAddr := extPeer.Address
|
||||||
|
if primaryAddr == "" {
|
||||||
|
primaryAddr = extPeer.Address6
|
||||||
|
}
|
||||||
|
peer = wgtypes.PeerConfig{
|
||||||
|
PublicKey: pubkey,
|
||||||
|
ReplaceAllowedIPs: true,
|
||||||
|
AllowedIPs: allowedips,
|
||||||
|
}
|
||||||
|
peers = append(peers, peer)
|
||||||
|
idsAndAddr = append(idsAndAddr, models.IDandAddr{
|
||||||
|
ID: peer.PublicKey.String(),
|
||||||
|
Name: extPeer.ClientID,
|
||||||
|
Address: primaryAddr,
|
||||||
|
IsExtClient: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return peers, idsAndAddr, egressRoutes, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getExtPeerEgressRoute(extPeer models.ExtClient) (egressRoutes []models.EgressNetworkRoutes) {
|
||||||
|
if extPeer.Address != "" {
|
||||||
|
egressRoutes = append(egressRoutes, models.EgressNetworkRoutes{
|
||||||
|
NodeAddr: extPeer.AddressIPNet4(),
|
||||||
|
EgressRanges: extPeer.ExtraAllowedIPs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if extPeer.Address6 != "" {
|
||||||
|
egressRoutes = append(egressRoutes, models.EgressNetworkRoutes{
|
||||||
|
NodeAddr: extPeer.AddressIPNet6(),
|
||||||
|
EgressRanges: extPeer.ExtraAllowedIPs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getExtpeersExtraRoutes(network string) (egressRoutes []models.EgressNetworkRoutes) {
|
||||||
|
extPeers, err := GetNetworkExtClients(network)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, extPeer := range extPeers {
|
||||||
|
egressRoutes = append(egressRoutes, getExtPeerEgressRoute(extPeer)...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -129,6 +129,9 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
||||||
EgressRanges: peer.EgressGatewayRanges,
|
EgressRanges: peer.EgressGatewayRanges,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if peer.IsIngressGateway {
|
||||||
|
hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(peer.Network)...)
|
||||||
|
}
|
||||||
if (node.IsRelayed && node.RelayedBy != peer.ID.String()) || (peer.IsRelayed && peer.RelayedBy != node.ID.String()) {
|
if (node.IsRelayed && node.RelayedBy != peer.ID.String()) || (peer.IsRelayed && peer.RelayedBy != node.ID.String()) {
|
||||||
// if node is relayed and peer is not the relay, set remove to true
|
// if node is relayed and peer is not the relay, set remove to true
|
||||||
if _, ok := peerIndexMap[peerHost.PublicKey.String()]; ok {
|
if _, ok := peerIndexMap[peerHost.PublicKey.String()]; ok {
|
||||||
|
@ -207,9 +210,11 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
||||||
}
|
}
|
||||||
var extPeers []wgtypes.PeerConfig
|
var extPeers []wgtypes.PeerConfig
|
||||||
var extPeerIDAndAddrs []models.IDandAddr
|
var extPeerIDAndAddrs []models.IDandAddr
|
||||||
|
var egressRoutes []models.EgressNetworkRoutes
|
||||||
if node.IsIngressGateway {
|
if node.IsIngressGateway {
|
||||||
extPeers, extPeerIDAndAddrs, err = getExtPeers(&node, &node)
|
extPeers, extPeerIDAndAddrs, egressRoutes, err = getExtPeers(&node, &node)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, egressRoutes...)
|
||||||
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, extPeers...)
|
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, extPeers...)
|
||||||
for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
||||||
extPeerIdAndAddr := extPeerIdAndAddr
|
extPeerIdAndAddr := extPeerIdAndAddr
|
||||||
|
@ -290,76 +295,6 @@ func GetPeerListenPort(host *models.Host) int {
|
||||||
return peerPort
|
return peerPort
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, error) {
|
|
||||||
var peers []wgtypes.PeerConfig
|
|
||||||
var idsAndAddr []models.IDandAddr
|
|
||||||
extPeers, err := GetNetworkExtClients(node.Network)
|
|
||||||
if err != nil {
|
|
||||||
return peers, idsAndAddr, err
|
|
||||||
}
|
|
||||||
host, err := GetHost(node.HostID.String())
|
|
||||||
if err != nil {
|
|
||||||
return peers, idsAndAddr, err
|
|
||||||
}
|
|
||||||
for _, extPeer := range extPeers {
|
|
||||||
extPeer := extPeer
|
|
||||||
if !IsClientNodeAllowed(&extPeer, peer.ID.String()) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pubkey, err := wgtypes.ParseKey(extPeer.PublicKey)
|
|
||||||
if err != nil {
|
|
||||||
logger.Log(1, "error parsing ext pub key:", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if host.PublicKey.String() == extPeer.PublicKey ||
|
|
||||||
extPeer.IngressGatewayID != node.ID.String() || !extPeer.Enabled {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var allowedips []net.IPNet
|
|
||||||
var peer wgtypes.PeerConfig
|
|
||||||
if extPeer.Address != "" {
|
|
||||||
var peeraddr = net.IPNet{
|
|
||||||
IP: net.ParseIP(extPeer.Address),
|
|
||||||
Mask: net.CIDRMask(32, 32),
|
|
||||||
}
|
|
||||||
if peeraddr.IP != nil && peeraddr.Mask != nil {
|
|
||||||
allowedips = append(allowedips, peeraddr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if extPeer.Address6 != "" {
|
|
||||||
var addr6 = net.IPNet{
|
|
||||||
IP: net.ParseIP(extPeer.Address6),
|
|
||||||
Mask: net.CIDRMask(128, 128),
|
|
||||||
}
|
|
||||||
if addr6.IP != nil && addr6.Mask != nil {
|
|
||||||
allowedips = append(allowedips, addr6)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
primaryAddr := extPeer.Address
|
|
||||||
if primaryAddr == "" {
|
|
||||||
primaryAddr = extPeer.Address6
|
|
||||||
}
|
|
||||||
peer = wgtypes.PeerConfig{
|
|
||||||
PublicKey: pubkey,
|
|
||||||
ReplaceAllowedIPs: true,
|
|
||||||
AllowedIPs: allowedips,
|
|
||||||
}
|
|
||||||
peers = append(peers, peer)
|
|
||||||
idsAndAddr = append(idsAndAddr, models.IDandAddr{
|
|
||||||
ID: peer.PublicKey.String(),
|
|
||||||
Name: extPeer.ClientID,
|
|
||||||
Address: primaryAddr,
|
|
||||||
IsExtClient: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return peers, idsAndAddr, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAllowedIPs - calculates the wireguard allowedip field for a peer of a node based on the peer and node settings
|
// GetAllowedIPs - calculates the wireguard allowedip field for a peer of a node based on the peer and node settings
|
||||||
func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet {
|
func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet {
|
||||||
var allowedips []net.IPNet
|
var allowedips []net.IPNet
|
||||||
|
@ -367,7 +302,7 @@ func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet
|
||||||
|
|
||||||
// handle ingress gateway peers
|
// handle ingress gateway peers
|
||||||
if peer.IsIngressGateway {
|
if peer.IsIngressGateway {
|
||||||
extPeers, _, err := getExtPeers(peer, node)
|
extPeers, _, _, err := getExtPeers(peer, node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Log(2, "could not retrieve ext peers for ", peer.ID.String(), err.Error())
|
logger.Log(2, "could not retrieve ext peers for ", peer.ID.String(), err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,4 +134,18 @@ func RemoveStringSlice(slice []string, i int) []string {
|
||||||
return append(slice[:i], slice[i+1:]...)
|
return append(slice[:i], slice[i+1:]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSlicesEqual tells whether a and b contain the same elements.
|
||||||
|
// A nil argument is equivalent to an empty slice.
|
||||||
|
func IsSlicesEqual(a, b []string) bool {
|
||||||
|
if len(a) != len(b) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i, v := range a {
|
||||||
|
if v != b[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// == private ==
|
// == private ==
|
||||||
|
|
|
@ -192,6 +192,22 @@ func (node *Node) PrimaryAddress() string {
|
||||||
return node.Address6.IP.String()
|
return node.Address6.IP.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExtClient.PrimaryAddress - returns ipv4 IPNet format
|
||||||
|
func (extPeer *ExtClient) AddressIPNet4() net.IPNet {
|
||||||
|
return net.IPNet{
|
||||||
|
IP: net.ParseIP(extPeer.Address),
|
||||||
|
Mask: net.CIDRMask(32, 32),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtClient.AddressIPNet6 - return ipv6 IPNet format
|
||||||
|
func (extPeer *ExtClient) AddressIPNet6() net.IPNet {
|
||||||
|
return net.IPNet{
|
||||||
|
IP: net.ParseIP(extPeer.Address),
|
||||||
|
Mask: net.CIDRMask(128, 128),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Node.PrimaryNetworkRange - returns node's parent network, returns ipv4 address if present, else return ipv6
|
// Node.PrimaryNetworkRange - returns node's parent network, returns ipv4 address if present, else return ipv6
|
||||||
func (node *Node) PrimaryNetworkRange() net.IPNet {
|
func (node *Node) PrimaryNetworkRange() net.IPNet {
|
||||||
if node.NetworkRange.IP != nil {
|
if node.NetworkRange.IP != nil {
|
||||||
|
|
Loading…
Add table
Reference in a new issue