Apple OSX DHCP Server Challenges

The last week, I've been experimenting with the Juniper Mobility System Software (MSS) in conjunction with two Juniper/Trapeze Access Points (type WLA522E). The MSS software is a Wireless LAN Controller (WLC) with manages the Access Points, and like so many Juniper Product; it can run in a virtual machine.

For the AP's to boot / connect to the network they need some basic information about where to find the WLC from which they receive their wireless settings. This can be done through DNS, or through DHCP. The first uses specific DNS records, and the latter uses DHCP Options (option 43 to be precise). I wanted to use the latter (which is a bit more challenging).

Experimenting with wireless LAN's (802.1x Enterprise authentication, guest networks etc.) requires several different VLAN's on the network. Something I lacked at the time, so I needed a network migration in my lab (create different VLAN's for different purposes etc.).

Using different VLAN's for different purposes meant that the VM's I have needed to be in different VLAN's. Not a problem since Apple OSX supports 802.1q on the ethernet interface. This way I could assign a specific VLAN interface to the VM in which it could communicate with the network. Communication between the VLAN's is handled by a Juniper SRX firewall.

This resulted in the following Zones/VLAN's:

  • Client VLAN
  • Server VLAN
  • Internet VLAN
  • Quarantine VLAN
  • Management VLAN
  • DMZ VLAN

Having multiple VLAN's also means that I need IP addresses on different locations. My Apple OSX server should be able to handle that (or so I thought).

Since the Server had (VLAN) interfaces in most VLAN's I used those interface to distribute the IP addresses through DHCP. Having a so-called multi-homed server isn't the most secure way, but eliminates the need for relaying DHCP requests across the network (and firewall).

After configuring the DHCP scopes on the server, I tested the DHCP service by placing DHCP client in the configured networks. These clients got the first available IP address from the scope. So I guess it worked, but I was wrong.

As soon as I added another DHCP client to that network, it also got the first available IP address from that scope. This meant that I had two clients with the same IP address in the same VLAN. And it turned out that this happened in every VLAN where I had a scope configured.
Note that the IP address came from the right scope, but for some reason the DHCP server forgot that it had leased the IP address to another client.

Through Google I found out that the DHCP Server uses a file called dhcpd_leases (located in /var/db/) to record the active IP address leases. It turned out that the file didn't get any updates since the time I had introduced the 802.1q VLAN's on the server. Possible problem identified. Restarting the DHCP service or even the entire server didn't solve the problem. Neither did deleting the file (and recreating a new empty file).

The only way to get the DHCP server running again was to limit the (active) server interfaces to 1 (one). The other interface where still configured but not in use. So I guess I still needed to use a relaying function in the network to distribute the IP addresses to the various VLAN's.

That was the first Apple OSX DHCP Server challenge. Then came the second....

As mentioned earlier the Access Point rely on DNS or DHCP information in contacting the Wireless LAN Controller. When the Access Point boots it gets the IP address from the DHCP server and I needs a specific DHCP option which tells the AP what the IP address of the WLC is.

The DHCP server of the OSX Server platform is fairly limited in what you can do with it. E.g. distributing specific options is not something that is provided in the user interface. And that is just what I need.

Another Google search lead me to the DHCP configuration file (/etc/bootpd.plist). This file can be edited (need administrative rights, AND the DHCP service should be stopped).

The bootpd.plist file is a typical Apple XML-formatted configuration file. So editing shouldn't be that hard. The Juniper documentation mentions that the value of the DHCP Option 43 should be:

ip:<IP ADDRESS #1>,<IP ADDRESS #2>, etc.

Putting one-and-one together should result in the following entry in the DHCP scope section part of the bootpd.plist file:

 <key>dhcp_option_43</key>
    <data>
        ip:192.168.1.40
    </data>

But that didn't work. Some sniffing on the switch revealed that the information was send and received, but the Access Point didn't act on the information. So there was something else....

It turns out that readable data isn't something that goes well with a DHCP server. The data transmitted with option 43 should be encoded. So the next mission reared its ugly head.

Again, after searching the Interwebs (what would we do without it) I stumbled on a (OSX) tool called the DHCP Code Option Utility [direct link, alternate link], that could encode the information in different formats. After fiddling around with the various settings I found the  setting that worked (Code Option Type: Null-terminated String).

DHCP Code Option Utility for Option 43

The final DHCP scope settings were (only one scope is displayed. Other DHCP settings are left out):

<dict>
        <key>allocate</key>
        <true/>
        <key>dhcp_domain_name</key>
        <string>lan</string>
        <key>dhcp_domain_name_server</key>
        <array>
                <string>192.168.10.1</string>
        </array>
        <key>dhcp_domain_search</key>
        <array>
                <string>lan</string>
                <string>local</string>
        </array>
        <key>dhcp_option_43</key>
        <data>
        aXA6MTkyLjE2OC4xLjQwAA==
        </data>
        <key>dhcp_router</key>
        <string>192.168.1.254</string>
        <key>lease_max</key>
        <integer>86400</integer>
        <key>lease_min</key>
        <integer>604800</integer>
        <key>name</key>
        <string>Management</string>
        <key>net_address</key>
        <string>192.168.1.0</string>
        <key>net_mask</key>
        <string>255.255.255.0</string>
        <key>net_range</key>
        <array>
                <string>192.168.1.100</string>
                <string>192.168.1.125</string>
        </array>
        <key>selected_port_name</key>
        <string>vlan4</string>
        <key>uuid</key>
        <string>9D72C2B1-ABD6-4B3F-AAEB-0C266AC98E57</string>
</dict>

With this scope, the Access Points were able to boot, get their configuration info from the WLC and accepted wireless clients.

Having figured this out leaves me with two questions;

  1. Why has the DHCP Server interface not an advanced setting for fiddling around with other DHCP settings?
    It's not that every OSX user runs an Apple OSX Server platform.
  2. Why doesn't the DHCP server work if you make it multi-homed?
Posted on August 25, 2014 and filed under Annoying, Apple, Tips'n Tricks.