DNS SRV support for LDAP authentication

From: Thomas Munro <thomas(dot)munro(at)enterprisedb(dot)com>
To: Pg Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: DNS SRV support for LDAP authentication
Date: 2018-09-25 02:09:08
Message-ID: CAEepm=2hAnSfhdsd6vXsM6VZVN0br-FbAZ-O+Swk18S5HkCP=A@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox
Lists: pgsql-hackers

Hello hackers,

Some people like to use DNS SRV records to advertise LDAP servers on
their network. Microsoft Active Directory is usually (always?) set up
that way. Here is a patch to allow our LDAP auth module to support
that kind of discovery. It copies the convention of the OpenLDAP
command line tools: if you give it a URL that has no hostname, it'll
try to extract a domain name from the bind DN, and then ask your DNS
server for a SRV record for LDAP-over-TCP at that domain. The
OpenLDAP version of libldap.so exports the magic to do that, so the
patch is very small (but the infrastructure set-up to test it is a bit
of a schlep, see below). I'll add this to the next Commitfest.

Testing instructions for (paths and commands given for FreeBSD, adjust
as appropriate):

1. Install BIND:

$ sudo pkg install bind99

2. Define a new zone for testing, by adding the following to the end
of /usr/local/etc/namedb/named.conf:

===== 8< =====
zone "my.test.domain" {
type master;
file "/usr/local/etc/namedb/master/my.test.domain";
===== 8< =====

3. Create that zone file in /usr/local/etc/namedb/master/my.test.domain:

===== 8< =====
$TTL 10
@ IN SOA ns.my.test.domain. admin.my.test.domain. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
IN NS ns.my.test.domain.
ns.my.test.domain. IN A
my.test.domain. IN A
ldap-server.my.test.domain. IN A
_ldap._tcp.my.test.domain. IN SRV 0 0 389
===== 8< =====

4. Start up bind:

# service named onestart

5. Confirm that SRV lookups find our record:

$ dig @localhost _ldap._tcp.my-domain.com SRV
_ldap._tcp.my-domain.com. 10 IN SRV 0 0 389

6. Tell your system libraries to use this DNS server by temporarily
changing /etc/resolv.conf to say:

===== 8< =====
===== 8< =====

7. Confirm that the OpenLDAP tools can look that SRV record up:

$ ldapsearch -H 'ldap:///ou%3Dblah%2Cdc%3Dmy-domain%2Cdc%3Dcom'

(That's "ou=blah,dc=my-domain,dc=com" URL-encoded, from which
"my-domain.com" will be extracted.) You should see that it's trying
to connect to ldap-server port 389, and you can stick 'x' on the end
of it to see what it looks like when it can't find a SRV record, as a
sanity check:

$ ldapsearch -H 'ldap:///ou%3Dblah%2Cdc%3Dmy-domain%2Cdc%3Dcomx'
DNS SRV: Could not turn domain=my-domain.comx into a hostlist

8. Set up an LDAP server listening on localhost port 389, and create
a user, such that you can actually authenticate from PostgreSQL with
it. Gory details omitted. First test that you can log in with LDAP
authentication when using a pg_hba.conf line like this:

host all fred ldap

9. Next apply the patch and verify that you can take out the hostname
and let it be discovered via DNS SRV:

host all fred ldap ldapurl="ldap:///dc=my-domain,dc=com?cn?sub"

(You can stick some elog(LOG, ...) lines into
InitializeLDAPConnection() if you want to check that
ldap_domain2hostlist() is in fact finding the hostname and port.)

This is a first draft. Not tested much yet. I wonder if
HAVE_LDAP_INITIALIZE is a reasonable way to detact OpenLDAP. The
documentation was written in about 7 seconds so probably needs work.
There is probably a Windowsy way to do this too but I didn't look into

Thomas Munro

Attachment Content-Type Size
0001-Add-DNS-SRV-support-for-LDAP-server-discovery.patch application/octet-stream 5.1 KB


Browse pgsql-hackers by date

  From Date Subject
Next Message Thomas Munro 2018-09-25 02:20:23 Re: DNS SRV support for LDAP authentication
Previous Message Michael Paquier 2018-09-25 02:08:30 Re: [patch] Bug in pg_dump/pg_restore using --no-publication