0

I'm trying to configure Apache httpd v2.4 for LDAP authentication to AD. LDAPS certificates are issued by the internal CA. For whatever reason (I'm not on the AD team), neither our prod or non-prod environments publish the full chain.

Non-prod sends the server and intermediate certs, but not the root. I am able to successfully connect via Apache with:

LDAPVerifyServerCert On
LDAPTrustedGlobalCert CA_BASE64 chain.crt
# $cat intermediate.pem root.pem > chain.crt

Unfortunately, prod only sends the server cert. No intermediate (issuer) and no root. Providing the same chain containing the issuer and root doesn't work. I've tried everything I can think of: server cert only, int only, server + int, server + int + root, but none of it works, either in Apache or testing with openssl s_client -connect $x -CAfile $y.

Obviously, the best option is getting the AD team to publish the full chain, but is there any other way to verify the connection (other than disabling verification)?

Edit:

Here is the output of openssl s_client -connect devldap.company.com:636 -CAfile int+root.pem:

CONNECTED(00000003)
depth=2 CN = Company Root CA
verify return:1
depth=1 DC = com, DC = company CN = Company Intermediate CA
verify return:1
depth=0 C = US, ST = State, O = Company, OU = OTS, CN = devldap.company.com
verify return:1
---
Certificate chain
 0 s:C = US, ST = State, O = Company, OU = OTS, CN = devldap.company.com
   i:DC = com, DC = company CN = Company Intermediate CA
 1 s:DC = com, DC = company CN = Company Intermediate CA
   i:CN = Company Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIH8TCCBtmgAwIBAgITTQACdEm5xkCMTnqGDQAAAAJ0STANBgkqhkiG9w0BAQsF
...
jce8VpEUyZKDClUrcyRBSxd0rq2I
-----END CERTIFICATE-----
subject=C = US, ST = State, O = Company, OU = OTS, CN = devldap.company.com

issuer=DC = com, DC = company CN = Company Intermediate CA

---
No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA256:RSA+SHA384:RSA+SHA1:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA1:DSA+SHA1:RSA+SHA512:ECDSA+SHA512
Shared Requested Signature Algorithms: RSA+SHA256:RSA+SHA384:RSA+SHA1:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA1:RSA+SHA512:ECDSA+SHA512
Peer signing digest: SHA256
Peer signature type: RSA
Server Temp Key: ECDH, P-384, 384 bits
---
SSL handshake has read 4639 bytes and written 486 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: F90...411
    Session-ID-ctx: 
    Master-Key: 985...D1E
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1651420792
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---
DONE

And for prod, openssl s_client -connect ldap.company.com:636 -CAfile int+root.pem:

CONNECTED(00000003)
depth=0 C = US, ST = State, O = Company, CN = ldap.company.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, ST = State, O = Company, CN = ldap.company.com
verify error:num=21:unable to verify the first certificate
verify return:1
depth=0 C = US, ST = State, O = Company, CN = ldap.company.com
verify return:1
---
Certificate chain
 0 s:C = US, ST = State, O = Company, CN = ldap.company.com
   i:DC = com, DC = company CN = Company Intermediate CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIHXzCCBkegAwIBAgITTQADO1BEj8rlaKH+eQAAAAM7UDANBgkqhkiG9w0BAQsF
...
FGBKggzc3AK2pcHT9E3f46Oy+A==
-----END CERTIFICATE-----
subject=C = US, ST = State, O = Company, CN = ldap.company.com

issuer=DC = com, DC = company CN = Company Intermediate CA

---
No client certificate CA names sent
---
SSL handshake has read 2059 bytes and written 655 bytes
Verification error: unable to verify the first certificate
---
New, SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : AES256-SHA
    Session-ID: 33B...377
    Session-ID-ctx: 
    Master-Key: A5D...ACE
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1651420815
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
    Extended master secret: no
---
DONE

Edit: Turns out the file called "int.pem" was actually a server cert from a different project. Neato. Wish I had checked that before wasting so much time on this. With a chain containing the actual intermediate CA cert and root, it verifies successfully.

  • TLS servers are permitted (and sometimes encouraged) to omit the root cert; your non-prod case is normal and should work with (only) root in `LDAPTrustedGlobalCert CA*`. OpenSSL by default can fill-in chain from truststore, and `openssl s_client -connect $prod:636 -CAfile int_and_root.pem` (if openssl below 1.1.1 _and_ server wants SNI which I don't know for MS, add `-servername $prod`) should work; if not, can you give details? But while Apache uses OpenSSL for https, it's not clear to me if (or how) it uses OpenSSL for ldaps, so that may not help. – dave_thompson_085 May 01 '22 at 05:03
  • @dave_thompson_085 I've added the s_client output to the post. Would you mind taking another look? – Joe Buckley May 01 '22 at 16:40
  • @dave_thompson_085 Thanks so much! Unfortunately, it was user error on my part. Somehow, what I swore was the intermediate cert was actually a server cert for something else entirely. Created a new .pem with the actual int + root, and it verifies and is also working in Apache. – Joe Buckley May 01 '22 at 16:53

0 Answers0