marOne
marOne

Reputation: 149

How to deny all traffic from other kubernetes namespaces

Hey it's been a while trying to block traffic from other namespaces and only access pods in same namespace, I looked over many threads but none work! What I tried so far is:

I created a globalnetworkpolicy using calico to allow egress traffic:

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: allow-all-egress
spec:
  egress:
  - action: Allow
    destination: {}
    source: {}
  order: 100
  selector: all()
  types:
  - Egress
  1. created two namespaces:
kubectl create ns policy-demo1
kubectl create ns policy-demo2
  1. applied following networkpolicy in each namespace to enable ingress only in each namespace:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-ingress
  namespace: policy-demo1
spec:
  podSelector: {}
  ingress:
  - {}
  policyTypes:
  - Ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-ingress
  namespace: policy-demo2
spec:
  podSelector: {}
  ingress:
  - {}
  policyTypes:
  - Ingress
  1. created in each namespace an nginx server and a busybox to test:
# for namespace: policy-demo1
kubectl create deployment --namespace=policy-demo1 nginx --image=nginx
kubectl expose --namespace=policy-demo1 deployment nginx --port=80
kubectl run --namespace=policy-demo1 access --rm -ti --image busybox /bin/sh

# did same for namespace policy-demo2

The wget -q --timeout=5 nginx -O - and ping <IP_of_nginx_pod> works as expected in same namespace. However when I ping nginx container that lives in policy-demo1 from policy-demo2 it works, which I don't want this behavior. Want to block traffic comming from different namespaces.

I tried another networkpolicy and added namespaceSelector:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-ingress
  namespace: policy-demo1
spec:
  podSelector: {}
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
           name: policy-demo1 # added this label to policy-demo namespace
  policyTypes:
  - Ingress

but pinging or doing wget from busybox image to nginx in the same namespace stopped working, what am I doing wrong please?

Thank you.

Upvotes: 1

Views: 677

Answers (4)

Fredrik
Fredrik

Reputation: 494

Follow the official documentation Deny all traffic, but this is not all and you have to consider the cluster flavor you are using, GKE, Rancher, Openshift which works slightly different.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

This will block the traffic if you have Prerequisites fulfilled. If you use Google Kubernetes engine you have to create the cluster with the flag enable-network-policy

gcloud container clusters create <cluster name> --enable-network-policy

Otherwise your network policy will not have any impact even that it exists.

Warning: If you omit the --enable-network-policy flag, any NetworkPolicy resources you create are silently ignored.

To check if you have a for example, cilium enabled you can;

  kubectl -n kube-system get pods -l k8s-app=cilium

Upvotes: 0

Jen Luther Thomas
Jen Luther Thomas

Reputation: 59

Admittedly I've put this together based on examples from the doc and haven't had a chance to test yet, but in case this gets you on your way. I have two policy examples you could try for the policy-demo1 namespace (and rinse repeat for the second namespace). The first one is a simpler, namespace scoped calico network policy, but I'm still allowing access to kube-dns from that namespace. The second example is a bit more specific with namespace selectors within the allow/deny rules for both ingress/egress.

The last policy is a default deny, because by default kubernetes will allow traffic. If these don't work you could also try setting the policy action to log and see what you get. More info on logging here.

Also note the order of the policies. Default deny is 2000 because you want that to be evaluated last.

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-policy-demo1
  namespace: policy-demo1
spec:
  order: 20
  ingress:
    - action: Allow
      protocol: TCP
  egress:
    - action: Allow
      protocol: UDP
      source: {}
      destination:
        selector: k8s-app == "kube-dns"
        ports:
          - "53"
    - action: Allow
      protocol: TCP
      source: {}
      destination:
        selector: k8s-app == "kube-dns"
        ports:
          - "53"
  types:
    - Ingress
    - Egress
---
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: policy-demo1-allow
  namespace: policy-demo1
spec:
  order: 25
  ingress:
    - action: Allow
      source:
        selector: projectcalico.org/namespace in  {'policy-demo1', 'kube-system', 'calico-system', 'calico-apiserver'}
      destination: {}
    - action: Deny
      source:
        selector: projectcalico.org/namespace not in  {'policy-demo1', 'kube-system', 'calico-system', 'calico-apiserver'}
      destination: {}
  egress:
    - action: Allow
      source: {}
      destination:
        selector: projectcalico.org/namespace in  {'policy-demo1', 'kube-system', 'calico-system', 'calico-apiserver'}
    - action: Deny
      source: {}
      destination:
        selector: projectcalico.org/namespace not in  {'policy-demo1', 'kube-system', 'calico-system', 'calico-apiserver'}
  types:
    - Ingress
    - Egress
---
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: default-deny
spec:
  order: 2000
  selector: projectcalico.org/namespace not in  {'kube-system', 'calico-system', 'calico-apiserver'}
  types:
  - Ingress
  - Egress

Upvotes: 0

hasouscsed
hasouscsed

Reputation: 46

You should address both ingress and egress in your NetworkPolicy to get the results you desire.

Here's all you need - Create this NetworkPolicy in namespace policy-demo1:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: restrict-to-policy-demo1
  namespace: policy-demo1
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector: {}
  egress:
  - to:
    - podSelector: {}

Create this NetworkPolicy in namespace policy-demo2:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: restrict-to-policy-demo2
  namespace: policy-demo2
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector: {}
  egress:
  - to:
    - podSelector: {}

The pods in policy-demo1 can now only communicate with pods in policy-demo1. Same applies for pods in policy-demo2.

You can remove your GlobalNetworkPolicy and any other NetworkPolicy objects.

Upvotes: 0

ABWassim
ABWassim

Reputation: 623

Could it be the fact that in the namespaceSelector, you specified policy-demo1 instead of policy-demo2 ?

  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
           name: policy-demo1 # added this label to policy-demo namespace

instead of

  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
           name: policy-demo2 # added this label to policy-demo namespace

Upvotes: 0

Related Questions