Calico+Istio Application Layer Policy - Sane Default-deny

Hello everyone,

I am trying to implement the Calico Zero-Trust setup, as recommended by the Calico documentation.

In order to have a safety net in case a developer forgets/makes a mistake in writing a service Network Policy, I am looking at implementing a default-deny policy for every namespace where we are going to deploy applications.
For this, I am mostly looking at this page.

The policy that I have in mind for - let’s say - a namespace called “common” is the following:

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: common
spec:
  selector: all()
  types:
  - Ingress

This policy should match every application in the namespace and should block all ingress traffic not allowed explicitly.

If I apply this policy though, istio-proxy liveness probe starts failing, with errors such as:

Readiness probe failed: Get http://10.244.4.23:15021/healthz/ready: dial tcp 10.244.4.23:15021: connect: connection refused

Enabling a policy that allows ingress traffic to port 15021 fixes the specific issue, for example:

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-liveness-probe
  namespace: common
spec:
  selector: name == 'app'
  ingress:
  - action: Allow
    protocol: TCP
    destination:
      ports:
        - 15021

The problem that I am facing though is now that:

  1. Istio has multiple ports it uses, according to its documentation, should they all be allowed? For example 15006, 15090 etc.?
  2. Is it possible, and what’s the recommended way, to restrict the source for these ports that eventually need to be whitelisted? For example, the liveness probe seems to be coming from Kubelet itself, how can I limit the access to port 15021 to this only?

So I guess the question that sums up the topic is: what is a sane default-deny policy that doesn’t break not only the cluster control plane, but also istio’s own functionalities?

kubelet liveness checks shouldn’t be blocked by policy; perhaps istio is not ready because it needs to reach the pods in that namespace and it cannot.

Hey, thanks for getting back on this.

So the istio liveness probe I mentioned is the sidecar one, so as far as I understood this liveness probe is to check whether the istio sidecar itself is ready. With the policy, this fails, with a policy that allows it, it works fine.

Right now I have made a default deny that allows all istio-ports, I wonder if this is required to have istio working with all its features (including for example prometheus metrics) or if it is a sign of some misconfiguration along the way.

I have also tried to add a Log directive before the Allow directive for traffic to port 15021, but I couldn’t find such logs anywhere. Could you maybe point me to the correct direction?