# 在 BYOC 中配置 TLS/SSL

EMQX BYOC 部署使用 TLS/SSL 加密协议，建立安全的加密通信通道，在数据传输过程中保护数据的机密性。本页概述了如何在单向和双向认证模式下启用 TLS/SSL 通信，确保 MQTT 系统的安全通信。

下表概述了单向和双向认证模式下的不同认证要求。

| 认证方式 | 是否支持自签名证书 | 服务器证书 | 证书链 | 私有秘钥 | 客户端 CA 证书 |
| -------- | ------------------ | ---------- | ------ | -------- | -------------- |
| 单向认证 | 支持               | 需要       | 需要   | 需要     | 不需要         |
| 双向认证 | 支持               | 需要       | 需要   | 需要     | 需要           |

## 单向认证模式

单向认证确保服务器（EMQX MQTT 代理）在 TLS/SSL 握手期间向客户端（设备或应用程序）呈现有效的证书。客户端通过将呈现的证书与受信任的证书颁发机构（CA）进行验证，以验证服务器的真实性。

在 BYOC 部署中，目前只接受受信任的 CA 颁发的证书。

### 证书组件

要为您的 BYOC 部署配置 TLS/SSL，您需要准备一个PEM 文件，这个文件对于启用 MQTT 客户端与 EMQX MQTT 代理之间的安全单向认证至关重要。PEM 文件需要包含以下组件：

- **服务器证书**：这是由受信任的证书颁发机构（CA）颁发的证书，使 EMQX MQTT 代理能够与客户端建立安全连接。

- **证书链**：包含完整的证书链，直至受信任的根 CA 证书。这使客户端设备能够验证服务器证书的真实性。

- **私钥**：与服务器证书关联的私钥是解密客户端与 EMQX MQTT 代理之间通信的关键。

### 证书格式和标准指南

在准备用于 TLS/SSL 配置的证书时，请考虑以下准则：

- 证书必须指定加密算法和密钥大小。EMQX Cloud 支持 1024 位 RSA（RSA_1024）和 2048 位 RSA（RSA_2048）算法。

- 证书必须符合 SSL/TLS X.509 第 3 版标准。它们应包含公钥、网站的完全限定域名（FQDN）或 IP 地址以及发布者信息。

- 证书可以使用您的私钥或颁发 CA 的私钥进行自签名。如果由 CA 签名，导入证书时必须包括证书链。

- 证书必须有效，在其有效期开始或结束之前的 **30 天** 内不能导入。

- 确保证书、私钥和证书链使用 **PEM 编码**。

- 私钥必须无密码并支持 PKCS#1 和 PKCS#8。

- 证书的加密算法必须与签发 CA 的加密算法匹配。例如，如果签发 CA 使用 RSA，则证书的密钥类型也应为 RSA。

这些准则确保了在您的 BYOC 部署中正确配置 TLS/SSL。

<!-- ## 创建 PEM 文件

要创建所需的 PEM 文件，请按照以下步骤操作：

1. 打开文本编辑器。
2. 复制服务器证书的内容并粘贴到编辑器中。
3. 复制证书链的内容并将其粘贴在服务器证书下方。
4. 复制私钥的内容并将其粘贴在证书链下方。

生成的 PEM 文件应具有以下结构：

```txt
-----BEGIN CERTIFICATE-----
Base64 编码的服务器证书内容
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
Base64 编码的证书链内容
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
Base64 编码的私钥内容
-----END RSA PRIVATE KEY-----
``` -->
```

### 在 "byoc create" 命令中使用证书文件

创建 BYOC 部署时，在执行 `./byoc create` 命令之前，请确保已将证书和私钥文件复制到您的 Ubuntu 环境目录，并且可以轻松访问。在执行 `./byoc create` 命令部署您的 BYOC 环境时，参数中需提供服务器证书和私钥的 PEM 文件路径。关于如何配置参数，详见[执行部署](../create/byoc.md#执行部署)。

## 创建双向认证

1. 登录 [EMQX Cloud 控制台](<https://cloud.emqx.com/console>)。
2. 进入部署详情，点击 **+ TLS/SSL 配置** 按钮，配置证书内容，您可以上传文件或者直接填写证书内容:
   - TLS/SSL 认证类型：选择双向认证（客户端和服务端相互验证证书）。
   - 公钥证书：自定义的服务端证书（包括证书链：通常第三方机构签发证书时会提供，如缺失您可以前往 [证书链补全](https://myssl.com/chain_download.html)）
   - 私钥：私有秘钥
   - 客户端 CA 证书：选择双向认证时，需要提供客户端的 CA 证书
3. 填写完成后，点击**确认**。

### 使用 MQTTX 测试双向 TLS

测试之前，请确保创建了认证信息，参考[认证](./default_auth.md)，您可以使用 [MQTTX](<https://mqttx.app/>) 连接和测试。在本教程中我们将使用用 MQTTX 进行测试：

1. 新建连接，输入 Name，Client ID 随机生成即可。
2. 选择 Host，填入部署的连接地址和端口。
   - 若选择 SSL 连接，选择 `mqtts://` 和 `8883` 端口
   - 若选择 WebSocket with SSL，选择 `wss://` 和 `8084` 端口
3. 输入创建的认证信息：用户名和密码。
4. 启用 SSL/TLS。
5. 选择证书：
   - 如果是 CA 机构认证的服务端证书，点击 `Self signed`，在 CA File 填入证书。
   - 如果是自签名证书，点击 `Self signed`，提供自签名服务端 CA 证书。
   - 双向认证还需填入客户端证书以及客户端密钥。
6. 点击右上角的**连接**。

![mqttx_tls](./_assets/mqttx_tls_shuang.png)

您还可以查看[双向认证教程视频](https://www.bilibili.com/video/BV1sP4y1c7tN/)了解每一步的设置。


## 生成自签名证书

请先确保您已经安装了 [OpenSSL](https://www.openssl.org/)。

### 生成自签名服务端证书

1. CA 证书生成 `server-ca.crt`。

   subj 依据实际使用情况调整。

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

2. 服务端秘钥生成 `server.key`。

```bash
openssl genrsa -out server.key 2048
```

3. 创建 `openssl.cnf` 文件。

**替换 IP.1 地址为当前部署地址**

> 注意：使用亚马逊中国的用户，请将 IP.1 替换成 DNS.1

```
cat << EOF > ./openssl.cnf
[policy_match]
countryName             = match
stateOrProvinceName     = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[req]
default_bits       = 2048
distinguished_name = req_distinguished_name
req_extensions     = req_ext
x509_extensions    = v3_req
prompt             = no

[req_distinguished_name]
commonName          = Server

[req_ext]
subjectAltName = @alt_names

[v3_req]
subjectAltName = @alt_names

[alt_names]
# EMQX deployment connections address
# 非亚马逊的部署使用 IP.1
IP.1 = <当前部署的地址>
# 亚马逊中国的部署使用 DNS.1
# DNS.1 = <当前部署的地址>
EOF
```

4. 生成服务端证书请求文件 `server.csr`。

```bash
openssl req -new -key server.key -config openssl.cnf -out server.csr
```

5. 用 CA 证书给服务端证书签名，生成服务端证书 `server.crt`。

```bash
openssl x509 -req \
    -days 365 \
    -sha256 \
    -in server.csr \
    -CA server-ca.crt \
    -CAkey server-ca.key \
    -CAcreateserial -out server.crt \
    -extensions v3_req -extfile openssl.cnf
```

6. 查看服务端证书信息。

```bash
openssl x509 -noout -text -in server.crt
```

7. 验证证书。

```bash
openssl verify -CAfile server-ca.crt server.crt
```

### 生成自签名客户端证书

1. CA 证书生成 `client-ca.crt`。

   subj 依据实际使用情况调整。

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

2. 客户端秘钥生成 `client.key`。

```bash
openssl genrsa -out client.key 2048
```

3. 生成客户端证书请求文件 `client.csr`。

```bash
openssl req -new -key client.key -out client.csr -subj "/CN=Client"
```

4. 用 CA 证书给客户端证书签名，生成 `client.crt`。

```bash
openssl x509 -req -days 365 -sha256 -in client.csr -CA client-ca.crt -CAkey client-ca.key -CAcreateserial -out client.crt
```

6. 查看客户端端证书信息。

```bash
openssl x509 -noout -text -in client.crt
```

7. 验证证书。

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

## 删除证书

删除证书会断开客户端到 `8883` 和 `8084` 的连接，请确保这不会影响到您的业务。

1. 登录 [EMQX Cloud 控制台](<https://cloud.emqx.com/console>)。
2. 进入部署详情，点击 **TLS/SSL 配置**部分的证书的删除按钮。
3. 在对话框点击“确定”，完成删除。
