Files
Johnathan Corgan 6ccd30416e Screen the gateway's DNS queries and copy RD and CD into its replies
The gateway's forwarder answered anything simple-dns could parse. A
response for a name outside .fips drew a REFUSED back, so a forged
datagram could set the gateway and another DNS server answering each
other without end; a response for a .fips name was even forwarded to
the daemon and minted a pool address. A query of several questions got
every question back, about twice its size when a later name pointed
into an earlier one's bytes. Query types simple-dns does not know, a Z
bit or an unusual class got no reply at all, and replies never carried
RD.

The forwarder now runs every datagram through the same screen as the
.fips responder before it does anything else: responses, text,
datagrams not shaped like a query and datagrams from service ports get
no reply; a non-QUERY opcode gets NOTIMP, a malformed question FORMERR
and a class other than IN or ANY REFUSED. Replies are built fresh with
the client's ID, RD and CD, RA, the one question byte for byte and only
the records the gateway produced. Any query type for a .fips name is
forwarded, and every type but AAAA and ANY ends in NODATA.

A relayed NXDOMAIN now carries the same SOA as NODATA, so LAN resolvers
cache it for gateway.dns.ttl. A name that becomes resolvable at runtime
can therefore stay NXDOMAIN to them that long after a failed lookup.
The SOA of a negative answer is owned by the zone apex rather than the
query name, with its names compressed against the question, so NODATA
stays 75 bytes for a short name. The relayed rcode is read from the
upstream header directly.

The upstream query always asks class IN, and per-query upstream
failures (bind, connect, send, receive, timeout, a non-mesh answer) log
at debug level, since while the daemon is down every LAN query would
otherwise log a warning.

The gateway design document's DNS resolution flow now describes the
screen and the SOA on a relayed NXDOMAIN.
2026-10-10 13:27:48 +00:00
..