mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-14 09:04:44 +08:00
add extclient egress ranges
This commit is contained in:
parent
2cc54d949c
commit
ebc3e90301
7 changed files with 137 additions and 93 deletions
|
@ -7,6 +7,7 @@ import (
|
|||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
|
@ -128,7 +129,7 @@ func createAcl(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
acl := req
|
||||
acl.GetID(req.NetworkID, req.Name)
|
||||
acl.ID = uuid.New().String()
|
||||
acl.CreatedBy = user.UserName
|
||||
acl.CreatedAt = time.Now().UTC()
|
||||
acl.Default = false
|
||||
|
@ -187,14 +188,6 @@ func updateAcl(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
if !acl.Default && updateAcl.NewName != "" {
|
||||
//check if policy exists with same name
|
||||
id := models.FormatAclID(updateAcl.NetworkID, updateAcl.NewName)
|
||||
_, err := logic.GetAcl(id)
|
||||
if err == nil {
|
||||
logic.ReturnErrorResponse(w, r,
|
||||
logic.FormatError(errors.New("policy already exists with name "+updateAcl.NewName), "badrequest"))
|
||||
return
|
||||
}
|
||||
updateAcl.ID = id
|
||||
updateAcl.Acl.Name = updateAcl.NewName
|
||||
}
|
||||
err = logic.UpdateAcl(updateAcl.Acl, acl)
|
||||
|
@ -218,7 +211,7 @@ func deleteAcl(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("acl id is required"), "badrequest"))
|
||||
return
|
||||
}
|
||||
acl, err := logic.GetAcl(models.AclID(aclID))
|
||||
acl, err := logic.GetAcl(aclID)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
|
|
|
@ -16,10 +16,11 @@ func CreateDefaultAclNetworkPolicies(netID models.NetworkID) {
|
|||
if netID.String() == "" {
|
||||
return
|
||||
}
|
||||
if !IsAclExists(models.AclID(fmt.Sprintf("%s.%s", netID, "all-nodes"))) {
|
||||
if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-nodes")) {
|
||||
defaultDeviceAcl := models.Acl{
|
||||
ID: models.AclID(fmt.Sprintf("%s.%s", netID, "all-nodes")),
|
||||
Name: "all-nodes",
|
||||
ID: fmt.Sprintf("%s.%s", netID, "all-nodes"),
|
||||
Name: "All Nodes",
|
||||
MetaData: "This Policy allows all nodes in the network to communicate with each other",
|
||||
Default: true,
|
||||
NetworkID: netID,
|
||||
RuleType: models.DevicePolicy,
|
||||
|
@ -40,11 +41,12 @@ func CreateDefaultAclNetworkPolicies(netID models.NetworkID) {
|
|||
}
|
||||
InsertAcl(defaultDeviceAcl)
|
||||
}
|
||||
if !IsAclExists(models.AclID(fmt.Sprintf("%s.%s", netID, "all-users"))) {
|
||||
if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-users")) {
|
||||
defaultUserAcl := models.Acl{
|
||||
ID: models.AclID(fmt.Sprintf("%s.%s", netID, "all-users")),
|
||||
ID: fmt.Sprintf("%s.%s", netID, "all-users"),
|
||||
Default: true,
|
||||
Name: "all-users",
|
||||
Name: "All Users",
|
||||
MetaData: "This policy gives access to everything in the network for an user",
|
||||
NetworkID: netID,
|
||||
RuleType: models.UserPolicy,
|
||||
Src: []models.AclPolicyTag{
|
||||
|
@ -69,11 +71,11 @@ func CreateDefaultAclNetworkPolicies(netID models.NetworkID) {
|
|||
InsertAcl(defaultUserAcl)
|
||||
}
|
||||
|
||||
if !IsAclExists(models.AclID(fmt.Sprintf("%s.%s", netID, "all-remote-access-gws"))) {
|
||||
if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-remote-access-gws")) {
|
||||
defaultUserAcl := models.Acl{
|
||||
ID: models.AclID(fmt.Sprintf("%s.%s", netID, "all-remote-access-gws")),
|
||||
ID: fmt.Sprintf("%s.%s", netID, "all-remote-access-gws"),
|
||||
Default: true,
|
||||
Name: "all-remote-access-gws",
|
||||
Name: "All Remote Access Gateways",
|
||||
NetworkID: netID,
|
||||
RuleType: models.DevicePolicy,
|
||||
Src: []models.AclPolicyTag{
|
||||
|
@ -115,15 +117,10 @@ func ValidateCreateAclReq(req models.Acl) error {
|
|||
if err != nil {
|
||||
return errors.New("failed to get network details for " + req.NetworkID.String())
|
||||
}
|
||||
err = CheckIDSyntax(req.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.GetID(req.NetworkID, req.Name)
|
||||
_, err = GetAcl(req.ID)
|
||||
if err == nil {
|
||||
return errors.New("acl exists already with name " + req.Name)
|
||||
}
|
||||
// err = CheckIDSyntax(req.Name)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -133,13 +130,13 @@ func InsertAcl(a models.Acl) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return database.Insert(a.ID.String(), string(d), database.ACLS_TABLE_NAME)
|
||||
return database.Insert(a.ID, string(d), database.ACLS_TABLE_NAME)
|
||||
}
|
||||
|
||||
// GetAcl - gets acl info by id
|
||||
func GetAcl(aID models.AclID) (models.Acl, error) {
|
||||
func GetAcl(aID string) (models.Acl, error) {
|
||||
a := models.Acl{}
|
||||
d, err := database.FetchRecord(database.ACLS_TABLE_NAME, aID.String())
|
||||
d, err := database.FetchRecord(database.ACLS_TABLE_NAME, aID)
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
|
@ -151,7 +148,7 @@ func GetAcl(aID models.AclID) (models.Acl, error) {
|
|||
}
|
||||
|
||||
// IsAclExists - checks if acl exists
|
||||
func IsAclExists(aclID models.AclID) bool {
|
||||
func IsAclExists(aclID string) bool {
|
||||
_, err := GetAcl(aclID)
|
||||
return err == nil
|
||||
}
|
||||
|
@ -252,15 +249,11 @@ func UpdateAcl(newAcl, acl models.Acl) error {
|
|||
acl.Dst = newAcl.Dst
|
||||
}
|
||||
acl.Enabled = newAcl.Enabled
|
||||
if acl.ID != newAcl.ID {
|
||||
database.DeleteRecord(database.ACLS_TABLE_NAME, acl.ID.String())
|
||||
acl.ID = newAcl.ID
|
||||
}
|
||||
d, err := json.Marshal(acl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return database.Insert(acl.ID.String(), string(d), database.ACLS_TABLE_NAME)
|
||||
return database.Insert(acl.ID, string(d), database.ACLS_TABLE_NAME)
|
||||
}
|
||||
|
||||
// UpsertAcl - upserts acl
|
||||
|
@ -269,12 +262,12 @@ func UpsertAcl(acl models.Acl) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return database.Insert(acl.ID.String(), string(d), database.ACLS_TABLE_NAME)
|
||||
return database.Insert(acl.ID, string(d), database.ACLS_TABLE_NAME)
|
||||
}
|
||||
|
||||
// DeleteAcl - deletes acl policy
|
||||
func DeleteAcl(a models.Acl) error {
|
||||
return database.DeleteRecord(database.ACLS_TABLE_NAME, a.ID.String())
|
||||
return database.DeleteRecord(database.ACLS_TABLE_NAME, a.ID)
|
||||
}
|
||||
|
||||
// GetDefaultPolicy - fetches default policy in the network by ruleType
|
||||
|
@ -283,7 +276,7 @@ func GetDefaultPolicy(netID models.NetworkID, ruleType models.AclPolicyType) (mo
|
|||
if ruleType == models.DevicePolicy {
|
||||
aclID = "all-nodes"
|
||||
}
|
||||
acl, err := GetAcl(models.AclID(fmt.Sprintf("%s.%s", netID, aclID)))
|
||||
acl, err := GetAcl(fmt.Sprintf("%s.%s", netID, aclID))
|
||||
if err != nil {
|
||||
return models.Acl{}, errors.New("default rule not found")
|
||||
}
|
||||
|
|
|
@ -443,39 +443,62 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
|
|||
if userNodeI.StaticNode.Address != "" {
|
||||
if !defaultUserPolicy.Enabled {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIp: userNodeI.StaticNode.AddressIPNet4().IP,
|
||||
DstIP: peer.StaticNode.AddressIPNet4().IP,
|
||||
SrcIP: userNodeI.StaticNode.AddressIPNet4(),
|
||||
DstIP: peer.StaticNode.AddressIPNet4(),
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIp: peer.StaticNode.AddressIPNet4().IP,
|
||||
DstIP: userNodeI.StaticNode.AddressIPNet4().IP,
|
||||
SrcIP: peer.StaticNode.AddressIPNet4(),
|
||||
DstIP: userNodeI.StaticNode.AddressIPNet4(),
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
if userNodeI.StaticNode.Address6 != "" {
|
||||
if !defaultUserPolicy.Enabled {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIp: userNodeI.StaticNode.AddressIPNet6().IP,
|
||||
DstIP: peer.StaticNode.AddressIPNet6().IP,
|
||||
SrcIP: userNodeI.StaticNode.AddressIPNet6(),
|
||||
DstIP: peer.StaticNode.AddressIPNet6(),
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIp: peer.StaticNode.AddressIPNet6().IP,
|
||||
DstIP: userNodeI.StaticNode.AddressIPNet6().IP,
|
||||
SrcIP: peer.StaticNode.AddressIPNet6(),
|
||||
DstIP: userNodeI.StaticNode.AddressIPNet6(),
|
||||
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 {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIp: userNodeI.StaticNode.AddressIPNet4().IP,
|
||||
DstIP: peer.Address.IP,
|
||||
SrcIP: userNodeI.StaticNode.AddressIPNet4(),
|
||||
DstIP: peer.Address,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
@ -483,8 +506,8 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
|
|||
|
||||
if userNodeI.StaticNode.Address6 != "" {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIp: userNodeI.StaticNode.AddressIPNet6().IP,
|
||||
DstIP: peer.Address6.IP,
|
||||
SrcIP: userNodeI.StaticNode.AddressIPNet6(),
|
||||
DstIP: peer.Address6,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
@ -509,30 +532,53 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
|
|||
if peer.IsStatic {
|
||||
if nodeI.StaticNode.Address != "" {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIp: nodeI.StaticNode.AddressIPNet4().IP,
|
||||
DstIP: peer.StaticNode.AddressIPNet4().IP,
|
||||
SrcIP: nodeI.StaticNode.AddressIPNet4(),
|
||||
DstIP: peer.StaticNode.AddressIPNet4(),
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
if nodeI.StaticNode.Address6 != "" {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIp: nodeI.StaticNode.AddressIPNet6().IP,
|
||||
DstIP: peer.StaticNode.AddressIPNet6().IP,
|
||||
SrcIP: nodeI.StaticNode.AddressIPNet6(),
|
||||
DstIP: peer.StaticNode.AddressIPNet6(),
|
||||
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 != "" {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIp: nodeI.StaticNode.AddressIPNet4().IP,
|
||||
DstIP: peer.Address.IP,
|
||||
SrcIP: nodeI.StaticNode.AddressIPNet4(),
|
||||
DstIP: peer.Address,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
if nodeI.StaticNode.Address6 != "" {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIp: nodeI.StaticNode.AddressIPNet6().IP,
|
||||
DstIP: peer.Address6.IP,
|
||||
SrcIP: nodeI.StaticNode.AddressIPNet6(),
|
||||
DstIP: peer.Address6,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
@ -642,8 +688,30 @@ func getExtPeerEgressRoute(node models.Node, extPeer models.ExtClient) (egressRo
|
|||
return
|
||||
}
|
||||
|
||||
func getExtpeersExtraRoutes(node models.Node, network string) (egressRoutes []models.EgressNetworkRoutes) {
|
||||
extPeers, err := GetNetworkExtClients(network)
|
||||
func getExtpeerEgressRanges(node models.Node) (ranges []net.IPNet) {
|
||||
extPeers, err := GetNetworkExtClients(node.Network)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, extPeer := range extPeers {
|
||||
if len(extPeer.ExtraAllowedIPs) == 0 {
|
||||
continue
|
||||
}
|
||||
if !IsNodeAllowedToCommunicate(extPeer.ConvertToStaticNode(), node) {
|
||||
continue
|
||||
}
|
||||
for _, allowedRange := range extPeer.ExtraAllowedIPs {
|
||||
_, ipnet, err := net.ParseCIDR(allowedRange)
|
||||
if err == nil {
|
||||
ranges = append(ranges, *ipnet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func getExtpeersExtraRoutes(node models.Node) (egressRoutes []models.EgressNetworkRoutes) {
|
||||
extPeers, err := GetNetworkExtClients(node.Network)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
|||
})
|
||||
}
|
||||
if peer.IsIngressGateway {
|
||||
hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(node, peer.Network)...)
|
||||
hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(node)...)
|
||||
}
|
||||
_, isFailOverPeer := node.FailOverPeers[peer.ID.String()]
|
||||
if servercfg.IsPro {
|
||||
|
@ -301,6 +301,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
|||
Network6: node.NetworkRange6,
|
||||
AllowAll: defaultDevicePolicy.Enabled && defaultUserPolicy.Default,
|
||||
StaticNodeIps: GetStaticNodeIps(node),
|
||||
EgressRanges: getExtpeerEgressRanges(node),
|
||||
Rules: GetFwRulesOnIngressGateway(node),
|
||||
}
|
||||
hostPeerUpdate.FwUpdate.IngressInfo[node.ID.String()] = ingFwUpdate
|
||||
|
|
|
@ -1,24 +1,9 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AclID string
|
||||
|
||||
func (aID AclID) String() string {
|
||||
return string(aID)
|
||||
}
|
||||
|
||||
func (a *Acl) GetID(netID NetworkID, name string) {
|
||||
a.ID = AclID(fmt.Sprintf("%s.%s", netID.String(), name))
|
||||
}
|
||||
|
||||
func FormatAclID(netID NetworkID, name string) AclID {
|
||||
return AclID(fmt.Sprintf("%s.%s", netID.String(), name))
|
||||
}
|
||||
|
||||
// AllowedTrafficDirection - allowed direction of traffic
|
||||
type AllowedTrafficDirection int
|
||||
|
||||
|
@ -66,8 +51,9 @@ type AclPolicy struct {
|
|||
}
|
||||
|
||||
type Acl struct {
|
||||
ID AclID `json:"id"`
|
||||
ID string `json:"id"`
|
||||
Default bool `json:"default"`
|
||||
MetaData string `json:"meta_data"`
|
||||
Name string `json:"name"`
|
||||
NetworkID NetworkID `json:"network_id"`
|
||||
RuleType AclPolicyType `json:"policy_type"`
|
||||
|
|
|
@ -27,19 +27,20 @@ type HostPeerUpdate struct {
|
|||
}
|
||||
|
||||
type FwRule struct {
|
||||
SrcIp net.IP
|
||||
DstIP net.IP
|
||||
SrcIP net.IPNet
|
||||
DstIP net.IPNet
|
||||
Allow bool
|
||||
}
|
||||
|
||||
// IngressInfo - struct for ingress info
|
||||
type IngressInfo struct {
|
||||
IngressID string `json:"ingress_id"`
|
||||
Network net.IPNet `json:"network"`
|
||||
Network6 net.IPNet `json:"network6"`
|
||||
StaticNodeIps []net.IP `json:"static_node_ips"`
|
||||
Rules []FwRule `json:"rules"`
|
||||
AllowAll bool `json:"allow_all"`
|
||||
IngressID string `json:"ingress_id"`
|
||||
Network net.IPNet `json:"network"`
|
||||
Network6 net.IPNet `json:"network6"`
|
||||
StaticNodeIps []net.IP `json:"static_node_ips"`
|
||||
Rules []FwRule `json:"rules"`
|
||||
AllowAll bool `json:"allow_all"`
|
||||
EgressRanges []net.IPNet `json:"egress_ranges"`
|
||||
}
|
||||
|
||||
// EgressInfo - struct for egress info
|
||||
|
|
|
@ -1141,10 +1141,11 @@ func CreateDefaultUserPolicies(netID models.NetworkID) {
|
|||
return
|
||||
}
|
||||
|
||||
if !logic.IsAclExists(models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin))) {
|
||||
if !logic.IsAclExists(fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin)) {
|
||||
defaultUserAcl := models.Acl{
|
||||
ID: models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin)),
|
||||
Name: fmt.Sprintf("%s-grp", models.NetworkAdmin),
|
||||
ID: fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin),
|
||||
Name: "Network Admin",
|
||||
MetaData: "This Policy allows all network admins to communicate with all remote access gateways",
|
||||
Default: true,
|
||||
NetworkID: netID,
|
||||
RuleType: models.UserPolicy,
|
||||
|
@ -1166,10 +1167,11 @@ func CreateDefaultUserPolicies(netID models.NetworkID) {
|
|||
logic.InsertAcl(defaultUserAcl)
|
||||
}
|
||||
|
||||
if !logic.IsAclExists(models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser))) {
|
||||
if !logic.IsAclExists(fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser)) {
|
||||
defaultUserAcl := models.Acl{
|
||||
ID: models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser)),
|
||||
Name: fmt.Sprintf("%s-grp", models.NetworkUser),
|
||||
ID: fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser),
|
||||
Name: "Network User",
|
||||
MetaData: "This Policy allows all network users to communicate with all remote access gateways",
|
||||
Default: true,
|
||||
NetworkID: netID,
|
||||
RuleType: models.UserPolicy,
|
||||
|
|
Loading…
Add table
Reference in a new issue