0

I have been trying to experiment with the calico network rules and I'm finding it tough to get the ingress and the egress rules to work with order in calico after denying all ingress and egress rules.

 kubectl get pods --show-labels
NAME         READY   STATUS    RESTARTS   AGE   LABELS
hello-web3   1/1     Running   0          45m   app=foo
hello-web4   1/1     Running   0          45m   app=bar
hello-web5   1/1     Running   0          15s   app=foobar
hello-web6   1/1     Running   0          4s    app=barbar

My network policy is as follows

---
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: ppdp-default
spec:
  selector: all()
  order: 2000
  types:
  - Ingress
  - Egress
---
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: ppdp-egress-trusted
spec:
  selector: app == 'foo'
  order: 1000
  types:
  - Egress
  egress:
  - action: Allow
    destination:
      selector: app == 'bar'
---
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: ppdp-ingress-trusted
spec:
  selector: app == 'foobar'
  order: 100
  types:
  - Ingress
  ingress:
  - action: Allow
    source:
      selector: app == 'barbar'

Output for Ingress:

(base) ➜ ✗ kubectl exec --stdin --tty hello-web5 -- sh
/ # ^C
/ # wget -qO- --timeout=2 http://hello-web6:8080
^C
/ # wget -qO- --timeout=2 http://hello-web6:8080
wget: bad address 'hello-web6:8080'
/ # command terminated with exit code 1
---
(base) ➜ ✗ kubectl exec --stdin --tty hello-web6 -- sh
/ # wget -qO- --timeout=2 http://hello-web5:8080
wget: bad address 'hello-web5:8080'
/ # command terminated with exit code 1

Output for Egress

(base) ➜ ✗ kubectl exec --stdin --tty hello-web3 -- sh
/ # wget -qO- --timeout=2 http://hello-web4:8080
^C
/ # command terminated with exit code 130

Am I missing anything? Any help would be of great use.

Thanks in advance

user3398900
  • 795
  • 2
  • 13
  • 31
  • Since you mention that you have problems with order, can I assume that without specifying the order the network policies work fine? – acid_fuji Apr 20 '21 at 07:22
  • No, its not working then i want to know how to define and give the order to them – user3398900 Apr 20 '21 at 12:44
  • Sure, what namespaces your pod are running? Can you describe your goal with this network policy? It might be easier that way for me to reproduce this. – acid_fuji Apr 20 '21 at 12:48
  • in a namespace, I want to deny traffic among all pods in the first place and then allow egress or ingress traffic between specific pods (matching labels) – user3398900 Apr 21 '21 at 06:28

1 Answers1

1

In a namespace, I want to deny traffic among all pods in the first place and then allow egress or ingress traffic between specific pods (matching labels)

While I don't know why you're using the order or calico network policies the goal described in the comments can be achieved with Kubernetes network policies supported by Calico CNI. I prepared a simple example of how network policies work with those. So let's start with a list of pods that I have created in dev namespace:

➜  ~ kgp -n dev --show-labels -owide

NAME          READY   STATUS    RESTARTS   AGE   IP              NODE       NOMINATED NODE   READINESS GATES   LABELS
centos        1/1     Running   0          30m   10.244.120.68   minikube   <none>           <none>            host=centos
echo-server   1/1     Running   0          30m   10.244.120.69   minikube   <none>           <none>            host=echo-server

Notice the labels. In my example we are going to allow ingress traffic to echo-server from host named centos. Let's first test if the connections works between those:

[root@centos /]# curl 10.244.120.69:80 -v
* About to connect() to 10.244.120.69 port 80 (#0)
*   Trying 10.244.120.69...
* Connected to 10.244.120.69 (10.244.120.69) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 10.244.120.69
> Accept: */*
  "path": "/",
  "headers": {
    "user-agent": "curl/7.29.0",
    "host": "10.244.120.69",
    "accept": "*/*"
  "os": {
    "hostname": "echo-server"
  },
  "connection": {}
* Connection #0 to host 10.244.120.69 left intact

Now let's deny all traffic in that namespace:

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

Once this policy is in place previous test fails:

➜  ~ keti -n dev centos bash 
[root@centos /]# curl 10.244.120.69:80 -v
* About to connect() to 10.244.120.69 port 80 (#0)
*   Trying 10.244.120.69...
* Connection timed out
* Failed connect to 10.244.120.69:80; Connection timed out
* Closing connection 0
curl: (7) Failed connect to 10.244.120.69:80; Connection timed out

Let's now apply the ingress policy that will allow us to reach the echo-server. So basically we selects the pod's label that we want the policy to be applied to and the choose which pod ingress traffic is allowed from:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-echo
  namespace: dev    
spec:
  podSelector:
    matchLabels:
      host: echo-server
  ingress:
    - from:
      - podSelector:
          matchLabels:
            host: centos

Now since we allowed the traffic towards our echo-server, we might feel tempted to test this straight away but this still won't work. While we allowed the ingress traffic toward echo-server we have to remember that we denied both ingress and egress in our deny-all policy. This means that we have to allow the egress traffic from centos pod:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: egress-centos
  namespace: dev    
spec:
  podSelector:
    matchLabels:
      host: centos
  egress:
    - to:
      - podSelector:
          matchLabels:
            host: echo-server      

After that we have successfully allowed traffic for some specific pods in the same namespace while deny every pod that don't match the labels.

acid_fuji
  • 6,287
  • 7
  • 22
  • Then why is it that in this link https://docs.projectcalico.org/security/tutorials/kubernetes-policy-demo/kubernetes-demo they allowed only ingress traffic ?? – user3398900 Apr 24 '21 at 12:49
  • This is happening because isolation policy there does not have any Ingress/Egress type specified and by default. If no `policyTypes` are specified on a `NetworkPolicy` then by default **Ingress will always be set** and Egress will be set if the NetworkPolicy has any egress rules. This is described [here](https://kubernetes.io/docs/concepts/services-networking/network-policies/#networkpolicy-resource) under `PolicyTypes`. I provide the example above to match exactly scenario that you described, meaning that you want to control both ingress and egress. – acid_fuji Apr 26 '21 at 07:53