osixia / docker-openldap

OpenLDAP container image 🐳🌴
MIT License
4.05k stars 977 forks source link

TLS certificates - ldap_start_tls: Connect error (-11) TLS: can't accept: No certificate was found #477

Open kevdogg opened 4 years ago

kevdogg commented 4 years ago

I can't seem to get TLS functioning properly from the client. I'm using an Arch Linux host with docker images osixia/openldap:latest and osixia/phpldapadmin:latest

I created self-signed client and server certificate files. I created the server with a CN and Subject Alternative Names. Here is a snipped of my server certificate:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = IL, L = CH, O = domain.com, CN = Docker OpenLDAP CA, emailAddress = user@domain.com
        Validity
            Not Before: Oct  4 15:24:30 2020 GMT
            Not After : Jan 10 15:24:30 2031 GMT
        Subject: C = US, ST = IL, L = CH, O = domain.com, CN = openldap, emailAddress = user@domain.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
        ...
        ...
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Self-Sign Server Certificate
            X509v3 Subject Key Identifier:
                55:B6:18:93:93:5B:1B:07:86:7F:5D:B7:24:CE:55:4E:78:A5:14:30
            X509v3 Authority Key Identifier:
                keyid:B8:36:51:11:8F:0D:86:9E:4B:B4:9D:78:A2:00:0C:B3:4A:F3:F9:63
                DirName:/C=US/ST=IL/L=CH/O=domain.com/CN=Docker OpenLDAP CA/emailAddress=user@domain.com
                serial:50:32:38:00:49:9E:47:82:3B:E1:0F:03:83:D8:FC:C7:9D:A0:A8:AA

            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Client Authentication, TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:openldap.domain.com, DNS:ldap.domain.com, DNS:openldap, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1

The client certificate was created and signed by the same CA:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 2 (0x2)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = IL, L = CH, O = domain.com, CN = Docker OpenLDAP CA, emailAddress = user@domain.com
        Validity
            Not Before: Oct  4 15:54:58 2020 GMT
            Not After : Jan 10 15:54:58 2031 GMT
        Subject: C = US, ST = IL, L = CH, O = domain.com, CN = phpldapamin, emailAddress = user@domain.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
        ....
        ....
       X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Self-Signed Client Certificate
            X509v3 Subject Key Identifier:
                36:9A:BE:AB:DD:72:C2:DE:92:F4:46:9D:CD:75:65:62:F9:F0:D5:07
            X509v3 Authority Key Identifier:
                keyid:B8:36:51:11:8F:0D:86:9E:4B:B4:9D:78:A2:00:0C:B3:4A:F3:F9:63
                DirName:/C=US/ST=IL/L=CH/O=domain.com/CN=Docker OpenLDAP CA/emailAddress=user@domain.com
                serial:50:32:38:00:49:9E:47:82:3B:E1:0F:03:83:D8:FC:C7:9D:A0:A8:AA

            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Client Authentication, TLS Web Server Authentication

The openldap container within the docker network is simply reachable via openldap.

Here is my docker-compose file:

  openldap:
    image: osixia/openldap:latest
    container_name: openldap
    restart: unless-stopped
    domainname: "example.org"
    hostname: "openldap"
    networks:
      - net
    ports:
      - "389:389"
      - "636:636"
    secrets:
      - authentication_backend-ldap_secret
    environment:
      - LDAP_LOG_LEVEL=256
      - LDAP_ORGANISATION=domain
      - LDAP_DOMAIN=ldap.domain.com
      - LDAP_BASE_DN=dc=ldap,dc=domain,dc=com
      - LDAP_ADMIN_PASSWORD_FILE=/run/secrets/authentication_backend-ldap_secret
      - LDAP_TLS=true
      - LDAP_TLS_CRT_FILENAME=cert.pem
      - LDAP_TLS_KEY_FILENAME=key.pem
      - LDAP_TLS_CA_CRT_FILENAME=ca.pem
      - LDAP_TLS_ENFORCE=false
      - LDAP_TLS_VERIFY_CLIENT=demand
      - LDAP_REPLICATION=false
      - KEEP_EXISTING_CONFIG=false
      - LDAP_REMOVE_CONFIG_AFTER_SETUP=false
      - LDAP_SSL_HELPER_PREFIX=ldap
    tty: true
    command: --loglevel debug
    stdin_open: true
    volumes:
      - /var/data/ldap/db:/var/lib/ldap
      - /etc/ldap/config:/etc/ldap/slapd.d
      - /etc/docker/compose/authelia/certs/openldap2/server:/container/service/slapd/assets/certs

  phpldapadmin:
    image: osixia/phpldapadmin:latest
    container_name: phpldapadmin
    restart: unless-stopped
    hostname: phpldapadmin.example.org
    networks:
      - net
    ports:
      - 6443:80
    depends_on:
      - openldap
    environment:
      PHPLDAPADMIN_LDAP_HOSTS: "openldap"
      PHPLDAPADMIN_HTTPS: "false"
      PHPLDAPADMIN_LDAP_CLIENT_TLS: "true"
      PHPLDAPADMIN_LDAP_CLIENT_TLS_REQCERT: "demand"
      PHPLDAPADMIN_LDAP_CLIENT_TLS_CA_CRT_FILENAME: "ca.pem"
      PHPLDAPADMIN_LDAP_CLIENT_TLS_CRT_FILENAME: "cert.pem"
      PHPLDAPADMIN_LDAP_CLIENT_TLS_KEY_FILENAME: "key.pem"
    command: --loglevel debug
    volumes:
      - /etc/docker/compose/authelia/certs/openldap2/client:/container/service/ldap-client/assets/certs

From the Arch linux docker host I'm able to reach the openldap container using the generated client cert.pem and key.pem:

openssl s_client -connect 127.0.0.1:636 -showcerts -state -CAfile ca.pem
...
...
---
SSL handshake has read 3890 bytes and written 398 bytes
Verification: OK
---
openssl s_client -connect 127.0.0.1:636 -state -CAfile ../ca/ca.pem -cert cert.pem -key key.pem
...
...
SSL handshake has read 3941 bytes and written 3875 bytes
Verification: OK
---

I've also verified without TLS I can query the database from the docker host:

ldapsearch -x -b 'dc=ldap,dc=domain,dc=com' -D "cn=admin,dc=ldap,dc=domain,dc=com" '(objectclass=*)' -H ldap://127.0.0.1:389 -W
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
...
...

When I try to invoke TLS from the docker host however I receive a ldap_start_tls: Connect error (-11):

# ldapsearch -x -b 'dc=ldap,dc=domain,dc=com' -D "cn=admin,dc=ldap,dc=domain,dc=com" '(objectclass=*)' -H ldap://127.0.0.1:389 -Z -W
ldap_start_tls: Connect error (-11)
...

Examining the logs of the docker container (docker logs openldap), I get the following:

5f7a529e conn=1087 fd=12 ACCEPT from IP=172.18.0.1:57744 (IP=0.0.0.0:389)
5f7a529e conn=1087 op=0 EXT oid=1.3.6.1.4.1.1466.20037
5f7a529e conn=1087 op=0 STARTTLS
5f7a529e conn=1087 op=0 RESULT oid= err=0 text=
TLS: can't accept: No certificate was found..
5f7a529e conn=1087 fd=12 closed (TLS negotiation failure)

From within the openldap container however I'm able to run the same query and things seem to work:

docker exec -it openldap /bin/bash
ldapsearch -x -b 'dc=ldap,dc=domain,dc=com' -D "cn=admin,dc=ldap,dc=domain,dc=com" '(objectclass=*)' -H ldap://openldap:389 -Z -W
...
...

I tried running the same query from within the phpldapadmin container and received the same errors I received from the docker host.

I don't understand the error: TLS: can't accept: No certificate was found... From within the openldap container the certs seem to be in place:

root@openldap:/container/service/slapd/assets/certs# ls -la
total 324
drwxr-xr-x 2 openldap openldap    8 Oct  4 16:49 .
drwxrwxr-x 5 openldap openldap    8 Oct  4 16:49 ..
-rw-r--r-- 1 openldap openldap 2204 Oct  4 15:25 01.pem
-rw-r--r-- 1 openldap openldap 2358 Oct  4 14:26 ca.pem
-rw-r--r-- 1 openldap openldap 1025 Oct  4 14:40 cert.csr
-rw-r--r-- 1 openldap openldap 2204 Oct  4 15:25 cert.pem
-rw------- 1 openldap openldap  424 Oct  4 16:49 dhparam.pem
-rw------- 1 openldap openldap 1679 Oct  4 14:32 key.pem

What am I missing here?

CodingJaw commented 3 years ago

not sure if it applies or not... but could your adminldap be telling openldap to look for domain "openldap" instead of "domain.com"? try changing the name of the openldap container to match the domain.com you are useing? that way the headers passed contain the correct domain? and you may want to use a static ip with the openldap docker container so you can also add the ldap.domain.com to the hosts file so your dns points back inside? im kinda new to openldap so not sure if it cares about what domain you are coming from or not but might be worth a try?

mq2195 commented 3 years ago

Did you configure ldap utils to use the certificate?

/etc/openldap/ldap.conf /etc/openldap/certs/* ~/.ldaprc

wayilau commented 3 years ago

i also met this problem, have you resolved? i remembered it works well a few days ago @kevdogg

wayilau commented 3 years ago

i use the default certs.