Implementing SSL on AEM
July 17, 2018By default, server-to-server communication on AEM is all in plaintext HTTP. As these connections are usually all on the backend, this generally isn’t much of a security concern aside from the fact that the user that is used to replicate content between AEM Author & Publish instances generally has sufficient permissions to create & replicate content throughout the entire site. So, anyone sniffing traffic momentarily on the network would see the masses of repl events between servers, and thus you have yourselves a compromised site.
Table of Contents
SSL in AEM 6.3, 6.4 and Later
Though there is definitely a performance hit for running SSL on AEM, most of why most implementations I’ve seen tend to go all-http instead of all-SSL is complexity. SSL on AEM 6.2 and earlier was a nightmare. However, Adobe implemented a vastly simplified scheme to implement SSL on Adobe Experience Manager 6.3. The following instructions work to get SSL up between AEM instances, using self-signed certs:
1) First create the keys you’ll need for AEM. Below are the steps for generating a self-signed certificate.
### Create Private Key $ openssl genrsa -aes256 -out localhostprivate.key 4096 ### Generate Certificate Signing Request using private key $ openssl req -sha256 -new -key localhostprivate.key -out localhost.csr -subj '/CN=localhost' ### Generate the SSL certificate and sign with the private key, will expire one year from now $ openssl x509 -req -days 365 -in localhost.csr -signkey localhostprivate.key -out localhost.crt ### Convert Private Key to DER format - SSL wizard requires key to be in DER format $ openssl pkcs8 -topk8 -inform PEM -outform DER -in localhostprivate.key -out localhostprivate.der -nocrypt
1a) Generate a separate unencrypted private key to use for Apache
[me@localhost ssl]$ openssl rsa -in localhostprivate.key -out localhost_apache.key Enter pass phrase for localhostprivate.key: writing RSA key
1b) Create a new file that has the key on top and the crt below it, to be used on the apache servers. You’ll put it at /etc/pki/tls/certs/.
2) On the Author or publisher, go into http://localhost:4502/libs/granite/security/content/sslConfig.html to configure SSL. Upload the .der file generate above as the key, and the .crt file as the certificate
3) AEM will then fire up on SSL without a restart. I like to restart it anyhow after SSL is instantiated, but it will in-fact work on the SSL port that you’ve configured without an AEM restart.
Further info on this is on Adobe’s site here:
- https://helpx.adobe.com/experience-manager/kt/platform-repository/using/ssl-wizard-technical-video-use.html
- https://helpx.adobe.com/experience-manager/6-3/sites/administering/using/ssl-by-default.html
AEM SSL Keystore Location in the new 6.3+ way vs the old way
It’s worth noting that AEM stores the SSL certificates in different locations on pre-6.3 releases, than it now does currently. Up through AEM 6.2, SSL was configured by creating org.apache.felix.https configurations directly, and then storing the SSL truststore and keystores on-disk in a Java keystore (JKS) file.
With AEM 6.3 and later (it’s unchanged in 6.4 and 6.5), AEM now stores the keystore in the JCR, under /home/users/system/security/ssl-service/keystore/store.p12, and the truststore is in /etc/truststore/truststore.p12.
Problems when Upgrading from an earlier SSL implementation into AEM 6.3/6.4/6.5
When I’ve done in-place upgrades of an SSL-enabled AEM 6.2 instance to AEM 6.3 or 6.4, the legacy org.apache.felix.https configurations were migrated over with the upgrade, and SSL continued to work as before.
However, don’t try to then update SSL using the new SSL wizard, as the configurations will then get into a fight and won’t work. You’ll have to use one or the other.
Steps for SSL installation on the Dispatcher
These are the steps I’ve done to get SSL working both for inbound HTTP requests, as well as for the backend SSL requests that are then made to the publishers.
- Install mod_ssl (command below is for mod_ssl on Apache 2.4 for CentOS 7)
yum install httpd24u-mod_ssl
- Make a new vhost_ssl.conf file in /etc/httpd/vhosts/ (assuming you’re using such) which will take the *:443 requests:
<VirtualHost *:443> ServerName ThisFrickingServerName DocumentRoot /var/www/html/ DocumentRoot /var/www/html ErrorLog logs/ssl_error_log TransferLog logs/ssl_access_log LogLevel warn SSLEngine on SSLProtocol all -SSLv3 SSLProxyProtocol all -SSLv3 SSLHonorCipherOrder on SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4 SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4 SSLCertificateFile /etc/pki/tls/certs/environment_name.crt <Directory /var/www/html/> <IfModule mod_deflate.c> # Enable gzip compression SetOutputFilter DEFLATE # Don't compress binaries SetEnvIfNoCase Request_URI .(?:exe|t?gz|zip|iso|tar|bz2|sit|rar) no-gzip dont-vary # Don't compress images SetEnvIfNoCase Request_URI .(?:gif|jpe?g|jpg|ico|png) no-gzip dont-vary # Don't compress PDFs SetEnvIfNoCase Request_URI .pdf no-gzip dont-vary # Don't compress flash files SetEnvIfNoCase Request_URI .flv no-gzip dont-vary # Netscape 4.X has some problems BrowserMatch ^Mozilla/4 gzip-only-text/html # Netscape 4.06-4.08 have some more problems BrowserMatch ^Mozilla/4.0[678] no-gzip # MSIE masquerades as Netscape, but it is fine BrowserMatch \bMSIE !no-gzip !gzip-only-text/html # Make sure proxies don't deliver the wrong content Header append Vary User-Agent env=!dont-vary </IfModule> <IfModule disp_apache2.c> SetHandler dispatcher-handler ModMimeUsePathInfo On DirectorySlash Off </IfModule> Options FollowSymLinks AllowOverride None </Directory> </VirtualHost>
For the SSLCertificateFile listed above, paste in the name you saved your new cert as.
- Update Dispatcher module in /etc/httpd/modules to at least 4.2.3 from https://www.adobeaemcloud.com/content/companies/public/adobe/dispatcher/dispatcher.html and ln -s /etc/httpd/modules/mod_dispatcher.so to this new version. NOTE: The AWS boxes we’ve been using have come with OpenSSL 1.0.2k which does not work with Dispatcher 4.2.2 and earlier. It will work on the front side, but will not make SSL backend connections and you’ll get errors. Make sure that it is the SSL version of the dispatcher as well. If the file is already there, remove it and download this version of it.
- Change your dispatcher.any to point at the SSL port on the backend author or publisher:
/renders { /ThisFrickingRenderName { /hostname "127.0.0.1" /port "5443" #put in your ssl port here /timeout "0" /secure "1" #this enables SSL on the dispatcher } }
- Restart Apache
I’ll make a separate post on how to do SSL on AEM 6.2 and earlier, as with those you have to keep your SSL keys in a Java keystore (.jks file) on-disk, and manage your SSL inside of those JKS files. Also, there are a number of OSGI console configs you have to make (difficult to automate generically).
Hope this works well for you!
[…] 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 […]