diff --git a/management/server/types/account_components.go b/management/server/types/account_components.go index 27ab456e5..ad2bccee8 100644 --- a/management/server/types/account_components.go +++ b/management/server/types/account_components.go @@ -41,7 +41,7 @@ func (a *Account) GetPeerNetworkMapComponents( ResourcePoliciesMap: make(map[string][]*Policy), RoutersMap: make(map[string]map[string]*routerTypes.NetworkRouter), NetworkResources: make([]*resourceTypes.NetworkResource, 0), - PostureFailedPeers: make(map[string]map[string]struct{}, len(a.Policies)), + PostureFailedPeers: make(map[string]map[string]struct{}, len(a.PostureChecks)), } components.AccountSettings = &AccountSettingsInfo{ @@ -105,11 +105,13 @@ func (a *Account) GetPeerNetworkMapComponents( if addSourcePeers { var peers []string if policy.Rules[0].SourceResource.Type == ResourceTypePeer && policy.Rules[0].SourceResource.ID != "" { - peers = []string{policy.Rules[0].SourceResource.ID} + if _, validated := validatedPeersMap[policy.Rules[0].SourceResource.ID]; validated { + peers = []string{policy.Rules[0].SourceResource.ID} + } } else { peers = a.getUniquePeerIDsFromGroupsIDs(ctx, policy.SourceGroups()) } - for _, pID := range a.getPostureValidPeersSaveFailed(peers, policy.SourcePostureChecks, &components.PostureFailedPeers) { + for _, pID := range a.getPostureValidPeersSaveFailed(peers, policy.SourcePostureChecks, validatedPeersMap, &components.PostureFailedPeers) { if _, exists := components.Peers[pID]; !exists { components.Peers[pID] = a.GetPeer(pID) } @@ -174,6 +176,7 @@ func (a *Account) GetPeerNetworkMapComponents( } filterGroupPeers(&components.Groups, components.Peers) + filterPostureFailedPeers(&components.PostureFailedPeers, components.Policies, components.ResourcePoliciesMap, components.Peers) return components } @@ -251,7 +254,9 @@ func (a *Account) getPeersGroupsPoliciesRoutes( var peerInSources, peerInDestinations bool if rule.SourceResource.Type == ResourceTypePeer && rule.SourceResource.ID != "" { - sourcePeers = []string{rule.SourceResource.ID} + if _, validated := validatedPeersMap[rule.SourceResource.ID]; validated { + sourcePeers = []string{rule.SourceResource.ID} + } if rule.SourceResource.ID == peerID { peerInSources = true } @@ -260,7 +265,9 @@ func (a *Account) getPeersGroupsPoliciesRoutes( } if rule.DestinationResource.Type == ResourceTypePeer && rule.DestinationResource.ID != "" { - destinationPeers = []string{rule.DestinationResource.ID} + if _, validated := validatedPeersMap[rule.DestinationResource.ID]; validated { + destinationPeers = []string{rule.DestinationResource.ID} + } if rule.DestinationResource.ID == peerID { peerInDestinations = true } @@ -332,6 +339,10 @@ func (a *Account) getPeersFromGroups(ctx context.Context, groups []string, peerI continue } + if _, ok := validatedPeersMap[peer.ID]; !ok { + continue + } + isValid, pname := a.validatePostureChecksOnPeerGetFailed(ctx, sourcePostureChecksIDs, peer.ID) if !isValid && len(pname) > 0 { if _, ok := (*postureFailedPeers)[pname]; !ok { @@ -341,10 +352,6 @@ func (a *Account) getPeersFromGroups(ctx context.Context, groups []string, peerI continue } - if _, ok := validatedPeersMap[peer.ID]; !ok { - continue - } - if peer.ID == peerID { peerInGroups = true continue @@ -365,6 +372,10 @@ func (a *Account) getPeersFromGroups(ctx context.Context, groups []string, peerI continue } + if _, ok := validatedPeersMap[peer.ID]; !ok { + continue + } + isValid, pname := a.validatePostureChecksOnPeerGetFailed(ctx, sourcePostureChecksIDs, peer.ID) if !isValid && len(pname) > 0 { if _, ok := (*postureFailedPeers)[pname]; !ok { @@ -374,10 +385,6 @@ func (a *Account) getPeersFromGroups(ctx context.Context, groups []string, peerI continue } - if _, ok := validatedPeersMap[peer.ID]; !ok { - continue - } - if peer.ID == peerID { peerInGroups = true continue @@ -412,9 +419,12 @@ func (a *Account) validatePostureChecksOnPeerGetFailed(ctx context.Context, sour return true, "" } -func (a *Account) getPostureValidPeersSaveFailed(inputPeers []string, postureChecksIDs []string, postureFailedPeers *map[string]map[string]struct{}) []string { +func (a *Account) getPostureValidPeersSaveFailed(inputPeers []string, postureChecksIDs []string, validatedPeersMap map[string]struct{}, postureFailedPeers *map[string]map[string]struct{}) []string { var dest []string for _, peerID := range inputPeers { + if _, validated := validatedPeersMap[peerID]; !validated { + continue + } valid, pname := a.validatePostureChecksOnPeerGetFailed(context.Background(), postureChecksIDs, peerID) if valid { dest = append(dest, peerID) @@ -447,6 +457,41 @@ func filterGroupPeers(groups *map[string]*Group, peers map[string]*nbpeer.Peer) } } +func filterPostureFailedPeers(postureFailedPeers *map[string]map[string]struct{}, policies []*Policy, resourcePoliciesMap map[string][]*Policy, peers map[string]*nbpeer.Peer) { + if len(*postureFailedPeers) == 0 { + return + } + + referencedPostureChecks := make(map[string]struct{}) + for _, policy := range policies { + for _, checkID := range policy.SourcePostureChecks { + referencedPostureChecks[checkID] = struct{}{} + } + } + for _, resPolicies := range resourcePoliciesMap { + for _, policy := range resPolicies { + for _, checkID := range policy.SourcePostureChecks { + referencedPostureChecks[checkID] = struct{}{} + } + } + } + + for checkID, failedPeers := range *postureFailedPeers { + if _, referenced := referencedPostureChecks[checkID]; !referenced { + delete(*postureFailedPeers, checkID) + continue + } + for peerID := range failedPeers { + if _, exists := peers[peerID]; !exists { + delete(failedPeers, peerID) + } + } + if len(failedPeers) == 0 { + delete(*postureFailedPeers, checkID) + } + } +} + func filterDNSRecordsByPeers(records []nbdns.SimpleRecord, peers map[string]*nbpeer.Peer) []nbdns.SimpleRecord { if len(records) == 0 || len(peers) == 0 { return nil diff --git a/management/server/types/networkmap_components.go b/management/server/types/networkmap_components.go index a17464749..5ac1b0352 100644 --- a/management/server/types/networkmap_components.go +++ b/management/server/types/networkmap_components.go @@ -5,6 +5,7 @@ import ( "net" "net/netip" "slices" + "strconv" "strings" "time" @@ -292,19 +293,21 @@ func (calc *NetworkMapCalculator) connResourcesGenerator(ctx context.Context, ta peersExists[peer.ID] = struct{}{} } + protocol := rule.Protocol + if protocol == PolicyRuleProtocolNetbirdSSH { + protocol = PolicyRuleProtocolTCP + } + fr := FirewallRule{ PolicyID: rule.ID, PeerIP: net.IP(peer.IP).String(), Direction: direction, Action: string(rule.Action), - Protocol: string(rule.Protocol), + Protocol: string(protocol), } - ruleID := rule.ID + fr.PeerIP + string(rune(direction)) + - fr.Protocol + fr.Action - for _, port := range rule.Ports { - ruleID += port - } + ruleID := rule.ID + fr.PeerIP + strconv.Itoa(direction) + + fr.Protocol + fr.Action + strings.Join(rule.Ports, ",") if _, ok := rulesExists[ruleID]; ok { continue }