Existing Behavior <v1.3.0
NPM used to take a decision on a given packets based on rules in a single direction. If there is a DENY rule in EGRESS and ALLOW rule in INGRESS, NPM would have ALLOWED the packet, even though it should have been blocked. This is incorrect behavior. Original behavior logic examples:
-
(Ingress allow rule 1 OR egress deny rule 1) - Packet ALLOWED
-
(Ingress deny rule 1 OR egress allow rule 1) - Packet ALLOWED
-
(Ingress allow rule 1 OR NO EGRESS rules) - Packet ALLOWED
-
(NO INGRESS rules OR Egress allowrule 1) - Packet ALLOWED
-
(NO RULES) - Packet ALLOWED
New and correct behavior >v1.3.0
With the latest update, NPM evaluates both ingress and egress rules to take a decision on the packet. In either direction, if there is one or more explicit deny rules without a ALLOW in that particular packet direction, NPM will drop the packet. Current Behavior:
- (Ingress allow rule 1 ) AND (egress deny rule 1) - Packet DROPPED
- (Ingress deny rule 1 AND egress allow rule 1) - Packet DROPPED
- (Ingress allow rule 1 AND NO EGRESS rules) - Packet ALLOWED
- (NO INGRESS rules AND Egress allowrule 1) - Packet ALLOWED
- (NO RULES) - Packet ALLOWED
Some rule example of this behavior
- If there is one allow rule in INGRESS and no rules in EGRESS - applicable traffic will be allowed
- If there is one allow rule in EGRESS and no rules in INGRESS - applicable traffic will be allowed
- If there is one allow rule in EGRESS and one (or more) DENY rule(s) in INGRESS - applicable traffic will be DENIED
- If there is one allow rule in INGRESS and one (or more) DENY rule(s) in EGRESS - applicable traffic will be DENIED
- If INGRESS and EGRESS have allow rules - traffic is allowed.
Take this example Policy 1
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: untitled-policy
namespace: testpolicy
spec:
podSelector: {}
ingress:
- from:
- podSelector:
matchLabels:
app: test
ports:
- port: 80
- port: 81
egress:
- to:
- podSelector:
matchLabels:
app: test
ports:
- port: 81
Old behavior would have allowed Port 80 and Port 81 traffic from app=test Pods to all pods of testpolicy namespace.
With new 1.3.0 NPM, the correct behavior will be enforced. Port 80 traffic is blocked and Port 81 will be allowed from app=test Pods to all pods of testpolicy namespace.
Take this example Policy 2
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: untitled-policy
namespace: testpolicy
spec:
podSelector: {}
ingress:
- from:
- podSelector:
matchLabels:
app: test
ports:
- port: 80
- port: 81
Old behavior would allow Port 80 and Port 81 traffic from and to app=test Pods.
With new 1.3.0 NPM, same behavior, would allow Port 80 and Port 81 traffic from and to app=test Pods.
Terminology:
Ingress = Ingress rule which gets applied on the destination Pod
Egress = Egress rule which gets applied on the Source Pod
For TCP connections: only the first SYN packet will go through the rules, once the rules allow the SYN packet and connection is established, NPM will not interfere.
Azure Container Networking