---
# System prepended metadata

title: Devices auto-provision on AuthN over MQTT using X.509 certificate chain
tags: [ServicePleX]

---

# Devices auto-provision on AuthN over MQTT using X.509 certificate chain

X.509 CA certificate authentication offers elegant solutions to these challenges by using certificate chains. A certificate chain results from a CA signing an intermediate CA that in turn signs another intermediate CA, and so on, until a final intermediate CA signs a device. 
In our example, Company-X signs Factory-Y, which in turn signs Technician-Z that finally signs Smart-X-Widget.

![image](https://hackmd.io/_uploads/H1Y8-9zd6.png)

[toc]

## Advantages

Configure **ServicePleX** to trust all client certificates from a specific trust anchor (intermediate certificate). 

The device name is automatically discovered from the certificate **Common Name (CN)** using configurable regular expression. 
This feature eliminates the need for manual certificate updates on each device when certificate rotation occurs. 
++Furthermore, it allows auto-provisioning new devices over MQTT, if Create new devices is enabled in the configuration.++

## Preknowledge

Authentication (AuthN) verifies the identity of a device to ``ServicePleX``.
Authorization (AuthZ) is the process of confirming the permissions for an authticated device on ``ServicePleX``.

X.509 certificates are used for authentication in ``ServicePlex``, not authorization. Authorization would be based on MQTT Client Credentials.



## Steps

### 0. Enable MQTT over SSL in ServicePleX [here](https://thingsboard.io/docs/pe/user-guide/mqtt-over-ssl/)
  :::spoiler docker-compose.yml
    version: '2.2'
    services:
      mytbpe:
        restart: always
        image: "thingsboard/tb-pe:3.6.2PE"
        ports:
          - "8080:8080"
          - "8883:8883"
          - "7070:7070"
          - "5683-5688:5683-5688/udp"
        environment:
          ...
          ...
          MQTT_SSL_ENABLED: "true"
          MQTT_SSL_CREDENTIALS_TYPE: PEM
          MQTT_SSL_PEM_CERT: cert.pem //Path to the server cert file.
          MQTT_SSL_PEM_KEY: key.pem //Path to the server private key file
          ... 
          ...
  :::

### 1. Prepare your server and certificate chain

* A CA root certificate in pem format, e.g. ca-root.pem

### 2. Generate Client certificate chain
#### 2.1 Generate root certificate
1. openssl req -x509 -newkey rsa:4096 -keyout rootKey.pem -out rootCert.pem -sha256 -days 365 -nodes
```
victor@feb:~/workspace/x509$ openssl req -x509 -newkey rsa:4096 -keyout rootKey.pem -out rootCert.pem -sha256 -days 365 -nodes
Generating a RSA private key
............................++++
......................................................................++++
writing new private key to 'rootKey.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:5giotlead.com
Email Address []:
```

#### 2.2 Generate intermediate certificate
1. openssl req -new -newkey rsa:4096 -keyout intermediateKey.pem -out intermediate.csr -sha256 -nodes
```
victor@feb:~/workspace/x509$ openssl req -new -newkey rsa:4096 -keyout intermediateKey.pem -out intermediate.csr -sha256 -nodes
Generating a RSA private key
..........................................................++++
...............++++
writing new private key to 'intermediateKey.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:smartpole.5giotlead.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
```
2. openssl x509 -req -in intermediate.csr -out intermediateCert.pem -CA rootCert.pem -CAkey rootKey.pem -days 365 -sha256 -CAcreateserial
```
victor@feb:~/workspace/x509$ openssl x509 -req -in intermediate.csr -out intermediateCert.pem -CA rootCert.pem -CAkey rootKey.pem -days 365 -sha256 -CAcreateserial
Signature ok
subject=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = smartpole.5giotlead.com
Getting CA Private Key
victor@feb:~/workspace/x509$
```
#### 2.3 Generate device certificate
1. openssl req -new -newkey rsa:4096 -keyout deviceKey.pem -out device.csr -sha256 -nodes
```
victor@feb:~/workspace/x509$ openssl req -new -newkey rsa:4096 -keyout deviceKey.pem -out device.csr -sha256 -nodes
Generating a RSA private key
....................................................................................................................................++++
..........++++
writing new private key to 'deviceKey.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:X509.smartpole.5giotlead.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
```

2. openssl x509 -req -in device.csr -out deviceCert.pem -CA intermediateCert.pem -CAkey intermediateKey.pem -days 365 -sha256 -CAcreateserial
```
victor@feb:~/workspace/x509$ openssl x509 -req -in device.csr -out deviceCert.pem -CA intermediateCert.pem -CAkey intermediateKey.pem -days 365 -sha256 -CAcreateserial
Signature ok
subject=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = X509.smartpole.5giotlead.com
Getting CA Private Key
```

3. cat deviceCert.pem intermediateCert.pem rootCert.pem > chain.pem

### 3. Provision Client Intermediate Public Key as Device Profile X509 provision strategy
1. Open intermediateCert.pem
2. Put all content into device profile
![image](https://hackmd.io/_uploads/HkSnAuquT.png)
3. Set your CN regular expression

### 4. Test the connection

* mosquitto_pub
  ```!
    $ mosquitto_pub --cafile ca-root.pem -d -q 1 -h "mqtt.thingsboa                                                                                             rd.cloud" -p "8883" \                                                                                                                                                        -t "v1/devices/me/telemetry" --key deviceKey.pem --cert chain.pem -m {"temperatu                                                                                             re":25}
    Client (null) sending CONNECT
    Client (null) received CONNACK (0)
    Client (null) sending PUBLISH (d0, q1, r0, m1, 'v1/devices/me/telemetry', ... (1                                                                                             6 bytes))
    Client (null) received PUBACK (Mid: 1, RC:0)
    Client (null) sending DISCONNECT
  ```
* MQTTX


---

**Device profile**

There are three provision strategies available:

**Allowing creating new devices** - checks that the device with the same name has not registered in ThingsBoard yet. This strategy is useful when you don’t know the list of unique device names (MAC addresses, etc.) during manufacturing, but the device itself has access to this info in the firmware. It is easier to implement, but it is less secure than the second strategy.
**Checking pre-provisioned devices** - checks that the device with the same name has been already created in ThingsBoard, but hasn’t been provisioned yet. This strategy is useful when you want to allow provisioning only for a specific list of devices. Let’s assume that you have collected a list of unique IDS (MAC addresses, etc) during the manufacturing. You can use bulk provisioning to upload this list to ThingsBoard. Now, devices from the list can issue provision requests, and no other devices will be able to provision themselves.
**X.509 Certificates Chains**
X.509 certificates strategy is used to provision devices by client certificates in two-way TLS communication.
**This strategy can:**
* check for pre-provisioned devices 
* update X.509 device credentials
* create new devices

The user uploads X.509 certificate to the device profile and sets a regular expression to fetch the device name from Common Name (CN).

Client certificates must be signed by X.509 certificate, pre-uploaded for this device profile to provision devices by the strategy.

The client must establish a TLS connection using the entire chain of certificates (this chain must include device profile X.509 certificate on the last level).

If a device already exists with outdated X.509 credentials, this strategy automatically updates it with the device certificate's credentials from the chain.

**Important:** Uploaded certificates should be neither root nor intermediate certificates that are provided by a well-known Certificate Authority (CA).

## References

* [MQTT over SSL](https://thingsboard.io/docs/pe/user-guide/mqtt-over-ssl/)
* [EMQX SSL/TLS 使用配置指南](https://www.emqx.com/zh/blog/emqx-ssl-tls-configuration-guide)