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
Related
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 :)
Please help me to understand one thing.
There is block of settings in cassandra for client's path of keystore and truststore SSL. I.e. I should configure in server node of Cassandra paths to CLIENT keystore.
But how does it work? It seems It is correct would be locate keystore/truststore of cliet on Application host, like POD, docker or
Application server and use keystore to connect to DBMS Cassandra. How client can use
his keystore, which is located on server?
enabled: true
keystore: E:/apache-cassandra-2.1.4/conf/.keystore
keystore_password: cassandra
# require_client_auth: false
# Set trustore and truststore_password if require_client_auth is true
# truststore: conf/.truststore
# truststore_password: cassandra
# More advanced defaults below:
# protocol: TLS
# 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]
This block is used to check that the clients have valid certificate (that it's signed by trusted authority), use correct cipher, etc., or even enforce that client's certificate is registered in the truststore (if you set require_client_auth: true).
Basically, what you need is that your clients did use certificate that is signed by valid authority, known by Cassandra. DataStax has very detailed documentation on how to setup client-to-server SSL. Cassandra site also includes a lot, but some things could be specific to 4.0 release.
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.
I am trying to set up an MQTT broker with SSL. When I start the broker, I get this error:
1452342536: Error: Unable to load server key file "/home/ilab/mqtt/server/server.key". Check keyfile.
The following is my mosquitto.conf:
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
include_dir /etc/mosquitto/conf.d
cafile /home/ilab/mqtt/CA/ca.crt
certfile /home/ilab/mqtt/server/server.crt
keyfile /home/ilab/mqtt/server/server.key
port 8883
tls_version tlsv1
I also followed the step mentioned in THIS question. But still didn't solve the problem.
As #hardillb implies, try removing the password or start the broker manually.
Alternatively, if you're on Ubuntu then apparmor may be restricting access to those files. Try put them in /etc/mosquitto/certs instead.
I had the same issue. I fixed it by providing the fullchain.pem instead of the chain.pem in the configuration.
You can even try changing the name of server.crt to cert.pem and server .key to key.pem in the path mqtt/certs/
Also don't forget to change the path and file name in your code.
I tried to config SSL for mostquitto following these steps.
When I restart mosquitto, there is an error:
1435120150: mosquitto version 1.4.2 (build date Mon, 18 May 2015 15:25:19 +0100) starting
1435120150: Config loaded from /etc/mosquitto/mosquitto.conf.
1435120150: Opening ipv4 listen socket on port 8883.
1435120150: Error: Unable to create TLS context.
This is my mosquitto config:
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
include_dir /etc/mosquitto/conf.d
bind_address Dell
port 8883
cafile /etc/mosquitto/ca_certificates/ca.crt
certfile /etc/mosquitto/certs/Dell.crt
keyfile /etc/mosquitto/certs/Dell.key
tls_version tlsv1
How to configure it correctly?
Unable to create TLS context suggests that the call to SSL_CTX_new() failed. This is right at the beginning of setting up the SSL options for the listening socket and is very unexpected.
The only things you can do to influence this are to check your version of openssl, and to change/remove the tls_version option. Removing it is the best bet unless you have a particular reason to disallow TLSv1.1 or TLSv1.2 (or TLSv1.3 in the future).
Another solution ... for a [different] specific cause.
For the error "Error: Problem setting TLS options", one specific cause was fixed like this:
-- in the mosquitto config file, the lines of config parameters with cert, key, and CA filenames contained a 'space' character after each filename, and before the end-of-line character.
-- removing the space just before the end-of-line character caused the error to no longer appear.
-- the mosquitto broker then started up with no errors.
Please check client system time and ssl certificate end date, client system time must be in between ssl certificate start time and end time
Check Client System Date :
date
Check openssl certificate end date :
openssl x509 -enddate -noout -in cacert.pem