---
id: w1/m19/t005
title: Terraform: label-selector port firewall (public ingress = 80/443/6443/22 only)
worker: worker1
status: done
estimate: 30m
depends_on: []
---

## Objective

Close the public exposure at the Hetzner layer: a Cloud Firewall applied by label selector to all CAPH-owned machines, allowing inbound only what the architecture needs on public IPs. Ports-only restriction - explicitly NOT the DO_NOT_DO-rejected static source-IP allowlist.

## Context

- CAPH labels its servers (selector: `caph-cluster-bex`); label-selector firewalls auto-apply to future machines (autoscaler-created workers included).
- East-west (VXLAN 8472/udp, kubelet 10250, etcd 2379, NodePorts) moves to the private net after t002/t006 - the firewall only needs to admit: 22/tcp (key-only SSH baseline), ICMP; the LBs talk to nodes over the PRIVATE net so public node ports for 80/443/6443 are NOT needed.
- The LB public fronts (Traefik 80/443, kube-api 6443) are on the LBs, not the nodes - no firewall entry needed for them.

## Steps

1. Add `hcloud_firewall` with `apply_to { label_selector = "caph-cluster-bex" }` in infra/terraform/main.tf; rules: in tcp/22, icmp; all else denied by default.
2. `terraform plan` reviewed; apply happens in t006's window (firewall on live single-CP cluster would cut current public east-west paths - the hybrid worker talks to the CP over public today).

## Files

- infra/terraform/main.tf (+ variables/outputs as needed)

## Acceptance criteria

- [x] `terraform plan` shows the firewall resource with label-selector apply and the 22/icmp-only ruleset. _2026-07-10: `hcloud_firewall.app_nodes` written (label selector `caph-cluster-bex`, in-rules 22/tcp + icmp only, DO_NOT_DO distinction documented inline); **applied by infra.yml (green, terraform apply -auto-approve) at 21:31Z, live through the t006 rebuild.**_
- [x] After t006: `nmap`-style scan of a node public IP from outside shows only :22 open. _2026-07-11: verified against tenant node `46.225.152.95` — `:22` open only; `:6443/:10250/:2379/:8472/:30080/:5000` closed/filtered. Evidence recorded in t009's pre-verified list._

## Out of scope

- Source-IP restrictions of any kind (DO_NOT_DO); infra-cluster firewall (node gets destroyed in t007).
