View Source:
JavaLdapCerts
You are viewing an old revision of this page.
View the current version.
!!! Java, LDAP, and Chained Self-Signed Certificates !! Introduction I had a java / tomcat app (Artifactory) that was configured to use LDAP for user authentication, and I was asked to make it use LDAP over SSL with a self-signed certificate. That turned out to be not very well documented, so here are my notes on how to do it. First of all, you need to understand how java applications use security certificates. There's a certificate store file (typically called <code>cacerts</code>) that contains all the public ssl trusted root keys. That file is loaded by the java interpreter when it starts up and serves as the source of truth for which certificates to trust. If your application uses an 'officially' signed certificate, everything will automatically work. However, you may need to use a self-signed certificate. In this case, java doesn't know about the authenticity of your certificate because it isn't a descendent of one of the official root certificates. Thus you need to manually add your server public key to a new <code>cacerts</code> file and tell java to use that file instead of the default one. !! Obtaining Public Certificates In my case, I needed to make my tomcat application accept a self-signed certificate from my ldap server. The first step is to download the public certificate(s) from the ldap server (or whatever sort of server you are trying to use): {{{ openssl s_client -connect 192.168.1.10:636 -showcerts < /dev/null > certs.txt }}} Next, examine the <code>certs.txt</code> file. It will contain at least one certificate between <code>BEGIN CERTIFICATE</code> and <code>END CERTIFICATE</code> lines. It may as in my case contain two or more certificates. You need to put each of these certificates in separate files, preserving only the BEGIN and END lines and everything in between. All the other text in the certs.txt file can be discarded. I created two files, <code>192.168.1.10</code> and <code>intermediate</code>. Next, you need a copy of your existing java <code>cacerts</code> file. As I mentioned, that file contains all the public ssl certificates that java trusts. In my case, that file was <code>/usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts</code>. I made a copy of that file in /tmp. !! Adding Certificates Use the keytool program to add the new certificates to the <code>cacerts</code> file. You need to add every certificate that the server returned. Documentation on the internet is not clear on this point. Each certificate must be added with a different alias in the cacerts file. In my case: {{{ $ for i in intermediate 192.168.1.10; do keytool -import -trustcacerts -file $i -keystore cacerts -alias $i }}} keytool will ask you for the cacerts file password each time it tries to add a certificate. The default file for the cacerts file is //changeit//. keytool will also ask you whether to trust each certificate as you add it. Choose 'yes'. You can verify that your new certificates are part of the cacerts file by running <code>keytool -list -v -keystore cacerts |less</code>. You now have an updated cacerts files, next you need to tell java to use it. Place the file in an appropriate location (in my case /etc/opt/jfrog/artifactory/cacerts) and modify your startup JAVA_OPTIONS: {{{ echo "export JAVA_OPTIONS=\"\$JAVA_OPTIONS -Djavax.net.ssl.trustStore=/etc/opt/jfrog/artifactory/cacerts\"" \ >> /etc/opt/jfrog/artifactory/default }}} this will obviously vary depending on what tomcat application you are using. Restart your java app and verify that the new cacerts file has been loaded by using <code>ps</code> to check that the javax.net.ssl.trustStore option is set and points to your new cacerts file. !! Server Config Now that java has your self-signed certificates, you need to modify your server configuration to use ssl. Again in my case I'm using Artifactory but other apps will need similar configuration changes. Navigate to the Artifactory web page and log on as an administrator. Go to <code>Admin->Security->LDAP</code> and modify your ldap server to ldaps, i.e. <code>ldaps://192.168.1.10</code>. Save your settings and use the 'Test LDAP Connection' box to confirm that user authentication is now working over SSL. !! Troubleshooting It can be useful to verify that java can make ssl connections without going through your tomcat application. To do this, use the java utility <code>SSLPoke</code>, which you can [[https://confluence.atlassian.com/kb/unable-to-connect-to-ssl-services-due-to-pkix-path-building-failed-779355358.html|download from Atlassian]]. To test that you can make ssl connections to an ldap server, use {{{ $ /usr/bin/java -Djavax.net.ssl.trustStore=/etc/opt/jfrog/artifactory/cacerts SSLPoke 192.168.1.10 636 }}} if that command succeeds, you know that your java is loading your self-signed certificates correctly. You can also turn on ssl debugging by passing <code>-Djavax.net.debug=all</code> in your java startup. That will print lots and lots of debug messages about ssl when your app tries to make ssl connections. In the case of Artifactory, those messages will be printed to <code>/etc/opt/jfrog/artifactory/logs/catalina/catalina.out</code>. You can also check <code>/etc/opt/jfrog/artifactory/logs/artifactory.log</code> for any other ldap error messages. If you see {{{ Authentication failed. Probably a wrong manager dn or manager password: [LDAP: error code 49 - 80090308: LdapErr: nested exception is javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, }}} that means that the ldap server is not accepting your username/password. If you see {{{ [Root exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPath BuilderException: unable to find valid certification path to requested target] }}} that means that java is not finding your self-signed certificates in the cacerts file. !! Conclusion Well, that's how you deal with self-signed certificates in java. IT's a confusing process so I hope that these notes help others.
Please enable JavaScript to view the
comments powered by Disqus.
HollenbackDotNet
Home Page
Popular Pages
All Categories
Main Categories
General Interest
Geek Stuff
DevOps
Linux Stuff
Pictures
Search
Toolbox
RecentChanges
RecentNewPages
What links here
Printable version
AllPages
RecentChanges
Recent Changes Cached
No changes found
Favorite Categories
ActionPage
(150)
WikiPlugin
(149)
GeekStuff
(137)
PhpWikiAdministration
(102)
Help/PageList
(75)
Help/MagicPhpWikiURLs
(75)
Blog
(69)
Pictures
(60)
GeneralInterest
(44)
LinuxStuff
(38)
Views
View Page
View Source
History
Diff
Sign In