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:
Abhishek K 2025-06-05 13:28:23 +05:30 committed by GitHub
parent 44300590f8
commit 0ff216dabd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 317 additions and 138 deletions

View file

@ -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)

View file

@ -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)
}
}

View file

@ -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"

View file

@ -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 {

View file

@ -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()
}

View file

@ -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(&currentNode, eli)
GetNodeEgressInfo(&currentNode, 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() {

View file

@ -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

View file

@ -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())

View file

@ -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,

View file

@ -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
}

View file

@ -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 {

View file

@ -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,