Learn Calico - Host Endpoint & Node Security
Series/Learn Calico/Episode 14
Episode 14 of 23

Learn Calico - Host Endpoint & Node Security

This episode covers HostEndpoint: protecting the Kubernetes nodes themselves, policy for node-bound traffic, locking down management ports, applying policy to host VMs, and managing node-to-node connections.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

So far all the policies protect pods. But the Kubernetes nodes themselves — kubelet, API server, SSH, and other management ports — also need protection. Who limits SSH access to the nodes? In most clusters, the answer is "nobody" until an external firewall steps in.

Episode 14 introduces HostEndpoint: Calico's way to protect the host interfaces themselves. With this, the security you've built for pods extends to the nodes, in the same policy model.

HostEndpoint

What Is a HostEndpoint

A HostEndpoint is a representation of a network interface on a node, complete with labels and expected IPs. Once created, all policies that select the host endpoint labels apply to traffic entering or leaving that interface. The simplest pattern — tag the main interface of every node:

HostEndpoint for all nodes
apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
  name: eth0-all-nodes
  labels:
    host-endpoint: eth0
spec:
  node: '*'
  interfaces:
    - eth0
  expectedIPs:
    - 172.18.0.0/16

node: '*' matches all Calico nodes. This endpoint tags the eth0 interface as a security unit that policies can select.

Creating It with calicoctl

Create a host endpoint
calicoctl apply -f eth0-all-nodes.yaml
calicoctl get hostendpoint -o wide

calicoctl get hostendpoint shows the host endpoints with their nodes and interfaces. If the columns are empty, the node selector isn't matching.

Policy for Node-Bound Traffic

Host Endpoint Selectors

Policies targeting host endpoints use the selector on hostEndpoints (not selector which is for workloads):

Allow SSH only from the office
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: security-allow-ssh-office
spec:
  tier: security
  order: 100
  selector: host-endpoint == 'eth0'
  types:
    - Ingress
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: office-ip == 'true'
      destination:
        ports:
          - 22

With the global default deny from episode 6, this policy ensures SSH can only enter from tagged sources. Other traffic to port 22 is denied.

Tagging Trusted Sources

The "office-ip" source can be defined once as a GlobalNetworkSet (episode 6), for example calicoctl apply -f office-nets.yaml with the nets 203.0.113.0/24 and the label office-ip: true. The policy and the set work without touching the node firewall — everything is handled by Felix.

Locking Down Management Ports

Critical Port List

For production, the ports that must be considered for lockdown: SSH (22), kubelet (10250), API server (6443), node-exporter (9100), and other Kubernetes ports. Here's a policy example for inbound API server traffic only from the admin subnet:

Lock down the API server
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: security-allow-apiserver-admin
spec:
  tier: security
  order: 110
  selector: host-endpoint == 'eth0'
  types:
    - Ingress
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: admin-nets == 'true'
      destination:
        ports:
          - 6443

Test Before Locking Yourself Out

The most important warning in this episode: host endpoint policy can lock you out of your own nodes. Always test carefully and provide a recovery path — for example, a break-glass policy from the jump host subnet with the smallest order. After applying, make sure kubectl get nodes still shows the nodes and the kubelet is still connected.

Policy to Hosts and Node-to-Node

Workload-to-Node Traffic

Sometimes workloads need to access the nodes — for example, for metrics. Create a policy that selects the host endpoint as the destination:

Allow workloads to node-exporter
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: platform-allow-node-exporter
spec:
  tier: platform
  selector: host-endpoint == 'eth0'
  types:
    - Ingress
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: app == 'prometheus'
      destination:
        ports:
          - 9100

Node-to-Node

Inter-node traffic (kubelet to kubelet, for example) needs to be explicitly allowed when nodes are tightened:

Allow node-to-node
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: security-allow-node-to-node
spec:
  tier: security
  order: 90
  selector: host-endpoint == 'eth0'
  types:
    - Ingress
    - Egress
  ingress:
    - action: Allow
      source:
        selector: host-endpoint == 'eth0'
  egress:
    - action: Allow
      destination:
        selector: host-endpoint == 'eth0'

The order: 90 — smaller than the default deny's order (100) — lets node-to-node traffic be allowed before the deny is evaluated.

Conclusion

Episode 14 extends Calico security to the nodes: HostEndpoint as the host security unit, policy for management ports, and management of workload-to-node and node-to-node traffic in a single policy model.

Key takeaways:

  • HostEndpoint tags a node interface as a policable unit.
  • The hostEndpoints selector selects host endpoints, not workloads.
  • Management ports like 22 and 6443 must be locked down with policy.
  • Host endpoint policy can lock you out — prepare a break-glass path.
  • Workload-to-node traffic is managed with policy targeting host endpoints.
  • Node-to-node must be explicitly allowed with an order before the default deny.

In the next episode, episode 15, we cover encryption and advanced network security — WireGuard for node-to-node traffic encryption, combining it with encapsulation, and composing a layered security posture that combines network, host, and workload.

Learn Calico - Host Endpoint & Node Security | Learn Calico