Francisco Tacoronte
Francisco Tacoronte

Reputation: 43

How to enable authentication via openLDAP on JupyterHub without SSL certificate?

I am trying to create a JupyterHub that uses an LDAP to authenticate users.

The JupyterHub is working but when I am trying log on the web page show a Error 500.

I must clarify that when I tried it with the PAM method it worked without problems, but when configuring it to use the LDAP it started to fail.

I am using docker-compose. I currently have three containers:

1. JupyterHub:

jupyter:
  build:
    context: ./jupyterhub
  ports:
    - "8380:8000"
  environment:
    VIRTUAL_HOST: jupyter.probandofran.eu
    LETSENCRYPT_HOST: jupyter.probandofran.eu
    VIRTUAL_PORT: 8000
  restart: on-failure
  depends_on:
    - jupyterlab      
    - revproxy-letsencrypt
  volumes:
    - ${VOLUMES_BASE_PATH}/jupyter:/home
    - /var/run/docker.sock:/var/run/docker.sock:ro
  healthcheck:
    test: curl --fail -s http://jupyter:8000/ || exit 1
    interval: 10s # time between tests
    timeout: 5s # time waiting for a response
    start_period: 30s # time from launch when the failed tests are ignored
    retries: 5 # countdown of failed tests

2.Jupyterlab:

jupyterlab:
  build:
    context: ./jupyterlab
  image: ngd-jupyterlab
  command: echo
  healthcheck:
    test: curl --fail -s http://jupyterlab:8080/ || exit 1
    interval: 10s # time between tests
    timeout: 5s # time waiting for a response
    start_period: 30s # time from launch when the failed tests are ignored
    retries: 5 # countdown of failed tests

3. OpenLDAP

openldap:
  image: docker.io/bitnami/openldap:2.6
  ports:
    - '1389:1389'
    - '1636:1636'
  environment:
    - LDAP_ENABLE_TLS=no
    - LDAP_ADMIN_USERNAME=admin
    - LDAP_ADMIN_PASSWORD=adminpassword
    - LDAP_USERS=user1,user02
    - LDAP_PASSWORDS=user1,password2
  volumes:
    - 'openldap_data:/bitnami/openldap'

I think the problem is in the JupyterHub configuration file

jupyterhub_config.py

    from jupyter_client.localinterfaces import public_ips
    ip = public_ips()[0]

    c.Spawner.default_url = '/lab'
    c.Authenticator.admin_users = {'fran'}
    c.JupyterHub.admin_access = False
    in_docker_compose = True  # "False" for standalone testing (for instance, to check changes to Jupyterlab image)
    c.JupyterHub.hub_ip = ip if not in_docker_compose else '0.0.0.0'
    # 'jupyter' is the name of Jupyterhub service in "docker-compose" file
    c.JupyterHub.hub_connect_ip = '' if not in_docker_compose else 'jupyter'
    if in_docker_compose:
        c.DockerSpawner.network_name = 'webproxy'  # Should match the network name used in the docker compose file
    c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
    c.DockerSpawner.image = 'ngd-jupyterlab'  # 'jupyter/datascience-notebook:r-4.0.3'
    notebook_dir = "/home/jovyan/"
    c.DockerSpawner.notebook_dir = notebook_dir
    c.DockerSpawner.volumes = {'jupyterhub-user-{username}': dict(bind=notebook_dir, mode="rw")}
    c.DockerSpawner.use_internal_ip = True
    c.DockerSpawner.remove_containers = True
    c.DockerSpawner.remove = True

    # c.DockerSpawner.extra_host_config = { 'network_mode': network_name }
    c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
    c.LDAPAuthenticator.lookup_dn = False
    c.LDAPAuthenticator.bind_dn_template = [
        "uid={username},ou=people,dc=wikimedia,dc=org",
        "cn={username},ou=users,dc=example,dc=org"
    ]


    # c.JupyterHub.allow_named_servers = False
    # c.JupyterHub.authenticator_class = 'jupyterhub.auth.PAMAuthenticator'
    c.JupyterHub.cleanup_proxy = True
    c.JupyterHub.cleanup_servers = True
    c.LDAPAuthenticator.server_use_ssl = False
    c.LDAPAuthenticator.use_ssl = False
    c.LDAPAuthenticator.server_address = 'openldap' 
    c.LDAPAuthenticator.server_port = 1389
    c.LDAPAuthenticator.user_search_base = 'dc=example,dc=org'
    # c.JupyterHub.reset_db = True

When I use the docker-compose up it show:


    jupyter_1               | [E 2022-04-20 11:57:07.496 JupyterHub web:1789] Uncaught exception POST /hub/login?next=%2Fhub%2F (192.168.112.1)
    jupyter_1               |     HTTPServerRequest(protocol='http', host='jupyter.probandofran.eu', method='POST', uri='/hub/login?next=%2Fhub%2F', version='HTTP/1.1', remote_ip='192.168.112.1')
    jupyter_1               |     Traceback (most recent call last):
    jupyter_1               |       File "/usr/local/lib/python3.8/dist-packages/tornado/web.py", line 1704, in _execute
    jupyter_1               |         result = await result
    jupyter_1               |       File "/usr/local/lib/python3.8/dist-packages/jupyterhub/handlers/login.py", line 151, in post
    jupyter_1               |         user = await self.login_user(data)
    jupyter_1               |       File "/usr/local/lib/python3.8/dist-packages/jupyterhub/handlers/base.py", line 804, in login_user
    jupyter_1               |         authenticated = await self.authenticate(data)
    jupyter_1               |       File "/usr/local/lib/python3.8/dist-packages/jupyterhub/auth.py", line 473, in get_authenticated_user
    jupyter_1               |         authenticated = await maybe_future(self.authenticate(handler, data))
    jupyter_1               |       File "/usr/local/lib/python3.8/dist-packages/ldapauthenticator/ldapauthenticator.py", line 382, in authenticate
    jupyter_1               |         conn = self.get_connection(userdn, password)
    jupyter_1               |       File "/usr/local/lib/python3.8/dist-packages/ldapauthenticator/ldapauthenticator.py", line 314, in get_connection
    jupyter_1               |         conn = ldap3.Connection(
    jupyter_1               |       File "/usr/local/lib/python3.8/dist-packages/ldap3/core/connection.py", line 355, in __init__
    jupyter_1               |         self.do_auto_bind()
    jupyter_1               |       File "/usr/local/lib/python3.8/dist-packages/ldap3/core/connection.py", line 374, in do_auto_bind
    jupyter_1               |         self.start_tls(read_server_info=False)
    jupyter_1               |       File "/usr/local/lib/python3.8/dist-packages/ldap3/core/connection.py", line 1264, in start_tls
    jupyter_1               |         if self.server.tls.start_tls(self) and self.strategy.sync:  # for asynchronous connections _start_tls is run by the strategy
    jupyter_1               |       File "/usr/local/lib/python3.8/dist-packages/ldap3/core/tls.py", line 277, in start_tls
    jupyter_1               |         raise LDAPStartTLSError(connection.last_error)
    jupyter_1               |     ldap3.core.exceptions.LDAPStartTLSError: startTLS failed - protocolError
    jupyter_1               |     

It's my first time posting on stackOverflow, I'm sorry if I made any mistake posting.

Upvotes: 2

Views: 1286

Answers (1)

Phan Nguyen
Phan Nguyen

Reputation: 68

I think it is bug from ldapauthenticator, we can hot fix by change the logic inside this lib (file jupyterhub_config.py)

As @jnishii suggestion in https://github.com/jupyterhub/ldapauthenticator/issues/211

Upvotes: 1

Related Questions