Summary

  • RFC 3397 assigned DHCP option 119 to an ordered DNS domain-search list and nested two reconstruction rules: RFC 3396 first joined option fragments, then RFC 1035 pointers rebuilt names inside the complete aggregate.
  • The search list acted before DNSSEC. A hostile but accepted suffix could redirect a short name to another domain whose records were legitimately signed, producing an authentic answer to a question the user never intended.

The green lock was never the whole story. Long before a resolver could validate a DNS response, something had to decide which fully qualified domain name to place in the question. When a user typed a short name such as myhost, the missing suffix was policy. RFC 3397 gave a DHCP server a standard way to supply that policy.

Published on the Standards Track in November 2002, RFC 3397 defined the DHCP Domain Search option and assigned it code 119. Its job was narrow: configure the ordered list of DNS domains used when resolving hostnames. It did not choose between DNS and other naming systems. That distinction mattered because RFC 2937 had defined a different option for ordering name services. Option 119 governed suffixes inside DNS alone.

The wire format had to conserve space. Its Searchstring was not a row of printable domains but a concatenation of DNS names in RFC 1035 label form. A repeated suffix could be replaced with a two-octet compression pointer to its earlier occurrence. If two search domains ended in apple.com., the second did not need to carry those labels again.

The pointer's address space was local and exact. Offset zero meant the beginning of option 119's data, excluding the option code and length octets. A pointer was not a DNS referral, a network address or a link to another packet. It referred backward within the one logical option-data block that the client was decoding.

That block might not exist physically in one place. RFC 3397 invoked RFC 3396, published alongside it, so a long value could arrive in several instances of option 119. The receiver first concatenated every data portion in the required aggregate order. Only then could it follow RFC 1035 compression pointers. A pointer was allowed to cross a fragment boundary because its coordinate system was the completed aggregate, not any individual DHCP field.

The RFC's worked example made this layering visible. It encoded eng.apple.com. followed by marketing.apple.com. and divided the bytes among three option instances. The second name ended with C004, a pointer to aggregate offset four, where apple.com. began. Interpreting any fragment on arrival would make that address meaningless. Reassembly was not an optimization; it was a precondition for naming.

Termination rules prevented an incomplete byte stream from becoming an invented domain. Every search name had to reach either the zero-length root label or a valid two-octet pointer. If the aggregate ended in the middle of a name without either terminator, the client had to discard that partial name. Possessing most labels was not permission to guess the rest.

Once decoded, the list changed how incomplete user input became a DNS question. RFC 3397 drew on resolver-security guidance in RFC 1535 and RFC 1536. Search lists should be explicit, not inferred from a host's name. A string containing a dot should first be tried as a fully qualified name and only after failure with local search domains appended. A string containing no dots could receive search suffixes immediately.

That order exposed the control surface. A person could enter myhost expecting the resolver to try myhost.bigco.com. A rogue DHCP server could instead install roguedomain.com and cause the machine to ask for myhost.roguedomain.com. The redirection occurred before the authoritative DNS server replied and before a validating resolver examined signatures.

RFC 3397's sharpest sentence was that DNSSEC did not avert this attack. The rogue domain could publish its own records and sign them correctly. DNSSEC could then establish that the returned data was authentic for myhost.roguedomain.com. It could not establish that myhost.roguedomain.com was the name the user, administrator or application meant to reach.

This was not a cryptographic failure. It was a separation of authorities. DHCP acceptance governed whether the search list entered the machine. Resolver policy governed which suffix was tried. DNS supplied records for the resulting name. DNSSEC authenticated those records. The application then decided what to do with the address. Evidence from the last stage could not retroactively authorize the first.

The RFC considered suffix manipulation more fruitful than merely supplying an illegitimate DNS-server option. An attacker did not need a visibly strange resolver or forged answer. Ordinary authoritative infrastructure for a domain the attacker controlled could answer the redirected query. Every DNSSEC check might pass while the semantic destination had changed one step earlier.

Its mitigations therefore addressed provenance as well as parsing. Implement the resolver behavior described by RFC 1536. Do not let DHCP overwrite manually configured DNS parameters. Where appropriate, require DHCP authentication before accepting option 119. Each measure reduced an avenue of unauthorized policy, but none allowed an operator to collapse all receipts into a single word such as “secure.”

Authentication itself had limits. RFC 3118 could authenticate DHCP messages, but a valid DHCP credential proved the message came from an accepted principal, not necessarily that its suffix matched a particular user's intention. Manual precedence proved which configuration won, not that an application used the resulting name. Packet receipt proved delivery, not acceptance. DNSSEC proved answer authenticity, not query provenance.

This is why operational evidence must preserve the chain. Start with the short input. Record the active manual and learned search lists, their order and provenance. Preserve option 119's raw instances and their RFC 3396 aggregate. Record decoded names, pointer targets and invalid-name decisions. Then preserve each candidate FQDN, the query actually sent, the DNSSEC result, the returned address and the application connection.

Without those layers, a successful lookup is ambiguous. A capture containing option 119 does not show that the client accepted it. A decoded list does not show which suffix was tried. A DNS query does not expose the user's original text. A validated answer does not show why that query was constructed. And an application log containing an address may have lost the name altogether.

The IANA BOOTP/DHCP parameters registry records code 119, which establishes coordinated assignment rather than deployment or correctness. The RFC Editor's current search reports no matching errata for RFC 3397. Neither fact is running evidence that an implementation concatenates fragments before decompression, rejects unfinished names, respects manual precedence or records the chosen suffix.

Lu Heng's Minimum Initial Specification principle explains the document's economy. RFC 3397 defined the smallest shared wire and decoding contract: one DNS-only list, one aggregate-relative pointer space and explicit termination. It left local interfaces, storage and resolver internals to implementations. Coordination occurred at the boundary where independent machines had to agree.

Running-Code Primacy supplies the harder test. Feed a client split option instances whose compression pointer crosses the cut. Observe the exact aggregate, decoded order, rejected malformed tail, candidate-name sequence and emitted DNS packet. Change manual precedence and DHCP authentication state. A parser test alone cannot prove the behavior that determines where the connection goes.

RFC 3397 is therefore a history of a question, not merely an option. It shows that authenticity attaches to a named object after another layer has selected that object. A signed answer may be wholly true. The unanswered question is who chose the name that was allowed to become true.

Sources