Emqx: self signed ssl certificate issue

Created on 24 May 2016  Â·  16Comments  Â·  Source: emqx/emqx

Hi, I have tried to use Let's Encrypt which will offer a free SSL, and emqttd will run perfectly.
Unfortunately, when I used self signed ssl certificate, my mqtt client will be unable to connect to server. Do I miss something?
P.s I am sure that self signed ssl certificate is correct.

Support

Most helpful comment

@freedomsean

Create CA organization

  • 1.Create ca-key.pem, enter the password like 123456

    openssl genrsa -out ca-key.pem -des 1024

  • 2.Create ca-csr.pem

    openssl req -new -key ca-key.pem -out ca-csr.pem

  • 3.Create ca-cert.pem

    openssl x509 -req -in ca-csr.pem -signkey ca-key.pem -out ca-cert.pem

Create server certificate

  • 1.Create server-key.pem

    openssl genrsa -out server-key.pem 1024

  • 2.Create server-csr.pem

    create the openssl.cnf file in current directory, content like:

    [req]  
      distinguished_name = req_distinguished_name  
      req_extensions = v3_req  
    
      [req_distinguished_name]  
      countryName = Country Name (2 letter code)  
      countryName_default = CN  
      stateOrProvinceName = State or Province Name (full name)  
      stateOrProvinceName_default = BeiJing  
      localityName = Locality Name (eg, city)  
      localityName_default = YaYunCun  
      organizationalUnitName  = Organizational Unit Name (eg, section)  
      organizationalUnitName_default  = Domain Control Validated  
      commonName = Internet Widgits Ltd  
      commonName_max  = 64  
    
      [ v3_req ]  
    
      basicConstraints = CA:FALSE  
      keyUsage = nonRepudiation, digitalSignature, keyEncipherment  
      subjectAltName = @alt_names  
    
      [alt_names]  
    
      IP.1 = 127.0.0.1
    

    then execute:
    openssl req -new -key server-key.pem -config openssl.cnf -out server-csr.pem

  • 3.Create server-cert.pem

openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in server-csr.pem -out server-cert.pem -extensions v3_req -extfile openssl.cnf

Create client certificate

  • 1.Create client-key.pem

    openssl genrsa -out client-key.pem

  • 2.Create client-csr.pem

    openssl req -new -key client-key.pem -out client-csr.pem

  • 3.Create client-cert.pem

    openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in client-csr.pem -out client-cert.pem

All files like follow

➜  ssl ls -l
total 88
-rw-r--r--  1 mac  staff  757 May 25 15:29 ca-cert.pem
-rw-r--r--  1 mac  staff   17 May 25 15:46 ca-cert.srl
-rw-r--r--  1 mac  staff  603 May 25 15:29 ca-csr.pem
-rw-r--r--  1 mac  staff  958 May 25 15:25 ca-key.pem
-rw-r--r--  1 mac  staff  664 May 25 15:46 client-cert.pem
-rw-r--r--  1 mac  staff  420 May 25 15:45 client-csr.pem
-rw-r--r--  1 mac  staff  497 May 25 15:44 client-key.pem
-rw-r--r--  1 mac  staff  928 May 25 15:34 openssl.cnf
-rw-r--r--  1 mac  staff  847 May 25 15:35 server-cert.pem
-rw-r--r--  1 mac  staff  704 May 25 15:35 server-csr.pem
-rw-r--r--  1 mac  staff  891 May 25 15:33 server-key.pem
➜  ssl 

MQTT.fx setting

client_setting

All 16 comments

Hi @freedomsean, usually the MQTT client library should be configured to allow self-signed SSL certificate. Please discuss this issue with @CrazyWisdom

Hi @freedomsean, what mqtt client are you using?

Thanks @emqplus and @CrazyWisdom.
I use mqttfx for testing to eMQTT. This tool is based on paho.
The bottom quote is the error log.
My MQTT broker is setup in the intranet. All of required port(1883 & 8883) are opened. If there is no SSL setting, it will be connected perfectly.
My SSL certificate follow this tutorial.

2016-05-25 09:14:13,098  INFO --- MqttFX ClientModel             : MqttClient with ID 50c8a7c7635c427789fa assigned.
2016-05-25 09:14:13,202 ERROR --- MqttFX ClientModel             : Error when connecting
org.eclipse.paho.client.mqttv3.MqttException: MqttException
    at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:604) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_77]
Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[?:1.8.0_77]
    at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:89) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:590) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    ... 1 more
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[?:1.8.0_77]
    at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:89) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:590) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    ... 1 more
2016-05-25 09:14:13,203 ERROR --- MqttFX ClientModel             : Please verify your Settings (e.g. Broker Address, Broker Port & Client ID) and the user credentials!
org.eclipse.paho.client.mqttv3.MqttException: MqttException
    at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:604) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_77]
Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[?:1.8.0_77]
    at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:89) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:590) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    ... 1 more
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[?:1.8.0_77]
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[?:1.8.0_77]
    at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:89) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:590) ~[org.eclipse.paho.client.mqttv3-1.0.2.jar:?]
    ... 1 more
2016-05-25 09:14:13,214  INFO --- ScriptsController              : Clear console.
2016-05-25 09:14:13,215 ERROR --- BrokerConnectService           : MqttException

@freedomsean

Create CA organization

  • 1.Create ca-key.pem, enter the password like 123456

    openssl genrsa -out ca-key.pem -des 1024

  • 2.Create ca-csr.pem

    openssl req -new -key ca-key.pem -out ca-csr.pem

  • 3.Create ca-cert.pem

    openssl x509 -req -in ca-csr.pem -signkey ca-key.pem -out ca-cert.pem

Create server certificate

  • 1.Create server-key.pem

    openssl genrsa -out server-key.pem 1024

  • 2.Create server-csr.pem

    create the openssl.cnf file in current directory, content like:

    [req]  
      distinguished_name = req_distinguished_name  
      req_extensions = v3_req  
    
      [req_distinguished_name]  
      countryName = Country Name (2 letter code)  
      countryName_default = CN  
      stateOrProvinceName = State or Province Name (full name)  
      stateOrProvinceName_default = BeiJing  
      localityName = Locality Name (eg, city)  
      localityName_default = YaYunCun  
      organizationalUnitName  = Organizational Unit Name (eg, section)  
      organizationalUnitName_default  = Domain Control Validated  
      commonName = Internet Widgits Ltd  
      commonName_max  = 64  
    
      [ v3_req ]  
    
      basicConstraints = CA:FALSE  
      keyUsage = nonRepudiation, digitalSignature, keyEncipherment  
      subjectAltName = @alt_names  
    
      [alt_names]  
    
      IP.1 = 127.0.0.1
    

    then execute:
    openssl req -new -key server-key.pem -config openssl.cnf -out server-csr.pem

  • 3.Create server-cert.pem

openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in server-csr.pem -out server-cert.pem -extensions v3_req -extfile openssl.cnf

Create client certificate

  • 1.Create client-key.pem

    openssl genrsa -out client-key.pem

  • 2.Create client-csr.pem

    openssl req -new -key client-key.pem -out client-csr.pem

  • 3.Create client-cert.pem

    openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in client-csr.pem -out client-cert.pem

All files like follow

➜  ssl ls -l
total 88
-rw-r--r--  1 mac  staff  757 May 25 15:29 ca-cert.pem
-rw-r--r--  1 mac  staff   17 May 25 15:46 ca-cert.srl
-rw-r--r--  1 mac  staff  603 May 25 15:29 ca-csr.pem
-rw-r--r--  1 mac  staff  958 May 25 15:25 ca-key.pem
-rw-r--r--  1 mac  staff  664 May 25 15:46 client-cert.pem
-rw-r--r--  1 mac  staff  420 May 25 15:45 client-csr.pem
-rw-r--r--  1 mac  staff  497 May 25 15:44 client-key.pem
-rw-r--r--  1 mac  staff  928 May 25 15:34 openssl.cnf
-rw-r--r--  1 mac  staff  847 May 25 15:35 server-cert.pem
-rw-r--r--  1 mac  staff  704 May 25 15:35 server-csr.pem
-rw-r--r--  1 mac  staff  891 May 25 15:33 server-key.pem
➜  ssl 

MQTT.fx setting

client_setting

Hi, @CrazyWisdom, Thanks for your kind tutorial. I found the root cause.
I have started a emqtt in "screen" and I forgot to stop it, so no matter how did I change the config and restart it, the second emqtt instance could not use 8883 port, because the other emqtt is used.
If emqtt can notify user when user executes more than one process, I think it will be a useful feature.
Thanks again for @CrazyWisdom and @emqplus, it is a wonderful project.

Hi, @CrazyWisdom ,Thank you, I want to kown if i can use java or python client connect the emqtt‘s ssl port 8883 without certfile,if yes, how can i do it ,thank you,

@hello-liuyi Did you figure it out? I have tried a bunch of things and can't seem to get it working to connect from python or javascript without the certfile. Would love to hear if you get it figured out.

@CrazyWisdom

Hi.

Where and how did you get the MQTT.fx setting UI-tool? Is the connection profile for client or eqmtt server?

@hello-liuyi @brechmos

Were you able to figure out how to connect to emqtt ssl port 8883 without cacert? It will be very helpful if some one can provide me a script to do so.

@KohliDev In paho c client, set MQTTClient_SSLOptions.enableServerCertAuth = 0 and it will not check cacert.

But python and java client has no such option.

Thanks @grutabow

I was able to achieve this functionality in Python with help of following code:

#!/usr/bin/env python

import paho.mqtt.client as mqtt
import ssl

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.publish("paho/temperature", "temperature")

client = mqtt.Client()
client.on_connect = on_connect
client.tls_set("/Users/vkohli/Desktop/mqtt_cert/cert.pem",
               None,
               None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
# disables peer verification
client.tls_insecure_set(True)
client.connect("ip-address", 8883, 60)

client.loop_forever()

I need to provide a random cacert.pem but the above configuration works and I`m able to connect to the server with SSL encryption without checking its certificate.

@CrazyWisdom I worked the exact same steps that you did to generate the keys, used the exact same commands and the same conf file, and it seems like my emqtt broker is still not working. The handshake is consistently failing with these messages

11:30:21.925 [error] CRASH REPORT Process <0.1461.0> with 0 neighbours crashed with reason: {ssl_error,{options,{certfile,"etc/certs/new_certs/server-cert.pem",{error,enoent}}}} in esockd_connection:upgrade/1 line 131
11:30:21.926 [error] Supervisor 'esockd_connection_sup - <0.1255.0>' had child connection started with emqttd_client:start_link([{max_publish_rate,0},{client_idle_timeout,30000},{client_enable_stats,true},{max_clientid_len,1024},...]) at <0.1461.0> exit with reason {ssl_error,{options,{certfile,"etc/certs/new_certs/server-cert.pem",{error,enoent}}}} in context connection_crashed
11:30:21.927 [error] CRASH REPORT Process <0.1463.0> with 0 neighbours crashed with reason: {ssl_error,{options,{certfile,"etc/certs/new_certs/server-cert.pem",{error,enoent}}}} in esockd_connection:upgrade/1 line 131
11:30:21.928 [error] Supervisor 'esockd_connection_sup - <0.1255.0>' had child connection started with emqttd_client:start_link([{max_publish_rate,0},{client_idle_timeout,30000},{client_enable_stats,true},{max_clientid_len,1024},...]) at <0.1463.0> exit with reason {ssl_error,{options,{certfile,"etc/certs/new_certs/server-cert.pem",{error,enoent}}}} in context connection_crashed

it seems like the cert files are incorrect, is this true? Could it be some other configuration error? Because when connecting using fx without ssl/tls, it works perfectly fine!

EDIT: This is on the new 2.2 version

Thank you for your help and time!

Hi @CrazyWisdom

I am doing the same exercise (https://github.com/emqtt/emqttd/issues/562#issuecomment-221500588) with VerneMQ broker, and it fails connecting.

In the MQTT.fx client you've defined the client certificates. Where are you placing the server certificates?

In my case, I am pointing those server certificates in vernemq.conf file.
listener.ssl.cafile = /home/osboxes/mqttfx-certs/ca-cert.pem
listener.ssl.certfile = /home/osboxes/mqttfx-certs/server-cert.pem
listener.ssl.keyfile = /home/osboxes/mqttfx-certs/server-key.pem

Appreciate any help here.

Thanks!

@rauger is my old account 2 up. I didn't realize that I didn't edit it. 'enoent' means that the file doesn't exist... the path was wrong.

@CrazyWisdom I know its like 4.5 years later but just to let you know your post was tremendously helpful

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rootqa picture rootqa  Â·  3Comments

heyoka picture heyoka  Â·  3Comments

jbrzozoski picture jbrzozoski  Â·  4Comments

mikybone picture mikybone  Â·  3Comments

kenpeter picture kenpeter  Â·  6Comments