kafka 2 way ssl authentication - ssl

I am trying to setup 2 way ssl authentication. My requirement is broker should authenticate only specific clients.
My organization has a CA which issue all certificates in pkcs12 format. steps i followed are as follows.
get a certificate for the broker and configured it in the broker keystore
ssl.keystore.location=/home/kafka/certificate.p12
ssl.keystore.password=xxxxx
ssl.client.auth=required
get a certificate for the client and configured it in the client keystore
ssl.keystore.location=/home/kafka/certificate.p12
ssl.keystore.password=xxxxx
extracted the public certificate from the client certificate using keytool command
keytool -export -file cert -keystore certificate.p12 -alias "12345" -storetype pkcs12 -storepass xxxxx
imported the certificate into broker truststore. broker truststore contains only the client 12345 certificate.
keytool -keystore truststore.p12 -import -file cert -alias 12345 -storetype pkcs12 -storepass xxxxx -noprompt
configured the truststore in the broker.
ssl.truststore.location=/home/kafka/truststore.p12
ssl.truststore.password=xxxxx
configured the truststore in client. client truststore contains CA certificates.
ssl.truststore.location=/etc/pki/java/cacerts
ssl.truststore.password=xxxxx
When i run the broker and client i expect the broker to authenticate the client and establish ssl connection. but instead following error is thrown.
[2021-06-03 23:32:06,864] ERROR [AdminClient clientId=adminclient-1] Connection to node -1 (abc.com/10.129.140.212:9093) failed authentication due to: SSL handshake failed (org.apache.kafka.clients.NetworkClient)
[2021-06-03 23:32:06,866] WARN [AdminClient clientId=adminclient-1] Metadata update failed due to authentication error (org.apache.kafka.clients.admin.internals.AdminMetadataManager)
org.apache.kafka.common.errors.SslAuthenticationException: SSL handshake failed
Caused by: javax.net.ssl.SSLProtocolException: Unexpected handshake message: server_hello
I tried various things but nothing seems to work. when i replace the broker truststore with /etc/pki/java/cacerts truststore file which contains only the CA certificate
then it works fine. but it will authenticate any client which has certificate issued by the CA.
what could be the issue ?

The default format is jks,
use keytool to create a Java KeyStore (JKS) with the certificate and key for use by Kafka. You'll be prompted to create a new password for the resulting file as well as enter the password for the PKCS12 file from the previous step. Hang onto the new JKS password for use in configuration below.
$ keytool -importkeystore -srckeystore server.p12 -destkeystore kafka.server.keystore.jks -srcstoretype pkcs12 -alias myserver.internal.net
Note: It's safe to ignore the following warning from keytool.
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore server.p12 -destkeystore kafka.server.keystore.jks -srcstoretype pkcs12"

Related

How to install CA certificate on Nexus 3?

I have installed Nexus Repository Manager OSS 3.0.2-02 on my CentOS Linux release 7.4.1708.
Also I have CA certificate:
Issued to: \*.mycompany.com
Issued by: Go Daddy Secure Certificate Authority - G2
Valid from 2016-11-12 to 2018-01-11
The RSA private key match with my CA certificate, which was checked with Certificate Key Matcher and reported:
The certificate and private key match!
In Nexus3 directory I made the following changes:
Added to the file org.sonatype.nexus.cfg the lines:
nexus-args=${karaf.etc}/jetty.xml,${karaf.etc}/jetty-http.xml,${karaf.etc}/jetty-requestlog.xml,${karaf.etc}/jetty-https.xml
application-port-ssl=8443
Added to jetty-https.xml file next lines:
KeyStorePath /ssl/test.jks
KeyStorePassword 123456
KeyManagerPassword 123456
TrustStorePath ssl/test.jks
TrustStorePassword 123456
Created SSL directory in $NEXUS_HOME/etc/ and created inside the SSL directory a Java keystore file test.jks with command:
openssl pkcs12 -export -in mycompany.com.pem -inkey key.pem -name xxx.mycompany.com -out test.pks
keytool -importkeystore -deststorepass 123456 -destkeystore test.jks -srckeystore test.pks -srcstoretype PKCS12
keytool -import -alias bundle -trustcacerts -file gd_bundle.crt -keystore test.jks
After Nexus restart I can't not reach it by URL //xxx.mycompany.com:8443. Firefox says:
The page you are trying to view cannot be shown because the
authenticity of the received data could not be verified
Also trying to do: docker login xxx.mycompany.com:8443 and providing default admin:admin:123 credentials cause:
Error response from daemon: Get xxx.mycompany.com:8443/v1/users/:
x509: certificate signed by unknown authority
I also try to chain certificates by various scenarions from Google, including How to add certificate chain to keystore?, but got error on Docker:
Error response from daemon: Get //xxx.mycompany.com:8443/v1/users/: EOF
on Firefox, the same as first time and on Chrome:
//xxx.mycompany.com unexpectedly closed the connection
Question: Where is my mistake, or how to correctly install CA certificate on Nexus3?
I've found the resolution. Just needed to set in jetty-https.xml next lines:
<Set name="NeedClientAuth"><Property name="jetty.ssl.needClientAuth" default="false"/></Set>
<Set name="WantClientAuth"><Property name="jetty.ssl.wantClientAuth" default="false"/></Set>

import ssl certificate in Glassfish

i have the following issue:
I obtain a free certificate from comodo (90 days) for my glassfish web application and then i have imported the certs into glassfish 3.1 by following http://javadude.wordpress.com/2010/04/06/getting-started-with-glassfish-v3-and-ssl/
I have also modify the domain.xml file by replacing the alias s1as with my certificate alias and the file keystore.jks with the server.keystore....but when i try to access my web application with https protocol i got the following log error:
[#|2012-10-12T14:41:18.828+0200|WARNING|glassfish3.1.2|com.sun.grizzly.config.Gr
izzlyServiceListener|_ThreadID=25;_ThreadName=http-thread-pool-443(1);|GRIZZLY00
07: SSL support could not be configured!
java.io.IOException: SSL configuration is invalid due to No available certificat
e or key corresponds to the SSL cipher suites which are enabled.
Please help me..i know that here i can find the solution to my issue...
Unfortunately I don`t have enough reputation to post images of glassfish console admin, but let me try to help somebody just using text.
NOTE1: The configuration was done on Ubuntu 12.04 server and glassfish 3.1.2
Comodo gives you 4 files
your_domain.key (your private key)
your_domain.crt (your public key)
PositiveSSLCA2.crt (CA public key)
AddTrustExternalCARoot.crt (CA public key)
Import every public key into the file cacerts.jks. To do that merge the public key files in one file:
NOTE2: The order of the files DOES matter.
cat your_domain.crt PositiveSSLCA2.crt AddTrustExternalCARoot.crt > all.crt
Now import them using keytool:
keytool -import -trustcacerts -alias tomcat -file all.crt -keystore cacerts.jks
Create a p12 file with your private key:
NOTE3: You can use the same password for every file to make things easier.
openssl pkcs12 -export -in all.crt -inkey your_domain.key -out your_domain.p12 - name your_alias -CAfile PositiveSSLCA2.crt -caname immed
NOTE4: Don`t forget you alias (your_alias), you will need to reference it in glassfish admin console later.
Now import the private key using keytool:
keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore keystore.jks -srckeystore your_domain.p12 -srcstoretype PKCS12 -srcstorepass changeit -alias your_alias
Now your keystore.jks (with your private keys) and your cacerts.jks (with you public key) are ready to me used. If you want to check if everything is ok run:
keytool -list -keystore keystore.jks
keytool -list -keystore cacerts.jks
Go to the glassfish admin console and find the session:
Configurations->server-config->HTTP Service->Http Listeners->http-listener-2
Go to the SSL tab and change the Certificate NickName to your_domain.
Restart Glassfish server.
Preconditions:
installed keytool and GlassFish 4.x (with default keystore password changeit)
your source keystore used to generate CSR
e.g. ~/mySourceKeystore.jks with password myPassword and private key with alias myAlias
your valid certificate (obtained from CA)
e.g. ~/myCertificate.crt with password myPassword and alias myAlias
certificate of CA (obtained from CA)
e.g. ~/AwesomeCA.crt
Here are all steps how to import SSL certificate into GlassFish:
Navigate to GLASSFISH-HOME/domains/domain1/config
Import your source keystore (with private key) into GlassFish keystore:
$ keytool -importkeystore -srckeystore ~/mySourceKeystore.jks -destkeystore keystore.jks`
Enter destination keystore password: changeit
Enter source keystore password: myPassword
Entry for alias server successfully imported.
Import command completed: 1 entries successfully imported, 0 entries failed or cancelled
Import certificate of CA into GlassFish keystore:
$ keytool -import -v -trustcacerts -alias AwesomeCA -file ~/AwesomeCA.crt -keystore keystore.jks
Enter keystore password: changeit
Certificate was added to keystore
[Storing keystore.jks]
Import obtained SSL certificate into GlassFish keystore:
$ keytool -import -v -trustcacerts -alias myAlias -file ~/myCertificate.crt -keystore keystore.jks
Enter keystore password: changeit
Enter key password for <myAlias>: myPassword
Certificate reply was installed in keystore
[Storing keystore.jks]
At this moment error java.security.UnrecoverableKeyException: Cannot recover key would occur during GlassFish startup because you have different keystore password and alias key password. To prevent this error you need to execute:
$ keytool -keypasswd -alias myAlias -new changeit -keystore keystore.jks
Enter keystore password: changeit
Enter key password for <myAlias>: myPassword
Change default alias (s1as) in GlassFish to your myAlias:
$ asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-2.ssl.cert-nickname=myAlias
(Optional) You can change default SSL port (8181) in GlassFish to well known 443:
$ asadmin set server.network-config.network-listeners.network-listener.http-listener-2.port=443
Restart GlassFish
For Glassfish 4.x you can follow this Comodo Guide
Here is the web archive if link expires.

Using self signed certificates

I am using self signed certificate for HTTPS connection to and from Axis2 server. All of these connections works fine and as desired.
There is a part in my web service which is responsible for sending emails. I am using GMail for the purpose of sending mail.
The problem is when I try to send a mail using an SSL connection I get certificate error, i.e. GMail certificate is not trusted. I had faced a similar problem with JBoss as well. For once I was able to get around this problem downloading GMail certificate and than importing it into the Keystore using Keytool utility. For a long time this had worked.
But only recently I have started to get the Old problem again. I tried to use the old technique that fixed the problem last time, but this time that did not work. (not sure why)
I reckon that GMail uses a signed certificate which out of the box should be trusted by any of the servers, let it be JBoss or Axis2. I fail to figure out what the problem actually is. Is it because of using of Self Signed certificate? Or are there any specific way of creating it so that the Signed certificates are trusted?
Thanks for the help.
To have a SSL encrypted Server/Client communication we need to Keystores and Truststore for Server & Client. Following are the steps to create them.
#Creating Server keystore and exporting a certificate
keytool -genkey -alias serverkeys -keyalg RSA -keystore server.keystore -storepass changeit -keypass changeit -dname "CN=test.com, OU=Test, O=Test, L=London, ST=London, C=UK"
keytool -export -alias serverkeys -keystore server.keystore -storepass changeit -file server.cer
#Creating Client keystore and exporting a certificate
keytool -genkey -alias clientkeys -keyalg RSA -keystore client.keystore -storepass changeit -keypass changeit -dname "CN=test.com, OU=test, O=test, L=London, ST=London, C=UK"
keytool -export -alias clientkeys -keystore client.keystore -storepass changeit-file client.cer
#Making a copy of cacerts file. These copies will be used for client/server truststore
cp /usr/java/jdk1.6.0_14/jre/lib/security/cacerts client.truststore
cp /usr/java/jdk1.6.0_14/jre/lib/security/cacerts server.truststore
#Copying server certificate to Client truststore
keytool -import -trustcacerts -v -keystore client.truststore -storepass changeit -file server.cer
#Copying Client certificate to Server truststore
keytool -import -trustcacerts -v -keystore server.truststore -storepass changeit -file client.cer
During the first few iteration I was not using cacert but directly create truststores from the certificate and that too worked well. Problems came up when we need to connect to some other services using SSL and connection could not be establised even when the service used a Signed Certificate.
For example connecting to GMail SMTP server would faile if the truststore were not created up from cacerts. Reason being even though GMail uses a signed certificate, we wold be using a truststore that would not know if the GMail certificate can be trusted. For this reason we used cacerts to create out truststore. After which we were able to connector any service that uses a Signed Certificate.
If in case we encounter a unsigned certificate we will then have to add them to the Components Truststore.

"unable to find valid certification path to requested target" after adding new Keystore to ActiveMQ

We use ActiveMQ to queue up messages from remote clients.
The clients use the following URL to connect to ActiveMQ on our server;
ssl://www.mydomain.com:61616
This worked fine in the past and was set up by a developer know longer with the company.
Recently we had to update our SSL Cert as the old one had ran out. We did this successfully for our http server but have only now realised that a copy of the original keystore still resided in the ActiveMQ config folders.
We have tried to place the new keystore into the ActiveMQ config folders, overwriting the old keystore. However this does not appear to work and all connections are rejected with the following stack trace;
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
What are we doing wrong here?
We've listed the contents of both the old and new keystore using the keytool -list command and they appear to be very similar (apart from the dates of course).
Is there additional updates we need to make to the clients calling the above url to accept our new keystore?
It may be that your truststore is out of synch with your keystore. Here is the general way to set it up from scratch; your config will differ, so adapt as needed:
Generate certs for each of the clients, and register the client certs with the broker truststore.
> keytool -genkey -alias producer -keyalg RSA -keystore myproducer.ks
> keytool -genkey -alias consumer -keyalg RSA -keystore myconsumer.ks
Export both certs
> keytool -export -alias producer -keystore myproducer.ks -file producer_cert
> keytool -export -alias consumer -keystore myconsumer.ks -file consumer_cert
Import the certs into the producer truststore (new file)
> keytool -import -alias producer -keystore mybroker.ts -file producer_cert
> keytool -import -alias consumer -keystore mybroker.ts -file consumer_cert
Copy the broker truststore to whichever location you had the old one in, usually {ACTIVEMQ_HOME}/conf. You can generally see this in your broker config:
<broker ...>
<sslContext>
<sslContext keyStore="file:${activemq.base}/conf/mybroker.ks"
keyStorePassword="test123"
trustStore="file:${activemq.base}/conf/mybroker.ts"
trustStorePassword="test123"/>
</sslContext>
</broker>

setup SSL connection with JSSE (Javase6) and self-signed certificate

I'm trying to build a simple client/server system wich uses SSLSocket to exchange data. (JavaSE 6)
The server must have its own certificate, clients don't need one.
I started with this
http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore
To generate key for the server and a self signed certificate.
To sum it up:
Create a new keystore and self-signed certificate with corresponding public/private keys.
keytool -genkeypair -alias mytest -keyalg RSA -validity 7 -keystore /scratch/stores/server.jks
Export and examine the self-signed certificate.
keytool -export -alias mytest -keystore /scratch/stores/server.jks -rfc -file server.cer
Import the certificate into a new truststore.
keytool -import -alias mytest -file server.cer -keystore /scratch/stores/client.jks
Then in my server code I do
System.setProperty("javax.net.ssl.keyStore", "/scratch/stores/server.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "123456");
SSLServerSocketFactory sf = sslContext.getServerSocketFactory();
SSLServerSocket sslServerSocket = (SSLServerSocket)sf.createServerSocket( port );
Socket s = sslServerSocket.accept();
I am basically missing some point because I get a "javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled." when I try to run the server.
Can it be a problem with the certificate? When using -validity in keytool the certificate gets self-signed, so it should work if I'm not wrong.
Reading the docs seems that setting the property "javax.net.ssl.keyStore" is sufficient for the SSLContext to setup correctly. Any suggestion?
I messed up things a little, complete solution is here: https://forums.oracle.com/forums/thread.jspa?threadID=1531716