Locking the cluster behind the jump: ufw without the foot-gun
The admin path is one jump host; this is the firewall layer that makes that statement true. The whole trick is ordering — and one kubernetes-specific detail that quietly bites everyone.
First: let Kubernetes forward
Ubuntu ships ufw with DEFAULT_FORWARD_POLICY="DROP", which silently breaks pod traffic that traverses a node. Fix before anything else:
sudo sed -i 's/DEFAULT_FORWARD_POLICY=.*/DEFAULT_FORWARD_POLICY="ACCEPT"/' /etc/default/ufw
The rules
sudo ufw allow in from 10.22.50.0/24 # nodes: etcd, kubelet, VXLAN
sudo ufw allow in from 10.22.10.120 # jump: SSH + API
sudo ufw allow in from 10.22.10.50 # break-glass springboard
sudo ufw deny in 2379,2380 # etcd: nodes only
sudo ufw deny in 22
sudo ufw deny in 6443
sudo ufw enable
Why the order is the whole article
UFW is first-match-wins. The three allows match their sources and stop; the two denies only ever catch everyone else. Move a deny above the allows and you have silently locked out your own jump host. Note what is not listed: web, DNS and node ports stay reachable, because the INPUT policy itself is left permissive — the deny lines are targeted, not a blanket.
Operating discipline
Apply per node, one at a time, with an SSH session already open (ufw keeps established connections alive). Verify before closing it: from the jump kubectl get nodes is green, from anywhere else port 22/6443 on the node answers refused, and the public services are untouched. Rollback is one command on the offending node — sudo ufw disable — which is exactly why this change is allowed to be boring.
Keep the etcd deny in even though the nodes are already trusted: defense in depth costs one line, and 2379 is the root of the whole cluster.