Site icon LDAP.com

DNS SRV Records for LDAP

Most LDAP clients need to be explicitly configured with the addresses of the LDAP servers to use. However, RFC 2782 describes an alternative way of figuring out what directory servers are available: DNS SRV resource records, also called DNS service records. If a network’s DNS servers have been configured with the appropriate records, then clients that support this feature can automatically discover the LDAP servers that they should use.

A DNS SRV resource record has a number of components, including:

Configuring DNS SRV Records in BIND9

In the BIND9 nameserver, you can configure SRV records in the file that defines the zone for name-to-address lookups for the desired domain.

As an example, let’s say that we have the following:

The records you would use to describe this configuration in a BIND9 zone file would look like:

_ldap._tcp.example.com. IN SRV 10 50 389 ds1.example.com.
_ldap._tcp.example.com. IN SRV 10 50 389 ds2.example.com.
_ldap._tcp.example.com. IN SRV 20 75 389 ds3.example.com.
_ldap._tcp.example.com. IN SRV 20 25 389 ds4.example.com.

Testing DNS SRV Records From the Command Line

If you’ve got these records configured properly, then you should be able to check that with either the nslookup or dig command-line tools. For nslookup (at least on Linux; the command might be different on other operating systems), the command should look like:

$ nslookup -type=SRV _ldap._tcp.example.com
Server:        127.0.0.1
Address:    127.0.0.1#53

_ldap._tcp.example.com    service = 20 25 389 ds4.example.com.
_ldap._tcp.example.com    service = 10 50 389 ds1.example.com.
_ldap._tcp.example.com    service = 20 75 389 ds3.example.com.
_ldap._tcp.example.com    service = 10 50 389 ds2.example.com.

Using the dig client, the command and output are more like the following:

$ dig SRV _ldap._tcp.example.com

; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> SRV _ldap._tcp.example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20541
;; flags: qr aa rd; QUERY: 1, ANSWER: 4, AUTHORITY: 1, ADDITIONAL: 6
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;_ldap._tcp.example.com.        IN    SRV

;; ANSWER SECTION:
_ldap._tcp.example.com.    10800    IN    SRV    10 50 389 ds2.example.com.
_ldap._tcp.example.com.    10800    IN    SRV    20 25 389 ds4.example.com.
_ldap._tcp.example.com.    10800    IN    SRV    20 75 389 ds3.example.com.
_ldap._tcp.example.com.    10800    IN    SRV    10 50 389 ds1.example.com.

;; AUTHORITY SECTION:
example.com.        10800    IN    NS    ns.example.com.

;; ADDITIONAL SECTION:
ds1.example.com.    10800    IN    A    10.0.2.1
ds2.example.com.    10800    IN    A    10.0.2.2
ds3.example.com.    10800    IN    A    10.0.2.3
ds4.example.com.    10800    IN    A    10.0.2.4
ns.example.com.        10800    IN    A    10.0.2.15

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Jan 23 01:48:25 CST 2019
;; MSG SIZE  rcvd: 288

This includes a lot of helpful output, but you can add “+short” to the end of the command to get a much more concise version of the output, like:

$ dig SRV _ldap._tcp.example.com +short
10 50 389 ds1.example.com.
20 75 389 ds3.example.com.
10 50 389 ds2.example.com.
20 25 389 ds4.example.com.

Note that with either tool (or any other type of DNS client), if you’ve got your search path configured properly, it should be possible to leave off the domain and just specify the name of the service (for example, just “_ldap._tcp” instead of “_ldap._tcp.example.com”).

Using DNS SRV Records in LDAP Clients

Obviously, DNS SRV records aren’t very useful if nothing can use them. To be honest, a lot of software doesn’t support them, and in such cases, you just have to manually configure them to specify which servers to use.

But of the software that does support them, the way that you use them may vary from one type of client to another. In some cases, it may be that the client will just automatically send a DNS query for “_ldap._tcp” if you don’t give it any information about which LDAP server to use.

In other cases, you might have to explicitly indicate it in some way. For example, in the OpenLDAP version of the ldapsearch tool, you can use the “-H” argument followed by an LDAP URL that specifies the protocol, host, and port to use (like “-H ldap://ds.example.com:389/”). However, it also allows you to specify an LDAP URL without the host or port but that uses a base DN that uses only “dc” components (with special characters escaped, like %3D in place of an equal sign and %2C in place of a comma) to indicate that the tool should request the “_ldap._tcp” record for the specified domain (for example, “-H ldap:///dc%3Dexample%2Cdc%3Dcom” will cause it to look up the SRV records for “_ldap._tcp.example.com” and select an appropriate server from that response).

If you’re writing your own LDAP client and want to build support for DNS SRV records into it, then you may need to query DNS directly using whatever facility your programming language of choice might allow. However, the LDAP API that you’re using might also have special support for DNS SRV records. For example, the UnboundID LDAP SDK for Java provides a DNSSRVRecordServerSet class that can do all the work for you, including providing support for priorities and weights.

Using DNS SRV Records With LDAP Over TLS

One of the limitations of using DNS SRV records for LDAP is that these records don’t provide any way to indicate whether the client should use any kind of transport-layer security when contacting the server. It is strongly recommended that you always communicate over a secure channel, but there are a couple of possibilities that you can consider when you want to use DNS SRV records.

One option would be to define records for “_ldaps._tcp” instead of or in addition to “_ldap._tcp”. If you do that, and a client wants to establish a secure connection, then it could request the SRV records for “_ldaps._tcp” and then assume that it needs to perform TLS negotiation on the connection before sending any LDAP requests. This is certainly a workable solution, but it does require that the client have support for this feature and know that it should use the “_ldaps._tcp” variant.

Another option would be to go ahead and establish an insecure connection to one of the servers returned in response to the “_ldap._tcp” request, but then to immediately use the StartTLS extended operation to convert that insecure connection to a secure one. Again, this does require that the client know that it should do this, but it may be possible to indicate that through configuration options. However, this approach should be used with caution because if the client doesn’t actually send the StartTLS request after establishing the connection, then any LDAP requests and responses that get transferred over that connection will be in the clear.

Exit mobile version