Creating and Installing a Self-Signed Certificate for OpenDJ

The OpenDJ documentation for this is quite good, and highly recommended. See Configuring Servers for Client Application Access. My own example configuration follows.

This procedure can be used where the server name has changed or after cloning an instance to another server (in the latter case you may also need to change the admin certs — that procedure is also listed below, official doc is Changing Server Certificates in the Admin Guide). Also see the official doc for the Java keytool (the latest release, OpenDJ 2.6.0, works best with Oracle’s Java 7, not Java 8, or the OpenJDK).

There are actually 5 different certificate stores used by OpenDJ:

keystore and truststore – for client LDAPS connections
admin-keystore and admin-truststore – for admin utilities connections
ads-truststore – for replication connections

In the examples below, $DSHOME is /opt/opendj/ds-user2. The host name (CNAME, actually) is ldap2.example.com.

Back up everything before beginning, particularly the keystore and keystore.pin files.

Perform operations after changing your working directory to $DSHOME/config.

NOTE: To check the contents of the keystore (truststore, admin-keystore or admin-truststore):

keytool -list -v -keystore keystore -storepass `cat keystore.pin`

Changing the Server Certificate

1. Remove the existing certificates from both the keystore and truststore.

keytool -delete 
-alias server-cert 
-keystore keystore 
-storepass `cat keystore.pin`
keytool -delete 
-alias server-cert 
-keystore truststore 
-storepass `cat keystore.pin`

2. Create a new key pair.

keytool 
-genkey 
-alias server-cert 
-keyalg rsa 
-dname "CN=ldap2.example.com,O=Bigco,C=US" 
-keystore keystore 
-storepass `cat keystore.pin` 
-keypass `cat keystore.pin` 
-validity 1800

Note the storepass and keypass values are the same, this is required by OpenDJ. The value used is what is already in keystore.pin (hashed). Doing a `cat keystore.pin` is a clever way to reuse that value gleaned from the doc. You could (and probably should) substitute a new, strong, password (but be sure to delete keystore.pin before you do). The keystore name is “keystore” by default, the truststore “truststore”. It is recommended that you stick with that default names and paths,

3. Sign the certificate.

keytool 
-selfcert 
-alias server-cert 
-keystore keystore 
-storepass `cat keystore.pin`

Note: Changing the expiration date of the cert can be accomplished by re-running this command with “-validity [days]”, like “-validity 3600” to make it 10, rather than 5, years.

4. Export the cert.

keytool -export 
-alias server-cert 
-keystore keystore 
-storepass `cat keystore.pin` 
-file server-cert.crt

Note that by default keytool exports the cert in binary, not ASCII (a/k/a PEM) format. Binary format is what you want, as it is directly importable into the truststore.

5. Import the cert into the trust store.

keytool -import 
-alias server-cert 
-keystore truststore 
-storepass `cat keystore.pin` 
-file server-cert.crt

Changing the Admin Certificate

1. Remove the existing certificates from both the admin keystore and truststore.

keytool -delete 
-alias admin-cert 
-keystore admin-keystore 
-storepass `cat admin-keystore.pin`
keytool -delete 
-alias admin-cert 
-keystore admin-truststore 
-storepass `cat admin-keystore.pin`

2. Make the private key and store in keystore (have it expire in 5 years).

keytool -genkey 
-alias admin-cert 
-keyalg rsa 
-dname "CN=ldap2.example.com, O=Administration Connector Self-Signed Certificate" 
-keystore admin-keystore 
-storepass `cat admin-keystore.pin` 
-keypass `cat admin-keystore.pin` 
-validity 1800

3. Self-sign the cert.

keytool -selfcert 
-alias admin-cert 
-keystore admin-keystore 
-storepass `cat admin-keystore.pin`

4. Export the cert.

keytool -export 
-alias admin-cert 
-keystore admin-keystore 
-storepass `cat admin-keystore.pin` 
-file admin-cert.txt

5. Import the cert into the trust store.

keytool -import 
-alias admin-cert 
-keystore admin-truststore 
-storepass `cat admin-keystore.pin` 
-file admin-cert.txt

Effecting the Change

Restart the server to effect the change.

$DSHOME/bin/stop-ds --restart

Changing the Replication Cert

Changing the cert used for replication between OpenDJ servers uses an internal process to remove the old certificate and create a new one. Certificate attributes like hostname and expiration date are imported from the server certificate. The official doc, once again, does an admirable job of explaining what to do. Here are the steps from my own notes.

1. Delete the existing ads-certificate entry in the directory using ldapmodify.

Create an LDIF file like this:

# ads-del.ldif
dn: ds-cfg-key-id=ads-certificate,cn=ads-truststore
changetype: delete

Then run the command:

ldapmodify -h ldap2.example.com -p 1389 \
-D "cn=directory manager" -w xxxxx \
-f ads-del.ldif

2. Delete the ads-truststore and ads-truststore.pin files from $DSHOME/config.

3. Command the server to create a new ads-certificate entry with ldapmodify (this should create new ads-truststore and ads-truststore.pin files).

Create an LDIF command file:

# ads-add.ldif
dn: ds-cfg-key-id=ads-certificate,cn=ads-truststore
changetype: add
objectclass: ds-cfg-self-signed-cert-request

Now run ldapmodify:

ldapmodify -h ldap2.example.com -p 1389 \
-D "cn=directory manager" -w xxxxx \
-f ads-add.ldif

4. Restart the OpenDJ service to effect the change.

$DSHOME/bin/stop-ds --restart

NOTE: If replication is already enabled and running follow the more involved procedure in the documentation.

Enabling LDAPS Connections

This is covered elsewhere in the official documentation under Configuring Connection Handlers.

Configuring the Key Manager Provider

1. Set the file name and key store PIN in the File Based Key Manager Provider for JKS.

dsconfig 
set-key-manager-provider-prop 
--hostname ldap2.example.com 
--port 5445 
--bindDN "cn=Directory Manager" 
--bindPassword xxxxxxxx 
--provider-name JKS 
--set enabled:true 
--set key-store-pin:`cat keystore.pin` 
--remove key-store-pin-file:config/keystore.pin 
--trustAll 
 --no-prompt

The default admin port for OpenDJ is 4444. Many of us change that at install time. My practice is to use 5444 for the first instance on a server, 5445 for the second, and so on.

Also notice that the path entered for the keystore PIN is relative to $DSHOME. This is how OpenDJ likes it.

2. Set the File Based Trust Manager to use the same key store and PIN.

dsconfig 
set-trust-manager-provider-prop 
--hostname ldap2.example.com 
--port 5445 
--bindDN "cn=Directory Manager" 
--bindPassword xxxxxxx
--provider-name JKS 
--set enabled:true 
--set trust-store-file:config/keystore 
--set trust-store-pin:`cat keystore.pin` 
--trustAll 
--no-prompt

Enabling the TLS and/or SSL Listeners

To enable TLS (Transport Layer Security). This protocol is newer than SSL, and does not require the server listen on a special port for encrypted communications. It will instead listen on whatever is specified as the standard LDAP port (usually 389, but 1389 by default if OpenDJ is installed by a user other than root). If you install OpenDJ with TLS and LDAPS security it will already be enabled (making it unnecessary to follow these steps).

dsconfig 
set-connection-handler-prop 
--hostname ldap2.example.com 
--port 5445 
--bindDN "cn=Directory Manager" 
--bindPassword xxxxxxx 
--handler-name "LDAP Connection Handler" 
--set allow-start-tls:true 
--set key-manager-provider:JKS 
--set trust-manager-provider:JKS 
--trustAll 
--no-prompt

Most applications looking for “secure LDAP” really want LDAPS. If the application wants to connect over port 636, the standard LDAPS port, then LDAPS will need to be configured (as mentioned above, this can be set up during installation of OpenDJ).

dsconfig 
set-connection-handler-prop 
--hostname ldap.example.com 
--port 4444 
--bindDN "cn=Directory Manager" 
--bindPassword xxxxxxx 
--handler-name "LDAPS Connection Handler" 
--set listen-port:636 
--set enabled:true 
--set use-ssl:true 
--trustAll

If you want to have the server listen on port 636, its owner will need to be root because Java applications can’t be made to switch owners after starting up. The solution is to listen on a port above 1000, like 1636, and then use the host firewall to redirect incoming port 636 traffic to port 1636 (see how I do that here).

Changing the LDAPS port number can be done with this procedure, although you could also shut down the server and modify the $DSHOME/config/config.ldif file to accomplish the same result (search for ds-cfg-listen-port under “dn: cn=LDAPS Connection Handler, cn=Connection Handlers, cn=config”).

dsconfig 
set-connection-handler-prop 
--hostname ldap2.example.com 
--port 5445 
--bindDN "cn=Directory Manager" 
--bindPassword xxxxxx 
--handler-name "LDAPS Connection Handler" 
--set listen-port:1636 
--trustAll 
--no-prompt