← Recipes

阅读中文版本

Block Unnecessary Outbound Egress

Apply a default-deny egress policy so a compromised workload cannot reach arbitrary hosts on the internet.

~35 minkubernetessecuritynetwork

Task

Restrict namespace egress to an allowlist of required destinations with a network policy.

When to use this

A workload is compromised and immediately reaches a command-and-control server because egress is unrestricted.

Prerequisites

  • A CNI that supports network policies
  • An inventory of required egress destinations
  • A staging namespace to test

Steps

1. Deny all egress by default in the namespace.

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

Expected output: Workloads cannot reach anything not explicitly allowed.

2. Allow only required destinations such as the database and DNS.

spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              name: data
      ports:
        - protocol: TCP
          port: 5432

Expected output: Only the database port is reachable, matching the allowlist.

Troubleshooting

Problem

DNS breaks after default deny

Solution

Explicitly allow UDP and TCP 53 to the cluster DNS service.

Problem

Policy not enforced

Solution

Confirm the CNI actually supports network policy and that the namespace is selected.

Limitations

  • Does not cover traffic outside the cluster boundaries.
  • Requires an accurate destination inventory.
  • Policy support varies by CNI.

What this recipe does

Restrict namespace egress to an allowlist of required destinations with a network policy.

A workload is compromised and immediately reaches a command-and-control server because egress is unrestricted.

Prerequisites

  • A CNI that supports network policies
  • An inventory of required egress destinations
  • A staging namespace to test

Procedure

  1. Deny all egress by default in the namespace.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
spec:
  podSelector: {}
  policyTypes:
    - Egress

Expected result: Workloads cannot reach anything not explicitly allowed.

  1. Allow only required destinations such as the database and DNS.
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              name: data
      ports:
        - protocol: TCP
          port: 5432

Expected result: Only the database port is reachable, matching the allowlist.

How to confirm it worked

Run the commands above and confirm every expected result in order. If a step does not produce the stated output, use the troubleshooting notes before continuing. A passing run shows the workload reaches only allowlisted destinations and a test connection to an arbitrary host times out.

Troubleshooting

DNS breaks after default deny — Explicitly allow UDP and TCP 53 to the cluster DNS service.

Policy not enforced — Confirm the CNI actually supports network policy and that the namespace is selected.

Limitations

  • Does not cover traffic outside the cluster boundaries.
  • Requires an accurate destination inventory.
  • Policy support varies by CNI.