Connecting Mulesoft to Kafka hosted at Heroku - heroku

community!
I'm trying to connect my Mulesoft application to a Kafka Server that is hosted at Heroku. Anypoint Studio 7 (Mule 4) have a Kafka connector that has a few options to connect (Basic, Kerberos, Kerberos SSL and SSL):
According to Heroku's docs it "support" SSL but does not mention that is required. Can anyone confirm?
Heroku documentation that I saw [https://devcenter.heroku.com/articles/kafka-on-heroku]
When I set up an app at Heroku, add the Kafka AddOn, create the topic, I get the bootstrap server(s) from running the command heroku config:get KAFKA_URL If I try to to abasic test I get the following error:
The error states org.mule.runtime.api.connection.ConnectionException: invalid connection!
org.mule.runtime.api.connection.ConnectionException: invalid connection!
Caused by: org.apache.kafka.common.errors.TimeoutException: Timed out waiting for a node assignment.
what I'm trying to build is a PoC with 2 flows... one that produces a message to a Topic and the other flow to consume from it.
Any help on how to set up the connector and the Heroku environment will be most welcome
UPDATE:
I found that when you create the app at Heroku and include the KAFKA addon, you get the following variables:
KAFKA_URL: A comma-separated list of SSL URLs to the Kafka brokers making up the cluster. Example:
kafka+ssl://ec2-3-*****-100.compute-1.amazonaws.com:9096,kafka+ssl://ec2-3-******-127.compute-1.amazonaws.com:9096
KAFKA_TRUSTED_CERT: The brokers’ SSL certificate (in PEM format), to check that you’re connecting to the right servers. Example:
-----BEGIN CERTIFICATE----- MIIDfzCCAmegAwIBAgIBADANBgkqhkiG9w0BAQsFADAyMTAwLgYDVQQDDCdjYS1l
ZjQwOWUzNy00NjhhLTRiMGEtOGVkOC0wZWYxMmRhYjkyZWEwHhcNMTkxMjEyMTUx
NzU5WhcNMjkxMjEyMTUxNzU5WjAyMTAwLgYDVQQDDCdjYS1lZjQwOWUzNy00Njhh
KAFKA_CLIENT_CERT: The required client certificate (in PEM format) to authenticate clients against the broker. Example:
-----BEGIN CERTIFICATE----- MIIDQzCCAiugAwIBAgIBADANBgkqhkiG9w0BAQsFADAyMTAwLgYDVQQDDCdjYS1l
ZjQwOWUzNy00NjhhLTRiMGEtOGVkOC0wZWYxMmRhYjkyZWEwHhcNMjAwMTE1MTU1
MjU2WhcNMzAwMTE1MTU1MjU2WjAZMRcwFQYDVQQDDA51NnZtYWVzM2cwZnMyZjCC
KAFKA_CLIENT_CERT_KEY: The required client certificate key (in PEM format) to authenticate clients against the broker.
Kafka clusters require authenticating using the provided client certificate. Any requests not using the client certificate will be denied. Example:
-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAmmu+j9DulVnqwIOt02++6Ehw9Mg7KaocdIQjODVtVipC5AyK
iaHsdNVh9bgJQAJSfstIV/6O1mCLmjUS/YmyIEEgmBvATFxcldPGBGcpPVSV2R3Q
I assume that I need to "transform" those into the KeyStore and TrustStore for the Connector SSL config.. can anyone confirm? since for what I see from the docs, SSL is required
Another Update:
I downloaded the certificates I describe above and using the tool "Key explorer" I created a keystore.jks and imported the KAFKA_CLIENT_CERT and KAFKA_CLIENT_CERT_KEY into it and then I created a truststore.jsk and imported the file KAFKA_TRUSTED_CERT there. on both cases I set a basic password ... was looking good but I get an error:
org.mule.runtime.api.connection.ConnectionException: invalid connection!
org.mule.runtime.api.connection.ConnectionException: invalid connection!
Caused by: org.apache.kafka.common.errors.SslAuthenticationException: SSL handshake failed
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1521)
at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:528)
at sun.security.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1197)
at sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1165)
at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:469)
at org.apache.kafka.common.network.SslTransportLayer.handshakeWrap(SslTransportLayer.java:448)
at org.apache.kafka.common.network.SslTransportLayer.doHandshake(SslTransportLayer.java:313)
at org.apache.kafka.common.network.SslTransportLayer.handshake(SslTransportLayer.java:265)
at org.apache.kafka.common.network.KafkaChannel.prepare(KafkaChannel.java:170)
at org.apache.kafka.common.network.Selector.pollSelectionKeys(Selector.java:547)
at org.apache.kafka.common.network.Selector.poll(Selector.java:483)
at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:540)
at org.apache.kafka.clients.admin.KafkaAdminClient$AdminClientRunnable.run(KafkaAdminClient.java:1196)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1709)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:318)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
at sun.security.ssl.Handshaker$1.run(Handshaker.java:970)
at sun.security.ssl.Handshaker$1.run(Handshaker.java:967)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1459)
at org.apache.kafka.common.network.SslTransportLayer.runDelegatedTasks(SslTransportLayer.java:402)
at org.apache.kafka.common.network.SslTransportLayer.handshakeUnwrap(SslTransportLayer.java:484)
at org.apache.kafka.common.network.SslTransportLayer.doHandshake(SslTransportLayer.java:340)
... 7 more
Caused by: java.security.cert.CertificateException: No name matching ec2-3-220-121-33.compute-1.amazonaws.com found
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:231)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:96)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:252)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1626)
... 16 more
Could be related to the line Caused by:
java.security.cert.CertificateException: No name matching
ec2-3-220-121-33.compute-1.amazonaws.com found

I got it to work.
create the JKS files using these commands (require HEROKU CLI)
client_key=`heroku config:get KAFKA_CLIENT_CERT_KEY --app <SET_HEROKU_APP_NAME_HERE>`
client_cert=`heroku config:get KAFKA_CLIENT_CERT --app <SET_HEROKU_APP_NAME_HERE>`
trusted_cert=`heroku config:get KAFKA_TRUSTED_CERT --app <SET_HEROKU_APP_NAME_HERE>`
# Write config vars to files.
echo "$client_key" >> keystore.pem
echo -n "$client_cert" >> keystore.pem
echo -n "$trusted_cert" > truststore.pem
# Set passwords
TRUSTSTORE_PASSWORD=<SET_PASSWORD_HERE>
KEYSTORE_PASSWORD=<SET_PASSWORD_HERE>
echo $TRUSTSTORE_PASSWORD
echo $KEYSTORE_PASSWORD
# Import cert.
keytool -importcert -file truststore.pem -keystore kafka.client.truststore.jks -deststorepass $TRUSTSTORE_PASSWORD -noprompt
# Create PKCS12 file.
openssl pkcs12 -export -in keystore.pem -out keystore.pkcs12 -password pass:$KEYSTORE_PASSWORD
# Create jks files.
keytool -importkeystore -srcstoretype PKCS12 \
-destkeystore kafka.client.keystore.jks -deststorepass $KEYSTORE_PASSWORD \
-srckeystore keystore.pkcs12 -srcstorepass $KEYSTORE_PASSWORD
Then config the connector with the SSL option and add the following INLINE:

Related

How to establish SSL connection from Spring Boot client to Redis Server

Having my redis server with self_signed certificate (in certificate_base64 format) running on IBM cloud. wanted to connect to redis (server) through SSL from Spring Boot application (client).
Tried decrypting the base64 and saved it as .cer file and stored that certification in C:\Program Files\Java\jre1.8.0_341\lib\security\cacerts using the command line keytool -keystore "JRE_CA_CERT_PATH" -import -alias servername -file ".cer FILE"
but it was not as expected, still got unable to find valid certification path to requested target
I'm super new to this topic, any thoughts here would be helpful :-)

Making POST request on HTTPS using Jira API in a Jira instance

My Jira instance is running on an HTTPS port. I have written a script that creates sub-tasks of a task in a project using a Jira API POST request on the Jira instance. It was working fine on my HTTP version. When I shifted to the HTTPS version, it started giving errors.
Error 1:
It gave the certificate error that was not present in Java.
Resolution. I resolved the issue using the below commands in my Jira instance.
openssl x509 -in <(openssl s_client -connect 192.168.2.214:8083 -prexit 2>/dev/null) -out ~/server-name.crt
keytool -importcert -file ~/server-name.crt -alias server-name -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
My Instance is running on AWS and has different internal and external IPs to access it.
The problem I am facing after resolving the above issue is :
javax.net.ssl.SSLHandshakeException: No subject alternative names matching IP address 192.168.2.214 found
at Script2.run(Script2.groovy:11)
Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 192.168.2.214 found
... 1 more
My internal IP is 192.168.2.214 and my external IP is different from it.
My external IP is mapped to a URL and the certificate is purchased against that URL.
How do I get rid of this error as I only can access my HTTPS port using the internal IP when making an API call and there is no HTTP port defined. If I define an HTTP port, I would need to reconstruct my whole instance which is not possible at the moment.

SpringBoot fails to start due to jsse.alias_no_key_entry using JKS with GoDaddy signed certificate

I am trying to secure my SpringBoot server with SSL. I've generated a keystore and CSR. I received the intermediate and domain certificate from GoDaddy. I imported those into my keystore that was used to generate the CSR.
I used the following commands to generate the keystore and CSR.
keytool -genkey -alias server-alias -keyalg RSA -keysize 2048 -keystore keystore.jks -dname "CN=name,OU=Unit, O=Org, L=NoWhere, ST=NoWhere, C=CA"
keytool -certreq -alias server-alias -file domain.csr -keystore keystore.jks
In my SpringBoot application, I have the following configurations in my applications.properties file.
server.ssl.key-store-type=JKS
server.ssl.key-store=location/keystore.jks
server.ssl.key-store-password=password
server.ssl.key-alias=server-alias
security.require-ssl=true
I received the follow exception cause on startup:
Caused by: java.io.IOException: jsse.alias_no_key_entry
at org.apache.tomcat.util.net.SSLUtilBase.getKeyManagers(SSLUtilBase.java:317)
at org.apache.tomcat.util.net.SSLUtilBase.createSSLContext(SSLUtilBase.java:239)
at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:97)
... 20 common frames omitted
I would really appreciate any help. Thanks!
There seem to be (at least) a couple reasons that this can occur:
The keystore contains a cert but not a private key ... or at least not the right key. See How to resolve : java.io.IOException: jsse.alias_no_key_entry
You have simply configured the wrong alias; if you enter an alias that does not exist in the keystore, you will get this same error.
The alias being looked up needs to exist in the keystore, and the associated private key needs to exist there (not just the cert.) If those conditions aren't met, it will throw this error.

Configure Keycloak with server certificate bundle

I have configured HTTPS on a Keycloak server by placing a certificate A.crt in a Java keystore and configuring that keystore in standalone.xml. HTTPS access has worked well from a given client so far. The certificate is signed by an intermediate CA B, which is signed by a root CA C.
I now encounter problems when accessing Keycloak from another client. It says: "unable to get local issuer certificate" or "certificate signed by unknown authority" (depending on the client software). I'm quite sure the root cause is that CA certificate B.crt is not known to this client. A strong indication is that I can access Keycloak from that client with curl --cacert B.crt https://keycloak....
Since I cannot predict which clients will have what CA certificates installed I would like to configure a bundle consisting of A.crt, B.crt, and C.crt as root certificate. If this were a server that directly took a PEM certificate I would use the bundle resulting from cat A.crt B.crt C.crt > bundle.crt, but because of its use of a Java keystore this is not an option with Keycloak.
So how can I store a server certificate bundle (it that's the right terminology) into a Java keystore so that Keycloak can make use of it in such a way that "all" clients can access the service?
UPDATE I've tried adding the intermediate and root certificates B and C to the keystore already used by Keycloak, but this did not solve the current issue:
keytool -import -alias b -file B.crt -keystore $KEYSTORE
keytool -import -alias c -file C.crt -keystore $KEYSTORE
You said having a keystore configured in your standalone.xml where A.crt was imported, but do you have a truststore? You could try adding B.crt in your truststore.

UI not opening in the nifi 1.0.0 secure cluster

Tried to form a secure cluster in nifi 1.0.0 by following the instructions from the below link
http://bryanbende.com/development/2016/08/17/apache-nifi-1-0-0-authorization-and-multi-tenancy
I have generated keystore and truststore file in the target folder, from nifi-cert.pem and nifi-key.key I have generated the p12 file and loaded it in browser
After starting the nif instances, nodes has been connected and exchanging the heartbeat signals between them and the port specified are listening to their numbers but when we launch the UI, It's not viewing in the browser
Update:
Update:
Update:
Update:
due to org.apache.nifi.cluster.protocol.ProtocolException: Failed marshalling protocol message in response to message type: CONNECTION_REQUEST due to java.net.SocketException: Software caused connection abort: socket write error
org.apache.nifi.cluster.protocol.ProtocolException: Failed marshalling protocol message in response to message type: CONNECTION_REQUEST due to java.net.SocketException: Software caused connection abort: socket write error
at org.apache.nifi.cluster.protocol.impl.SocketProtocolListener.dispatchRequest(SocketProtocolListener.java:176) ~[nifi-framework-cluster-protocol-1.0.0.jar:1.0.0]
at org.apache.nifi.io.socket.SocketListener$2$1.run(SocketListener.java:136) [nifi-socket-utils-1.0.0.jar:1.0.0]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_91]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91]
There are a couple steps you can take to continue debugging:
Run NiFi with Java TLS (SSL) debugging enabled. In conf/bootstrap.conf add the line java.arg.15=-Djavax.net.debug=ssl,handshake (ensuring that 15 is a number that does not conflict with your existing list of arguments). This will add a substantial amount of log output, but will explicitly document any TLS handshake negotiation attempts.
Use the OpenSSL s_client tool to debug the connection. Running the command below will attempt a handshake negotiation with additional log output: $ openssl s_client -connect <host:port> -debug -state -cert <path_to_your_cert.pem> -key <path_to_your_key.pem> -CAfile <path_to_your_CA_cert.pem>
Substitute your server for <host:port>
Substitute your public key certificate for <path_to_your_cert.pem>
Substitute your private key for <path_to_your_key.pem>
Substitute your server's public key certificate or the CA public key certificate for <path_to_your_CA_cert.pem>
You can extract the public key certificate and private key from your PKCS12 keystore by using the following commands
Extract the private key: $ openssl pkcs12 -in CN\=Andy_LoPresto_OU\=Apache_NiFi.p12 -nocerts -out client.key
Extract the public key: $ openssl pkcs12 -in CN\=Andy_LoPresto_OU\=Apache_NiFi.p12 -clcerts -nokeys -out client.pem
As #bryan-bende pointed out above, the error message in the browser screenshot you shared does seem to indicate that the TLS cipher suites cannot be negotiated due to a protocol version incompatibility. The commands above will output all available cipher suites for the connection. You can also use a tool like CipherScan to enumerate these explicitly.
One possible issue is that Java 7 defaults to TLS 1.0 and Java 8 to TLS 1.2. What OS and JRE are you using to host NiFi?
In some rare cases, a user deploys NiFi with a keystore that does not actually contain an RSA key, and TLS handshake negotiation fails because "no cipher suites are available", when the issue is really that all of the available cipher suites require an RSA key (if not to encrypt the actual channel data, at least to sign the ephemeral keys). Can you verify that the keystore you provided NiFi has a valid (check dates as well) private key available?
Hopefully these steps help you diagnose the issue. If you can provide more information, we're happy to work with you to investigate further.

Resources