Security Directory Integrator connecting to Active Directory LDAPS

Created:
Author: Christoph Stoettner
Read in about 4 min · 769 words

Fence with padlock

Photo by Markus Winkler | Unsplash

I had one Connections’ environment that I wanted to switch from OpenLDAP to Active Directory LDAP. The old OpenLDAP environment used LDAPS to connect, and so I assumed that the change was done quickly.

The first step was to make a copy of the tdisol folder I used for OpenLDAP and start changing the configuration files for the new LDAP server.

Now we need to import the certificate used for LDAPS. You can use keytool, Keystore Explorer or openssl to get the SSL certificate from the server and store it into a JKS keystore.

openssl s_client -showcerts -connect ad-server-hostname:636 < /dev/null > temp-key.out
openssl x509 -outform DER < temp-key.out > temp-key.der
openssl x509 -inform der -in temp-key.der -out temp-key.pem
/opt/IBM/TDI/V7.0/jvm/jre/bin/keytool -import -alias ldap-certificate -keystore ldapcerts.jks -file temp-key.pem

This asks you for a keystore password and if you want to trust the certificate.

Example

[root@cnx8-db2-db ad_ldaps]# openssl s_client -showcerts -connect dc1.win.stoeps.home:636 < /dev/null > temp-key.out
depth=0 CN = DC1.WIN.STOEPS.HOME
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = DC1.WIN.STOEPS.HOME
verify error:num=21:unable to verify the first certificate
verify return:1
depth=0 CN = DC1.WIN.STOEPS.HOME
verify return:1
DONE
[root@cnx8-db2-db ad_ldaps]# openssl x509 -outform DER < temp-key.out > temp-key.der
[root@cnx8-db2-db ad_ldaps]# openssl x509 -inform der -in temp-key.der -out temp-key.pem
[root@cnx8-db2-db ad_ldaps]# /opt/IBM/TDI/V7.20/jvm/jre/bin/keytool -import -alias ldap-certificate -keystore ldapcerts.jks -file temp-key.pem
Enter keystore password:
Re-enter new password:
Owner: CN=DC1.WIN.STOEPS.HOME
Issuer: CN=WIN-DC1-CA, DC=WIN, DC=STOEPS, DC=HOME

...

Trust this certificate? [no]:  yes
Certificate was added to keystore

Now add the new keystore to solution.properties in the tdisol directory.

The example solution.properties has the trustStore configuration, which just needs to be uncommented.

...
## server authentication

#javax.net.ssl.trustStore=key.jks
#{protect}-javax.net.ssl.trustStorePassword=
#javax.net.ssl.trustStoreType=jks

# by default the server API is not used.
api.on=false

For my newly created keystore I added the following.

javax.net.ssl.trustStore=ldapcerts.jks
{protect}-javax.net.ssl.trustStorePassword={encr}VK/JddYbHYHDbjQ/jO91wvVJ0howxCge2Ded409WgNRoQq1JHsEMKnZa1OuWSmgnoNwUnRRTQpr9v3lbvwFSULLAUjZTClD5jkgHeHTU/dUE0OXtsSlK+gBaIOBF9IZqybZJF1hlnuWsZx29gshwY2wANrIkgzmpWYs55XwdC9A=
javax.net.ssl.trustStoreType=jks

We will later see that this is the issue here, but these three lines are enough to get a working TDI SSL connection to Domino LDAP or OpenLDAP.

Adjust the server and the bind user

I adjusted profiles_tdi.properties and ran collect_dns.sh to check the LDAP connection.

Changed values in profiles_tdi.properties:

source_ldap_url=ldap://dc1.win.stoeps.home:636
source_ldap_search_base=dc=win,dc=stoeps,dc=home
source_ldap_search_filter=(objectclass=Person)
source_ldap_user_login=CN=Bind LDAP,OU=Stoeps Users,DC=WIN,DC=STOEPS,DC=HOME
{protect}-source_ldap_user_password=<password of the bind user>

Double check that SSL is enabled:

source_ldap_use_ssl=true

Running collect_dns.sh failed with the message simple bind failed.

Error message in ibmdi.log

2023-11-02 12:36:34,931 INFO  [AssemblyLine.AssemblyLines/_internal_ldap_iterate] - [ldap_iterate] CTGDJQ001I Using LDAP SSL connection. Ensure TCP port number is changed accordingly.
2023-11-02 12:36:35,162 ERROR [AssemblyLine.AssemblyLines/_internal_ldap_iterate] - [ldap_iterate] CTGDIS181E Error while evaluating Hook 'On Error' in the Component 'ldap_iterate' (ldap_iterate.initialize_fail).
javax.naming.CommunicationException: simple bind failed: dc1.win.stoeps.home:636
        at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:231) ~[?:1.8.0]

My first change was to check if the credentials and server information were valid. So I set:

source_ldap_url=ldap://dc1.win.stoeps.home:389
source_ldap_use_ssl=false

Without SSL, I was able to connect to AD LDAP and synchronize the users, but I wanted to get it working with SSL. Starting with some tracing (after enabling SSL again) in solution.properties:

...
javax.net.debug=all

Running collect_dns.sh again produces a lot of debug output. The most important part is:

javax.net.ssl|FINE|1C|Thread-3|2023-11-02 12:36:35.149 UTC|Thread.java:1178|Produced client Certificate handshake message (
"Certificates": [
  "certificate" : {
    "version"            : "v3",
    "serial number"      : "45 01 B2 CD",
    "signature algorithm": "MD5withRSA",
    "issuer"             : "CN=API Admin, OU=test, O=test, L=test, ST=test, C=US",
    "not before"         : "2006-09-08 18:13:33.000 UTC",
    "not  after"         : "2010-09-07 18:13:33.000 UTC",
    "subject"            : "CN=API Admin, OU=test, O=test, L=test, ST=test, C=US",
    "subject public key" : "RSA"}
]

I wondered about this user, but after some research and checking serverapi/testadmin.jks, I found an expired API Admin user, and it seems that TDI tries to send his client certificate to the AD LDAP server. AD does not accept the user (because the user is unknown, expired and uses an old signature algorithm).

When we open the file serverapi/testadmin.jks we find an expired user CN=API Admin, OU=test, O=test, ST=test, C=US, but why does TDI try to use this certificate?

Screenshot with ikeyman

Some internet searches later, I found the post from Robert Farstad TDI/SDI - Connect to AD over SSL and Michael Urspringer IBM Connections 4: Connect TDI to Secure LDAP server via SSL .

Both added a keystore and a truststore to their tdisol folder, I did just the trustStore. So the keyStore gets inherited from global.properties which points to serverapi/testadmin.jks.

Solution

So I changed my solution.properties to:

...
# Truststore
javax.net.ssl.trustStore=ldapcerts.jks
{protect}-javax.net.ssl.trustStorePassword={encr}VK/JddYbHYHDbjQ/jO9...
javax.net.ssl.trustStoreType=jks

# KeyStore (can use the same key store as the trustStore!)
javax.net.ssl.keyStore=ldapcerts.jks
{protect}-javax.net.ssl.keyStorePassword={encr}VK/JddYbHYHDbjQ/jO9...
javax.net.ssl.keyStoreType=jks

and ran collect_dns.sh again. Now the collect.dns gets created and contains users, and the next check with sync_all_dns.sh is successfully synchronizing the AD users to Connections profilesDB.

I assume that AD asks optionally for a client certificate, and as there is one present in the keystore, TDI tries to send it.

Author
Add a comment
Error
There was an error sending your comment, please try again.
Thank you!
Your comment has been submitted and will be published once it has been approved.

Your email address will not be published. Required fields are marked with *

Suggested Reading
Card image cap

Last week, I had three systems with issues displaying the Top Updates in the Orient Me. So I tried to find out which applications and containers are involved in generating the content for this view.

Created: Read in about 4 min
Card image cap

With HCL Connections 6.5 and later, we got the add-on HCL Connections Engagement Center (aka CEC, HCEC, ICEC or XCC) included in a normal HCL Connections deployment.

Created: Read in about 6 min
Card image cap

The official documentation, “Migrating data from MongoDB 3 to 5”, wants to dump the MongoDB databases in 3.6 and then restore this data into the newly deployed MongoDB 5.

One issue with this process is that we can’t run the two MongoDB versions in parallel on Kubernetes because the provided helm charts and container for MongoDB 3.6 stop running after Kubernetes 1.21. On the other side, the helm chart providing MongoDB 5 can’t be installed on those old Kubernetes versions. So the process to update is:

Created:
Last Update:
Read in about 7 min