|
@@ -6,6 +6,7 @@ import (
|
|
"fmt"
|
|
"fmt"
|
|
"net"
|
|
"net"
|
|
"reflect"
|
|
"reflect"
|
|
|
|
+ "sort"
|
|
"strings"
|
|
"strings"
|
|
"sync"
|
|
"sync"
|
|
"time"
|
|
"time"
|
|
@@ -115,6 +116,7 @@ func DeleteExtClient(network string, clientid string) error {
|
|
}
|
|
}
|
|
deleteExtClientFromCache(key)
|
|
deleteExtClientFromCache(key)
|
|
}
|
|
}
|
|
|
|
+ go RemoveNodeFromAclPolicy(extClient.ConvertToStaticNode())
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
@@ -416,6 +418,27 @@ func GetAllExtClients() ([]models.ExtClient, error) {
|
|
return clients, nil
|
|
return clients, nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// GetAllExtClientsWithStatus - returns all external clients with
|
|
|
|
+// given status.
|
|
|
|
+func GetAllExtClientsWithStatus(status models.NodeStatus) ([]models.ExtClient, error) {
|
|
|
|
+ extClients, err := GetAllExtClients()
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var validExtClients []models.ExtClient
|
|
|
|
+ for _, extClient := range extClients {
|
|
|
|
+ node := extClient.ConvertToStaticNode()
|
|
|
|
+ GetNodeCheckInStatus(&node, false)
|
|
|
|
+
|
|
|
|
+ if node.Status == status {
|
|
|
|
+ validExtClients = append(validExtClients, extClient)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return validExtClients, nil
|
|
|
|
+}
|
|
|
|
+
|
|
// ToggleExtClientConnectivity - enables or disables an ext client
|
|
// ToggleExtClientConnectivity - enables or disables an ext client
|
|
func ToggleExtClientConnectivity(client *models.ExtClient, enable bool) (models.ExtClient, error) {
|
|
func ToggleExtClientConnectivity(client *models.ExtClient, enable bool) (models.ExtClient, error) {
|
|
update := models.CustomExtClient{
|
|
update := models.CustomExtClient{
|
|
@@ -442,7 +465,18 @@ func ToggleExtClientConnectivity(client *models.ExtClient, enable bool) (models.
|
|
return newClient, nil
|
|
return newClient, nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 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) {
|
|
func GetStaticNodeIps(node models.Node) (ips []net.IP) {
|
|
|
|
+ defer func() {
|
|
|
|
+ sortIPs(ips)
|
|
|
|
+ }()
|
|
defaultUserPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
|
|
defaultUserPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
|
|
defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
|
defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
|
|
|
|
|
@@ -464,210 +498,192 @@ func GetStaticNodeIps(node models.Node) (ips []net.IP) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
-func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
|
|
|
|
- // fetch user access to static clients via policies
|
|
|
|
|
|
+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),
|
|
|
|
+ },
|
|
|
|
+ AllowedProtocol: policy.Proto,
|
|
|
|
+ AllowedPorts: policy.Port,
|
|
|
|
+ Allow: true,
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
|
|
- defaultUserPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
|
|
|
|
- defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
|
|
|
- nodes, _ := GetNetworkNodes(node.Network)
|
|
|
|
- nodes = append(nodes, GetStaticNodesByNetwork(models.NetworkID(node.Network), true)...)
|
|
|
|
- userNodes := GetStaticUserNodesByNetwork(models.NetworkID(node.Network))
|
|
|
|
- for _, userNodeI := range userNodes {
|
|
|
|
- for _, peer := range nodes {
|
|
|
|
- if peer.IsUserNode {
|
|
|
|
- continue
|
|
|
|
|
|
+ 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),
|
|
|
|
+ },
|
|
|
|
+ AllowedProtocol: policy.Proto,
|
|
|
|
+ AllowedPorts: policy.Port,
|
|
|
|
+ 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),
|
|
|
|
+ },
|
|
|
|
+ AllowedProtocol: policy.Proto,
|
|
|
|
+ AllowedPorts: policy.Port,
|
|
|
|
+ Allow: true,
|
|
|
|
+ })
|
|
}
|
|
}
|
|
- if ok, allowedPolicies := IsUserAllowedToCommunicate(userNodeI.StaticNode.OwnerID, peer); ok {
|
|
|
|
- if peer.IsStatic {
|
|
|
|
- if userNodeI.StaticNode.Address != "" {
|
|
|
|
- if !defaultUserPolicy.Enabled {
|
|
|
|
- for _, policy := range allowedPolicies {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: userNodeI.StaticNode.AddressIPNet4(),
|
|
|
|
- DstIP: peer.StaticNode.AddressIPNet4(),
|
|
|
|
- AllowedProtocol: policy.Proto,
|
|
|
|
- AllowedPorts: policy.Port,
|
|
|
|
- Allow: true,
|
|
|
|
- })
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: peer.StaticNode.AddressIPNet4(),
|
|
|
|
- DstIP: userNodeI.StaticNode.AddressIPNet4(),
|
|
|
|
- AllowedProtocol: policy.Proto,
|
|
|
|
- AllowedPorts: policy.Port,
|
|
|
|
- Allow: true,
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- if userNodeI.StaticNode.Address6 != "" {
|
|
|
|
- if !defaultUserPolicy.Enabled {
|
|
|
|
- for _, policy := range allowedPolicies {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: userNodeI.StaticNode.AddressIPNet6(),
|
|
|
|
- DstIP: peer.StaticNode.AddressIPNet6(),
|
|
|
|
- Allow: true,
|
|
|
|
- AllowedProtocol: policy.Proto,
|
|
|
|
- AllowedPorts: policy.Port,
|
|
|
|
- })
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: peer.StaticNode.AddressIPNet6(),
|
|
|
|
- DstIP: userNodeI.StaticNode.AddressIPNet6(),
|
|
|
|
- AllowedProtocol: policy.Proto,
|
|
|
|
- AllowedPorts: policy.Port,
|
|
|
|
- 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 {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: userNodeI.StaticNode.AddressIPNet4(),
|
|
|
|
- DstIP: *ipNet,
|
|
|
|
- Allow: true,
|
|
|
|
- })
|
|
|
|
- } else {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: userNodeI.StaticNode.AddressIPNet6(),
|
|
|
|
- DstIP: *ipNet,
|
|
|
|
- Allow: true,
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- if userNodeI.StaticNode.Address != "" {
|
|
|
|
- if !defaultUserPolicy.Enabled {
|
|
|
|
- for _, policy := range allowedPolicies {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: userNodeI.StaticNode.AddressIPNet4(),
|
|
|
|
- DstIP: net.IPNet{
|
|
|
|
- IP: peer.Address.IP,
|
|
|
|
- Mask: net.CIDRMask(32, 32),
|
|
|
|
- },
|
|
|
|
- AllowedProtocol: policy.Proto,
|
|
|
|
- AllowedPorts: policy.Port,
|
|
|
|
- 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),
|
|
|
|
+ },
|
|
|
|
+ AllowedProtocol: policy.Proto,
|
|
|
|
+ AllowedPorts: policy.Port,
|
|
|
|
+ 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 userNodeI.StaticNode.Address6 != "" {
|
|
|
|
- if !defaultUserPolicy.Enabled {
|
|
|
|
- for _, policy := range allowedPolicies {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: userNodeI.StaticNode.AddressIPNet6(),
|
|
|
|
- DstIP: net.IPNet{
|
|
|
|
- IP: peer.Address6.IP,
|
|
|
|
- Mask: net.CIDRMask(128, 128),
|
|
|
|
- },
|
|
|
|
- AllowedProtocol: policy.Proto,
|
|
|
|
- AllowedPorts: policy.Port,
|
|
|
|
- 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,
|
|
|
|
+ })
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
|
|
- if defaultDevicePolicy.Enabled {
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
- for _, nodeI := range nodes {
|
|
|
|
- if !nodeI.IsStatic || nodeI.IsUserNode {
|
|
|
|
- continue
|
|
|
|
}
|
|
}
|
|
- for _, peer := range nodes {
|
|
|
|
- if peer.StaticNode.ClientID == nodeI.StaticNode.ClientID || peer.IsUserNode {
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
- if ok, allowedPolicies := IsNodeAllowedToCommunicate(nodeI, peer, true); ok {
|
|
|
|
- if peer.IsStatic {
|
|
|
|
- if nodeI.StaticNode.Address != "" {
|
|
|
|
- for _, policy := range allowedPolicies {
|
|
|
|
|
|
+
|
|
|
|
+ // add egress range rules
|
|
|
|
+ for _, dstI := range policy.Dst {
|
|
|
|
+ if dstI.ID == models.EgressRange {
|
|
|
|
+ ip, cidr, err := net.ParseCIDR(dstI.Value)
|
|
|
|
+ if err == nil {
|
|
|
|
+ if ip.To4() != nil {
|
|
|
|
+ if node.Address.IP != nil {
|
|
rules = append(rules, models.FwRule{
|
|
rules = append(rules, models.FwRule{
|
|
- SrcIP: nodeI.StaticNode.AddressIPNet4(),
|
|
|
|
- DstIP: peer.StaticNode.AddressIPNet4(),
|
|
|
|
|
|
+ SrcIP: net.IPNet{
|
|
|
|
+ IP: node.Address.IP,
|
|
|
|
+ Mask: net.CIDRMask(32, 32),
|
|
|
|
+ },
|
|
|
|
+ DstIP: *cidr,
|
|
AllowedProtocol: policy.Proto,
|
|
AllowedProtocol: policy.Proto,
|
|
AllowedPorts: policy.Port,
|
|
AllowedPorts: policy.Port,
|
|
Allow: true,
|
|
Allow: true,
|
|
})
|
|
})
|
|
- if policy.AllowedDirection == models.TrafficDirectionBi {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: peer.StaticNode.AddressIPNet4(),
|
|
|
|
- DstIP: nodeI.StaticNode.AddressIPNet4(),
|
|
|
|
- AllowedProtocol: policy.Proto,
|
|
|
|
- AllowedPorts: policy.Port,
|
|
|
|
- Allow: true,
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
-
|
|
|
|
- }
|
|
|
|
- if nodeI.StaticNode.Address6 != "" {
|
|
|
|
- for _, policy := range allowedPolicies {
|
|
|
|
|
|
+ } else {
|
|
|
|
+ if node.Address6.IP != nil {
|
|
rules = append(rules, models.FwRule{
|
|
rules = append(rules, models.FwRule{
|
|
- SrcIP: nodeI.StaticNode.AddressIPNet6(),
|
|
|
|
- DstIP: peer.StaticNode.AddressIPNet6(),
|
|
|
|
|
|
+ SrcIP: net.IPNet{
|
|
|
|
+ IP: node.Address6.IP,
|
|
|
|
+ Mask: net.CIDRMask(128, 128),
|
|
|
|
+ },
|
|
|
|
+ DstIP: *cidr,
|
|
AllowedProtocol: policy.Proto,
|
|
AllowedProtocol: policy.Proto,
|
|
AllowedPorts: policy.Port,
|
|
AllowedPorts: policy.Port,
|
|
Allow: true,
|
|
Allow: true,
|
|
})
|
|
})
|
|
- if policy.AllowedDirection == models.TrafficDirectionBi {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: peer.StaticNode.AddressIPNet6(),
|
|
|
|
- DstIP: nodeI.StaticNode.AddressIPNet6(),
|
|
|
|
- AllowedProtocol: policy.Proto,
|
|
|
|
- AllowedPorts: policy.Port,
|
|
|
|
- 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 {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: nodeI.StaticNode.AddressIPNet4(),
|
|
|
|
- DstIP: *ipNet,
|
|
|
|
- Allow: true,
|
|
|
|
- })
|
|
|
|
- } else {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: nodeI.StaticNode.AddressIPNet6(),
|
|
|
|
- DstIP: *ipNet,
|
|
|
|
- Allow: true,
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- if nodeI.StaticNode.Address != "" {
|
|
|
|
- for _, policy := range allowedPolicies {
|
|
|
|
|
|
+ return
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func getFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []models.FwRule) {
|
|
|
|
+ defaultUserPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
|
|
|
|
+ userNodes := GetStaticUserNodesByNetwork(models.NetworkID(node.Network))
|
|
|
|
+ for _, userNodeI := range userNodes {
|
|
|
|
+ for _, peer := range nodes {
|
|
|
|
+ if peer.IsUserNode {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ok, allowedPolicies := IsUserAllowedToCommunicate(userNodeI.StaticNode.OwnerID, peer); ok {
|
|
|
|
+ if peer.IsStatic {
|
|
|
|
+ peer = peer.StaticNode.ConvertToStaticNode()
|
|
|
|
+ }
|
|
|
|
+ if !defaultUserPolicy.Enabled {
|
|
|
|
+ for _, policy := range allowedPolicies {
|
|
|
|
+ if userNodeI.StaticNode.Address != "" {
|
|
rules = append(rules, models.FwRule{
|
|
rules = append(rules, models.FwRule{
|
|
- SrcIP: nodeI.StaticNode.AddressIPNet4(),
|
|
|
|
|
|
+ SrcIP: userNodeI.StaticNode.AddressIPNet4(),
|
|
DstIP: net.IPNet{
|
|
DstIP: net.IPNet{
|
|
IP: peer.Address.IP,
|
|
IP: peer.Address.IP,
|
|
Mask: net.CIDRMask(32, 32),
|
|
Mask: net.CIDRMask(32, 32),
|
|
@@ -676,24 +692,10 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
|
|
AllowedPorts: policy.Port,
|
|
AllowedPorts: policy.Port,
|
|
Allow: true,
|
|
Allow: true,
|
|
})
|
|
})
|
|
- if policy.AllowedDirection == models.TrafficDirectionBi {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: net.IPNet{
|
|
|
|
- IP: peer.Address.IP,
|
|
|
|
- Mask: net.CIDRMask(32, 32),
|
|
|
|
- },
|
|
|
|
- DstIP: nodeI.StaticNode.AddressIPNet4(),
|
|
|
|
- AllowedProtocol: policy.Proto,
|
|
|
|
- AllowedPorts: policy.Port,
|
|
|
|
- Allow: true,
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
- }
|
|
|
|
- if nodeI.StaticNode.Address6 != "" {
|
|
|
|
- for _, policy := range allowedPolicies {
|
|
|
|
|
|
+ if userNodeI.StaticNode.Address6 != "" {
|
|
rules = append(rules, models.FwRule{
|
|
rules = append(rules, models.FwRule{
|
|
- SrcIP: nodeI.StaticNode.AddressIPNet6(),
|
|
|
|
|
|
+ SrcIP: userNodeI.StaticNode.AddressIPNet6(),
|
|
DstIP: net.IPNet{
|
|
DstIP: net.IPNet{
|
|
IP: peer.Address6.IP,
|
|
IP: peer.Address6.IP,
|
|
Mask: net.CIDRMask(128, 128),
|
|
Mask: net.CIDRMask(128, 128),
|
|
@@ -702,19 +704,34 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
|
|
AllowedPorts: policy.Port,
|
|
AllowedPorts: policy.Port,
|
|
Allow: true,
|
|
Allow: true,
|
|
})
|
|
})
|
|
- if policy.AllowedDirection == models.TrafficDirectionBi {
|
|
|
|
- rules = append(rules, models.FwRule{
|
|
|
|
- SrcIP: net.IPNet{
|
|
|
|
- IP: peer.Address6.IP,
|
|
|
|
- Mask: net.CIDRMask(128, 128),
|
|
|
|
- },
|
|
|
|
- DstIP: nodeI.StaticNode.AddressIPNet6(),
|
|
|
|
- AllowedProtocol: policy.Proto,
|
|
|
|
- AllowedPorts: policy.Port,
|
|
|
|
- Allow: true,
|
|
|
|
- })
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // add egress ranges
|
|
|
|
+ for _, dstI := range policy.Dst {
|
|
|
|
+ if dstI.ID == models.EgressRange {
|
|
|
|
+ ip, cidr, err := net.ParseCIDR(dstI.Value)
|
|
|
|
+ if err == nil {
|
|
|
|
+ if ip.To4() != nil && userNodeI.StaticNode.Address != "" {
|
|
|
|
+ rules = append(rules, models.FwRule{
|
|
|
|
+ SrcIP: userNodeI.StaticNode.AddressIPNet4(),
|
|
|
|
+ DstIP: *cidr,
|
|
|
|
+ AllowedProtocol: policy.Proto,
|
|
|
|
+ AllowedPorts: policy.Port,
|
|
|
|
+ Allow: true,
|
|
|
|
+ })
|
|
|
|
+ } else if ip.To16() != nil && userNodeI.StaticNode.Address6 != "" {
|
|
|
|
+ rules = append(rules, models.FwRule{
|
|
|
|
+ SrcIP: userNodeI.StaticNode.AddressIPNet6(),
|
|
|
|
+ DstIP: *cidr,
|
|
|
|
+ AllowedProtocol: policy.Proto,
|
|
|
|
+ AllowedPorts: policy.Port,
|
|
|
|
+ Allow: true,
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -724,6 +741,70 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
|
|
return
|
|
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 = IsNodeAllowedToCommunicateV1(nodeI.StaticNode.ConvertToStaticNode(), peer, true); ok {
|
|
|
|
+ rules = append(rules, getFwRulesForNodeAndPeerOnGw(nodeI.StaticNode.ConvertToStaticNode(), peer, allowedPolicies1)...)
|
|
|
|
+ }
|
|
|
|
+ if ok, allowedPolicies2 := IsNodeAllowedToCommunicateV1(peer, nodeI.StaticNode.ConvertToStaticNode(), true); ok {
|
|
|
|
+ rules = append(rules,
|
|
|
|
+ getFwRulesForNodeAndPeerOnGw(peer, nodeI.StaticNode.ConvertToStaticNode(),
|
|
|
|
+ GetUniquePolicies(allowedPolicies1, allowedPolicies2))...)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ 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 GetExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, []models.EgressNetworkRoutes, error) {
|
|
func GetExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, []models.EgressNetworkRoutes, error) {
|
|
var peers []wgtypes.PeerConfig
|
|
var peers []wgtypes.PeerConfig
|
|
var idsAndAddr []models.IDandAddr
|
|
var idsAndAddr []models.IDandAddr
|
|
@@ -812,13 +893,21 @@ func GetExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandA
|
|
}
|
|
}
|
|
|
|
|
|
func getExtPeerEgressRoute(node models.Node, extPeer models.ExtClient) (egressRoutes []models.EgressNetworkRoutes) {
|
|
func getExtPeerEgressRoute(node models.Node, extPeer models.ExtClient) (egressRoutes []models.EgressNetworkRoutes) {
|
|
- egressRoutes = append(egressRoutes, models.EgressNetworkRoutes{
|
|
|
|
|
|
+ r := models.EgressNetworkRoutes{
|
|
|
|
+ PeerKey: extPeer.PublicKey,
|
|
EgressGwAddr: extPeer.AddressIPNet4(),
|
|
EgressGwAddr: extPeer.AddressIPNet4(),
|
|
EgressGwAddr6: extPeer.AddressIPNet6(),
|
|
EgressGwAddr6: extPeer.AddressIPNet6(),
|
|
NodeAddr: node.Address,
|
|
NodeAddr: node.Address,
|
|
NodeAddr6: node.Address6,
|
|
NodeAddr6: node.Address6,
|
|
EgressRanges: extPeer.ExtraAllowedIPs,
|
|
EgressRanges: extPeer.ExtraAllowedIPs,
|
|
- })
|
|
|
|
|
|
+ }
|
|
|
|
+ for _, extraAllowedIP := range extPeer.ExtraAllowedIPs {
|
|
|
|
+ r.EgressRangesWithMetric = append(r.EgressRangesWithMetric, models.EgressRangeMetric{
|
|
|
|
+ Network: extraAllowedIP,
|
|
|
|
+ RouteMetric: 256,
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ egressRoutes = append(egressRoutes, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
@@ -831,7 +920,7 @@ func getExtpeerEgressRanges(node models.Node) (ranges, ranges6 []net.IPNet) {
|
|
if len(extPeer.ExtraAllowedIPs) == 0 {
|
|
if len(extPeer.ExtraAllowedIPs) == 0 {
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
- if ok, _ := IsNodeAllowedToCommunicate(extPeer.ConvertToStaticNode(), node, true); !ok {
|
|
|
|
|
|
+ if ok, _ := IsNodeAllowedToCommunicateV1(extPeer.ConvertToStaticNode(), node, true); !ok {
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
for _, allowedRange := range extPeer.ExtraAllowedIPs {
|
|
for _, allowedRange := range extPeer.ExtraAllowedIPs {
|
|
@@ -858,7 +947,7 @@ func getExtpeersExtraRoutes(node models.Node) (egressRoutes []models.EgressNetwo
|
|
if len(extPeer.ExtraAllowedIPs) == 0 {
|
|
if len(extPeer.ExtraAllowedIPs) == 0 {
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
- if ok, _ := IsNodeAllowedToCommunicate(extPeer.ConvertToStaticNode(), node, true); !ok {
|
|
|
|
|
|
+ if ok, _ := IsNodeAllowedToCommunicateV1(extPeer.ConvertToStaticNode(), node, true); !ok {
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
egressRoutes = append(egressRoutes, getExtPeerEgressRoute(node, extPeer)...)
|
|
egressRoutes = append(egressRoutes, getExtPeerEgressRoute(node, extPeer)...)
|
|
@@ -906,16 +995,11 @@ func GetStaticUserNodesByNetwork(network models.NetworkID) (staticNode []models.
|
|
for _, extI := range extClients {
|
|
for _, extI := range extClients {
|
|
if extI.Network == network.String() {
|
|
if extI.Network == network.String() {
|
|
if extI.RemoteAccessClientID != "" {
|
|
if extI.RemoteAccessClientID != "" {
|
|
- n := models.Node{
|
|
|
|
- IsStatic: true,
|
|
|
|
- StaticNode: extI,
|
|
|
|
- IsUserNode: extI.RemoteAccessClientID != "",
|
|
|
|
- }
|
|
|
|
|
|
+ n := extI.ConvertToStaticNode()
|
|
staticNode = append(staticNode, n)
|
|
staticNode = append(staticNode, n)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|