Mosquitto blocks all connections when using CRL file - ssl

I am hosting an MQTT broker on a linux server. So far none of the MQTT clients has any problem connecting (sub/pub) until I added the "crlfile" line in the Mosquitto configuration file. When I have the "crlfile" set in the configuration file, none of the clients can connect. What's weird is that the CRL file actually has no certs revoked. However, this error will come out for all clients:
Error: The connection was lost.
I am using Mosquitto 2.0.12 and here is my Mosquitto configuration file:
# For listener with port 1883
#listener 1883
# Set 8883 as the listener (port)
listener 8883
# Path to the password file
#password_file /etc/mosquitto/passwords
# Path to the cafile
cafile /etc/mosquitto/certs/ca.crt
# Path to the broker cert file
certfile /etc/mosquitto/certs/broker.crt
# Path to the broker key file
keyfile /etc/mosquitto/certs/broker.key
# Path to the CRL file
crlfile /etc/mosquitto/certs/ca.crl
# Whether a certificate is required to connect (Set to true for TLS)
require_certificate true
# Allow anonymous connection (Set to false for TLS)
allow_anonymous false
# Path to Dynamic Security Plugin
plugin /usr/lib/x86_64-linux-gnu/mosquitto_dynamic_security.so
# Path to Dynamic Security config file
plugin_opt_config_file /etc/mosquitto/conf.d/dynamic-security.json
# Whether each listener has the same settings
per_listener_settings false

I managed to fix the issue. The CRL file was generated using Python's cryptography library. The issue was that when I set the last update and next update datetime, I set it using my local time when I should've set it based on UTC time. So I changed my code from
crl_builder = crl_builder.last_update(datetime.utcnow())
crl_builder = crl_builder.next_update(datetime.utcnow() + timedelta(days=365000))
to
crl_builder = crl_builder.last_update(pytz.utc.localize(datetime.utcnow()))
crl_builder = crl_builder.next_update(pytz.utc.localize(datetime.utcnow()) + timedelta(days=365000))
And now my Mosquitto broker works fine :)

Related

Configuring MQTT broker(Mosquitto) to use SSL Encryption isn't working

I am trying to configure my MQTT broker(mosquito) to connect with MQTT client over SSL. For that I created ca.crt , server.crt, and server.key.
Then I edited the mosquito config file like this:
listener 8883
certfile /etc/mosquitto/ca_certificates/server.crt
cafile /etc/mosquitto/ca_certificates/ca.crt
keyfile /etc/mosquitto/ca_certificates/server.key
require_certificate false
use_identity_as_username true
When creating these certificates, I have made sure to add the common name to 127.0.0.1 as suggested in this guide
After that I run my mosquito broker using the config file that I created using:
mosquitto -c /etc/mosquitto/conf.d/password.conf
This command starts my MQTT broker and it starts listening at port 8883.
1645181786: mosquitto version 2.0.11 starting
1645181786: Config loaded from /etc/mosquitto/conf.d/password.conf.
1645181786: Opening ipv4 listen socket on port 8883.
1645181786: Opening ipv6 listen socket on port 8883.
1645181786: mosquitto version 2.0.11 running
Uptil here, I believe that now my broker will only allow connection at port 8883 only when ca.crt is provided in the connection call.
So, then I use this pub command to send a message to a test topic.
mosquitto_pub -h 127.0.0.1 -p 8883 --cafile /etc/mosquitto/ca_certificates/ca.crt -t test -m 45
But it results in following error:
1645182944: New connection from 127.0.0.1:58926 on port 8883.
1645182944: Client auto-7B1E49DA-54C1-532B-3948-35FFD3A11250 disconnected, not authorised.
Then I added a password file and added path to that password file in my mosquitto config file. My new config file started looking like this:
listener 8883
password_file /etc/mosquitto/conf.d/passwords
certfile /etc/mosquitto/ca_certificates/server.crt
cafile /etc/mosquitto/ca_certificates/ca.crt
keyfile /etc/mosquitto/ca_certificates/server.key
require_certificate false
use_identity_as_username true
After this update when I run the mosquitto_pub command with both my certificates and username, password. The client successfully connects to broker.
mosquitto_pub -h 127.0.0.1 -p 8883 --cafile /etc/mosquitto/ca_certificates/ca.crt -t test -m 45 -u "user" -P "pass123"
Note: if I run the pub command using only certs or only with password, it doesn't connect and it shouldn't too. Giving both attributes work only.
But what I want is to connect using only SSL certificates. Any help would be much appreciated.
The problem is probably use_identity_as_username true which tells mosquitto to use the client certificate's CN as the username.
But you are not sending a client certificate (the --cafile option is passing a CA cert to verify the brokers cert) in any of the examples you are showing, so remove that line from the config and see if it works.
EDIT:
If you also don't want to need to supply a username/password (or use a client certificate to identify a user) you need to include the allow_anonymous true configuration option.

LDAPS not working in Samba 4.3.11-Ubuntu

I'm running Samba 4.3.11-Ubuntu on Ubuntu 16.04, and I'm unable to get LDAPS (port 636) to work at all.
Samba is running as an Active Directory Domain Controller, and other AD DC fncitonality seems to be fine.
This used to work, but now there's nothing listening on that port. I'm not sure what I did to break it, but it stopped working after I updated my server with a trusted certificate.
Here's what I have for /etc/samba/smb.conf:
# Global parameters
[global]
workgroup = AD
realm = AD.<redacted>.COM
netbios name = SAMBADC
server role = active directory domain controller
dns forwarder = 8.8.8.8
idmap_ldb:use rfc2307 = yes
tls enabled = yes
tls keyfile = tls/ad.<redacted>.com.key
tls certfile = tls/c7535fc6c5e8e557.crt
tls cafile = tls/gd_bundle-g2-g1.crt
ldap server require strong auth = allow_sasl_over_tls
[netlogon]
path = /var/lib/samba/sysvol/ad.<redacted>.com/scripts
read only = No
[sysvol]
path = /var/lib/samba/sysvol
read only = No
The error I'm getting is:
nitsadmin#sambadc:/etc/samba$ telnet localhost 636
Trying 127.0.0.1...
Trying ::1...
telnet: Unable to connect to remote host: Cannot assign requested address
Anyone have any idea why this might not work? Any idea what Cannot assign requested address means?
Could you please provide a log file which is specified in your smb.conf parameter log file = while you start the samba service?
There could be something wrong with your certificates.
One thing you could try is to switch to autogenerated self-signed certificate and see if it solves the issue. If it does - you have to fix your certificates.
To do this, remove all certificates from tls folder and reconfigure smb.conf:
tls enabled = yes
tls keyfile = tls/key.pem
tls certfile = tls/cert.pem
tls cafile = tls/ca.pem
Then restart samba service and see if it helps.

Datastax Cassandra - Cqlsh with SSL not working

I've installed a single-node Datastax Cassandra v3.5 cluster on my Ubuntu machine. I'm trying to connect to the node using the command-line interface cqlsh using the SSL option without success (from the same machine). The steps I followed are:
Prepared the .keystore, .cer certificate and .truststore following this guide http://docs.datastax.com/en/cassandra/2.0/cassandra/security/secureSSLCertificates_t.html
Modified my cassandra.yaml accordingly:
client_encryption_options:
enabled: true
optional: false
keystore: /************************/.keystore
keystore_password: ************************
require_client_auth: false
# Set trustore and truststore_password if require_client_auth is true
truststore: /************************/.truststore
truststore_password: ************************
Created a cqlshrc conf file and filled it following this guide https://docs.datastax.com/en/cassandra/2.1/cassandra/security/secureCqlshSSL_t.html :
[connection]
hostname = *****
port = 9042
factory = cqlshlib.ssl.ssl_transport_factory
[ssl]
certfile = /home/conf/mycert.cer
validate = true ## Optional, true by default
So basically I created a private and public key, pointed Cassandra to my .keystore and .truststore (even tho I don't think it's necessary because I'm not enforcing the client auth) and cqlsh to the public key (certificate).
Whenever I try to launch cqlsh --ssl I get always the same error and not a single debug message inside Cassandra. The error message is:
Connection error: ('Unable to connect to any servers',
{'*.*****.******': error(0, "Tried connecting to
[('..*.***', 9042)]. Last error: _ssl.c:344:error:00000000:lib(0):func(0):reason(0)")})
Just a side note, if I remove SSL authentication everything works perfectly.
EDIT
I've solved my initial issue following #Adam Holmberg suggestion but still no luck with the SSL connection. I checked that I have JCE libraries installed and I've been trying to enforce cqslh to use SSLv23 or TLSv1 to establish the connection to the Cassandra server but I receive the following error all the times:
Connection error: ('Unable to connect to any servers', ... ... ...
Last error: _ssl.c:510: EOF occurred in violation of protocol")})
Moreover, I've also added the JVM option -Djavax.net.debug=all to no avail, I don't see any additional log about ssl.
Assuming "/home/conf/mycert.cer" is the file you created during server configuration, that is not the right format for Python (cqlsh). You need to export it in PEM format for Python:
keytool -exportcert -alias <alias> -keypass <pass> -keystore <keystore> -storepass <pass> -rfc -file cassandra_cert.pem
If you're just experimenting with cqlsh and are not concerned about true security, you can also omit those options (validate, certfile) from cqlshrc and connect with no cert validation.
After some trial and error and some useful hints gave by #Adam and #Aaron (thanks for the help) I managed to finally establish an SSL connection between cqlsh and my Cassandra server instance.
After pondering about the issue, I came to the conclusion that there was some kind of additional configuration error in both client and server and to help other people that may face the same issue I'll post here my final configuration:
cqlshrc
[connection]
hostname = *****.*****.*****.*****.*****
port = 9042
[cql]
version = 3.4
[tracing]
max_trace_wait = 10.0
[ssl]
certfile = /****/****/****/****.cer.pem
validate = false ## Optional, true by default
#version = SSLv23
#factory = cqlshlib.ssl.ssl_transport_factory
cassandra.yaml (relevant part)
# enable or disable client/server encryption.
client_encryption_options:
enabled: true
# If enabled and optional is set to true encrypted and unencrypted connections are handled.
optional: false
keystore: /***/****/****/.keystore
keystore_password: *********
require_client_auth: false
# Set trustore and truststore_password if require_client_auth is true
truststore: /****/****/****/.truststore
truststore_password: ****
# More advanced defaults below:
# protocol: TLSv1
# algorithm: SunX509
# store_type: JKS
# cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]
I was getting the error:
Last error: [SSL] internal error (_ssl.c:727)
What have solved this was adding the line of the SSL version at cqlshrc file:
[connection]
(...)
version = SSLv23

mosquitto-clients and broker running on SSL

I've managed to setup a broker using SSL using Let's Encrypt certs.
I've tried testing a websockets client connecting to wss://broker:9002/mqtt, and it's working. I've also tried using mqtt.js command-line interface to subscribe to a topic on the broker mqtts://broker:8883/mqtt successfully.
However, I can't get mosquitto_sub and mosquitto_pub to work.
I tried with,
$ mosquitto_sub -h www.my-host.com.ar -p 8883 -t hello -d --cafile fullchain.pem
Client mosqsub/21069-atlantis sending CONNECT
Error: A TLS error occurred.
where fullchain.pem is the same ca cert that's on the server.
The mosquitto.log's broker shows,
1456709201: OpenSSL Error: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
1456709201: OpenSSL Error: error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake failure
1456709201: Socket error on client <unknown>, disconnecting.
1456709206: New connection from <my-ip> on port 8883.
What could be happening? I didn't provide any cert for mqtt.js lib...
This is my broker conf (splitted in two files),
#################################
# /etc/mosquitto/mosquitto.conf #
#################################
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
listener 1883
listener 8883
cafile /etc/letsencrypt/live/www.my-host.com.ar/fullchain.pem
certfile /etc/letsencrypt/live/www.my-host.com.ar/cert.pem
keyfile /etc/letsencrypt/live/www.my-host.com.ar/privkey.pem
include_dir /etc/mosquitto/conf.d
#############################################
# /etc/mosquitto/conf.d/websockets_ssl.conf #
#############################################
listener 9002
protocol websockets
cafile /etc/letsencrypt/live/www.my-host.com.ar/fullchain.pem
certfile /etc/letsencrypt/live/www.my-host.com.ar/cert.pem
keyfile /etc/letsencrypt/live/www.my-host.com.ar/privkey.pem
Try adding "--insecure" at the end of the mosquitto_sub and mosquitto_pub commands. This allows the clients to bypass the check that matches the certificate hostname with the remote host name. I've had to do this with some of the self-signed certs that I generated.
Here is the relevant comments from the "--help" for those commands:
--insecure : do not check that the server certificate hostname matches the remote
hostname. Using this option means that you cannot be sure that the
remote host is the server you wish to connect to and so is insecure.
Do not use this option in a production environment.

How do you set up encrypted mosquitto broker like a webpage which has https?

I'm trying to setup a mosquitto broker which is encrypted using ssl/tls. I don't want to generate client certificates. I just want an encrypted connection.
The man page only described the settings which are available, not which are needed and how they are used.
Which settings are needed and how do you set them?
I use mosquitto 1.3.5
There is a small guide here, but it does not say much: http://mosquitto.org/man/mosquitto-tls-7.html
You need to set these:
certfile
keyfile
cafile
They can be generated with the commands in the link above. But easier is to use this script: https://github.com/owntracks/tools/blob/master/TLS/generate-CA.sh
After running the script and changing the config it could look something like this:
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/hostname.localdomain.crt
keyfile /etc/mosquitto/certs/hostname.localdomain.key
If mosquitto says Unable to load server key file it means that the user which is running mosquitto does not have permission to read the file. Even if you start it as root the broker might start as another user, mosquitto for example. To solve this do e.g. chown mosquitto:root keyfile
To connect to the broker the client will need the ca.crt-file. If you do not supply this the broker will say something like:
OpenSSL Error: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number
To supply it to the mosquitto_sub command you use --cafile pathToCaCrt. The ca.crt can be distributed with the clients and it will make sure that the server it is connected to actually is the correct server.
The --insecure flag of mosquitto_sub does not make the client accept all certificates (like with wget or similar), it just allows that the certificate not to have the host you are connecting to in common name. So you should make sure your certificate has your broker host as common name.
To secure WebSocket access of Mosquitto, e.g. using a Let's Encrypt certificate, your config file could look like this:
listener 9001
protocol websockets
certfile /etc/letsencrypt/live/yourdomain.com/cert.pem
cafile /etc/letsencrypt/live/yourdomain.com/chain.pem
keyfile /etc/letsencrypt/live/yourdomain.com/privkey.pem
Make sure that the files are readable by Mosquitto (Debian in particular runs Mosquitto under the mosquitto user, which is unprivileged). You need Mosquitto 1.4 to support WebSockets.
To connect to this WebSocket using the Paho JavaScript client:
// host and port overwritten at connect
var mqtt = new Paho.MQTT.Client("yourdomain.com", 9001, "");
mqtt.connect({
hosts: [ "wss://yourdomain.com:9001/" ],
useSSL: true
});
Note that this does not imply any access control yet, so your MQTT broker will be publicly accessible. You may want to add authorization, too.