mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-26 21:01:32 +08:00
NM-116: Acl Fixes (#3652)
* handle all resources tag on gw * add egress domain ranges to node acls * simplify extclient egress alloweips, handle nil acl rule * fix static node status check for gw acls * skip ns ip if contains network cidr * skip ns ip if contains network cidr * skip ns ip if contains network cidr
This commit is contained in:
@@ -50,16 +50,31 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
|
|||||||
if defaultDevicePolicy.Enabled {
|
if defaultDevicePolicy.Enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
if len(rules) == 0 && IsNodeAllowedToCommunicateWithAllRsrcs(node) {
|
||||||
|
if node.NetworkRange.IP != nil {
|
||||||
|
rules = append(rules, models.FwRule{
|
||||||
|
SrcIP: node.NetworkRange,
|
||||||
|
Allow: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if node.NetworkRange6.IP != nil {
|
||||||
|
rules = append(rules, models.FwRule{
|
||||||
|
SrcIP: node.NetworkRange6,
|
||||||
|
Allow: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
for _, nodeI := range nodes {
|
for _, nodeI := range nodes {
|
||||||
if !nodeI.IsStatic || nodeI.IsUserNode {
|
if !nodeI.IsStatic || nodeI.IsUserNode {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !node.StaticNode.Enabled {
|
if !nodeI.StaticNode.Enabled {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// if nodeI.StaticNode.IngressGatewayID != node.ID.String() {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
if IsNodeAllowedToCommunicateWithAllRsrcs(nodeI) {
|
if IsNodeAllowedToCommunicateWithAllRsrcs(nodeI) {
|
||||||
if nodeI.Address.IP != nil {
|
if nodeI.Address.IP != nil {
|
||||||
rules = append(rules, models.FwRule{
|
rules = append(rules, models.FwRule{
|
||||||
@@ -525,7 +540,18 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := eI.Nodes[targetnode.ID.String()]; ok {
|
if _, ok := eI.Nodes[targetnode.ID.String()]; ok {
|
||||||
if eI.Range != "" {
|
if servercfg.IsPro && eI.Domain != "" && len(eI.DomainAns) > 0 {
|
||||||
|
for _, domainAnsI := range eI.DomainAns {
|
||||||
|
ip, cidr, err := net.ParseCIDR(domainAnsI)
|
||||||
|
if err == nil {
|
||||||
|
if ip.To4() != nil {
|
||||||
|
egressRanges4 = append(egressRanges4, *cidr)
|
||||||
|
} else {
|
||||||
|
egressRanges6 = append(egressRanges6, *cidr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if eI.Range != "" {
|
||||||
_, cidr, err := net.ParseCIDR(eI.Range)
|
_, cidr, err := net.ParseCIDR(eI.Range)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if cidr.IP.To4() != nil {
|
if cidr.IP.To4() != nil {
|
||||||
@@ -535,6 +561,7 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dstTags[targetnode.ID.String()] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@@ -544,7 +571,18 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
|
|||||||
err := e.Get(db.WithContext(context.TODO()))
|
err := e.Get(db.WithContext(context.TODO()))
|
||||||
if err == nil && e.Status && len(e.Nodes) > 0 {
|
if err == nil && e.Status && len(e.Nodes) > 0 {
|
||||||
if _, ok := e.Nodes[targetnode.ID.String()]; ok {
|
if _, ok := e.Nodes[targetnode.ID.String()]; ok {
|
||||||
if e.Range != "" {
|
if servercfg.IsPro && e.Domain != "" && len(e.DomainAns) > 0 {
|
||||||
|
for _, domainAnsI := range e.DomainAns {
|
||||||
|
ip, cidr, err := net.ParseCIDR(domainAnsI)
|
||||||
|
if err == nil {
|
||||||
|
if ip.To4() != nil {
|
||||||
|
egressRanges4 = append(egressRanges4, *cidr)
|
||||||
|
} else {
|
||||||
|
egressRanges6 = append(egressRanges6, *cidr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if e.Range != "" {
|
||||||
_, cidr, err := net.ParseCIDR(e.Range)
|
_, cidr, err := net.ParseCIDR(e.Range)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if cidr.IP.To4() != nil {
|
if cidr.IP.To4() != nil {
|
||||||
@@ -554,6 +592,7 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dstTags[targetnode.ID.String()] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -800,10 +839,10 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
|
|||||||
if node.ID == targetnode.ID {
|
if node.ID == targetnode.ID {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if node.Address.IP != nil {
|
if !node.IsStatic && node.Address.IP != nil {
|
||||||
aclRule.IPList = append(aclRule.IPList, node.AddressIPNet4())
|
aclRule.IPList = append(aclRule.IPList, node.AddressIPNet4())
|
||||||
}
|
}
|
||||||
if node.Address6.IP != nil {
|
if !node.IsStatic && node.Address6.IP != nil {
|
||||||
aclRule.IP6List = append(aclRule.IP6List, node.AddressIPNet6())
|
aclRule.IP6List = append(aclRule.IP6List, node.AddressIPNet6())
|
||||||
}
|
}
|
||||||
if node.IsStatic && node.StaticNode.Address != "" {
|
if node.IsStatic && node.StaticNode.Address != "" {
|
||||||
|
19
logic/dns.go
19
logic/dns.go
@@ -434,6 +434,25 @@ func validateNameserverReq(ns schema.Nameserver) error {
|
|||||||
if len(ns.Servers) == 0 {
|
if len(ns.Servers) == 0 {
|
||||||
return errors.New("atleast one nameserver should be specified")
|
return errors.New("atleast one nameserver should be specified")
|
||||||
}
|
}
|
||||||
|
network, err := GetNetwork(ns.NetworkID)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("invalid network id")
|
||||||
|
}
|
||||||
|
_, cidr, err4 := net.ParseCIDR(network.AddressRange)
|
||||||
|
_, cidr6, err6 := net.ParseCIDR(network.AddressRange6)
|
||||||
|
for _, nsIPStr := range ns.Servers {
|
||||||
|
nsIP := net.ParseIP(nsIPStr)
|
||||||
|
if nsIP == nil {
|
||||||
|
return errors.New("invalid nameserver " + nsIPStr)
|
||||||
|
}
|
||||||
|
if err4 == nil && nsIP.To4() != nil {
|
||||||
|
if cidr.Contains(nsIP) {
|
||||||
|
return errors.New("cannot use netmaker IP as nameserver")
|
||||||
|
}
|
||||||
|
} else if err6 == nil && cidr6.Contains(nsIP) {
|
||||||
|
return errors.New("cannot use netmaker IP as nameserver")
|
||||||
|
}
|
||||||
|
}
|
||||||
if !ns.MatchAll && len(ns.MatchDomains) == 0 {
|
if !ns.MatchAll && len(ns.MatchDomains) == 0 {
|
||||||
return errors.New("atleast one match domain is required")
|
return errors.New("atleast one match domain is required")
|
||||||
}
|
}
|
||||||
|
@@ -70,23 +70,12 @@ func storeExtClientInCache(key string, extclient models.ExtClient) {
|
|||||||
func GetEgressRangesOnNetwork(client *models.ExtClient) ([]string, error) {
|
func GetEgressRangesOnNetwork(client *models.ExtClient) ([]string, error) {
|
||||||
|
|
||||||
var result []string
|
var result []string
|
||||||
networkNodes, err := GetNetworkNodes(client.Network)
|
|
||||||
if err != nil {
|
|
||||||
return []string{}, err
|
|
||||||
}
|
|
||||||
eli, _ := (&schema.Egress{Network: client.Network}).ListByNetwork(db.WithContext(context.TODO()))
|
eli, _ := (&schema.Egress{Network: client.Network}).ListByNetwork(db.WithContext(context.TODO()))
|
||||||
acls, _ := ListAclsByNetwork(models.NetworkID(client.Network))
|
for _, eI := range eli {
|
||||||
// clientNode := client.ConvertToStaticNode()
|
if !eI.Status || eI.Range == "" {
|
||||||
for _, currentNode := range networkNodes {
|
|
||||||
if currentNode.Network != client.Network {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
GetNodeEgressInfo(¤tNode, eli, acls)
|
result = append(result, eI.Range)
|
||||||
if currentNode.EgressDetails.IsEgressGateway { // add the egress gateway range(s) to the result
|
|
||||||
if len(currentNode.EgressDetails.EgressGatewayRanges) > 0 {
|
|
||||||
result = append(result, currentNode.EgressDetails.EgressGatewayRanges...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
extclients, _ := GetNetworkExtClients(client.Network)
|
extclients, _ := GetNetworkExtClients(client.Network)
|
||||||
for _, extclient := range extclients {
|
for _, extclient := range extclients {
|
||||||
|
@@ -149,10 +149,11 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
|||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if !hostPeerUpdate.FwUpdate.AllowAll {
|
if !hostPeerUpdate.FwUpdate.AllowAll {
|
||||||
|
if len(hostPeerUpdate.FwUpdate.AllowedNetworks) > 0 {
|
||||||
hostPeerUpdate.FwUpdate.EgressInfo["allowed-network-rules"] = models.EgressInfo{
|
hostPeerUpdate.FwUpdate.EgressInfo["allowed-network-rules"] = models.EgressInfo{
|
||||||
EgressID: "allowed-network-rules",
|
EgressID: "allowed-network-rules",
|
||||||
EgressFwRules: make(map[string]models.AclRule),
|
EgressFwRules: make(map[string]models.AclRule),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for _, aclRule := range hostPeerUpdate.FwUpdate.AllowedNetworks {
|
for _, aclRule := range hostPeerUpdate.FwUpdate.AllowedNetworks {
|
||||||
hostPeerUpdate.FwUpdate.AclRules[aclRule.ID] = aclRule
|
hostPeerUpdate.FwUpdate.AclRules[aclRule.ID] = aclRule
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -63,6 +64,10 @@ func migrateNameservers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, netI := range nets {
|
for _, netI := range nets {
|
||||||
|
_, cidr, err := net.ParseCIDR(netI.AddressRange)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if len(netI.NameServers) > 0 {
|
if len(netI.NameServers) > 0 {
|
||||||
ns := schema.Nameserver{
|
ns := schema.Nameserver{
|
||||||
ID: uuid.NewString(),
|
ID: uuid.NewString(),
|
||||||
@@ -78,8 +83,14 @@ func migrateNameservers() {
|
|||||||
Status: true,
|
Status: true,
|
||||||
CreatedBy: user.UserName,
|
CreatedBy: user.UserName,
|
||||||
}
|
}
|
||||||
for _, ip := range netI.NameServers {
|
|
||||||
ns.Servers = append(ns.Servers, ip)
|
for _, nsIP := range netI.NameServers {
|
||||||
|
if net.ParseIP(nsIP) == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !cidr.Contains(net.ParseIP(nsIP)) {
|
||||||
|
ns.Servers = append(ns.Servers, nsIP)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ns.Create(db.WithContext(context.TODO()))
|
ns.Create(db.WithContext(context.TODO()))
|
||||||
netI.NameServers = []string{}
|
netI.NameServers = []string{}
|
||||||
|
@@ -3,6 +3,7 @@ package logic
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"net"
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/db"
|
"github.com/gravitl/netmaker/db"
|
||||||
"github.com/gravitl/netmaker/logic"
|
"github.com/gravitl/netmaker/logic"
|
||||||
@@ -20,6 +21,25 @@ func ValidateNameserverReq(ns schema.Nameserver) error {
|
|||||||
if len(ns.Servers) == 0 {
|
if len(ns.Servers) == 0 {
|
||||||
return errors.New("atleast one nameserver should be specified")
|
return errors.New("atleast one nameserver should be specified")
|
||||||
}
|
}
|
||||||
|
network, err := logic.GetNetwork(ns.NetworkID)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("invalid network id")
|
||||||
|
}
|
||||||
|
_, cidr, err4 := net.ParseCIDR(network.AddressRange)
|
||||||
|
_, cidr6, err6 := net.ParseCIDR(network.AddressRange6)
|
||||||
|
for _, nsIPStr := range ns.Servers {
|
||||||
|
nsIP := net.ParseIP(nsIPStr)
|
||||||
|
if nsIP == nil {
|
||||||
|
return errors.New("invalid nameserver " + nsIPStr)
|
||||||
|
}
|
||||||
|
if err4 == nil && nsIP.To4() != nil {
|
||||||
|
if cidr.Contains(nsIP) {
|
||||||
|
return errors.New("cannot use netmaker IP as nameserver")
|
||||||
|
}
|
||||||
|
} else if err6 == nil && cidr6.Contains(nsIP) {
|
||||||
|
return errors.New("cannot use netmaker IP as nameserver")
|
||||||
|
}
|
||||||
|
}
|
||||||
if !ns.MatchAll && len(ns.MatchDomains) == 0 {
|
if !ns.MatchAll && len(ns.MatchDomains) == 0 {
|
||||||
return errors.New("atleast one match domain is required")
|
return errors.New("atleast one match domain is required")
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user