docs(dns): the origin is a tunnel, and there is nothing to cut over from

`After the move off Workers` described proxied `A` records to the host and an
ordering to avoid a gap while Worker routes were removed. Both are wrong.

There is no `A` record because there is no address to publish: each name is a
proxied CNAME to the tunnel, and the machine's address appears nowhere. And
there is no ordering problem because `api.nestri.io` and `auth.nestri.io` have
no DNS records and do not resolve — only the sandbox pair was ever deployed, so
these names are created for the first time with no window to protect.

The `nestri.link` section promised an origin certificate as the one key on our
host. There is no key on our host at all. Measured 2026-09-16: a public HTTPS
request served correctly while nothing listened on 443 or 8443 and both origins
spoke plain HTTP on loopback; the certificate was Cloudflare's, covering the
apex and one level, and a two-label name was refused at the handshake with no
certificate presented.
This commit is contained in:
Wanjohi
2026-09-16 21:57:20 +03:00
parent 15ad60bf49
commit e3c9416170

View File

@@ -67,15 +67,45 @@ property and none of the consequences, which is the point of having one.
## After the move off Workers ## After the move off Workers
Each of the four control-plane names becomes a proxied `A` record pointing at *Rewritten 2026-09-16. This said each name becomes **a proxied `A` record
the host running the containers, and nothing else about them changes: same pointing at the host**, and described an ordering to avoid a gap while Worker
names, same `iss` claim. Cloudflare keeps terminating public TLS, so there is routes were removed. Both are wrong now, and for two different reasons.*
no certificate on our own host to renew, and the origin is not addressable
except through the proxy.
The order that matters, on the day: create the `A` records with the proxy on, **There is no `A` record, because there is no address to put in one.** The
confirm the containers answer through them, *then* remove the Worker routes. control plane is reached through a Cloudflare Tunnel, so each name is a
Doing it the other way leaves a window where the name resolves to nothing. **proxied `CNAME` to `<tunnel-uuid>.cfargotunnel.com`** — a target that resolves
to nothing publicly and only means something inside Cloudflare. The machine's
own address appears in no record anywhere, which is the point: an `A` record is
a published address, and a published address is a thing that can be reached
around the proxy and flooded off the internet.
| Name | Record | Ingress rule on the machine |
| --- | --- | --- |
| `api.nestri.io` | `CNAME``<uuid>.cfargotunnel.com`, proxied | `http://127.0.0.1:3000` |
| `auth.nestri.io` | `CNAME``<uuid>.cfargotunnel.com`, proxied | `http://127.0.0.1:1337` |
| `*.nestri.link` | `CNAME``<uuid>.cfargotunnel.com`, proxied | `http://127.0.0.1:8443` — whatever serves box hostnames |
One tunnel serves all three, including the two zones, because a tunnel belongs
to the **account** and not to a zone. Measured 2026-09-16, both zones at once,
from one connector.
**The ordering problem does not exist, because there is nothing to cut over
from.** Checked on 2026-09-16: `api.nestri.io` and `auth.nestri.io` have no DNS
records and do not resolve. Only the *sandbox* pair was ever deployed, and it is
discarded by the move. So these names are created for the first time, pointing
at the tunnel, with no window in which anything is worse than it was.
Two things that are true of a tunnel and were not true of a proxied origin:
- **The record can be created before the machine exists, and it is harmless.**
A `CNAME` to a tunnel with no connector running answers with Cloudflare's own
error rather than resolving to somebody else's server — so the name is never
pointed anywhere it should not be, even for a minute. *Asserted, not measured:
the 2026-09-16 run only ever had the records and the connector up together.*
- **The zone must stay proxied — and here the failure is worse than before.**
An unproxied `CNAME` to `cfargotunnel.com` resolves to nothing at all. This
is the same *"pausing Cloudflare is an outage, not a fallback"* the origin
certificate used to imply, and it survives the certificate's removal.
## `nestri.link` ## `nestri.link`
@@ -87,6 +117,23 @@ content we do not write, and cookie scope is a property of the registrable
domain, so a name under `nestri.io` would put that content inside the same domain, so a name under `nestri.io` would put that content inside the same
cookie boundary as sign-in. cookie boundary as sign-in.
`*.nestri.link` will be proxied for the same reason the control plane is: the `*.nestri.link` is proxied for the same reason the control plane is: the public
public certificate stays Cloudflare's, and the only key on our own host is an certificate stays Cloudflare's. ~~and the only key on our own host is an origin
origin certificate that is useless anywhere else. certificate that is useless anywhere else~~*corrected 2026-09-16:* **there is
no key on our own host at all.** TLS terminates at Cloudflare and the tunnel
reaches whatever serves these hostnames over loopback, so the origin certificate
this sentence promised is not obtained, not stored, and not renewed.
Measured the same day, and the negative is the useful half: a public HTTPS
request to `m123.nestri.link` was served correctly while nothing on the machine
listened on `443` or `8443` and both origins spoke plain HTTP on `127.0.0.1`.
The certificate presented was `O=Google Trust Services, CN=WE1`, `SAN:
nestri.link, *.nestri.link` — issued by Cloudflare on a zone that held zero DNS
records, without being asked.
**One level, and it fails before HTTP.** That SAN covers `nestri.link` and
`*.nestri.link` and nothing deeper, so `deep.a.nestri.link` is refused with a
TLS `handshake failure` and **no certificate presented**. Not a `404` — nothing
reaches an application, so no application log will explain it. This is why
`box_id` is a single DNS label and why a two-label scheme costs $10/mo for
Advanced Certificate Manager rather than being free.