# mTLS Best Practices for Device Connection

Mutual TLS (mTLS) requires both the client and server to authenticate each other's certificates, fundamentally preventing devices without valid certificates from connecting. Combined with disabling password authentication on encrypted ports, devices can connect without providing a username or password; authentication relies entirely on the TLS client certificate.

The complete configuration involves three steps:

1. **Issue client certificates**: Issue a unique client certificate to each device and write the device's unique identifier into the certificate's CN field.
2. **Configure mTLS in EMQX Cloud**: Upload the server certificate and client CA, enable two-way authentication, and map the certificate CN field to Username or ClientID.
3. **Disable password authentication on encrypted ports**: Once password authentication is disabled on encrypted ports, devices connect using only their client certificates.

## Certificate Field Mapping

EMQX Cloud can automatically map a specific field from the client certificate to the MQTT connection's Username or ClientID. Once enabled, devices do not need to provide authentication credentials during connection; EMQX reads the value directly from the certificate. The mapped value can then be used as the basis for ACL rules.

Supported fields include CN, DN, and CRT, and can be selected in the [deployment settings](./deployment_settings.md#mqtt-settings). This guide uses the CN (Common Name) field as an example. When using CN, it is recommended to use the device serial number, MAC address, or UUID as the value. Each device's CN must be globally unique, and no two devices should share the same certificate.

## Prepare Certificates

mTLS requires the following two sets of certificates:

- **Server certificate**: Uploaded to EMQX Cloud so clients can verify the server's identity. For generation steps, see [Generate Server-Side CA Certificate](./tls_ssl.md#generate-server-side-ca-certificate).
- **Client certificates**: Distributed to each device so the server can verify device identity. Generation steps are described below.

## Issue Client Certificates

### Generate a Client CA

The Client CA is used to issue client certificates for each device and only needs to be generated once. Make sure [OpenSSL](https://www.openssl.org/) is installed first.

```bash
openssl req \
    -new \
    -newkey rsa:2048 \
    -days 3650 \
    -nodes \
    -x509 \
    -subj "/C=CN/O=EMQX Technologies Co., Ltd/CN=EMQ CA" \
    -keyout client-ca.key \
    -out client-ca.crt
```

The generated `client-ca.crt` will need to be uploaded to EMQX Cloud in a later step.

### Issue a Certificate for Each Device

Repeat the following steps for each device, replacing `device-001` with the actual device identifier.

1. Generate the device private key.

   ```bash
   openssl genrsa -out device-001.key 2048
   ```

2. Generate a certificate signing request (CSR) with the device's unique identifier in the CN field.

   ```bash
   openssl req -new -key device-001.key -out device-001.csr \
       -subj "/CN=device-001"
   ```

3. Sign with the Client CA to generate the device certificate.

   ```bash
   openssl x509 -req -days 3650 -sha256 \
       -in device-001.csr \
       -CA client-ca.crt \
       -CAkey client-ca.key \
       -CAcreateserial \
       -out device-001.crt
   ```

4. Verify the certificate.

   ```bash
   openssl verify -CAfile client-ca.crt device-001.crt
   ```

## Configure mTLS in EMQX Cloud

### Enable Two-Way TLS

Upload the server certificate, private key, and client CA certificate in the deployment's **TLS/SSL Configuration** panel. For step-by-step instructions, see [Configure TLS/SSL in Dedicated](./tls_ssl.md#configure-two-way-tls-ssl).

### Map CN to Username

Map the CN field to the MQTT connection's `Username` in the deployment settings. ACL rules can then be applied based on this Username.

::: tip Note
This feature is available for Dedicated v5 and Dedicated Flex deployments only. If you do not see this option, [submit a ticket](../feature/tickets.md#create-a-ticket) to contact us about upgrading your deployment.
:::

1. Go to the deployment details and click **Deployment Settings** in the left menu, then select the **MQTT Settings** tab.
2. In the **Use Peer Certificate as Username** dropdown, select `cn`.
3. Click **Save**.

### Map CN to ClientID

If your system needs to track devices by ClientID, you can also map CN to `ClientID`.

::: tip Note
This feature is available for Dedicated v5 and Dedicated Flex deployments only. If you do not see this option, [submit a ticket](../feature/tickets.md#create-a-ticket) to contact us about upgrading your deployment.
:::

1. Go to the deployment details and click **Deployment Settings** in the left menu, then select the **MQTT Settings** tab.
2. In the **Use Peer Certificate as ClientID** dropdown, select `cn`.
3. Click **Save**.

::: warning Note
When mapping CN to ClientID, you must ensure that every device's CN is globally unique. If multiple devices share the same CN, their connections will kick each other out due to a ClientID conflict.
:::

## Disable Password Authentication on Encrypted Ports

After completing the above configuration, you can disable password authentication on encrypted ports so that devices can connect using only their client certificates, without providing a username or password.

::: warning Note
Before disabling password authentication, confirm that all clients have valid client certificates and that end-to-end connectivity tests have passed, to avoid disrupting live device connections. It is also recommended to close the plaintext port (1883) and expose only the encrypted ports (8883 / 8084).
:::

**V5 Dedicated deployments** can perform this operation directly in the console. For steps, see [Ports Management - Manage Client Authentication for Encrypted Ports](./port_management.md#manage-client-authentication-for-encrypted-ports).

For other deployment types, please submit a support [ticket](../feature/tickets.md). The SRE team can help you disable client authentication on ports 8883 and 8084 for your deployment.

## Client Connection Examples

### MQTTX Example

Use [MQTTX](https://mqttx.app/) to test an mTLS connection:

1. Create a new connection, enter a connection name. The Client ID can be randomly generated.

2. Select the Host and enter the deployment's connection address and port:
   - TLS connection: select `mqtts://`, port `8883`.
   - WebSocket over TLS: select `wss://`, port `8084`.

3. If password authentication has been disabled, leave Username and Password blank.

4. Enable **SSL/TLS** and select **Self signed**.

5. Fill in the following certificate files:
   - **CA File**: Server CA certificate (`server-ca.crt`).
   - **Client Certificate File**: Device client certificate (`device-001.crt`).
   - **Client Key File**: Device client private key (`device-001.key`).

6. Click **Connect** in the upper right corner.

## FAQ

### Devices Getting Disconnected Due to ClientID Conflicts

**Symptom:** Two devices share the same ClientID or the same client certificate. The device that connects later kicks out the one that connected first.

**Cause:** The MQTT protocol requires that only one connection with a given ClientID can exist in a broker at a time.

**Solution:** Ensure each device holds a unique certificate with a unique CN. Using CN-to-Username mapping can further reduce the risk of ClientID conflicts.

### What to Do If a Certificate Is Compromised

1. If CN-to-Username mapping is enabled, immediately add the Username corresponding to the compromised device's CN to the [Blacklist](./blacklist.md) to prevent it from reconnecting.
2. Issue a new certificate to the target device and update the certificate configuration on the device.
3. Until the blacklist entry expires or is manually removed, the compromised certificate cannot be used to connect.

### Is Additional Authentication Needed After Disabling Password Authentication?

After disabling password authentication on encrypted ports, authentication relies entirely on TLS client certificates, which provides stronger security than username/password authentication. If some devices temporarily cannot use client certificates, you can keep password authentication enabled during the transition period and disable it after all devices have been migrated to certificate-based authentication.
