Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

W.I.P Exposure analysis with anp #486

Merged
merged 118 commits into from
Jan 27, 2025
Merged

Conversation

shireenf-ibm
Copy link
Contributor

@shireenf-ibm shireenf-ibm commented Jan 21, 2025

No description provided.

…ll but: udp 5353 instead of SCTP 1-65535,TCP 1-65535,UDP 1-5352,5354-65535)
@shireenf-ibm shireenf-ibm marked this pull request as draft January 21, 2025 19:36
@shireenf-ibm shireenf-ibm marked this pull request as ready for review January 26, 2025 20:50
Copy link
Collaborator

@adisos adisos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initial comments/questions, did not review all files yet

Comment on lines 612 to 613
// skip empty connections unless one of the peers is representative
if allowedConnections.IsEmpty() && !(pe.IsRepresentativePeer(srcPeer) || pe.IsRepresentativePeer(dstPeer)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i added it so i can handle the following case:
assume we have an ANP that denies all conns from a -> b ("b" is a representative peer)
and another (with lower priority) rule that allows all conns from a to entire-cluster

i.e "a" is exposed to entire-cluster on all conns except to b (conns are empty to b)
this was added so I can add the entry a->b in the exposure map (with "no conns" ) and display it in the output
see example: "tests/exposure_test_with_anp_9"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, please add comment in code explaining this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// check if the connection is contained in an entire cluster connection; if yes skip; if not store the connection data
contained, err := connectionContainedInEntireClusterConn(pe, peer, allowedConnSet, isIngress)
// check if the peer is exposed to entire-cluster and if connection equals the entire cluster connection;
equals, isExposed, err := connectionEqualsEntireClusterConn(pe, peer, allowedConnSet, isIngress)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contained-in instead of equals?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opposite, equals instead of contained-in (it was containedIn, where actually if it was not larger it was equals)
if there is a rule that allows any connection to entire-cluster when we compute allowed conns between peers, the result contains this connection ( so if it is same as entire-cluster connection, there is no need to add it as "separate" exposure).
if the connection is larger (i.e same conn to entire-cluster + other conn - it will be added as another exposure (was and yet))
the new case - with ANP we have deny rules that may be prior to the "allow to entire-cluster" :
so if a real-peer is exposed to entire-cluster on all-TCP
but there is a rule "deny to new-ns on TCP90" --- the exposure to "new-ns" is all TCP but TCP 90 which is different than the exposure to entire-cluster even it is containedIn it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add example/explanation in code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +141 to +142
// 2. if the connection is empty (no conns) and the peer is exposed to entire-cluster - add this empty connection to the exposure map
// to tell that this representative peer is excluded from `entire-cluster` connection
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is it going to be marked as excluded in the output?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see example tests/exposure_test_with_anp_9 and its document in connlist_test.go

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is also an example with real-pod tests/exposure_test_with_anp_10_with_real_pod (when a real is exposed to entire-cluster, but the connection to another real-pod is blocked);
with real pods connlist-output gives as the indication
(related also to this comment

pkg/netpol/eval/exposure.go Show resolved Hide resolved
// - if the rule's namespaceSelector is not nil, no representative namespace will be generated (representative pod has empty namespace name)
// anyway, the representative pod will store the namespace data.
func (pe *PolicyEngine) generateRepresentativePeers(selectors []k8s.SingleRuleSelectors, policyNs string) (err error) {
for i := range selectors {
podNs := "" // by default: representative peer has no namespace; (don't generate representative namespaces)
if selectors[i].NsSelector == nil {
// note that policyNs is "" (empty) for cluster-scoped policies (ANP and BANP) - means podNs kept empty in this case
if selectors[i].NsSelector == nil && policyNs != "" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

policyNs == "" does not necessarily indicate that the policy is cluster-scoped?
better rely on the policy type ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for all current cases, it does (as the code is written ) and because an NP without namespace would raise error before getting here; we can also change to be more "accurate and sure"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better rely on policy type, so the code is more robust

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

pkg/netpol/eval/check.go Outdated Show resolved Hide resolved
anpConnsDeterminedAllFlag := false
// if all cluster-wide conns were determined by the ANP then update the selected peer's cluster wide exposure
if pe.exposureAnalysisFlag && anpExposure.layerConns.DeterminesAllConns() {
podExposureUpdatedFlag = true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't exposure to external ip-blocks determined by regular netpols ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not only;
egress rules in (B)ANP can also determine conns to IPs (networks field)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can podExposureUpdatedFlag be set to true, if possibly more exposure should be inferred from regular netpols?

Copy link
Contributor Author

@shireenf-ibm shireenf-ibm Jan 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this is related to the other comment
the anser is no, if the flag is true means ANP determined all conns between the peer and entire-cluster

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not clear what do these flags mean? where is it documented?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is exposure updated related to? exposure to entire cluster? exposure to entire cluster and external ip-blocks?
what does value true marks?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to entire cluster only.
we have IP-peers for external exposure
will update the document more ; also described above type policiesLayerXgressConns

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider removing "entire-world" fields from exposure analysis structs, and mention in documentation that exposure analysis only computes exposure to entire-cluster (for external ip-blocks just copying the conn-list results).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opened #488

return anpConns.layerConns.AllowedConns, nil
}
// else : exposure-analysis is on and still not determined continue
anpConnsDeterminedAllFlag = true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how can get here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because if a->b allows all (or at least determined all conns (ports) from ANPs) does not necessary mean that all exposure to entire cluster was also determined from ANPs .. so need to analyze also NPs / BANP for exposure

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I follow why

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example:
ANP denies all conns from a -> b (ANP determined all conns to b; if exposure analysis is off no need to continue to NP/BANP)
But:
NP exposes A to entire-cluster on all-conns (if we don't continue - this would not be computed and will have wrong results as exposure to entire-cluster is computed once for each direction)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. might be useful to add this example in comment as documentation, so it is clear.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Co-authored-by: Adi Sosnovich <82078442+adisos@users.noreply.github.com>
Copy link
Collaborator

@adisos adisos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for test tests/exposure_test_with_anp_1/ , why isn't workload b mentioned in the output as "Workloads not protected by network policies:" ?

@shireenf-ibm
Copy link
Contributor Author

for test tests/exposure_test_with_anp_1/ , why isn't workload b mentioned in the output as "Workloads not protected by network policies:" ?

because the subject of the ANP is all hello-world pods
so it is protected and exposed to slytherin but since it is also exposed to entire-cluster on all connections (there is no deny rule/ any limiting policy selecting workload-b) then exposure to slytherin is actually contained in the exposure to entire-cluster

@adisos
Copy link
Collaborator

adisos commented Jan 27, 2025

for test tests/exposure_test_with_anp_1/ , why isn't workload b mentioned in the output as "Workloads not protected by network policies:" ?

because the subject of the ANP is all hello-world pods so it is protected and exposed to slytherin but since it is also exposed to entire-cluster on all connections (there is no deny rule/ any limiting policy selecting workload-b) then exposure to slytherin is actually contained in the exposure to entire-cluster

I see.. it's a bit misleading because its connectivity has the same effect as "not protected".. can open issue with this example to consider enhancements later.

@shireenf-ibm
Copy link
Contributor Author

exposure_test_with_anp_1/

done #489

@shireenf-ibm shireenf-ibm linked an issue Jan 27, 2025 that may be closed by this pull request
@shireenf-ibm shireenf-ibm merged commit 1d93856 into main Jan 27, 2025
4 checks passed
@shireenf-ibm shireenf-ibm deleted the exposure_analysis_with_anp branch January 27, 2025 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Exposure-Analysis extend support with (Baseline)AdminNetworkPolicy
3 participants