31 Jan

DHCP domain-search on Juniper SRX

In the last few years, the DHCP service in enterprises got more and more integrated into complex management and provisioning systems or became a part of the Active Directory solutions. Routers, switches, wireless controllers or other devices in such networks act as DHCP Proxy instead of DHCP Servers just sending the requests to the central server. But the feature itself is not dead! Sometimes you need to run it locally and not only provide the IP address and default gateway to the client device but also DNS servers information or domain-search parameters. The last feature is an DHCP Option 119 and I put it in “tricky, non-obvious DHCP config”, together with bunch of other DHCP options.

The central point of my home and lab networks is the Juniper SRX220H – it is quite old but the services and its performance fulfills my requirements so far. One of the services it provides is DHCP Server for some of the VLANs. I was not really missing the domain-search feature so far but decided to add it to make my work more convenient. This feature configuration is not straightforward, and there are many misleading guides about setting up this feature on different platforms or operating systems. Let me show you how it works on Juniper.

What is the domain-search?

The domain-search is a DHCP protocol feature to provide the client list of the domain suffixes to search if only the hostname is known. It is different than domain-name which points just to the primary domain. The domain-name is the first position in the domain-search list. Both of them are the implementation of the DHCP Options (check the link here).

The domain-search is an RFC-standardized DHCP Option 119. If you ever worked with DHCP Options you know it can be tricky. My router runs on 12.1X46 firmware (the latest for this hardware) which supports the JDHCP CLI – this is the standard one in newer JunOS lines. However, the JDHCP CLI does not support domain-search directly via the dedicated configuration option. It was quite simple with the older JunOS CLI

[edit system services dhcp]
set domain-search [ lan virl.lan ];

Using the modern approach the DHCP server configuration is part of the access address-assignment section. But there is no command to set the domain-search parameter, so we have to configure it straightforward as Option 119

The misleading docs

The RFC3397 states that Option 119 is “a string specifying the search list”. What it does not say is the value is a hex-string, but there is a little hint in the example in this RFC document. If you google a little you will find lots of examples dedicated to Cisco or Windows. You can see examples with string encoded into hex-string. You will also find there useful link to on-line converter (I put it at the end of this article). Use it to convert the list of domains into hex-string. For me, the “lan virl.lan” after conversion is “6c616e207669726c2e6c616e0d0a”. Lets put it into the configuration.

set access address-assignment pool LAN family inet dhcp-attributes option 119 hex-string 6c616e207669726c2e6c616e

If you now capture packets on the client device you can see the response is malformed

We can see the text containing list of provided domains in raw packet output but it is not recognized by the client.

Special characters

Lets get back to the example in RFC3397 describing how the DHCP Option 119 works.

   Below is an example encoding of a search list consisting of
   "eng.apple.com." and "marketing.apple.com.":

   |119| 9 | 3 |'e'|'n'|'g'| 5 |'a'|'p'|'p'|'l'|

   |119| 9 |'e'| 3 |'c'|'o'|'m'| 0 | 9 |'m'|'a'|

   |119| 9 |'r'|'k'|'e'|'t'|'i'|'n'|'g'|xC0|x04|

You will find the full explaination of this example in RFC. Lets focus on one aspect interesting us the most. Every Option 119 entry (first cell represents the option not the value) starts with number ‘9’. This numer must equal to a number of characters provided in the single Option 119 record. The limit of the single record is 255 characters, so we will not split in our configuration.

After the ‘9’ in the first record follows number ‘3’. This value must equal the length of the following part of the domain name. So the “eng.apple.com” must be encoded as “3eng5apple3com”. The checksum numbers replace the dot. Another special case is a ‘0’, which replaces the space (0x20) separating the domains in text configuration. And finally, there must be something closing the whole hex-string. In RFC it is ‘C004’ which is a pointer to use the ‘apple.com’ defined previously again, but for us, it will be a ‘0’.

We used the characters here to make the example more clear, but remember we have to provide the hexadecimal string as our record. Because each sign is encoded by hex duplet it is quite easy to split converted text and add the required special markers. There is one more thing – we don’t provide the first number, which tells about the lengths of each part of our configuration (the ‘9’ in the example). Therefor our command will be:

set access address-assignment pool LAN family inet dhcp-attributes option 119 hex-string 036c616e00047669726c036c616e00

Lets test it

Receipe and trick

As you can see it is working now. If you need a summary what to do here is a step-by-step recipe:

  • Convert into hex string the list of domains as you put it into domain-search parameter usually. You can use this website. Remember not to start a new line in this form
  • Split the output into individual hexadecimal numbers – every two characters in the output is one hexadecimal number.
  • Replace the spaces (0x20) with 0x00, put the 0x00 at the end
  • Replace the dots (0x2e) with 0x03
  • Prepend each word with value equals to a number of characters in this word. Should be easy to identify them because now every word ends with either 0x00 or 0x03, but don’t include them in calculated number.
  • Concatenate everything so you get a hex-string

However, if you want to provide more than 2 domains it may not be easy to calculate the proper value or update it. To simplify the work and make configuration more flexible instead of using the hex-string type we can use array hex-string instead. We list there each domain separately as next array elements.

set access address-assignment pool LAN family inet dhcp-attributes option 119 array hex-string [ 036c616e00 047669726c036c616e00 ]

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: