Enable two-way SSL/TLS for EMQX
As a security protocol based on modern cryptographic public key algorithms, TLS/SSL can ensure the security of transmission in the computer communication network. EMQX has built-in support for TLS/SSL including one-way/two-ways (mutual TLS, or mTLS) authentication, the X.509 certificate, load balance SSL and many other security certifications. You can enable SSL/TLS for all protocols supported by EMQX, and can also configure HTTP API provided by EMQX to use TLS.
In the previous article, we've introduced how to enable SSL/TLS one-way security connection for the EMQX. This article will introduce how to enable SSL/TLS two-way security connection for MQTT in EMQX.
The security advantages brought by SSL/TLS
- Strong certification. When using TLS to establish connections, both communicating parties can check each other's identity. One of the common methods to check identity is that check another party's digital certificate X.509. This kind of digital certificate normally issued by a trusted institution, can not be forged.
- Ensure confidentiality. Every session of TLS communicating will be encrypted by the session key which is negotiated by both parties. Any third party will not know the communication content. Although one of the session keys is leaked, it does not affect the security of other sessions.
- Completeness. It is difficult that tamper with the data in encrypted communication and without being discovered.
SSL/TLS protocol
The process of communication in the TLS/SSL protocol consists of two parts. The first part is the handshake protocol. The purpose of this handshake protocol is to identify the identity of another party and establish a safe communication channel. After a handshake, both parties will negotiate the next password suite and session key. The second part is the record protocol. Record is highly similar to other data transmission protocols. It carries content type, version, length, load, etc, and the difference is that the information carried by this protocol is encrypted.
The following picture describes the process of the TLS/SSL handshake protocol. From "hello" of the client until "finished" of the broker. If you are interested in this, you can view more detailed material. Even if you do not know this process, you can also enable this function in EMQX.
Why do we need SSL/TLS two-way (mTLS) certification
The two-way certification is that a certificate is required for service and client during the connection authentication. Both parties need to perform authentication for ensuring that both sides involved in communication are trusted. Both parties share their public certificates, and then perform verification and confirmation based on the certificate. For some application scenarios that required high security, we need to enable two-way SSL/TLS authentication.
Preparate of the SSL/TLS certificate
In the two-way certification, we generally use the way self-signed to generate the certificate of the server and client, so this article will take the self-signed certificate as an example.
Generally speaking, we need a digital certificate to ensure the strong certification of TLS communication. The use of digital certificates is a three-party protocol. In addition to the communicating parties, there is a trusted third party to issue the certificate. Sometimes, this trusted third party is a CA. Communicating with CA is usually done by issuing certificates in advance. So, we need a CA’s certificate and an EMQX’s certificate these two certificates at least, and the EMQX’s certificate is issued by CA and uses the CA’s certificate for verification.
We assume that your system has installed OpenSSL. Using the toolkit included with OpenSSL can generate the certificate we needed.
Generate the self-signed CA certificate
First, we need a self-signed CA certificate. If you want to generate this certificate, you need a private key to sign it. You can execute the following command to generate this private key:
openssl genrsa -out ca.key 2048
This command will generate a key with a length of 2048 and will be stored in ca.key
. If you have this key, you can use it to generate the root certificate of EMQX:
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.pem
The root certificate is the starting point of an entire chain of trust. If the issuer of each level of a certificate and the issuer of the root certificate is trusted, this certificate is trusted. We can use it to issue the certificate for EMQX.
Generate server certificate
EMQX also needs its private key to ensure control for its certificates. The process of generating this private key is similar to the above:
openssl genrsa -out emqx.key 2048
Create file openssl.cnf
- req_distinguished_name :according to the situation to modify
- alt_names: modify
BROKER_ADDRESS
to the real IP or DNS address of EMQX broker such as IP.1 = 127.0.0.1 or DNS.1 = broker.xxx.com
[req]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
countryName = CN
stateOrProvinceName = Zhejiang
localityName = Hangzhou
organizationName = EMQX
commonName = CA
[req_ext]
subjectAltName = @alt_names
[v3_req]
subjectAltName = @alt_names
[alt_names]
IP.1 = BROKER_ADDRESS
DNS.1 = BROKER_ADDRESS
Then, use this key and configuration to issue a certificate request:
openssl req -new -key ./emqx.key -config openssl.cnf -out emqx.csr
Then use the root certificate to issue the certificate of EMQX:
openssl x509 -req -in ./emqx.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out emqx.pem -days 3650 -sha256 -extensions v3_req -extfile openssl.cnf
Generate client certificate
Two-way connection authentication also needs to create the certificate of client. First, we need to create client key:
openssl genrsa -out client.key 2048
Using the generated client key to create a client request file:
openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=EMQX/CN=client"
Finally, we use the previously generated CA certificate to sign the client and generate a client certificate:
openssl x509 -req -days 3650 -in client.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out client.pem
After preparing the server and client certificate, we can enable TLS/SSL two-way authentication in the EMQX.
Enable and verify SSL/TLS two-way connection
EMQX v5 configuration
listeners.ssl.default {
bind = "0.0.0.0:8883"
ssl_options {
# PEM file containing the trusted CA (certificate authority) certificates that the listener uses to verify the authenticity of the client certificates.
# For one-way authentication, the file content can be empty.
cacertfile = "etc/certs/ca.pem"
# PEM file containing the SSL/TLS certificate chain for the listener.
# If the certificate is not directly issued by a root CA, the intermediate CA certificates should be appended after the listener certificate to form a chain.
certfile = "etc/certs/emqx.pem"
# PEM file containing the private key corresponding to the SSL/TLS certificate.
keyfile = "etc/certs/emqx.key"
# Set `verify_peer` to verify the authenticity of the client certificates. Must be set to 'verify_peer' for two-way authentication (mTLS).
# Set 'verify_none' to allow any client to connect, regardless of the client certificate.
verify = verify_peer
# If set to `true`, the handshake fails if the client does not have a certificate to send. Must be set to `true` for two-way authentication (mTLS).
# If set to `false`, it fails only if the client sends an invalid certificate (an empty certificate is considered valid). i.e. one-way authentication.
fail_if_no_peer_cert = true
}
}
EMQX v4 configuration
In the EMQX, the default listening port of mqtt:ssl
is 8883.
Copy the file emqx.pem
, emqx.key
and ca.pem
generated by OpenSSL tool into the directory etc/certs/
of EMQX, and refer the following configuration to modify emqx.conf
:
## listener.ssl.$name is the IP address and port that the MQTT/SSL
## Value: IP:Port | Port
listener.ssl.external = 8883
# PEM file containing the private key corresponding to the SSL/TLS certificate.
listener.ssl.external.keyfile = etc/certs/emqx.key
# PEM file containing the SSL/TLS certificate chain for the listener.
# If the certificate is not directly issued by a root CA, the intermediate CA certificates should be appended after the listener certificate to form a chain.
listener.ssl.external.certfile = etc/certs/emqx.pem
# PEM file containing the trusted CA (certificate authority) certificates that the listener uses to verify the authenticity of the client certificates.
# For one-way authentication, the file content can be empty.
listener.ssl.external.cacertfile = etc/certs/ca.pem
# Set `verify_peer` to verify the authenticity of the client certificates.
# Set `verify_none` to allow any client to connect, regardless of the client certificate.
listener.ssl.external.verify = verify_peer
# If set to `true`, the handshake fails if the client does not have a certificate to send. Must be set to `true` for two-way authentication (mTLS).
# If set to `false`, it fails only if the client sends an invalid certificate (an empty certificate is considered valid). i.e. one-way authentication.
listener.ssl.external.fail_if_no_peer_cert = true
MQTT connection test
After finished configuring and restarted EMQX, we use MQTT client tool - MQTTX (this tool is cross-platform and supports MQTT 5.0) to verify that whether TLS service is normally running.
The requirement of MQTTX version: v1.3.2 or higher version
- Refer to the following picture to create
MQTT client
in the MQTTX (127.0.0.1
in the Host input box need to be replaced by the real IP of EMQX broker)
At this time, you need to select Self signed
in the column Certificate
and carry the file ca.pem
generated in the self-signed certificate and the client certificate client.pem
and the client key client.key
file.
- Click the button
Connect
, after the connection succeeds, if you can normally perform MQTT publish/subscribe operation, the configuration of SSL two-way connection authentication succeeds.
EMQX Dashboard verification
Finally, open the Dashboard of EMQX. On the Listeners page, you can see that there is an mqtt:ssl
connection on port 8883.
So far, we successfully finished the SSL/TLS configuration of the EMQX Broker and the test of a two-way authentication connection.