AEM SSL Setup: AEM 6.1/6.2 & Java Keystore Based SSL ConfigurationJuly 18, 2018
As I noted in my other post on setting up AEM for server-to-server SSL, doing full SSL on AEM 6.3 and 6.4 can be done fairly simply these days using a relatively easy-to-use UI for the most part, with the SSL keys themselves stored in the repository. AEM 6.1 and 6.2 however required one to use a Java Keystore with the keys stored on-disk, a paradigm which still works for AEM 6.3/6.4 as well, though it’s somewhat deprecated and also significantly more difficult.
Most of the steps are in the official Adobe docs, though there are a few gotchas which I’ll document here to make it easier, should you need to set this up or debug it.
Generating SSL Certificates & Importing into Java Keystore
First, I’ll assume here that you’re going to need to generate SSL certificates that need to be signed by an external cert signing authority. Self-signed certs will work in AEM as well, but let’s just assume for the purposes of the docs here that you’re doing this for PRD and are required to use externally-valid SSL certs.
First, generate your cert-signing request (CSR) which will also create a JKS file and embed the private key for the SSL cert into the JKS file:
keytool -genkey -alias aem-author-test -keyalg RSA -keysize 2048 -keystore AEM_author_dev.jks -dname "CN=aem-author-dev.test.com, O=Companyname, L=CityName, ST=, C=US" && keytool -certreq -alias aem-author-test -file AEM_author_dev.csr -keystore AEM_author_dev.jks
Then, once you get the signed certs back from your certificate authority, you may first need to install their intermediate certs or root certs into your JKS file, presuming their intermediate certs aren’t embedded in the JDK. This is a vital step if your organization runs its own cert authority.
#import the Root cert into the keystore keytool -importcert -trustcacerts -file rootcert.pem -keystore AEM_author_dev.jks -alias "Root CA Cert" #import the intermediate cert into the keystore, ensuring the alias is correct (you can import into a browser to check) keytool -importcert -trustcacerts -file intermediatecert.pem -keystore AEM_author_dev.jks -alias "Intermediate Cert"
After this, you’ll want to import your signed cert back into the JKS file. First, make sure you have the alias correct for the cert you’re importing (important if you’re doing this for many servers). To see the certs which are loaded in a given JKS file use:
[me@localhost ssl]$ keytool -list -keystore aem-author-test.jks Enter keystore password: Keystore type: JKS Keystore provider: SUN Your keystore contains 3 entries test root ca, Nov 14, 2017, trustedCertEntry, Certificate fingerprint (SHA1): E6:45:FF:B1:C6:27:FA:A4:5C:06:1E:C7:5D:53:8C:86:37:93:C2:33 aem-author-test, Nov 14, 2017, PrivateKeyEntry, Certificate fingerprint (SHA1): 66:5F:F2:F3:E2:F3:FF:82:6D:15:FB:F3:F1:F0:AD:A9:D8:4D:4B:9D test intermediate ca, Nov 14, 2017, trustedCertEntry, Certificate fingerprint (SHA1): E6:45:FF:B1:C6:27:FA:A4:5C:06:1E:C7:5D:53:8C:86:37:93:C2:33
In this case, the ‘alias’ you would use for your import command would be ‘aem-author-test’. The alias is just a key to the entries in the JKS database. It’s an arbitrary name and can be anything you want.
(Important Note: have not tested this alias with ¯\_(ツ)_/¯ emoji, so perhaps not anything you want)
Import the signed cert back in with:
#import the signed cert into the keystore, using the same alias as you used above keytool -importcert -trustcacerts -file my-signed-cert.der -keystore AEM_author_dev.jks -alias "aem-author-test"
Assuming the alias names line up between the CSR and the imported signed cert, you’ll see:
Enter keystore password: Certificate reply was installed in keystore
When you import the cert.
Configuring AEM to use SSL
To get AEM to run on SSL using the certificate you’ve just created, you’ll need to do the following:
- Open CRXDE Lite and select the /apps folder. Click Create > Create Folder to create a folder named system (http://localhost:4502/crx/de).
- Below the system folder create a folder named config.author (or config.publish if this is a publisher)
- Select the /apps/system/config.author node.
- Click Create > Create Node and enter the following properties:
- Name: org.apache.felix.http
- Type: sling:OsgiConfig
- Add properties to the node according to the following table:
|org.osgi.service.http.port.secure||Long||5443 (what you want as your AEM SSL port)|
(or wherever you’ve put this keystore)
|org.apache.felix.https.keystore.password||String||The keystore password|
|org.apache.felix.https.keystore.key||String||The SSL key alias noted above (i.e. aem-author-test)|
|(optional) org.apache.felix.https.keystore.key.password||String||JKS files support a password on individual certificate entries in addition to the keystore password. If your key has one, put the password here. Otherwise, do not include this value.|
|(optional) org.apache.felix.https.truststore||String||Path to truststore. If you use a 3rd-party cert signing authority, you may need to create a separate truststore which includes the 3rd-party intermedia/root certs. If so, add this truststore path here.|
|(optional) org.apache.felix.https.truststore.password||String||Truststore password.|
|(Optional) org.apache.felix.https.clientcertificate||String||Defaults to none|
After you’ve added these nodes, click Save All in crxde. If you’re tailing the log, you’ll see a number of org.apache.felix entries streaming past, and you may see SSL attempt to be enabled. Once Felix finishes refreshing, restart the entire AEM instance.
Once AEM restarts, you should see an entry like this in the logs, indicating that it’s listening on the HTTPS port:
17.07.2018 22:04:01.142 *INFO* [CM Configuration Updater (ManagedService Update: pid=[org.apache.felix.http])] org.apache.felix.http.jetty Started Jetty 9.2.19.v20160908 at port(s) HTTP:4503 HTTPS:6443 on context path / [minThreads=8,maxThreads=200,acceptors=1,selectors=1]
Adding Truststore to the JVM
Some features of AEM, when making outbound calls, originate from within Felix and will use the org.apache.felix.https.truststore value you set up above for the truststore. However, some other calls (replication, flush agent requests) are made directly by the JDK, and require that the truststore you added be loaded into the JDK as well.
To do this, you will need to add an extra argument into your AEM start script to add a truststore to the JVM as well: