← All work

Migrating 20 public services across a subnet renumber

A LAN renumber invalidated routing for every published hostname at once. DNS looked correct while every route was dead — finding the real failure layer took separating three independent config surfaces.

Cloudflare TunnelZero TrustDNSTraefikLinux
Role
Sole engineer
Result
23 ingress rules repointed · 20/22 hostnames verified live

Context

A homelab serving roughly twenty self-hosted applications was renumbered from one private /24 to another. Every public hostname was published as a CNAME to a Cloudflare Tunnel, so the DNS zone itself stayed perfectly valid — which is precisely what made the outage confusing.

Constraints

  • No maintenance window — the services were in active daily use.
  • The tunnel ingress is managed remotely by Cloudflare; the local config file on the connector looked authoritative but was ignored.
  • A malformed ingress update replaces the entire route table for every hostname simultaneously.

Decisions

Audit the routing layer, not the zone

A DNS audit came back clean, which was a false negative: every ingress rule carried a hardcoded origin address while every published record was a CNAME to the tunnel. The lesson was to sweep origin addresses, not record types.

Snapshot before mutating

The full ingress array was exported to disk before any change. Because a PUT replaces all rules at once, a single bad edit can take down every hostname and the API will not say which rule was wrong.

Reconcile in both directions

Leftover rules pointing at dead services and DNS records with no matching rule both present identically — as the catch-all 404. Each direction had to be enumerated separately to account for every hostname.

Outcome

  • Ingress reduced from 24 to 23 rules, every origin repointed to the new subnet.
  • 20 of 22 hostnames verified end-to-end; the remaining two were origin service failures, not routing failures — confirming the edge was correct.
  • Established a rule that a 502 means routing is fixed and the origin is down, while a 404 means no rule matched. That single distinction cut future diagnosis time significantly.

What it taught me

A clean DNS audit is not evidence that routing works. When a layer reports success, verify the layer beneath it with a direct probe rather than trusting the status code.

Addresses, hostnames and identifiers in this write-up are abstracted or generalised. If you would like the specific detail, ask — I am happy to walk through it directly.

← Back to all work