Binding an OS X client to an LDAP server is pretty simple, but when it’s time to scale up, Apple wants us to use proxy servers and load balancers to offer failover and redundancy. This is by far the best approach, but sometimes setting up such a front-end for a cluster of servers is time or cost prohibitive depending on the scope of the project and the size of your fleet. In this case, it would be easier to simply have the OS X clients authenticate to a single server, using a list of trusted replica servers as a failover for when that primary server is unreachable for any reason. RFC4512 defines a LDAP attribute called
altServer, and we can use that attribute to configure exactly such a setup.
The RFC defines the
altServer attribute as follows:
The ‘altServer’ attribute lists URIs referring to alternative servers
that may be contacted when this server becomes unavailable. URIs for
servers implementing the LDAP are written according to [RFC4516].
Other kinds of URIs may be provided. If the server does not know of
any other servers that could be used, this attribute will be absent.
Clients may cache this information in case their preferred server
later becomes unavailable.
I won’t go into detail about how to set up the attribute on the server-side because this is usually done for you when you setup a master/replica scenario. Instead, I’ll focus on the OS X client. I spoke with an Apple engineer about this topic, and as far as we were able to tell, OS X has been aware of the altServer attribute since at least 10.6; probably earlier. However, it’s been ignoring this attribute that whole time. Sometimes you’ll even see a log message in /var/log/opendirectoryd.log that says
skipping altServer replica check - disabled. Fortunately, enabling the altServer replica check attribute is very simple, especially since
odutil showed up.
OS X 10.7+
sudo odutil set configuration /LDAPv3/ldap.example.com module \ ldap option "Use altServer replicas" "true"
OS X 10.6 (YMMV / untested)
- After binding and rebooting a client, edit /Library/Preferences/DirectoryServices/DSLDAPv3PlugInConfig.plist
- Navigate towards the end of the file and look for the following key/string pair:
Template Search Base Suffix dc=server,dc=company,dc=com
- Append the following after the key/string pair above:
Use altServer replicas
- Reboot or restart DirectoryService to read in the change
sudo killall DirectoryService
How might you simulate an unreachable server while making sure the replica servers are still reachable for the purposes of testing? The easiest way that I’ve found is to use
ipfw, OS X’s built-in firewall.
# replace 18.104.22.168 with your primary LDAP server's IP sudo ipfw add deny all from 22.214.171.124 to any in
This will make a temporary rule that should allow the client to make requests to your LDAP server while blocking the responses, which is exactly the scenario we wanted to test. So now that the server-down-simulation is up and running, try logging into the computer at the login window. If you can’t login, check /var/log/opendirectoryd.log for clues. Once you’re in, you can see which replica server you’re connected to by running
netstat | grep ldap
To undo this firewall rule, either reboot the computer, or run
# `sudo ipfw list` will show the real rule index, but unless you've # added others, it's going to be '00100' sudo ipfw delete 00100
As mentioned earlier, the preferable solution would be to hide a cluster of LDAP servers behind load balancers, LDAP proxies, DNS Round Robin, and so on. However, this alternative method can be just as good for smaller deployments. Whether you’re able to do it the “right” way or The Other Way™, the result is the same: your primary authentication server can crash and your fleet will continue running as if nothing happened as long as your replicas didn’t crash with it. This also adds a bit of a safety net to the process of applying server patches.
No matter how you do it, do it; your Help Desk and customers will thank you.