<p>By default pods can communicate with each other in Kubernetes, which is unwanted should a pod be compromised. We want to use <strong>NetworkPolicies</strong> to control inbound (ingress) and outbound (egress) traffic to/from pods.</p>
<p>Specifically pods should ONLY be able to:</p>
<ul>
<li>Egress: Call services on the internet</li>
<li>Ingress: Receive requests from the <strong>Nginx-ingress controller</strong></li>
<li>Ingress: Send logs via <strong>promtail</strong> to <strong>Loki</strong></li>
</ul>
<h2>What I have tried</h2>
<h2>1. Denying all ingress and egress</h2>
<p>This is the default policy that we want to gradually open up. It blocks all ingress and egress.</p>
<pre><code>kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny-all
  namespace: mynamespace
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
</code></pre>
<h2>2. Opening egress to internet only</h2>
<p>We allow egress only to IP-adresses that are not reserved for <strong>private networks</strong> according to <a href="https://en.wikipedia.org/wiki/Private_network#Private_IPv4_addresses" rel="nofollow noreferrer">wikipedia</a>.</p>
<pre><code>kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: egress-allow-internet-only
  namespace: mynamespace
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 10.0.0.0/8
        - 172.16.0.0/12
        - 192.168.0.0/16
</code></pre>
<h2>3. Opening Ingress from ingress controller and loki</h2>
<p>We have deployed the standard <strong>NginX Ingress Controller</strong> in namespace <strong>default</strong>, and it has the lable <strong>app.kubernetes.io/name=ingress-nginx</strong>. We have also deployed the standard <strong>loki-grafana stack</strong> to the <strong>default</strong> namespace, which uses <strong>promtail</strong> to transfer logs to <strong>Loki</strong>. Here I allow pods to recieve ingress from the <strong>promtail</strong> and <strong>ingress-nginx</strong> pods.</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: ingress-allow-ingress-controller-and-promptail
  namespace: mynamespace
spec:
  podSelector: {}
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name=default
    - podSelector:
        matchLabels:
          app.kubernetes.io/name=ingress-nginx
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name=default
    - podSelector:
        matchLabels:
          app.kubernetes.io/name=promtail
</code></pre>
<h2>So, does this configuration look right?</h2>
<p>I am new to Kubernetes, so I hope you guys can help point me in the right direction. Does this configuration do what I intent it to do, or have I missed something? E.g. is it enough that I have just blocked <strong>egress</strong> within the <strong>private network</strong> to ensure that the pods are isolated from each other, or should I also make the ingress configuration as I have done here?</p>

<p>For those curious I ended with the following network policy:</p>
<pre><code>---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-all
  namespace: &lt;K8S_NAMESPACE&gt; 
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-internet
  namespace: &lt;K8S_NAMESPACE&gt;
spec:
  podSelector: {}
  policyTypes:
  - Egress
  - Ingress
  egress:
  - to:
    - ipBlock:
        cidr: &quot;0.0.0.0/0&quot;
        except:
        - &quot;10.0.0.0/8&quot;
        - &quot;172.16.0.0/12&quot;
        - &quot;192.168.0.0/16&quot;
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: &quot;kube-system&quot;
    - podSelector:
        matchLabels:
          k8s-app: &quot;kube-dns&quot;
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-ingress-from-ingresscontroller
  namespace: &lt;K8S_NAMESPACE&gt;
spec:
  podSelector: {}
  policyTypes:
    - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: &quot;default&quot;
    - podSelector:
        matchLabels:
          app.kubernetes.io/name: &quot;ingress-nginx&quot;
---
</code></pre>
<p>It turned out that the DNS server had to be added to <strong>allow-internet</strong> and that it was not necessary to add <strong>allow-ingress-from-promtail</strong>, as promtail gets the log in another way that through ingress.</p>
