mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-08 14:15:25 +08:00
NET-1932: Fix static node comms on CE (#3481)
* move relevant acl and tag code to CE and Pro pkgs * intialise pro acl funcs * list gateways by user access * check user gw access by policies * filter out user policies on CE * filter out tagged policies on CE * fix ce acl comms * allow gateways tag * allow gateway tag on CE, remove failover and gw check on acl policy * add gw rules func to pro * add inet gw support on CE * add egress acl API * add egress acl API * fix(go): set is_gw when converting api node to server node; * fix(go): set is_gw when converting api node to server node; * fix policy validity checker for inet gws * move dns option to host model * fix node removal from egress policy on delete * add migration logic for ManageDNS * fix dns json field * fix nil error on node tags * add egress info to relayed nodes * fix default network user policy * fix egress migration * fix egress migration * add failover inet gw check * optiomise egress calls * auto create gw on inet egress node * optimise egress calls * add global user role check * fix egress on inet gw * remove addtional checks on inet policy * add acl policy for static nodes on CE * remove chained inet gws * fix multi-inet issue --------- Co-authored-by: Vishal Dalwadi <dalwadivishal26@gmail.com>
This commit is contained in:
parent
44300590f8
commit
0ff216dabd
12 changed files with 317 additions and 138 deletions
|
@ -181,11 +181,12 @@ func aclDebug(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
allowed, ps := logic.IsNodeAllowedToCommunicate(node, peer, true)
|
||||
isallowed := logic.IsPeerAllowed(node, peer, true)
|
||||
acls, _ := logic.ListAclsByNetwork(models.NetworkID(node.Network))
|
||||
re := resp{
|
||||
IsNodeAllowed: allowed,
|
||||
IsPeerAllowed: isallowed,
|
||||
Policies: ps,
|
||||
EgressNets: logic.GetNetworkEgressInfo(models.NetworkID(node.Network)),
|
||||
EgressNets: logic.GetNetworkEgressInfo(models.NetworkID(node.Network), acls),
|
||||
}
|
||||
if peerIsStatic == "true" {
|
||||
ingress, err := logic.GetNodeByID(peer.StaticNode.IngressGatewayID)
|
||||
|
|
|
@ -92,6 +92,12 @@ func createEgress(w http.ResponseWriter, r *http.Request) {
|
|||
node.IsGw = true
|
||||
node.IsIngressGateway = true
|
||||
node.IsRelay = true
|
||||
if node.Address.IP != nil {
|
||||
node.IngressDNS = node.Address.IP.String()
|
||||
} else {
|
||||
node.IngressDNS = node.Address6.IP.String()
|
||||
}
|
||||
|
||||
logic.UpsertNode(&node)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,7 +178,8 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
eli, _ := (&schema.Egress{Network: gwnode.Network}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
logic.GetNodeEgressInfo(&gwnode, eli)
|
||||
acls, _ := logic.ListAclsByNetwork(models.NetworkID(client.Network))
|
||||
logic.GetNodeEgressInfo(&gwnode, eli, acls)
|
||||
host, err := logic.GetHost(gwnode.HostID.String())
|
||||
if err != nil {
|
||||
logger.Log(
|
||||
|
@ -266,7 +267,7 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
var newAllowedIPs string
|
||||
if logic.IsInternetGw(gwnode) || gwnode.EgressDetails.InternetGwID != "" {
|
||||
if logic.IsInternetGw(gwnode) {
|
||||
egressrange := "0.0.0.0/0"
|
||||
if gwnode.Address6.IP != nil && client.Address6 != "" {
|
||||
egressrange += "," + "::/0"
|
||||
|
|
271
logic/acls.go
271
logic/acls.go
|
@ -21,8 +21,272 @@ import (
|
|||
// TODO: Write Diff Funcs
|
||||
|
||||
var IsNodeAllowedToCommunicate = isNodeAllowedToCommunicate
|
||||
var GetStaticNodeIps = func(node models.Node) (ips []net.IP) { return }
|
||||
var GetFwRulesOnIngressGateway = func(node models.Node) (rules []models.FwRule) { return }
|
||||
|
||||
var GetFwRulesForNodeAndPeerOnGw = getFwRulesForNodeAndPeerOnGw
|
||||
|
||||
var GetFwRulesForUserNodesOnGw = func(node models.Node, nodes []models.Node) (rules []models.FwRule) { return }
|
||||
|
||||
func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
|
||||
// fetch user access to static clients via policies
|
||||
defer func() {
|
||||
sort.Slice(rules, func(i, j int) bool {
|
||||
if !rules[i].SrcIP.IP.Equal(rules[j].SrcIP.IP) {
|
||||
return string(rules[i].SrcIP.IP.To16()) < string(rules[j].SrcIP.IP.To16())
|
||||
}
|
||||
return string(rules[i].DstIP.IP.To16()) < string(rules[j].DstIP.IP.To16())
|
||||
})
|
||||
}()
|
||||
defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
||||
nodes, _ := GetNetworkNodes(node.Network)
|
||||
nodes = append(nodes, GetStaticNodesByNetwork(models.NetworkID(node.Network), true)...)
|
||||
rules = GetFwRulesForUserNodesOnGw(node, nodes)
|
||||
if defaultDevicePolicy.Enabled {
|
||||
return
|
||||
}
|
||||
for _, nodeI := range nodes {
|
||||
if !nodeI.IsStatic || nodeI.IsUserNode {
|
||||
continue
|
||||
}
|
||||
// if nodeI.StaticNode.IngressGatewayID != node.ID.String() {
|
||||
// continue
|
||||
// }
|
||||
for _, peer := range nodes {
|
||||
if peer.StaticNode.ClientID == nodeI.StaticNode.ClientID || peer.IsUserNode {
|
||||
continue
|
||||
}
|
||||
if nodeI.StaticNode.IngressGatewayID != node.ID.String() &&
|
||||
((!peer.IsStatic && peer.ID.String() != node.ID.String()) ||
|
||||
(peer.IsStatic && peer.StaticNode.IngressGatewayID != node.ID.String())) {
|
||||
continue
|
||||
}
|
||||
if peer.IsStatic {
|
||||
peer = peer.StaticNode.ConvertToStaticNode()
|
||||
}
|
||||
var allowedPolicies1 []models.Acl
|
||||
var ok bool
|
||||
if ok, allowedPolicies1 = IsNodeAllowedToCommunicate(nodeI.StaticNode.ConvertToStaticNode(), peer, true); ok {
|
||||
rules = append(rules, GetFwRulesForNodeAndPeerOnGw(nodeI.StaticNode.ConvertToStaticNode(), peer, allowedPolicies1)...)
|
||||
}
|
||||
if ok, allowedPolicies2 := IsNodeAllowedToCommunicate(peer, nodeI.StaticNode.ConvertToStaticNode(), true); ok {
|
||||
rules = append(rules,
|
||||
GetFwRulesForNodeAndPeerOnGw(peer, nodeI.StaticNode.ConvertToStaticNode(),
|
||||
getUniquePolicies(allowedPolicies1, allowedPolicies2))...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getFwRulesForNodeAndPeerOnGw(node, peer models.Node, allowedPolicies []models.Acl) (rules []models.FwRule) {
|
||||
|
||||
for _, policy := range allowedPolicies {
|
||||
// if static peer dst rule not for ingress node -> skip
|
||||
if node.Address.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
DstIP: net.IPNet{
|
||||
IP: peer.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
||||
if node.Address6.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
DstIP: net.IPNet{
|
||||
IP: peer.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
if policy.AllowedDirection == models.TrafficDirectionBi {
|
||||
if node.Address.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: peer.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
DstIP: net.IPNet{
|
||||
IP: node.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
||||
if node.Address6.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: peer.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
DstIP: net.IPNet{
|
||||
IP: node.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
if len(node.StaticNode.ExtraAllowedIPs) > 0 {
|
||||
for _, additionalAllowedIPNet := range node.StaticNode.ExtraAllowedIPs {
|
||||
_, ipNet, err := net.ParseCIDR(additionalAllowedIPNet)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if ipNet.IP.To4() != nil && peer.Address.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: peer.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
DstIP: *ipNet,
|
||||
Allow: true,
|
||||
})
|
||||
} else if peer.Address6.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: peer.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
DstIP: *ipNet,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if len(peer.StaticNode.ExtraAllowedIPs) > 0 {
|
||||
for _, additionalAllowedIPNet := range peer.StaticNode.ExtraAllowedIPs {
|
||||
_, ipNet, err := net.ParseCIDR(additionalAllowedIPNet)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if ipNet.IP.To4() != nil && node.Address.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
DstIP: *ipNet,
|
||||
Allow: true,
|
||||
})
|
||||
} else if node.Address6.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
DstIP: *ipNet,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// add egress range rules
|
||||
for _, dstI := range policy.Dst {
|
||||
if dstI.ID == models.EgressID {
|
||||
|
||||
e := schema.Egress{ID: dstI.Value}
|
||||
err := e.Get(db.WithContext(context.TODO()))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
dstI.Value = e.Range
|
||||
|
||||
ip, cidr, err := net.ParseCIDR(dstI.Value)
|
||||
if err == nil {
|
||||
if ip.To4() != nil {
|
||||
if node.Address.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
DstIP: *cidr,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if node.Address6.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
DstIP: *cidr,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getUniquePolicies(policies1, policies2 []models.Acl) []models.Acl {
|
||||
policies1Map := make(map[string]struct{})
|
||||
for _, policy1I := range policies1 {
|
||||
policies1Map[policy1I.ID] = struct{}{}
|
||||
}
|
||||
for i := len(policies2) - 1; i >= 0; i-- {
|
||||
if _, ok := policies1Map[policies2[i].ID]; ok {
|
||||
policies2 = append(policies2[:i], policies2[i+1:]...)
|
||||
}
|
||||
}
|
||||
return policies2
|
||||
}
|
||||
|
||||
// Sort a slice of net.IP addresses
|
||||
func sortIPs(ips []net.IP) {
|
||||
sort.Slice(ips, func(i, j int) bool {
|
||||
ip1, ip2 := ips[i].To16(), ips[j].To16()
|
||||
return string(ip1) < string(ip2) // Compare as byte slices
|
||||
})
|
||||
}
|
||||
|
||||
func GetStaticNodeIps(node models.Node) (ips []net.IP) {
|
||||
defer func() {
|
||||
sortIPs(ips)
|
||||
}()
|
||||
defaultUserPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
|
||||
defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
||||
|
||||
extclients := GetStaticNodesByNetwork(models.NetworkID(node.Network), false)
|
||||
for _, extclient := range extclients {
|
||||
if extclient.IsUserNode && defaultUserPolicy.Enabled {
|
||||
continue
|
||||
}
|
||||
if !extclient.IsUserNode && defaultDevicePolicy.Enabled {
|
||||
continue
|
||||
}
|
||||
if extclient.StaticNode.Address != "" {
|
||||
ips = append(ips, extclient.StaticNode.AddressIPNet4().IP)
|
||||
}
|
||||
if extclient.StaticNode.Address6 != "" {
|
||||
ips = append(ips, extclient.StaticNode.AddressIPNet6().IP)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var MigrateToGws = func() {
|
||||
|
||||
nodes, err := GetAllNodes()
|
||||
|
@ -582,7 +846,7 @@ var GetInetClientsFromAclPolicies = func(eID string) (inetClientIDs []string) {
|
|||
return
|
||||
|
||||
}
|
||||
var IsNodeUsingInternetGw = func(node *models.Node) {
|
||||
var IsNodeUsingInternetGw = func(node *models.Node, acls []models.Acl) {
|
||||
host, err := GetHost(node.HostID.String())
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -590,7 +854,6 @@ var IsNodeUsingInternetGw = func(node *models.Node) {
|
|||
if host.IsDefault || node.IsFailOver {
|
||||
return
|
||||
}
|
||||
acls, _ := ListAclsByNetwork(models.NetworkID(node.Network))
|
||||
var isUsing bool
|
||||
for _, acl := range acls {
|
||||
if !acl.Enabled {
|
||||
|
|
|
@ -36,6 +36,7 @@ func ValidateEgressReq(e *schema.Egress) error {
|
|||
if len(e.Nodes) > 1 {
|
||||
return errors.New("can only set one internet routing node")
|
||||
}
|
||||
acls, _ := ListAclsByNetwork(models.NetworkID(e.Network))
|
||||
req := models.InetNodeReq{}
|
||||
eli, _ := (&schema.Egress{Network: e.Network}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
for k := range e.Nodes {
|
||||
|
@ -45,7 +46,7 @@ func ValidateEgressReq(e *schema.Egress) error {
|
|||
}
|
||||
// check if node is acting as egress gw already
|
||||
|
||||
GetNodeEgressInfo(&inetNode, eli)
|
||||
GetNodeEgressInfo(&inetNode, eli, acls)
|
||||
if err := ValidateInetGwReq(inetNode, req, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -130,7 +131,7 @@ func AddEgressInfoToPeerByAccess(node, targetNode *models.Node, eli []schema.Egr
|
|||
if targetNode.Mutex != nil {
|
||||
targetNode.Mutex.Lock()
|
||||
}
|
||||
IsNodeUsingInternetGw(targetNode)
|
||||
IsNodeUsingInternetGw(targetNode, acls)
|
||||
if targetNode.Mutex != nil {
|
||||
targetNode.Mutex.Unlock()
|
||||
}
|
||||
|
@ -140,7 +141,7 @@ func AddEgressInfoToPeerByAccess(node, targetNode *models.Node, eli []schema.Egr
|
|||
if !e.Status || e.Network != targetNode.Network {
|
||||
continue
|
||||
}
|
||||
if !isDefaultPolicyActive && !e.IsInetGw {
|
||||
if !isDefaultPolicyActive || e.IsInetGw {
|
||||
if !DoesNodeHaveAccessToEgress(node, &e, acls) {
|
||||
if node.IsRelayed && node.RelayedBy == targetNode.ID.String() {
|
||||
if !DoesNodeHaveAccessToEgress(targetNode, &e, acls) {
|
||||
|
@ -205,7 +206,7 @@ func AddEgressInfoToPeerByAccess(node, targetNode *models.Node, eli []schema.Egr
|
|||
}
|
||||
|
||||
// TODO
|
||||
func GetNetworkEgressInfo(network models.NetworkID) (egressNodes map[string]models.Node) {
|
||||
func GetNetworkEgressInfo(network models.NetworkID, acls []models.Acl) (egressNodes map[string]models.Node) {
|
||||
eli, _ := (&schema.Egress{Network: network.String()}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
egressNodes = make(map[string]models.Node)
|
||||
var err error
|
||||
|
@ -227,7 +228,7 @@ func GetNetworkEgressInfo(network models.NetworkID) (egressNodes map[string]mode
|
|||
NodeID: targetNode.ID.String(),
|
||||
NetID: targetNode.Network,
|
||||
}
|
||||
IsNodeUsingInternetGw(&targetNode)
|
||||
IsNodeUsingInternetGw(&targetNode, acls)
|
||||
if e.IsInetGw {
|
||||
targetNode.EgressDetails.IsInternetGateway = true
|
||||
targetNode.EgressDetails.InetNodeReq = models.InetNodeReq{
|
||||
|
@ -280,7 +281,7 @@ func GetNetworkEgressInfo(network models.NetworkID) (egressNodes map[string]mode
|
|||
return
|
||||
}
|
||||
|
||||
func GetNodeEgressInfo(targetNode *models.Node, eli []schema.Egress) {
|
||||
func GetNodeEgressInfo(targetNode *models.Node, eli []schema.Egress, acls []models.Acl) {
|
||||
|
||||
req := models.EgressGatewayRequest{
|
||||
NodeID: targetNode.ID.String(),
|
||||
|
@ -290,7 +291,7 @@ func GetNodeEgressInfo(targetNode *models.Node, eli []schema.Egress) {
|
|||
if targetNode.Mutex != nil {
|
||||
targetNode.Mutex.Lock()
|
||||
}
|
||||
IsNodeUsingInternetGw(targetNode)
|
||||
IsNodeUsingInternetGw(targetNode, acls)
|
||||
if targetNode.Mutex != nil {
|
||||
targetNode.Mutex.Unlock()
|
||||
}
|
||||
|
|
|
@ -75,12 +75,13 @@ func GetEgressRangesOnNetwork(client *models.ExtClient) ([]string, error) {
|
|||
return []string{}, err
|
||||
}
|
||||
eli, _ := (&schema.Egress{Network: client.Network}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
acls, _ := ListAclsByNetwork(models.NetworkID(client.Network))
|
||||
// clientNode := client.ConvertToStaticNode()
|
||||
for _, currentNode := range networkNodes {
|
||||
if currentNode.Network != client.Network {
|
||||
continue
|
||||
}
|
||||
GetNodeEgressInfo(¤tNode, eli)
|
||||
GetNodeEgressInfo(¤tNode, eli, acls)
|
||||
if currentNode.EgressDetails.IsEgressGateway { // add the egress gateway range(s) to the result
|
||||
if len(currentNode.EgressDetails.EgressGatewayRanges) > 0 {
|
||||
if currentNode.EgressDetails.IsInternetGateway && client.IngressGatewayID != currentNode.ID.String() {
|
||||
|
|
|
@ -178,15 +178,15 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
|||
if !node.Connected || node.PendingDelete || node.Action == models.NODE_DELETE || time.Since(node.LastCheckIn) > time.Hour {
|
||||
continue
|
||||
}
|
||||
acls, _ := ListAclsByNetwork(models.NetworkID(node.Network))
|
||||
eli, _ := (&schema.Egress{Network: node.Network}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
GetNodeEgressInfo(&node, eli)
|
||||
GetNodeEgressInfo(&node, eli, acls)
|
||||
hostPeerUpdate = SetDefaultGw(node, hostPeerUpdate)
|
||||
if !hostPeerUpdate.IsInternetGw {
|
||||
hostPeerUpdate.IsInternetGw = IsInternetGw(node)
|
||||
}
|
||||
defaultUserPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
|
||||
defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
||||
acls, _ := ListAclsByNetwork(models.NetworkID(node.Network))
|
||||
if (defaultDevicePolicy.Enabled && defaultUserPolicy.Enabled) ||
|
||||
(!CheckIfAnyPolicyisUniDirectional(node, acls) && !CheckIfAnyActiveEgressPolicy(node, acls)) ||
|
||||
CheckIfNodeHasAccessToAllResources(&node, acls) {
|
||||
|
@ -239,7 +239,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
|||
PersistentKeepaliveInterval: &peerHost.PersistentKeepalive,
|
||||
ReplaceAllowedIPs: true,
|
||||
}
|
||||
GetNodeEgressInfo(&peer, eli)
|
||||
GetNodeEgressInfo(&peer, eli, acls)
|
||||
if peer.EgressDetails.IsEgressGateway {
|
||||
AddEgressInfoToPeerByAccess(&node, &peer, eli, acls, defaultDevicePolicy.Enabled)
|
||||
}
|
||||
|
@ -589,9 +589,9 @@ func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet
|
|||
}
|
||||
if node.IsRelayed && node.RelayedBy == peer.ID.String() {
|
||||
allowedips = append(allowedips, GetAllowedIpsForRelayed(node, peer)...)
|
||||
if peer.EgressDetails.InternetGwID != "" {
|
||||
return allowedips
|
||||
}
|
||||
// if peer.EgressDetails.InternetGwID != "" {
|
||||
// return allowedips
|
||||
// }
|
||||
}
|
||||
|
||||
// handle ingress gateway peers
|
||||
|
|
|
@ -113,12 +113,13 @@ func ValidateRelay(relay models.RelayRequest, update bool) error {
|
|||
return errors.New("node is already acting as a relay")
|
||||
}
|
||||
eli, _ := (&schema.Egress{Network: node.Network}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
acls, _ := ListAclsByNetwork(models.NetworkID(node.Network))
|
||||
for _, relayedNodeID := range relay.RelayedNodes {
|
||||
relayedNode, err := GetNodeByID(relayedNodeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
GetNodeEgressInfo(&relayedNode, eli)
|
||||
GetNodeEgressInfo(&relayedNode, eli, acls)
|
||||
if relayedNode.IsIngressGateway {
|
||||
return errors.New("cannot relay an ingress gateway (" + relayedNodeID + ")")
|
||||
}
|
||||
|
@ -191,6 +192,7 @@ func DeleteRelay(network, nodeid string) ([]models.Node, models.Node, error) {
|
|||
func RelayedAllowedIPs(peer, node *models.Node) []net.IPNet {
|
||||
var allowedIPs = []net.IPNet{}
|
||||
eli, _ := (&schema.Egress{Network: node.Network}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
acls, _ := ListAclsByNetwork(models.NetworkID(node.Network))
|
||||
for _, relayedNodeID := range peer.RelayedNodes {
|
||||
if node.ID.String() == relayedNodeID {
|
||||
continue
|
||||
|
@ -199,7 +201,7 @@ func RelayedAllowedIPs(peer, node *models.Node) []net.IPNet {
|
|||
if err != nil {
|
||||
continue
|
||||
}
|
||||
GetNodeEgressInfo(&relayedNode, eli)
|
||||
GetNodeEgressInfo(&relayedNode, eli, acls)
|
||||
allowed := getRelayedAddresses(relayedNodeID)
|
||||
if relayedNode.EgressDetails.IsEgressGateway {
|
||||
allowed = append(allowed, GetEgressIPs(&relayedNode)...)
|
||||
|
@ -215,9 +217,9 @@ func GetAllowedIpsForRelayed(relayed, relay *models.Node) (allowedIPs []net.IPNe
|
|||
logger.Log(0, "RelayedByRelay called with invalid parameters")
|
||||
return
|
||||
}
|
||||
if relay.EgressDetails.InternetGwID != "" {
|
||||
return GetAllowedIpForInetNodeClient(relayed, relay)
|
||||
}
|
||||
// if relay.EgressDetails.InternetGwID != "" {
|
||||
// return GetAllowedIpForInetNodeClient(relayed, relay)
|
||||
// }
|
||||
peers, err := GetNetworkNodes(relay.Network)
|
||||
if err != nil {
|
||||
logger.Log(0, "error getting network clients", err.Error())
|
||||
|
|
|
@ -209,9 +209,10 @@ func failOverME(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
eli, _ := (&schema.Egress{Network: node.Network}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
logic.GetNodeEgressInfo(&node, eli)
|
||||
logic.GetNodeEgressInfo(&peerNode, eli)
|
||||
logic.GetNodeEgressInfo(&failOverNode, eli)
|
||||
acls, _ := logic.ListAclsByNetwork(models.NetworkID(node.Network))
|
||||
logic.GetNodeEgressInfo(&node, eli, acls)
|
||||
logic.GetNodeEgressInfo(&peerNode, eli, acls)
|
||||
logic.GetNodeEgressInfo(&failOverNode, eli, acls)
|
||||
if peerNode.IsFailOver {
|
||||
logic.ReturnErrorResponse(
|
||||
w,
|
||||
|
@ -369,9 +370,10 @@ func checkfailOverCtx(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
eli, _ := (&schema.Egress{Network: node.Network}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
logic.GetNodeEgressInfo(&node, eli)
|
||||
logic.GetNodeEgressInfo(&peerNode, eli)
|
||||
logic.GetNodeEgressInfo(&failOverNode, eli)
|
||||
acls, _ := logic.ListAclsByNetwork(models.NetworkID(node.Network))
|
||||
logic.GetNodeEgressInfo(&node, eli, acls)
|
||||
logic.GetNodeEgressInfo(&peerNode, eli, acls)
|
||||
logic.GetNodeEgressInfo(&failOverNode, eli, acls)
|
||||
if peerNode.IsFailOver {
|
||||
logic.ReturnErrorResponse(
|
||||
w,
|
||||
|
|
|
@ -155,8 +155,8 @@ func InitPro() {
|
|||
logic.CheckIfAnyPolicyisUniDirectional = proLogic.CheckIfAnyPolicyisUniDirectional
|
||||
logic.MigrateToGws = proLogic.MigrateToGws
|
||||
logic.IsNodeAllowedToCommunicate = proLogic.IsNodeAllowedToCommunicate
|
||||
logic.GetStaticNodeIps = proLogic.GetStaticNodeIps
|
||||
logic.GetFwRulesOnIngressGateway = proLogic.GetFwRulesOnIngressGateway
|
||||
logic.GetFwRulesForNodeAndPeerOnGw = proLogic.GetFwRulesForNodeAndPeerOnGw
|
||||
logic.GetFwRulesForUserNodesOnGw = proLogic.GetFwRulesForUserNodesOnGw
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"errors"
|
||||
"maps"
|
||||
"net"
|
||||
"sort"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitl/netmaker/db"
|
||||
|
@ -25,7 +24,7 @@ ranges should be replaced by egress identifier
|
|||
|
||||
*/
|
||||
|
||||
func getFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []models.FwRule) {
|
||||
func GetFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []models.FwRule) {
|
||||
defaultUserPolicy, _ := logic.GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
|
||||
userNodes := logic.GetStaticUserNodesByNetwork(models.NetworkID(node.Network))
|
||||
for _, userNodeI := range userNodes {
|
||||
|
@ -108,58 +107,7 @@ func getFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []
|
|||
return
|
||||
}
|
||||
|
||||
func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
|
||||
// fetch user access to static clients via policies
|
||||
defer func() {
|
||||
sort.Slice(rules, func(i, j int) bool {
|
||||
if !rules[i].SrcIP.IP.Equal(rules[j].SrcIP.IP) {
|
||||
return string(rules[i].SrcIP.IP.To16()) < string(rules[j].SrcIP.IP.To16())
|
||||
}
|
||||
return string(rules[i].DstIP.IP.To16()) < string(rules[j].DstIP.IP.To16())
|
||||
})
|
||||
}()
|
||||
defaultDevicePolicy, _ := logic.GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
||||
nodes, _ := logic.GetNetworkNodes(node.Network)
|
||||
nodes = append(nodes, logic.GetStaticNodesByNetwork(models.NetworkID(node.Network), true)...)
|
||||
rules = getFwRulesForUserNodesOnGw(node, nodes)
|
||||
if defaultDevicePolicy.Enabled {
|
||||
return
|
||||
}
|
||||
for _, nodeI := range nodes {
|
||||
if !nodeI.IsStatic || nodeI.IsUserNode {
|
||||
continue
|
||||
}
|
||||
// if nodeI.StaticNode.IngressGatewayID != node.ID.String() {
|
||||
// continue
|
||||
// }
|
||||
for _, peer := range nodes {
|
||||
if peer.StaticNode.ClientID == nodeI.StaticNode.ClientID || peer.IsUserNode {
|
||||
continue
|
||||
}
|
||||
if nodeI.StaticNode.IngressGatewayID != node.ID.String() &&
|
||||
((!peer.IsStatic && peer.ID.String() != node.ID.String()) ||
|
||||
(peer.IsStatic && peer.StaticNode.IngressGatewayID != node.ID.String())) {
|
||||
continue
|
||||
}
|
||||
if peer.IsStatic {
|
||||
peer = peer.StaticNode.ConvertToStaticNode()
|
||||
}
|
||||
var allowedPolicies1 []models.Acl
|
||||
var ok bool
|
||||
if ok, allowedPolicies1 = IsNodeAllowedToCommunicate(nodeI.StaticNode.ConvertToStaticNode(), peer, true); ok {
|
||||
rules = append(rules, getFwRulesForNodeAndPeerOnGw(nodeI.StaticNode.ConvertToStaticNode(), peer, allowedPolicies1)...)
|
||||
}
|
||||
if ok, allowedPolicies2 := IsNodeAllowedToCommunicate(peer, nodeI.StaticNode.ConvertToStaticNode(), true); ok {
|
||||
rules = append(rules,
|
||||
getFwRulesForNodeAndPeerOnGw(peer, nodeI.StaticNode.ConvertToStaticNode(),
|
||||
getUniquePolicies(allowedPolicies1, allowedPolicies2))...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getFwRulesForNodeAndPeerOnGw(node, peer models.Node, allowedPolicies []models.Acl) (rules []models.FwRule) {
|
||||
func GetFwRulesForNodeAndPeerOnGw(node, peer models.Node, allowedPolicies []models.Acl) (rules []models.FwRule) {
|
||||
|
||||
for _, policy := range allowedPolicies {
|
||||
// if static peer dst rule not for ingress node -> skip
|
||||
|
@ -335,52 +283,6 @@ func getFwRulesForNodeAndPeerOnGw(node, peer models.Node, allowedPolicies []mode
|
|||
return
|
||||
}
|
||||
|
||||
func getUniquePolicies(policies1, policies2 []models.Acl) []models.Acl {
|
||||
policies1Map := make(map[string]struct{})
|
||||
for _, policy1I := range policies1 {
|
||||
policies1Map[policy1I.ID] = struct{}{}
|
||||
}
|
||||
for i := len(policies2) - 1; i >= 0; i-- {
|
||||
if _, ok := policies1Map[policies2[i].ID]; ok {
|
||||
policies2 = append(policies2[:i], policies2[i+1:]...)
|
||||
}
|
||||
}
|
||||
return policies2
|
||||
}
|
||||
|
||||
func GetStaticNodeIps(node models.Node) (ips []net.IP) {
|
||||
defer func() {
|
||||
sortIPs(ips)
|
||||
}()
|
||||
defaultUserPolicy, _ := logic.GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
|
||||
defaultDevicePolicy, _ := logic.GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
||||
|
||||
extclients := logic.GetStaticNodesByNetwork(models.NetworkID(node.Network), false)
|
||||
for _, extclient := range extclients {
|
||||
if extclient.IsUserNode && defaultUserPolicy.Enabled {
|
||||
continue
|
||||
}
|
||||
if !extclient.IsUserNode && defaultDevicePolicy.Enabled {
|
||||
continue
|
||||
}
|
||||
if extclient.StaticNode.Address != "" {
|
||||
ips = append(ips, extclient.StaticNode.AddressIPNet4().IP)
|
||||
}
|
||||
if extclient.StaticNode.Address6 != "" {
|
||||
ips = append(ips, extclient.StaticNode.AddressIPNet6().IP)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Sort a slice of net.IP addresses
|
||||
func sortIPs(ips []net.IP) {
|
||||
sort.Slice(ips, func(i, j int) bool {
|
||||
ip1, ip2 := ips[i].To16(), ips[j].To16()
|
||||
return string(ip1) < string(ip2) // Compare as byte slices
|
||||
})
|
||||
}
|
||||
|
||||
func checkIfAclTagisValid(a models.Acl, t models.AclPolicyTag, isSrc bool) (err error) {
|
||||
switch t.ID {
|
||||
case models.NodeTagID:
|
||||
|
@ -1628,7 +1530,7 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
|
|||
continue
|
||||
}
|
||||
if _, ok := egI.Nodes[targetnode.ID.String()]; ok {
|
||||
if egI.Range == "*" {
|
||||
if egI.IsInetGw {
|
||||
targetNodeTags[models.TagID("0.0.0.0/0")] = struct{}{}
|
||||
targetNodeTags[models.TagID("::/0")] = struct{}{}
|
||||
} else {
|
||||
|
@ -1867,7 +1769,7 @@ func GetInetClientsFromAclPolicies(eID string) (inetClientIDs []string) {
|
|||
return
|
||||
}
|
||||
|
||||
func IsNodeUsingInternetGw(node *models.Node) {
|
||||
func IsNodeUsingInternetGw(node *models.Node, acls []models.Acl) {
|
||||
host, err := logic.GetHost(node.HostID.String())
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -1880,7 +1782,6 @@ func IsNodeUsingInternetGw(node *models.Node) {
|
|||
nodeTags = make(map[models.TagID]struct{})
|
||||
}
|
||||
nodeTags[models.TagID(node.ID.String())] = struct{}{}
|
||||
acls, _ := logic.ListAclsByNetwork(models.NetworkID(node.Network))
|
||||
var isUsing bool
|
||||
for _, acl := range acls {
|
||||
if !acl.Enabled {
|
||||
|
|
|
@ -166,10 +166,11 @@ func ResetFailOver(failOverNode *models.Node) error {
|
|||
func GetFailOverPeerIps(peer, node *models.Node) []net.IPNet {
|
||||
allowedips := []net.IPNet{}
|
||||
eli, _ := (&schema.Egress{Network: node.Network}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
acls, _ := logic.ListAclsByNetwork(models.NetworkID(node.Network))
|
||||
for failOverpeerID := range node.FailOverPeers {
|
||||
failOverpeer, err := logic.GetNodeByID(failOverpeerID)
|
||||
if err == nil && failOverpeer.FailedOverBy == peer.ID {
|
||||
logic.GetNodeEgressInfo(&failOverpeer, eli)
|
||||
logic.GetNodeEgressInfo(&failOverpeer, eli, acls)
|
||||
if failOverpeer.Address.IP != nil {
|
||||
allowed := net.IPNet{
|
||||
IP: failOverpeer.Address.IP,
|
||||
|
|
Loading…
Add table
Reference in a new issue