can't connect to mqtt broker via ssl - java

I have a raspberry running a mqtt broker and a java backend. I can't establish a connection from backend to broker since I've implemented ssl. I can connect the backend to the broker on raspberry from my IDE running on my MacBook like:
client = new MqttAsyncClient(
"ssl://my-domain.com:1883", "backend");
if the backend is on the raspberry I tried:
client = new MqttAsyncClient(
"ssl://localhost:1883", "backend");
client = new MqttAsyncClient(
"ssl://127.0.0.1:1883", "backend");
No success. I´ve never used a ssl connection in this context. did I oversee something?
Error:
Exception in thread "main" No connection to client (32104)
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:31)
at org.eclipse.paho.client.mqttv3.internal.ClientComms.sendNoWait(ClientComms.java:143)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.subscribe(MqttAsyncClient.java:721)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.subscribe(MqttAsyncClient.java:681)
at com.cdh.Service.mqttManager.subscribe(mqttManager.java:243)
at com.cdh.main.main(main.java:14)
EDIT:
I changed the port to 8883. It works if I run the backend on an other device but not if the broker and the backend are on the raspberry. I also tried to use the domain name from my cert.

The hostname you use to connect needs to match the CN or SAN entries in the certificate presented by the broker or else it will fail validation.
Unless you included 127.0.0.1 or localhost in the certificate the the client will reject the connection because the certificate doesn't validate for that address.
p.s. you should probably use a different port for MQTT of TLS rather than 1883 as that is the standard port for MQTT without TLS.

Related

How to resolve host name of kubernetes pod while creating grpc client from other pod?

Problem:
how to resolve host name of kubernetes pod?
I have the Following requirement we are using grpc with java where we have one app where we are running out grpc server other app where we are creating grpc client and connecting to grpc server (that is running on another pod).
We have three kubernetes pod running where our grpc server is running.
lets say :
my-service-0, my-service-1, my-service-2
my-service has a cluster IP as: 10.44.5.11
We have another three kubernetes pod running where our gprc client is running.
lets say:
my-client-0, my-client-1, my-client-2
Without Security:
i am try to connect grpc server pod with grpc client pod and it work fine.
grpc client (POD -> my-client) ----------------> groc server(POD -> my-service)
So without security i am giving host name as my-service and it's working fine without any problem..
ManagedChannel channel = ManagedChannelBuilder.forAddress("my-service", 50052)
.usePlaintext()
.build();
With SSL Security:
if i try to connect grpc server it will throw host name not match.
we have created a certificate with wild card *.default.pod.cluster.local
it will throw the below error:
java.security.cert.CertificateException: No name matching my-service found
at java.base/sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:225) ~[na:na]
at java.base/sun.security.util.HostnameChecker.match(HostnameChecker.java:98) ~[na:na]
at java.base/sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455) ~[na:na]
Not Working Code:
ManagedChannel channel = NettyChannelBuilder.forAddress("my-service", 50052)
.sslContext(GrpcSslContexts.forClient().trustManager(new File(System.getenv("GRPC_CLIENT_CA_CERT_LOCATION"))).build())
.build();
but if i give the host name as like this ==> 10-44-5-11.default.pod.cluster.local it will work fine correctly.
Working Code
ManagedChannel channel = NettyChannelBuilder.forAddress("10-44-5-11.default.pod.cluster.local", 50052)
.sslContext(GrpcSslContexts.forClient().trustManager(new File(System.getenv("GRPC_CLIENT_CA_CERT_LOCATION"))).build())
.build();
Now my problem is cluster ip of pod is dynamic and it will change every time during app deploy. what is the right way to resolve this host name?
is it possible if i give host name and it will return me the ip then i will append default.pod.cluster.local to hostname and try to connect to grpc server?
Addressing your pod directly is not a good solution since Kubernetes may need to move your pods around the cluster. This can occur for example because of the failing node.
To allow you clients/traffic to easy find desired containers you can place them behind a service with single static IP address. Service IP can be look up through DNS.
This is how you can connect to the service through it`s FQDN:
my-service.default.svc.cluster.local
Where my-service is your service name, default for your namespace and svc.cluster.local is a configurable cluster domain suffix used in all cluster services.
It's worth to know that you can skip svc.cluster.local suffix and even the namespace if the pods are in the same namespace. So you'll just refer to the service as my-service.
For more you can check K8s documents about DNS.

How to properly use a SSL configuration in HiveMQ Client? (MQTT)

I created a client to test using a secure connection and encrypted payload so I wanted to use the default SSL configuration. I tried to do this but I got a ConnectionClosedException and the server immediately closely. Should I be configuring something on the server? I left code and the exception down below.
HiveMQ:
https://github.com/hivemq/hivemq-community-edition https://github.com/hivemq/hivemq-mqtt-client
Code:
// Creates the client object using Blocking API
subscriber = Mqtt5Client.builder()
.identifier(UUID.randomUUID().toString()) // the unique identifier of the MQTT client. The ID is randomly generated between
.serverHost("localhost") // the host name or IP address of the MQTT server. Kept it localhost for testing. localhost is default if not specified.
.serverPort(1883) // specifies the port of the server
.addConnectedListener(context -> ClientConnectionRetreiver.printConnected("Subscriber1")) // prints a string that the client is connected
.addDisconnectedListener(context -> ClientConnectionRetreiver.printDisconnected("Subscriber1")) // prints a string that the client is disconnected
.sslWithDefaultConfig()
.buildBlocking(); // creates the client builder
subscriber.connect();
Exception:
com.hivemq.client.mqtt.exceptions.ConnectionClosedException: Server closed connection without DISCONNECT.
at com.hivemq.client.internal.mqtt.MqttBlockingClient.connect(MqttBlockingClient.java:91)
at com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient.connect(Mqtt5BlockingClient.java:64)
at com.main.SubThread.run(SubThread.java:71)
at java.base/java.lang.Thread.run(Thread.java:834)
In order to use Ssl communications I needed to set up the HiveMQ server to speak TLS. The server does not come pre configured and must be done manually. I followed this link:
https://github.com/hivemq/hivemq-community-edition/wiki/HowTos#howto-configure-server-side-tls-with-hivemq-and-keytool-self-signed

Securing Neo4J with TLS through bolt protocol

Neo4J server configuration allows to set up a server-side policy to secure both HTTPS and BOLT connections.
In my installation I secured the BOLT connection by setting up a policy with PEM public and private key and settings:
dbms.connector.bolt.enabled=true
dbms.connector.bolt.tls_level=REQUIRED
bolt.ssl_policy=my_policy
dbms.ssl.policy.my_policy..base_directory=...
...
The set up works with a browser client. When I connect to the server through HTTPS, I am able to log in using ":server connect" command and use Neo4J browser with my server.
What I cannot do is figure out how other client can connect to Neo4J with secure BOLT protocol. Specifically, I tried connecting from cypher-shell and from a Java client (using Java Driver v 1.6). When TLS for BOLT is disabled, both connect without a hitch. Enabling TLS causes bad_certificate error in both clients.
I tried starting both cypher-shell and my Java client by passing JVM properties pointing to my trust store and key store
(-Djavax.net.ssl.keyStore=...
-Djavax.net.ssl.keyStorePassword=...
-Djavax.net.ssl.trustStore=...
-Djavax.net.ssl.trustStorePassword=...)
These properties have no effect on either Neo4J client. I am getting a bad_certificate exception.
I tried enabling SSL debugging (-Djavax.net.debug=ssl,handshake). Calling the Java client or cypher-shell with keystore and truststore parameters has no effect on the SSL debug output.
How do I connect to the server with TLS for BOLT enabled from cypher-shell or a Java client?
Thank you.

Haproxy config for bitbucket server

I am using haproxy for port forwarding to Bitbucket server ssh. Here's haproxy config:
frontend sshd
bind *:7999
default_backend ssh
timeout client 1h
backend ssh
mode tcp
server localhost-bitbucket-ssh 127.0.0.1:7999 check port 7999
However if i do:
sudo haproxy -f haproxy.cfg
i am getting the following error:
[ALERT] 305/201411 (4168) : http frontend 'sshd' (haproxy.cfg:38) tries to use incompatible tcp backend 'ssh' (haproxy.cfg:43) as its default backend (see 'mode').
[ALERT] 305/201411 (4168) : Fatal errors found in configuration.
But i was referring to an official atlassian guide: https://confluence.atlassian.com/bitbucketserver/setting-up-ssh-port-forwarding-776640364.html are they wrong?
Also if i start haproxy before bitbucket server, bitbucket server cannot start on port 7999. I am totally confused. I have paid for that software and now i need to figure it out myself how to configure it for more than 2 days...
UPDATE
It was UFW as Thomj mentioned. But for what purposes do i need haproxy? If i can't bind Bitbucket's ssh to 22 port? I don't like to set port number.
The frontend configuration is defaulting to a mode of http which can't use a backend that's configured for tcp. Try adding 'mode tcp' to the frontend:
frontend sshd
bind *:7999
default_backend ssh
timeout client 1h
mode tcp

Connect to FTPS through proxy

The initial problem we encountered was that a regular FTPs download started failing due to an untrusted server certificate. This prompted us to wonder whether the certificate had been updated without the counterparty notifying us so we wanted to download the current certificate and compare it to the one we have in our keystore.
This seems to be a trickier problem than we had anticipated. The usual suspects (firefox, filezilla, ...) did not seem up to the task of connecting to an FTPs server through an FTP proxy so out of curiosity I started playing around with a more low level java approach. I can not for the life of me get it to work though.
First (overly simplistic) java attempt:
// create proxy connection
SocketFactory plainFactory = SocketFactory.getDefault();
Socket proxy = plainFactory.createSocket(proxyServer, proxyPort);
// create ssl connection on top of it?
SSLSocketFactory sslFactory = getSocketFactory();
SSLSocket socket = (SSLSocket) sslFactory.createSocket(proxy, server, port, true);
This approach obviously does not work.
Next I started playing around with ftp4j (http://www.sauronsoftware.it/projects/ftp4j/) it seems to have a clean and accessible codebase:
FTPClient client = new FTPClient();
client.setConnector(new FTPProxyConnector(proxyHost, proxyPort));
client.getConnector().setConnectionTimeout(0);
client.getConnector().setReadTimeout(0);
client.setSSLSocketFactory(getSocketFactory());
// also tried SECURITY_FTPS
client.setSecurity(FTPClient.SECURITY_FTPES);
client.connect(server, port);
This outputs:
REPLY: 220 Blue Coat FTP Service
SEND: USER anonymous
REPLY: 530-User Access denied.
REPLY: 530-
REPLY: 530-Usage: USER username#hostname
REPLY: 331 PASS userpassword
Exception in thread "main" java.io.IOException: Invalid proxy response
The proxy server has optional authentication and on our development servers we generally use "user#host" without proxy authentication. As such I assume the username, hostname and password are those of the remote server?
So I tried adding the remote parameters, this does not work:
REPLY: 220 Blue Coat FTP Service
SEND: USER test#ftps.example.com
Exception in thread "main" java.io.IOException: FTPConnection closed
Adding the proxy user to match the bluecoat format does not seem to work either:
USER %u#%h %s
PASS %p
ACCT %w
Any help with either of these two problems would be most welcome:
how to retrieve the server certificate from an ftps server through an ftp proxy
how to connect to an ftps server through an ftp proxy in java
You might want to try Apache Net commons libs.
Here is a similar thread that uses that Net Commons library
Net commons also has a fully functional FTP Client Example so you can test with something you know works.

Categories

Resources