Files
fips/src/gateway
Johnathan Corgan 210debc583 Validate gateway DNS answers before they become a NAT mapping
The gateway's DNS forwarder accepted whatever datagram arrived on its upstream
socket as the answer. It reused the client's own transaction ID in the upstream
query, bound that socket to a wildcard address, received with a call that
discards the sender, never compared the response ID or the question section
against what it asked, and never checked that the returned address was inside
the mesh prefix. The address it extracted is installed as a DNAT rule that
carries no interface constraint, so a forged answer redirected traffic rather
than merely poisoning a lookup.

Four changes close it. The upstream query now carries a freshly drawn random
transaction ID rather than the client's. The upstream socket is connected to
the resolver before use, so the kernel drops datagrams from anyone else. A
parsed response must be a response, carry the same ID, carry exactly one
question matching the qname and qclass that were sent, and be for AAAA;
anything else is discarded and the receive continues against the original
deadline instead of accepting the first datagram to arrive. The extracted
address goes through the validating address parser rather than a comment
asserting the prefix byte, and a non-mesh answer is refused before any pool
allocation, so no mapping event is emitted and no rule is installed.

The validation sits before the rcode check, which changes one behaviour worth
naming: an upstream that answers FORMERR or REFUSED with an empty question
section no longer has that rcode relayed to the client and gets SERVFAIL
instead. Checking after the rcode would let a forged NXDOMAIN through, so the
placement is deliberate.

Connecting the socket also fixes the dead-upstream half of the availability
problem in the same loop, since a connected socket surfaces ECONNREFUSED
immediately instead of stalling to the five second timeout. The serve loop
still handles one query at a time; that half is untouched here.

The tests drive real queries through a fake upstream: a foreign source
injecting a well-formed answer, a wrong transaction ID, a wrong question, a
non-mesh address, and the healthy path as an over-rejection guard. Each was
checked by reverting the corresponding fix and confirming the intended test
reds alone.
2026-08-11 15:37:51 +00:00
..
2026-04-09 16:53:32 +00:00
2026-04-15 05:04:37 +00:00
2026-04-10 08:47:02 +00:00