From c228f39fa62c98af4e6b077dc0746c6f8029cad7 Mon Sep 17 00:00:00 2001 From: Matthieu Cerda Date: Thu, 26 Oct 2017 10:39:47 +0200 Subject: [PATCH] Add STARTTLS support --- README.md | 5 ++++- nginx-ldap-auth-daemon.py | 19 +++++++++++++++++++ nginx-ldap-auth.conf | 14 +++++++++++--- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8ae1568..fba94f4 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,10 @@ For detailed instructions, see [Configuring the Reference Implementation](https: proxy_cache_valid 200 10m; # URL and port for connecting to the LDAP server - proxy_set_header X-Ldap-URL "ldaps://example.com:636"; + proxy_set_header X-Ldap-URL "ldap://example.com"; + + # Negotiate a TLS-enabled (STARTTLS) connection before sending credentials + proxy_set_header X-Ldap-Starttls "true"; # Base DN proxy_set_header X-Ldap-BaseDN "cn=Users,dc=test,dc=local"; diff --git a/nginx-ldap-auth-daemon.py b/nginx-ldap-auth-daemon.py index 31626d1..0f2af34 100755 --- a/nginx-ldap-auth-daemon.py +++ b/nginx-ldap-auth-daemon.py @@ -147,6 +147,7 @@ class LDAPAuthHandler(AuthHandler): # parameter header default 'realm': ('X-Ldap-Realm', 'Restricted'), 'url': ('X-Ldap-URL', None), + 'starttls': ('X-Ldap-Starttls', 'false'), 'basedn': ('X-Ldap-BaseDN', None), 'template': ('X-Ldap-Template', '(cn=%(username)s)'), 'binddn': ('X-Ldap-BindDN', ''), @@ -192,6 +193,20 @@ class LDAPAuthHandler(AuthHandler): ctx['action'] = 'initializing LDAP connection' ldap_obj = ldap.initialize(ctx['url']); + # Python-ldap module documentation advises to always + # explicitely set the LDAP version to use after running + # initialize() and recommends using LDAPv3. (LDAPv2 is + # deprecated since 2003 as per RFC3494) + # + # Also, the STARTTLS extension requires the + # use of LDAPv3 (RFC2830). + ldap_obj.protocol_version=ldap.VERSION3 + + # Establish a STARTTLS connection if required by the + # headers. + if ctx['starttls'] == 'true': + ldap_obj.start_tls_s() + # See http://www.python-ldap.org/faq.shtml # uncomment, if required # ldap_obj.set_option(ldap.OPT_REFERRALS, 0) @@ -255,6 +270,9 @@ if __name__ == '__main__': group.add_argument('-u', '--url', metavar="URL", default="ldap://localhost:389", help=("LDAP URI to query (Default: ldap://localhost:389)")) + group.add_argument('-s', '--starttls', metavar="starttls", + default="false", + help=("Establish a STARTTLS protected session (Default: false)")) group.add_argument('-b', metavar="baseDn", dest="basedn", default='', help="LDAP base dn (Default: unset)") group.add_argument('-D', metavar="bindDn", dest="binddn", default='', @@ -277,6 +295,7 @@ if __name__ == '__main__': auth_params = { 'realm': ('X-Ldap-Realm', args.realm), 'url': ('X-Ldap-URL', args.url), + 'starttls': ('X-Ldap-Starttls', args.starttls), 'basedn': ('X-Ldap-BaseDN', args.basedn), 'template': ('X-Ldap-Template', args.filter), 'binddn': ('X-Ldap-BindDN', args.binddn), diff --git a/nginx-ldap-auth.conf b/nginx-ldap-auth.conf index 1199444..e890444 100644 --- a/nginx-ldap-auth.conf +++ b/nginx-ldap-auth.conf @@ -61,17 +61,25 @@ http { # # Parameter Proxy header # ----------- ---------------- + # url X-Ldap-URL + # starttls X-Ldap-Starttls # basedn X-Ldap-BaseDN # binddn X-Ldap-BindDN # bindpasswd X-Ldap-BindPass # cookiename X-CookieName # realm X-Ldap-Realm # template X-Ldap-Template - # url X-Ldap-URL # (Required) Set the URL and port for connecting to the LDAP server, - # by replacing 'example.com' and '636'. - proxy_set_header X-Ldap-URL "ldaps://example.com:636"; + # by replacing 'example.com'. + # Do not mix ldaps-style URL and X-Ldap-Starttls as it will not work. + proxy_set_header X-Ldap-URL "ldap://example.com"; + + # (Optional) Establish a TLS-enabled LDAP session after binding to the + # LDAP server. + # This is the 'proper' way to establish encrypted TLS connections, see + # http://www.openldap.org/faq/data/cache/185.html + #proxy_set_header X-Ldap-Starttls "true"; # (Required) Set the Base DN, by replacing the value enclosed in # double quotes.