Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JupyterHub with LDAPAuthenticator startTLS failed - protocolError #211

Closed
myuser-git opened this issue Jun 15, 2022 · 8 comments · Fixed by #258
Closed

JupyterHub with LDAPAuthenticator startTLS failed - protocolError #211

myuser-git opened this issue Jun 15, 2022 · 8 comments · Fixed by #258

Comments

@myuser-git
Copy link

myuser-git commented Jun 15, 2022

Trying to use LDAPAuthenticator with JupyterHub. The authentication process returns the following error:

[I 2022-06-15 18:47:09.505 JupyterHub app:2479] **Running JupyterHub version 1.5.0**
[I 2022-06-15 18:47:09.505 JupyterHub app:2509] **Using Authenticator: ldapauthenticator.ldapauthenticator.LDAPAuthenticator-1.3.2**
[I 2022-06-15 18:47:09.505 JupyterHub app:2509] **Using Spawner: kubespawner.spawner.KubeSpawner-1.1.0**
[I 2022-06-15 18:47:09.505 JupyterHub app:2509] **Using Proxy: jupyterhub.proxy.ConfigurableHTTPProxy-1.5.0**
...
HTTPServerRequest(protocol='http', host='X.X.X.X:30080', method='POST', uri='/hub/login?next=%2Fhub%2F', version='HTTP/1.1', remote_ip='::ffff:192.168.0.12')
    Traceback (most recent call last):
      File "/usr/local/lib/python3.8/dist-packages/tornado/web.py", line 1704, in _execute
        result = await result
      File "/usr/local/lib/python3.8/dist-packages/jupyterhub/handlers/login.py", line 151, in post
        user = await self.login_user(data)
      File "/usr/local/lib/python3.8/dist-packages/jupyterhub/handlers/base.py", line 754, in login_user
        authenticated = await self.authenticate(data)
      File "/usr/local/lib/python3.8/dist-packages/jupyterhub/auth.py", line 469, in get_authenticated_user
        authenticated = await maybe_future(self.authenticate(handler, data))
      File "/usr/local/lib/python3.8/dist-packages/ldapauthenticator/ldapauthenticator.py", line 361, in authenticate
        username, resolved_dn = self.resolve_username(username)
      File "/usr/local/lib/python3.8/dist-packages/ldapauthenticator/ldapauthenticator.py", line 236, in resolve_username
        conn = self.get_connection(
      File "/usr/local/lib/python3.8/dist-packages/ldapauthenticator/ldapauthenticator.py", line 314, in get_connection
        conn = ldap3.Connection(
      File "/usr/local/lib/python3.8/dist-packages/ldap3/core/connection.py", line 363, in __init__
        self._do_auto_bind()
      File "/usr/local/lib/python3.8/dist-packages/ldap3/core/connection.py", line 391, in _do_auto_bind
        if self.start_tls(read_server_info=False):
      File "/usr/local/lib/python3.8/dist-packages/ldap3/core/connection.py", line 1314, in start_tls
        if self.server.tls.start_tls(self) and self.strategy.sync:  # for asynchronous connections _start_tls is run by the strategy
      File "/usr/local/lib/python3.8/dist-packages/ldap3/core/tls.py", line 277, in start_tls
        raise LDAPStartTLSError(connection.last_error)
    ldap3.core.exceptions.**LDAPStartTLSError: startTLS failed - protocolError**

[D 2022-06-15 18:48:20.863 JupyterHub base:1285] No template for 500
[E 2022-06-15 18:48:20.880 JupyterHub log:181] {
      "X-Forwarded-Host": "X.X.X.X:30080",
      "X-Forwarded-Proto": "http",
      "X-Forwarded-Port": "30080",
      "X-Forwarded-For": "::ffff:192.168.0.12",
      "Accept-Language": "en-US,en;q=0.9,it;q=0.8",
      "Accept-Encoding": "gzip, deflate",
      "Referer": "http://X.X.X.X:30080/hub/login?next=%2Fhub%2F",
      "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
      "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36",
      "Content-Type": "application/x-www-form-urlencoded",
      "Dnt": "1",
      "Upgrade-Insecure-Requests": "1",
      "Origin": "http://X.X.X.X:30080",
      "Cache-Control": "max-age=0",
      "Content-Length": "41",
      "Connection": "close",
      "Host": "X.X.X.X:30080"
    }

Here is the relevant portion of the config file for Helm:

# --------------------------------------------------------------------------------------------------------------- #
# Configure the authenticator provider (LDAP)                                                                     #
# --------------------------------------------------------------------------------------------------------------- #
hub:
  config:
    JupyterHub:
      authenticator_class: ldapauthenticator.LDAPAuthenticator
    LDAPAuthenticator:
      lookup_dn: true
      lookup_dn_search_filter: '(&(objectClass=inetOrgPerson)(uid={login}))'
      lookup_dn_user_dn_attribute: cn
      server_address: ldap-server
      server_port: 389
      user_search_base: 'ou=people,dc=example,dc=com'
      lookup_dn_search_user: 'cn=admin,dc=example,dc=com'
      lookup_dn_search_password: 'XXXXXXXX'

Any insight would be greatly appreciated.

@welcome
Copy link

welcome bot commented Jun 15, 2022

Thank you for opening your first issue in this project! Engagement like this is essential for open source projects! 🤗

If you haven't done so already, check out Jupyter's Code of Conduct. Also, please try to follow the issue template as it helps other other community members to contribute more effectively.
welcome
You can meet the other Jovyans by joining our Discourse forum. There is also an intro thread there where you can stop by and say Hi! 👋

Welcome to the Jupyter community! 🎉

@jnishii
Copy link

jnishii commented Jul 20, 2022

I had the same problem but was able to resolve it by fixing like this:

$ cd /usr/local/anaconda3/lib/python3.9/site-packages/ldapauthenticator 
$ diff -uN ldapauthenticator.py.org ldapauthenticator.py
--- ldapauthenticator.py.org    2020-08-28 14:09:52.000000000 +0000
+++ ldapauthenticator.py    2022-07-20 09:11:52.048574555 +0000
@@ -309,7 +309,8 @@
             self.server_address, port=self.server_port, use_ssl=self.use_ssl
         )
         auto_bind = (
-            ldap3.AUTO_BIND_NO_TLS if self.use_ssl else ldap3.AUTO_BIND_TLS_BEFORE_BIND
+            ldap3.AUTO_BIND_NO_TLS if not self.use_ssl else ldap3.AUTO_BIND_TLS_BEFORE_BIND
         )
         conn = ldap3.Connection(
             server, user=userdn, password=password, auto_bind=auto_bind

@ROOKIE20570
Copy link

I had the same problem but was able to resolve it by fixing like this:

$ cd /usr/local/anaconda3/lib/python3.9/site-packages/ldapauthenticator 
$ diff -uN ldapauthenticator.py.org ldapauthenticator.py
--- ldapauthenticator.py.org    2020-08-28 14:09:52.000000000 +0000
+++ ldapauthenticator.py    2022-07-20 09:11:52.048574555 +0000
@@ -309,7 +309,8 @@
             self.server_address, port=self.server_port, use_ssl=self.use_ssl
         )
         auto_bind = (
-            ldap3.AUTO_BIND_NO_TLS if self.use_ssl else ldap3.AUTO_BIND_TLS_BEFORE_BIND
+            ldap3.AUTO_BIND_NO_TLS if not self.use_ssl else ldap3.AUTO_BIND_TLS_BEFORE_BIND
         )
         conn = ldap3.Connection(
             server, user=userdn, password=password, auto_bind=auto_bind

That works for me~

@myuser-git
Copy link
Author

Thanks!

@marty90
Copy link

marty90 commented Dec 21, 2022

This is very annoying in case LDAP does not support SSL or StartTLS

@marty90
Copy link

marty90 commented Dec 21, 2022

Is there any way to make it work without modifying the code? At this point it appears unusable in case LDAP is not using SSL or StartTLS

@hilljairus
Copy link

If you don't want to change the code, you can use self-signed certificates (not recommended in prod):

`#!/bin/bash

Directory to store certificates

CERT_DIR="./certs"

Create directory if it doesn't exist

mkdir -p "$CERT_DIR"

Navigate to the directory

cd "$CERT_DIR"

Step 1: Generate the CA Key and Certificate

echo "Generating CA key..."
openssl genrsa -out openldapCA.key 2048

echo "Generating CA certificate..."
openssl req -x509 -new -nodes -key openldapCA.key -sha256 -days 1024 -out openldapCA.crt -subj "/C=KE/ST=Nairobi/L=Nairobi/O=MyCompany/OU=IT/CN=openldap"

Step 2: Create a Server Key and Certificate Request

echo "Generating LDAP server key..."
openssl genrsa -out openldap.key 2048

echo "Generating LDAP server certificate request..."
openssl req -new -key openldap.key -out openldap.csr -subj "C=KE/ST=Nairobi/L=Nairobi/O=MyCompany/OU=IT/CN=openldap"

Step 3: Generate the Server Certificate using the CA

echo "Generating LDAP server certificate..."
openssl x509 -req -in openldap.csr -CA openldapCA.crt -CAkey openldapCA.key -CAcreateserial -out openldap.crt -days 365 -sha256

Clean up CSR

rm openldap.csr

echo "Certificate generation complete. Files are located in $CERT_DIR"
`

@codedump
Copy link

I had the same problem but was able to resolve it by fixing like this:

$ cd /usr/local/anaconda3/lib/python3.9/site-packages/ldapauthenticator 
$ diff -uN ldapauthenticator.py.org ldapauthenticator.py
--- ldapauthenticator.py.org    2020-08-28 14:09:52.000000000 +0000
+++ ldapauthenticator.py    2022-07-20 09:11:52.048574555 +0000
@@ -309,7 +309,8 @@
             self.server_address, port=self.server_port, use_ssl=self.use_ssl
         )
         auto_bind = (
-            ldap3.AUTO_BIND_NO_TLS if self.use_ssl else ldap3.AUTO_BIND_TLS_BEFORE_BIND
+            ldap3.AUTO_BIND_NO_TLS if not self.use_ssl else ldap3.AUTO_BIND_TLS_BEFORE_BIND
         )
         conn = ldap3.Connection(
             server, user=userdn, password=password, auto_bind=auto_bind

So... is this a bug in JupyterHub that needs fixing, and is the above the fix?

Should we send it upstream?

I'm asking because I'm having the same problem right now, and I need to implement the same workaround.

If the ldapauthenticator is designed to not work without SSL or startTLS, then it needs to be documented.

If on the other hand it should work but is just buggy, and obviously this is the fix, then why not commit this?

I can prepare a PR if that's the issue...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants