mosquitto_sub Error:A TLS error occurred but is ok whit --insecure - linux

I'm building a mqtt server. I used the mosquitto with the TLS on the server as a broker.
I encountered this problem:
I created the ca.crt, server certificate, server key, client certificate, client key via generate-CA.sh
I can connect the broker and publish and subscribe msg via MQTT.fx, but when I tried to connect the broker with the mosquitto_sub, it came out Error:A TLS error occurred on the client PC(ubuntu), at the same time, the server prints
New connection from xx.xx.xx.xx on port 8883.
Openssl Error: error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown
Openssl Error: error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake failure
my command used is:
mosquitto_sub -p 8883 -i test -t mqtt -h 150.xx.xx.xx --cafile ca.crt --cert xx.crt --key xx.key in which, the 150.xx.xx.xx is the IP of my broker.
when I used the option --insecure with the command above, the problem disappeared.
so I think it is the server hostname which leads to this problem.
In the mosquitto_sub command the option -h specifies the hostname, but i need to use this parameter to point to the IP address of my broker, so how could i specify the hostname of my server??

Old question but perhaps this might help someone:
If the --insecure option makes it work, you have a certificate problem. What hostname did you set whilst signing the certificate? What does openssl s_client -showcerts -connect 150.xx.xx.xx:8883 say?
Related: although it should be possible to use SSL certs for your servers using public IP addresses (see Is it possible to have SSL certificate for IP address, not domain name?), I'd recommend not doing this and just using DNS, even if this means server.localdomain and/or editing your /etc/hosts file if necessary.

Related

Simulate MQTT TLS login by MQTT.FX in linux?

I am having some problems using mosquitto client in linux, more specifically I need to use mosquitto_sub but I don't really get how I should authenticate.
All I have is a json config file for MQTT.Fx, that works fine when imported in that application. I can see there are username and password, as well as host information, and that SSL/TSL is enabled.
My question is: how can I do the same thing that MQTT.Fx does automatically since option CA signed server certificate is selected? I have been trying a lot of alternatives, like downloading server certificate and passing it as --cafile, generating new certificate, signing them, editing mosquitto.conf, but I didn't match the right combination of operations.
Any suggestion, please?
Edit: here is current command:
mosquitto_sub -h myhost.example -p 8883 -i example1 -u myusername -P mypassword -t XXXXXXXXXXXX/# --cafile /etc/mosquitto/trycert.crt
where file trycert.crt contains the response to following request (of course only part between BEGIN CERTIFICATE and END CERTIFICATE)
openssl s_client -showcerts -servername myhost.example -connect myhost.example:8883 </dev/null
All the times I had problems with MQTT over SSL its been that the server cert chain of trust broken on my client. In other words, the server i am connecting to has a cert. This cert is authorized by another cert and so forth. Each of the certs in the chain need to be on the client.
If any of these certs are missing, the chain of trust is broken and the stack will abort the connection.

Issues connecting to mosquitto broker with node mqtt client via SSL/TLS

Helllo, I created a mosquitto broker via the eclipse docker image and recently followed this guide to add SSL/TLS support: http://www.steves-internet-guide.com/mosquitto-tls/.
When I am sshed in the VPS which is running the broker, I can use the command:
mosquitto_pub -h VPS_NAME -t test/topic -p 8883 --cafile ca.crt -m message -u BROKER_USERNAME -P BROKER_PASSWORD
and it publishes all fine and dandy. However when I run the same command on a local computer, I get the error:
'Unable to connect (Lookup error.).
I don't get any new logs from the broker container, so I think it's not even reaching the container. However when I run:
mosquitto_pub -h BROKER_IP_ADRESS -t test/topic -p 8883 --cafile ca.crt -m message -u BROKER_USERNAME -P BROKER_PASSWORD
I do get a response which is Error: A TLS error occured, and on my docker logs I get:
1583004287: New connection from LOCAL_IP_ADDRESS on port 8883.
1583004287: OpenSSL Error: error:14037438:SSL routines:ACCEPT_SR_KEY_EXCH:tlsv1 alert internal error
1583004287: OpenSSL Error: error:140370E5:SSL routines:ACCEPT_SR_KEY_EXCH:ssl handshake failure
1583004287: Socket error on client <unknown>, disconnecting.
I am only able to get a sucessful publish send when I add the --insecure command to the publish however I want to make sure the client knows that it's talking to the right server so I don't think this is the right solution.
In the end I want to run an mqtt client on a node application, I've tried this piece of code:
const fs = require('fs');
const optionsz = {
ca: [ fs.readFileSync(__dirname + '/ca.pem') ],
host: 'BROKER_IP_ADDRESS',
servername: 'VPS_NAME',
port: 8883,
rejectUnauthorized : false,
username : 'BROKER_USERNAME', // mqtt credentials if these are needed to connect
password : 'BROKER_PASSWORD',
clientId : 'test',
// Necessary only if the server's cert isn't for "localhost".
checkServerIdentity: () => { return null; },
};
class MqttHandler {
constructor() {
this.mqttClient = null;
};
connect() {
// Connect mqtt with credentials (in case of needed, otherwise we can omit 2nd param)
this.mqttClient = mqtt.connect(this.host, optionsz);
...
when I run this i keep getting disconnect events, and on my docker logs i get:
1583004505: New connection from LOCAL_IP_ADDRESS on port 8883.
1583004505: OpenSSL Error: error:140260FC:SSL routines:ACCEPT_SR_CLNT_HELLO:unknown protocol
1583004505: Socket error on client <unknown>, disconnecting.
I am really confused on how to even tackle this issue, I've been able to connect to a broker without SSL/TLS protection, but I wanted to make my device communication more secure.
Thank you for your time!
2 separate problems here.
Looks like you don't have a valid DNS entry for your VPS. mosquitto_pub is failing because it can't resolve the name to an IP address. It works with the --insecure and the IP address because you are telling mosquitto_pub to ignore the fact that the CN or SANs in the brokers certificate doesn't include the IP address only the name.
You are trying to connect with raw MQTT not MQTT over TLS, you need to use a URL not just a hostname or the first argument of the connect() function. e.g.
this.mqttClient = mqtt.connect("mqtts://" + this.host, optionsz);
To be honest you need to fix both of these to get things working properly.
To fix 1 you need to sort your DNS entries out so you have a valid fully qualified hostname that points to your VPS and matches the certificate you've deployed there.

AWS Load Balancer, enable listener for HTTPS and route to 80

I've an AWS LoadBalancer in front of two servers running SailsJS with PM2. The LB works very well and routes the incoming HTTP requests to the server, which is perfect.
Now, I need to add support for HTTPS, so I followed this guide:
AWS Create a Classic Load Balancer with an HTTPS Listener, using a self-generated SSL certificate, and used this configuration for the ports
LB Port 80 - Instance 80
LB Port 443 - Instance 80
And the security group has these ports opened:
22,
80,
443
So, if I understood correctly, the LB will receive the HTTPS request on port 443 and will forward it to port 80 of the instance. My instance, of course, is listening on port 80.
The problem is, this don't work! I can make HTTP requests to the LB and all is routed perfectly to the Sails instance and the response is perfect. But if I use exactly the same URL but with HTTPS, then it doesn't work and I get a "ERR_SSL_PROTOCOL_ERROR".
What am I doing wrong, what am I missing?
Thank you!
EDIT 1
This is what I get if I try curl -v https://example.com
* Trying xx.xx.xx.xx...
* Connected to example.com (xx.xx.xx.xx) port 443 (#0)
* Unknown SSL protocol error in connection to example.com:-9838
* Closing connection 0
curl: (35) Unknown SSL protocol error in connection to mydomain.com:-9838
EDIT 2
Found another thread which suggested a different way of creating the certificate. So I tried it, but now AWS don't even accept the private key and the certificate
Server Certificate not found for the key: arn:aws:iam::111111111:server-certificate/CertificateMyName
EDIT 3
OK, so found more info on why I couldn't load the certificates to AWS and after trying some times, I managed to load it and use it.
After these, it appears to be working (with the warnings that is not a valid cert and bla, bla, bla, which is expected)
* Trying XXX.XXX.XXX.XXX...
* Connected to example.com (XXX.XXX.XXX.XXX) port 443 (#0)
* SSL certificate problem: Invalid certificate chain
* Closing connection 0
curl: (60) SSL certificate problem: Invalid certificate chain
So it appears to be working, and it appears, as #MarkB suggested that the certificate was wrong. Using the info found on EDIT 2, I created a new one, and upload it (with the info of EDIT 3) and it appears to be working.
I'll perform more tests to make 100% sure that this works and will report back soon.
Ok, so the problem was a wrongly generated certificate. I used the first method I found and it wasn't working, so just use these:
openssl genrsa -out client-key.pem 2048
openssl req -new -key client-key.pem -out client.csr
openssl x509 -req -in client.csr -signkey client-key.pem -out client-cert.pem
Even after that, AWS told me:
Server Certificate not found for the key: arn:aws:iam::111111111:server-certificate/CertificateMyName
But the last error is wrong, even with the error the certificate WAS added to the ACM, and I used it in my HTTPS 443 listener, tested again the services and all was working. So just create the certificate with the instructions above, import it in ACM and if it gives you an error like above, just ignore it, your cert will be on place and ready to use.
Hope this helps others!

LDAP SSL client not sending hello packet

I'm trying to make LDAP setup using CentOS based OpenLDAP server and MCP Linux based PAM LDAP client.
Without SSL, I'm able to get the user authenticated successfully.
But with SSL('ssl start_tls' in /etc/pam_ldap.conf), I'm unable to get the user authenticated. When I did packet capture at server, I do not see client's HELLO packet.
Also, I'm not interested in server/client certificate verification hence at server I had 'TLSVerifyClient never' and at client I used 'TLS_REQCERT never' in /etc/openldap/ldap.conf(in addition to 'tls_checkpeer no' in /etc/pam_ldap.conf)
With CentOS based PAM LDAP client and with the same client configuration, I'm able to get the user authenticated successfully with the same server.
Can anyone tell me, in which cases SSL client doesn't send 'HELLO' packet ?
Here you go with logs at server:
...
connection_read(13): checking for input on id=1005
tls_read: want=3, got=0
TLS: error: accept - force handshake failure: errno 11 - moznss error -5938
TLS: can't accept: TLS error -5938:Encountered end of file.
connection_read(13): TLS accept failure error=-1 id=1005, closing
connection_closing: readying conn=1005 sd=13 for close
....
BTW, I'm trying to connect to client using SSH.
Also, if I use 'openssl s_client -connect my-domain.com:636 -showcerts -state -CAfile /etc/pki/tls/certs/cacert.pem' command at CLIENT, it is sending Client hello packet and is returing the server certificates
Thanks,
Sravani
From 'strace ldapsearch ....' log, I see that
open("/usr/lib/libsoftokn3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
I'll try to get this library for MCP Linux and give it a try again.
Thanks all for your support

trace a particular IP and port

I have an app running on port 9100 on a remote server serving http pages. After I ssh into the server I can curl localhost 9100 and I receive the response.
However I am unable to access the same app from the browser using http://ip:9100
I am also unable to telnet from my local PC. How do I debug it? Is there a way to traceroute a particular IP and port combination, to see where it is being blocked?
Any linux tools / commands / utilities will be appreciated.
Thanks,
Murtaza
You can use the default traceroute command for this purpose, then there will be nothing to install.
traceroute -T -p 9100 <IP address/hostname>
The -T argument is required so that the TCP protocol is used instead of UDP.
In the rare case when traceroute isn't available, you can also use ncat.
nc -Czvw 5 <IP address/hostname> 9100
tcptraceroute xx.xx.xx.xx 9100
if you didn't find it you can install it
yum -y install tcptraceroute
or
aptitude -y install tcptraceroute
you can use tcpdump on the server to check if the client even reaches the server.
tcpdump -i any tcp port 9100
also make sure your firewall is not blocking incoming connections.
EDIT: you can also write the dump into a file and view it with wireshark on your client if you don't want to read it on the console.
2nd Edit: you can check if you can reach the port via
nc ip 9100 -z -v
from your local PC.
Firstly, check the IP address that your application has bound to. It could only be binding to a local address, for example, which would mean that you'd never see it from a different machine regardless of firewall states.
You could try using a portscanner like nmap to see if the port is open and visible externally... it can tell you if the port is closed (there's nothing listening there), open (you should be able to see it fine) or filtered (by a firewall, for example).
it can be done by using this command: tcptraceroute -p destination port destination IP. like: tcptraceroute -p 9100 10.0.0.50 but don't forget to install tcptraceroute package on your system. tcpdump and nc by default installed on the system. regards
If you use the 'openssl' tool, this is one way to get extract the CA cert for a particular server:
openssl s_client -showcerts -servername server -connect server:443
The certificate will have "BEGIN CERTIFICATE" and "END CERTIFICATE" markers.
If you want to see the data in the certificate, you can do: "openssl x509 -inform PEM -in certfile -text -out certdata" where certfile is the cert you extracted from logfile. Look in certdata.
If you want to trust the certificate, you can add it to your CA certificate store or use it stand-alone as described. Just remember that the security is no better than the way you obtained the certificate.
https://curl.se/docs/sslcerts.html
After getting the certificate use keytool to install it.

Resources