

# CloudFront 的双向 TLS 身份验证（查看器 mTLS）
<a name="mtls-authentication"></a>

双向 TLS 身份验证（双向传输层安全身份验证，mTLS）是一种安全协议，它在标准 TLS 身份验证的基础上进行了扩展，要求进行基于证书的双向身份验证，在该机制下，客户端与服务器必须先证实自己的身份，然后才能建立安全连接。借助双向 TLS，您可以确保只有提供了可信 TLS 证书的客户端，才能获得对 CloudFront 分配的访问权限。

## 工作原理
<a name="how-mtls-works"></a>

在标准 TLS 握手过程中，只有服务器需要提供证书来向客户端证明其身份。借助双向 TLS，身份验证过程会变为双向验证。当客户端尝试连接到您的 CloudFront 分配时，CloudFront 会在 TLS 握手过程中请求客户端证书。在建立安全连接之前，客户端必须提供有效的 X.509 证书，CloudFront 会根据您配置的信任存储来验证该证书。

CloudFront 在 AWS 边缘站点执行此证书验证操作，这既能将身份验证的复杂性从原始服务器中剥离，又能保留 CloudFront 的全球性能优势。您可以在两种模式下配置 mTLS：验证模式（要求所有客户端提供有效证书）或可选模式（在客户端提供证书时对证书进行验证，但也允许无证书的连接）。

## 使用案例
<a name="mtls-use-cases"></a>

CloudFront 的双向 TLS 身份验证可应对传统身份验证方法难以满足需求的关键安全场景：
+ **使用内容缓存进行设备身份验证**：您可以要求游戏主机、IoT 设备或公司硬件需先通过身份验证，之后才能访问固件更新、游戏下载资源或内部资源。每台设备均包含一个唯一证书，该证书既能证明设备的真实性，又能获益于 CloudFront 的缓存功能。
+ **API 到 API 身份验证**：可用于保障可信业务合作伙伴之间、支付系统之间或微服务之间的机器对机器通信的安全。基于证书的身份验证不仅消除了对共享密钥或 API 密钥的需求，而且为自动化数据交换提供了强大的身份验证能力。

**Topics**
+ [

## 工作原理
](#how-mtls-works)
+ [

## 使用案例
](#mtls-use-cases)
+ [

# 信任存储和证书管理
](trust-stores-certificate-management.md)
+ [

# 为 CloudFront 分配启用双向 TLS
](enable-mtls-distributions.md)
+ [

# 关联 CloudFront 连接函数
](connection-functions.md)
+ [

# 配置其他设置
](configuring-additional-settings.md)
+ [

# 用于缓存策略并转发到源的查看器 mTLS 标头
](viewer-mtls-headers.md)
+ [

# 使用 CloudFront 连接函数和 KVS 实施吊销
](revocation-connection-function-kvs.md)
+ [

# 使用连接日志实现可观测性
](connection-logs.md)

# 信任存储和证书管理
<a name="trust-stores-certificate-management"></a>

要对 CloudFront 实施双向 TLS 身份验证，必须创建并配置信任存储。信任存储包含证书颁发机构（CA）证书，CloudFront 在身份验证过程中使用这些证书来验证客户端证书。

## 什么是信任存储？
<a name="what-is-trust-store"></a>

信任存储是 CA 证书的存储库，CloudFront 在双向 TLS 身份验证过程中使用这些证书来验证客户端证书。信任存储包含根证书和中间 CA 证书，这些证书构成了用于验证客户端证书的信任链。

在对 CloudFront 实施双向 TLS 时，信任存储会指定您可信任哪些证书颁发机构来颁发有效的客户端证书。在 TLS 握手过程中，CloudFront 会根据信任存储对每个客户端证书进行验证。客户端只有在提供了链接到信任存储中的某个 CA 的证书时，才能成功完成身份验证。

CloudFront 中的信任存储是账户级资源，可将其与多个分配关联。这可让您在整个 CloudFront 部署中保持一致的证书验证策略，并简化 CA 证书管理。

## 证书颁发机构支持
<a name="ca-support"></a>

CloudFront 支持由 AWS 私有证书颁发机构和第三方私有证书颁发机构颁发的证书。这让您可以根据组织要求，灵活地选择使用现有证书基础设施或者利用 AWS 托管证书服务。
+ **AWS 私有证书颁发机构：**您可以使用由 AWS 私有 CA 颁发的证书，这提供了托管私有证书颁发机构服务。此集成既简化了证书生命周期管理，又提供了与其他 AWS 服务的无缝集成。
+ **第三方私有证书颁发机构：**您也可以使用来自现有的私有证书颁发机构基础设施的证书，包括企业 CA 或其他第三方证书提供商。这可让您在添加 CloudFront 的 mTLS 功能的同时保留当前证书管理流程。

## 证书要求和规范
<a name="certificate-requirements"></a>

信任存储对自身包含的 CA 证书有特定的要求：

### CA 证书格式要求
<a name="ca-cert-format-requirements"></a>
+ **格式：**PEM（隐私增强邮件）格式
+ **内容边界：**证书必须包含在 -----BEGIN CERTIFICATE----- 和 -----END CERTIFICATE----- 边界内
+ **注释：**必须以 \$1 字符开头，并且不得包含任何 - 字符
+ **换行符：**证书之间不允许存在空行

### 支持的证书规范
<a name="supported-cert-specs"></a>
+ **证书类型：**X.509v3
+ **公有密钥类型：**
  + RSA 2048、RSA 3072、RSA 4096
  + ECDSA：secp256r1、secp384r1
+ **签名算法：**
  + 采用 RSA 的 SHA256、SHA384、SHA512
  + 采用 EC 的 SHA256、SHA384、SHA512
  + 采用 RSASSA-PSS 与 MGF1 的 SHA256、SHA384、SHA512

### 证书捆绑包格式示例
<a name="example-cert-bundle"></a>

多个证书（PEM 编码）：

```
# Root CA Certificate
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKoK/OvD/XqiMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTcwNzEyMTU0NzQ4WhcNMjcwNzEwMTU0NzQ4WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAuuExKvY1xzHFylsHiuowqpmzs7rEcuuylOuEszpFp+BtXh0ZuEtts9LP
-----END CERTIFICATE-----
# Intermediate CA Certificate
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKoK/OvD/XqjMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTcwNzEyMTU0NzQ4WhcNMjcwNzEwMTU0NzQ4WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAuuExKvY1xzHFylsHiuowqpmzs7rEcuuylOuEszpFp+BtXh0ZuEtts9LP
-----END CERTIFICATE-----
```

## 创建信任存储
<a name="create-trust-store"></a>

在创建信任存储之前，您必须将 PEM 格式的 CA 证书捆绑包上传到 Amazon S3 存储桶。此证书捆绑包应包含验证客户端证书所需的所有受信任的根证书和中间 CA 证书。

在创建信任存储时，仅从 S3 中读取一次 CA 证书捆绑包。如果后续对 CA 证书捆绑包进行修改，则需手动更新信任存储。信任存储和 S3 CA 证书捆绑包之间不会保持同步。

### 先决条件
<a name="trust-store-prerequisites"></a>
+ 来自证书颁发机构（CA）的证书捆绑包已上传到 Amazon S3 存储桶
+ 创建 CloudFront 资源所需的权限

### 创建信任存储（控制台）
<a name="create-trust-store-console"></a>

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 在导航窗格中，选择**信任存储**。

1. 选择**创建信任存储**。

1. 对于**信任存储名称**，输入信任存储的名称。

1. 对于**证书颁发机构（CA）捆绑包**，输入 PEM 格式的 CA 证书捆绑包的 Amazon S3 路径。

1. 选择**创建信任存储**。

### 创建信任存储（AWS CLI）
<a name="create-trust-store-cli"></a>

```
aws cloudfront create-trust-store \
  --name MyTrustStore \
  --certificate-authority-bundle-s3-location Bucket=my-bucket,Key=ca-bundle.pem \
  --tags Items=[{Key=Environment,Value=Production}]
```

## 将信任存储与分配关联
<a name="associate-trust-store"></a>

创建信任存储后，您必须将其与 CloudFront 分配关联来启用双向 TLS 身份验证。

### 先决条件
<a name="associate-prerequisites"></a>
+ 现有 CloudFront 分配，已启用仅 HTTPS 查看器协议策略并且禁用了 HTTP3 支持。

### 关联信任存储（控制台）
<a name="associate-trust-store-console"></a>

在 CloudFront 控制台中，可通过以下两个途径关联信任存储：信任存储详细信息页面或分配设置页面。

**通过信任存储详细信息页面关联信任存储：**

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 在导航窗格中，选择**信任存储**。

1. 选择要关联的信任存储的名称。

1. 选择**关联到分配**。

1. 配置可用的查看器 mTLS 选项：
   + **客户端证书验证模式：**在“必需”模式和“可选”模式之间进行选择。在必需模式下，所有客户端都需要提供证书。在可选模式下，系统会对提供证书的客户端进行验证，而未提供证书的客户端也允许访问。
   + **公布信任存储 CA 名称：**选择在 TLS 握手过程中，是否向客户端公布信任存储中的 CA 名称。
   + **忽略证书到期日期：**选择是否允许使用到期证书建立连接（其他验证标准仍将适用）。
   + **连接函数：**可以关联一个可选的连接函数，来基于其他自定义标准允许/拒绝连接。

1. 选择要与信任存储关联的一个或多个分配。分配只有在禁用了 HTTP3 且采用仅 HTTPS 缓存行为后，才能够支持查看器 mTLS。

1. 选择**关联**。

**通过分配设置页面关联信任存储：**

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 选择要关联的分配

1. 在**常规**选项卡下的**设置**容器中，选择右上角的**编辑**

1. 向下滚动到页面底部，在**连接性**容器中，打开**查看器 mTLS** 开关

1. 配置可用的查看器 mTLS 选项：
   + **客户端证书验证模式：**在“必需”模式和“可选”模式之间进行选择。在必需模式下，所有客户端都需要提供证书。在可选模式下，系统会对提供证书的客户端进行验证，而未提供证书的客户端也允许访问。
   + **公布信任存储 CA 名称：**选择在 TLS 握手过程中，是否向客户端公布信任存储中的 CA 名称。
   + **忽略证书到期日期：**选择是否允许使用到期证书建立连接（其他验证标准仍将适用）。
   + **连接函数：**可以关联一个可选的连接函数，来基于其他自定义标准允许/拒绝连接。

1. 选择右下角的**保存更改**。

### 关联信任存储（AWS CLI）
<a name="associate-trust-store-cli"></a>

通过 DistributionConfig.ViewerMtlsConfig 属性可以将信任存储与分配相关联。这意味着我们首先需要获取分配配置，然后在后续的 UpdateDistribution 请求中提供 ViewerMtlsConfig。

```
// First fetch the distribution
aws cloudfront get-distribution {DISTRIBUTION_ID}

// Update the distribution config, for example:
Distribution config, file://distConf.json: 
{
  ...other fields,
  ViewerMtlsConfig: {
    Mode: 'required',
    TrustStoreConfig: {
        AdvertiseTrustStoreCaNames: false,
        IgnoreCertificateExpiry: true,
        TrustStoreId: {TRUST_STORE_ID}
    }
  }
}

aws cloudfront update-distribution \
   --id {DISTRIBUTION_ID} \
   --if-match {ETAG} \
   --distribution-config file://distConf.json
```

## 管理信任存储
<a name="manage-trust-stores"></a>

### 查看信任存储详细信息
<a name="view-trust-store-details"></a>

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 在导航窗格中，选择**信任存储**。

1. 选择信任存储的名称以查看其详细信息页面。

详细信息页面将显示以下内容：
+ 信任存储名称和 ID
+ CA 证书数量
+ 创建日期和上次修改日期
+ 关联的分配
+ 标签

### 修改信任存储
<a name="modify-trust-store"></a>

要替换 CA 证书捆绑包，请执行以下操作：

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 在导航窗格中，选择**信任存储**。

1. 选择信任存储的名称。

1. 选择**操作**，然后选择**编辑**。

1. 对于**证书颁发机构（CA）捆绑包**，输入更新后的 CA 捆绑包 PEM 文件的 Amazon S3 位置。

1. 选择**更新信任存储**。

### 删除信任存储
<a name="delete-trust-store"></a>

**先决条件：**您必须先取消信任存储与所有 CloudFront 分配的关联。

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 在导航窗格中，选择**信任存储**。

1. 选择信任存储的名称。

1. 选择**删除信任存储**。

1. 选择**删除**以确认。

### 后续步骤
<a name="trust-store-next-steps"></a>

在创建信任存储并将其与 CloudFront 分配关联后，您可以继续在分配中启用双向 TLS 身份验证并配置其他设置，例如将证书标头转发到源。有关在分配中启用 mTLS 的详细说明，请参阅[为 CloudFront 分配启用双向 TLS](enable-mtls-distributions.md)。

# 为 CloudFront 分配启用双向 TLS
<a name="enable-mtls-distributions"></a>

## 先决条件和要求
<a name="mtls-prerequisites-requirements"></a>

CloudFront 的双向 TLS 验证模式要求所有客户端在 TLS 握手过程中提供有效证书，并拒绝未使用有效证书的连接。在 CloudFront 分配上启用双向 TLS 之前，请确保：
+ 已使用证书颁发机构证书创建信任存储
+ 已将信任存储与 CloudFront 分配关联
+ 所有分配缓存行为都使用仅 HTTPS 查看器协议策略
+ 分配使用的是 HTTP/2（默认设置，HTTP/3 不支持查看器 mTLS）

**注意**  
双向 TLS 身份验证要求在查看器和 CloudFront 之间建立 HTTPS 连接。您无法在具有任何支持 HTTP 连接的缓存行为的分配上启用 mTLS。

## 启用双向 TLS（控制台）
<a name="enable-mtls-console"></a>

### 对于新的分配
<a name="enable-mtls-new-distributions"></a>

在 CloudFront 控制台中创建新分配的过程中，无法配置查看器 mTLS。首先，通过任意方式（控制台、CLI、API）创建分配，然后根据以下现有分配说明操作，编辑分配设置以启用查看器 mTLS。

### 对于现有分配
<a name="enable-mtls-existing-distributions"></a>

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 从分配列表中，选择要修改的分配。

1. 确保将所有缓存行为的查看器协议策略设置为**将 HTTP 重定向到 HTTPS** 或**仅 HTTPS**。（您可以选择**缓存行为**选项卡，查看和更新任何使用 HTTP 协议策略的缓存行为。）

1. 选择**常规**选项卡。

1. 在**设置**部分中，选择**编辑**。

1. 在**连接性**部分中，找到**查看器双向身份验证(mTLS)**。

1. 将**启用双向身份验证**切换为“开启”状态。

1. 对于**客户端证书验证模式**，选择**必需**（所有客户端都必须提供证书）或**可选**（客户端可以选择性地提供证书）。

1. 对于**信任存储**，选择您之前创建的信任存储。

1. （可选）如果您希望 CloudFront 在 TLS 握手过程中向客户端发送 CA 名称，请切换**公布信任存储 CA 名称**。

1. （可选）如果您想允许使用到期证书进行连接，请切换**忽略证书到期日期**。

1. 选择**保存更改**。

## 启用双向 TLS（AWS CLI）
<a name="enable-mtls-cli"></a>

### 对于新的分配
<a name="enable-mtls-cli-new"></a>

以下示例演示如何创建包含 mTLS 设置的分配配置文件（distribution-config.json）：

```
{
  "CallerReference": "cli-example-1",
  "Origins": {
    "Quantity": 1,
    "Items": [
      {
        "Id": "my-origin",
        "DomainName": "example.com",
        "CustomOriginConfig": {
          "HTTPPort": 80,
          "HTTPSPort": 443,
          "OriginProtocolPolicy": "https-only"
        }
      }
    ]
  },
  "DefaultCacheBehavior": {
    "TargetOriginId": "my-origin",
    "ViewerProtocolPolicy": "https-only",
    "MinTTL": 0,
    "ForwardedValues": {
      "QueryString": false,
      "Cookies": {
        "Forward": "none"
      }
    }
  },
  "ViewerCertificate": {
    "CloudFrontDefaultCertificate": true
  },
  "ViewerMtlsConfig": {
    "Mode": "required", 
    "TrustStoreConfig": {
        "TrustStoreId": {TRUST_STORE_ID},
        "AdvertiseTrustStoreCaNames": true,
        "IgnoreCertificateExpiry": true
    }
  },
  "Enabled": true
}
```

使用以下示例命令创建启用了 mTLS 的分配：

```
aws cloudfront create-distribution --distribution-config file://distribution-config.json
```

### 对于现有分配
<a name="enable-mtls-cli-existing"></a>

使用以下示例命令获取当前分配配置：

```
aws cloudfront get-distribution-config --id E1A2B3C4D5E6F7 --output json > dist-config.json
```

编辑文件以添加 mTLS 设置。将以下示例部分配置添加到分配配置：

```
"ViewerMtlsConfig": {
    "Mode": "required", 
    "TrustStoreConfig": {
        "TrustStoreId": {TRUST_STORE_ID},
        "AdvertiseTrustStoreCaNames": true,
        "IgnoreCertificateExpiry": true
    }
}
```

从文件中删除 ETag 字段，但单独保存其值。

使用以下示例命令，以新配置更新分配：

```
aws cloudfront update-distribution \
    --id E1A2B3C4D5E6F7 \
    --if-match YOUR-ETAG-VALUE \
    --distribution-config file://dist-config.json
```

## 查看器协议策略
<a name="viewer-protocol-policies"></a>

在使用双向 TLS 时，必须为所有分配缓存行为配置仅 HTTPS 查看器协议策略：
+ **将 HTTP 重定向到 HTTPS**：在执行证书验证之前将 HTTP 请求重定向到 HTTPS。
+ **仅 HTTPS**：仅接受 HTTPS 请求并执行证书验证。

**注意**  
由于 HTTP 连接无法执行证书验证，因此双向 TLS 不支持 HTTP 和 HTTPS 查看器协议策略。

## 后续步骤
<a name="enable-mtls-next-steps"></a>

在 CloudFront 分配中启用查看器 TLS 后，您可以关联连接函数以实施自定义证书验证逻辑。利用连接函数，您可以通过自定义验证规则、证书吊销检查和日志记录来扩展内置 mTLS 身份验证功能。有关创建和关联连接函数的详细信息，请参阅[关联 CloudFront 连接函数](connection-functions.md)。

# 关联 CloudFront 连接函数
<a name="connection-functions"></a>

利用 CloudFront 连接函数，您可以在 TLS 握手过程中实施自定义证书验证逻辑，从而扩展内置 mTLS 身份验证功能。

## 什么是连接函数？
<a name="what-are-connection-functions"></a>

连接函数是指在客户端证书验证完成后，在 TLS 握手过程中运行的 JavaScript 函数。经过验证的客户端证书将传递给连接函数，此时连接函数可进一步决定是否授予访问权限。有关连接函数的详细信息，请参阅[使用 CloudFront Functions 在边缘进行自定义](cloudfront-functions.md)。

## 连接函数与 mTLS 的协作方式
<a name="how-connection-functions-work"></a>

当客户端尝试与 CloudFront 分配建立 mTLS 连接时，将遵循以下流程：

1. 客户端向 CloudFront 边缘站点发起 TLS 握手请求。

1. CloudFront 请求并接收客户端证书。

1. CloudFront 对信任存储执行标准证书验证。

1. 如果证书通过标准验证，CloudFront 将调用您的连接函数。如果在 **ViewerMtlsConfig** 中启用了 **IgnoreCertificateExpiry**，则虽已到期但其他条件均有效的证书也将传递至连接函数。如果客户端证书无效，则不会调用连接函数。

1. 您的连接函数接收经过解析的证书信息和连接详细信息。

1. 函数根据自定义逻辑做出允许/拒绝决定。

1. CloudFront 根据您的决定完成或终止 TLS 连接。

在验证模式和可选模式（当客户端提供证书时）下，都将调用连接函数。

## 创建连接函数
<a name="create-connection-function"></a>

您可以使用 CloudFront 控制台或 AWS CLI 创建连接函数。

### 创建连接函数（控制台）
<a name="create-connection-function-console"></a>

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 在导航窗格中，选择 **Functions**（函数）。

1. 选择**连接函数**选项卡，然后选择**创建连接函数**。

1. 输入在 AWS 账户中唯一的函数名称。

1. 选择**继续**。

1. 在函数编辑器中，编写用于证书验证的 JavaScript 代码。函数处理程序必须调用 allow 或 deny。

1. 可选：可将 KeyValueStore 与连接函数关联以实施吊销控制。

1. 选择**保存更改**。

### 创建连接函数（AWS CLI）
<a name="create-connection-function-cli"></a>

以下示例演示如何创建连接函数：

在单独的文件（例如 code.js）中编写函数代码：

```
function connectionHandler(connection) {
  connection.allow();
}
```

```
aws cloudfront create-connection-function \
  --name "certificate-validator" \
  --connection-function-config '{
      "Comment": "Client certificate validation function",
      "Runtime": "cloudfront-js-2.0"
  }' \
  --connection-function-code fileb://code.js
```

## 连接函数代码结构
<a name="connection-function-code-structure"></a>

连接函数会实施 connectionHandler 函数，该函数接收一个包含证书和连接信息的连接对象。您的函数必须使用 `connection.allow()` 或 `connection.deny()` 来决定是否允许该连接。

### 基本连接函数示例
<a name="basic-connection-function-example"></a>

以下示例展示了一个简单的连接函数，该函数用于验证客户端证书的主题字段：

```
function connectionHandler(connection) {
    // Only process if a certificate was presented
    if (!connection.clientCertificate) {
        console.log("No certificate presented");
        connection.deny();
    }
    
    // Check the subject field for specific organization
    const subject = connection.clientCertificate.certificates.leaf.subject;
    if (!subject.includes("O=ExampleCorp")) {
        console.log("Certificate not from authorized organization");
       connection.deny();
    } else {
        // All checks passed
        console.log("Certificate validation passed");
        connection.allow();
    }
}
```

此处提供了连接对象上可用的客户端证书属性的完整规范：

```
{
  "connectionId": "Fdb-Eb7L9gVn2cFakz7wWyBJIDAD4-oNO6g8r3vXDV132BtnIVtqDA==", // Unique identifier for this TLS connection
  "clientIp": "203.0.113.42", // IP address of the connecting client (IPv4 or IPv6)
  "clientCertificate": {
    "certificates": {
      "leaf": {
        "subject": "CN=client.example.com,O=Example Corp,C=US", // Distinguished Name (DN) of the certificate holder
        "issuer": "CN=Example Corp Intermediate CA,O=Example Corp,C=US", // Distinguished Name (DN) of the certificate authority that issued this certificate
        "serialNumber": "4a:3f:5c:92:d1:e8:7b:6c", // Unique serial number assigned by the issuing CA (hexadecimal)
        "validity": {
          "notBefore": "2024-01-15T00:00:00Z", // Certificate validity start date (ISO 8601 format)
          "notAfter": "2025-01-14T23:59:59Z"   // Certificate expiration date (ISO 8601 format)
        },
        "sha256Fingerprint": "a1b2c3d4e5f6...abc123def456", // SHA-256 hash of the certificate (64 hex characters)
      },
    },
  },
}
```

## 关联连接函数
<a name="associate-connection-function-section"></a>

创建连接函数后，必须将其发布到 LIVE 阶段并与分配相关联。

### 发布并关联连接函数（控制台）
<a name="publish-associate-console"></a>

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 在导航窗格中，选择**函数**

1. 选择**连接函数**选项卡，然后选择您的连接函数。

1. 选择**发布**以将其移至 LIVE 阶段。

1. 在“发布”部分下，在关联的分配表中选择**添加关联**。

1. 选择要关联的已启用查看器 mTLS 的分配。

或者，您也可以从分配详细信息页面关联已发布的连接函数。

1. 导航到控制台主页，该页面上列出了您的所有分配。

1. 选择要关联的分配。

1. 选择**常规**选项卡。

1. 在**设置**部分中，选择**编辑**。

1. 在**连接性**部分中，找到**查看器双向身份验证(mTLS)**。

1. 对于**连接函数**，选择您的函数。

1. 选择**保存更改**。

### 关联连接函数（AWS CLI）
<a name="associate-connection-function-cli"></a>

以下示例演示如何将连接函数与分配相关联：

```
// DistributionConfig:
{
   ...other settings,
    "ConnectionFunctionAssociation": {
        "Id": "cf_30c2CV2elHwCoInb3LtcaUJkZeD"
    }
}
```

## 连接函数的使用案例
<a name="connection-function-use-cases"></a>

连接函数支持多种高级 mTLS 使用案例：
+ **证书属性验证**：验证客户端证书中的特定字段，例如组织单元要求或主题备用名称模式。
+ **证书吊销检查**：使用 KeyValueStore 存储已吊销证书的序列号，以实施自定义证书吊销检查。
+ **基于 IP 的证书策略**：根据客户端 IP 地址或地理限制应用不同的证书策略。
+ **多租户验证**：实施特定于租户的验证规则，根据主机名或证书属性应用不同的证书要求。

**注意**  
在 TLS 握手过程中，针对每个客户端连接运行一次连接函数。  
连接函数只能允许或拒绝连接，而不能修改 HTTP 请求/响应。  
仅 LIVE 阶段函数（已发布）能够与分配相关联。  
每个分配可拥有最多一个连接函数。

## 后续步骤
<a name="connection-function-next-steps"></a>

将连接函数与 CloudFront 分配关联后，您可以配置可选设置以自定义 mTLS 实施的行为。有关配置其他设置（例如，可选的客户端证书验证模式）的详细说明，请参阅[配置其他设置](configuring-additional-settings.md)。

# 配置其他设置
<a name="configuring-additional-settings"></a>

启用基本双向 TLS 身份验证后，您可以配置其他设置，针对特定使用案例和要求来自定义身份验证行为。

## 客户端证书验证可选模式
<a name="optional-mode"></a>

CloudFront 提供了一种备用的可选客户端证书验证模式，该模式可验证所提供的客户端证书，但会向未提供证书的客户端授予访问权限。

### 可选模式行为
<a name="optional-mode-behavior"></a>
+ 允许拥有有效证书的客户端建立连接（无效证书将被拒绝）。
+ 允许无证书的客户端建立连接。
+ 允许通过单个分配实施的混合客户端身份验证场景。

可选模式非常适合向 mTLS 身份验证逐步迁移，既能支持拥有证书的客户端与无证书的客户端，又能保持与传统客户端的向后兼容性。

**注意**  
在可选模式下，即使客户端未提供证书，连接函数也将被调用。这可让您实施自定义逻辑，例如记录客户端 IP 地址或根据是否提供了证书来应用不同的策略。

### 配置可选模式（控制台）
<a name="configure-optional-mode-console"></a>

1. 在分配设置中，导航至**常规**选项卡，选择**编辑**。

1. 滚动到**连接性**容器中的**查看器双向身份验证(mTLS)** 部分。

1. 对于**客户端证书验证模式**，选择**可选**。

1. 保存更改。

### 配置可选模式（AWS CLI）
<a name="configure-optional-mode-cli"></a>

以下示例演示如何配置可选模式：

```
"ViewerMtlsConfig": {
   "Mode": "optional",
   ...other settings
}
```

## 证书颁发机构公告
<a name="ca-advertisement"></a>

AdvertiseTrustStoreCaNames 字段可控制 CloudFront 是否在 TLS 握手过程中向客户端发送可信 CA 名称列表，从而帮助客户端选择适当的证书。

### 配置 CA 公告（控制台）
<a name="configure-ca-advertisement-console"></a>

1. 在分配设置中，导航至**常规**选项卡，选择**编辑**。

1. 滚动到**连接性**容器中的**查看器双向身份验证(mTLS)** 部分。

1. 选中或取消选中**公布信任存储 CA 名称**复选框。

1. 选择**保存更改**。

### 配置 CA 公告（AWS CLI）
<a name="configure-ca-advertisement-cli"></a>

以下示例演示如何启用 CA 公告：

```
"ViewerMtlsConfig": {
   "Mode": "required", // or "optional"
   "TrustStoreConfig": {
      "AdvertiseTrustStoreCaNames": true,
      ...other settings
   } 
}
```

## 证书到期处理
<a name="certificate-expiration-handling"></a>

IgnoreCertificateExpiry 属性决定 CloudFront 对到期的客户端证书的响应方式。默认情况下，CloudFront 会拒绝到期的客户端证书，但您可将其配置为在必要时接受此类证书。对于证书已到期且无法即刻更新的设备，通常会启用此配置。

### 配置证书到期处理（控制台）
<a name="configure-expiration-console"></a>

1. 在分配设置中，导航至**常规**选项卡，选择**编辑**。

1. 滚动到**连接性**容器的**查看器双向身份验证(mTLS)** 部分。

1. 选中或取消选中**忽略证书到期日期**复选框。

1. 选择**保存更改**。

### 配置证书到期处理（AWS CLI）
<a name="configure-expiration-cli"></a>

以下示例演示如何忽略证书到期情况：

```
"ViewerMtlsConfig": {
  "Mode": "required", // or "optional"
  "TrustStoreConfig": {
     "IgnoreCertificateExpiry": false,
     ...other settings
  }
}
```

**注意**  
**IgnoreCertificateExpiry** 仅适用于证书有效日期。所有其他证书验证检查仍将适用（信任链、签名验证）。

## 后续步骤
<a name="additional-settings-next-steps"></a>

配置其他设置后，您可以设置标头转发以将证书信息传递至源，使用连接函数和 KeyValueStore 实施证书吊销，并启用连接日志以进行监控。有关将证书信息转发至源的详细信息，请参阅[将标头转发到源](viewer-mtls-headers.md)。

# 用于缓存策略并转发到源的查看器 mTLS 标头
<a name="viewer-mtls-headers"></a>

使用双向 TLS 身份验证时，CloudFront 可以从客户端证书中提取信息，并将其作为 HTTP 标头转发到源。这可让原始服务器访问证书详细信息，而无需实施证书验证逻辑。

以下标头可用于创建缓存行为：


| 标头名称 | 说明 | 示例值 | 
| --- | --- | --- | 
| CloudFront-Viewer-Cert-Serial-Number | 证书序列号的十六进制表示形式 | 4a:3f:5c:92:d1:e8:7b:6c | 
| CloudFront-Viewer-Cert-Issuer | 颁发者的可分辨名称（DN）的 RFC2253 字符串表示形式 | CN=rootcamtls.com,OU=rootCA,O=mTLS,L=Seattle,ST=Washington,C=US | 
| CloudFront-Viewer-Cert-Subject | 主题的可分辨名称（DN）的 RFC2253 字符串表示形式 | CN=client\$1.com,OU=client-3,O=mTLS,ST=Washington,C=US | 
| CloudFront-Viewer-Cert-Present | 1（提供）或 0（未提供），用于指示是否提供了证书。在“必需”模式下，此值始终为 1。 | 1 | 
| CloudFront-Viewer-Cert-Sha256 | 客户端证书的 SHA256 哈希 | 01fbf94fef5569753420c349f49adbfd80af5275377816e3ab1fb371b29cb586 | 

对于源请求，除上述可供缓存行为使用的标头外，还会额外提供两个标头：


| 标头名称 | 说明 | 示例值 | 
| --- | --- | --- | 
| CloudFront-Viewer-Cert-Validity | notBefore 和 notAfter 日期的 ISO8601 格式 | CloudFront-Viewer-Cert-Validity：NotBefore=2023-09-21T01:50:17Z;NotAfter=2024-09-20T01:50:17Z | 
| CloudFront-Viewer-Cert-Pem | 叶证书的经 URL 编码的 PEM 格式 | CloudFront-Viewer-Cert-Pem：-----BEGIN%20CERTIFICATE-----%0AMIIG<...reduced...>NmrUlw%0A-----END%20CERTIFICATE-----%0A | 

## 配置标头转发
<a name="configure-header-forwarding"></a>

### 控制台
<a name="configure-headers-console"></a>

在验证模式下，CloudFront 会自动将 CloudFront-Viewer-Cert-\$1 标头添加到所有查看器请求中。要将这些标头转发到源，请执行以下操作：

1. 在主列表分配页面中，选择已启用查看器 mTLS 的分配，然后转至**行为**选项卡

1. 选择缓存行为，然后选择**编辑**

1. 在**源请求策略**部分中，选择**创建策略**或选择现有策略

1. 确保源请求策略包含以下标头：
   + CloudFront-Viewer-Cert-Serial-Number
   + CloudFront-Viewer-Cert-Issuer
   + CloudFront-Viewer-Cert-Subject
   + CloudFront-Viewer-Cert-Present
   + Cloudfront-Viewer-Cert-Sha256
   + CloudFront-Viewer-Cert-Validity
   + CloudFront-Viewer-Cert-Pem

1. 选择**创建**（对于新策略）或**保存更改**（对于现有策略）

1. 在缓存行为中选择策略并保存更改

### 使用 AWS CLI
<a name="configure-headers-cli"></a>

以下示例演示如何创建包含用于验证模式的 mTLS 标头的源请求策略：

```
aws cloudfront create-origin-request-policy \
  --origin-request-policy-config '{
    "Name": "MTLSHeadersPolicy",
    "HeadersConfig": {
      "HeaderBehavior": "whitelist",
      "Headers": {
        "Quantity": 5,
        "Items": [
          "CloudFront-Viewer-Cert-Serial-Number",
          "CloudFront-Viewer-Cert-Issuer",
          "CloudFront-Viewer-Cert-Subject",
          "CloudFront-Viewer-Cert-Validity",
          "CloudFront-Viewer-Cert-Pem"
        ]
      }
    },
    "CookiesConfig": {
      "CookieBehavior": "none"
    },
    "QueryStringsConfig": {
      "QueryStringBehavior": "none"
    }
  }'
```

## 标头处理注意事项
<a name="header-processing-considerations"></a>

使用证书标头时，请考虑以下最佳实践：
+ **标头验证：**作为一项额外的安全措施，在源中验证证书标头值
+ **标头大小限制：**PEM 证书标头可能较大，请确保您的原始服务器能够处理此类标头
+ **缓存注意事项：**在缓存键中使用证书标头会加剧缓存碎片化
+ **跨源请求：**如果您的应用程序使用 CORS，则可能需要将其配置为允许使用证书标头

## 后续步骤
<a name="headers-next-steps"></a>

配置标头转发后，您可以使用 CloudFront 连接函数和 KeyValueStore 实施证书吊销检查。有关实施吊销检查的详细信息，请参阅[使用 CloudFront 连接函数和 KVS 实施吊销](revocation-connection-function-kvs.md)。

# 使用 CloudFront 连接函数和 KVS 实施吊销
<a name="revocation-connection-function-kvs"></a>

您可以将 CloudFront 连接函数与 KeyValueStore 结合使用，来实施双向 TLS 身份验证的证书吊销检查。此方法提供了一种可扩展的实时证书吊销机制，可作为 CloudFront 的内置证书验证的有力补充。

连接函数是指在 TLS 连接建立过程中，在 CloudFront 边缘站点运行的 JavaScript 函数，此类函数可用于为 mTLS 身份验证实施自定义证书验证逻辑。有关连接函数的详细信息，请参阅[关联 CloudFront 连接函数](connection-functions.md)。

## 证书吊销如何与连接函数结合使用
<a name="how-revocation-works"></a>

CloudFront 的标准证书验证功能可验证证书链、签名和到期日期，但不包括内置的证书吊销检查。通过使用连接函数，您可以在 TLS 握手过程中实施自定义吊销检查。

证书吊销流程如下所述：

1. 将已吊销证书的序列号存储在 CloudFront KeyValueStore 中。

1. 当客户端提供证书时，系统将调用您的连接函数。

1. 该函数会根据 KeyValueStore 中的数据核对证书序列号。

1. 如果在存储中找到了序列号，则证书将被吊销。

1. 您的函数拒绝已吊销证书的连接。

此方法可在 CloudFront 的全球边缘网络中提供近乎实时的吊销检查。

## 针对已吊销的证书设置 KeyValueStore
<a name="setup-kvs-revoked-certs"></a>

首先，创建一个 KeyValueStore 来存储已吊销证书的序列号：

### 创建 KeyValueStore（控制台）
<a name="create-kvs-console"></a>

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 在导航窗格中，选择**键值存储**。

1. 选择**创建键值存储**。

1. 输入键值存储的名称（例如，revoked-certificates）。

1. （可选）添加描述。

1. 选择**创建键值存储**。

### 创建 KeyValueStore（AWS CLI）
<a name="create-kvs-cli"></a>

以下示例演示如何创建 KeyValueStore：

```
aws cloudfront create-key-value-store \
  --name "revoked-certificates" \
  --comment "Store for revoked certificate serial numbers"
```

## 导入已吊销证书的序列号
<a name="import-revoked-serials"></a>

创建 KeyValueStore 之后，您需要导入已吊销证书的序列号：

### 准备吊销数据
<a name="prepare-revocation-data"></a>

创建包含已吊销证书序列号的 JSON 文件：

```
{
  "data": [
    {
      "key": "ABC123DEF456",
      "value": ""
    },
    {
      "key": "789XYZ012GHI",
      "value": ""
    }
  ]
}
```

### 从 S3 导入
<a name="import-from-s3"></a>

1. 将 JSON 文件上传到 S3 存储桶

1. 将该文件导入 KeyValueStore：

   ```
   aws cloudfront create-key-value-store \
     --name "revoked-certificates" \
     --import-source '{
       "SourceType": "S3",
       "SourceARN": "arn:aws:s3:::amzn-s3-demo-bucket1/revoked-serials.json"
     }'
   ```

## 创建用于吊销检查的连接函数
<a name="create-revocation-connection-function"></a>

创建连接函数，来根据 KeyValueStore 中的数据核对证书序列号：

### 连接函数代码示例
<a name="revocation-function-example"></a>

以下示例演示连接函数如何执行证书吊销检查：

```
import cf from 'cloudfront';

async function connectionHandler(connection) {
    const kvsHandle = cf.kvs();
    
    // Get client certificate serial number
    const clientSerialNumber = connection.clientCertificate.certificates.leaf.serialNumber;
    
    // Check if the serial number exists in the KeyValueStore
    const isRevoked = await kvsHandle.exists(clientSerialNumber.replaceAll(':', ''));
    
    if (isRevoked) {
        console.log(`Certificate ${clientSerialNumber} is revoked. Denying connection.`);
        connection.logCustomData(`REVOKED:${clientSerialNumber}`);
        connection.deny();
    } else {
        console.log(`Certificate ${clientSerialNumber} is valid. Allowing connection.`);
        connection.allow();
    }
    
}
```

### 创建连接函数（AWS CLI）
<a name="create-revocation-function-cli"></a>

以下示例演示如何创建连接函数与 KeyValueStore 关联：

```
aws cloudfront create-connection-function \
  --name "revocation-checker" \
  --connection-function-config '{
      "Comment": "Certificate revocation checking function",
      "Runtime": "cloudfront-js-2.0",
      "KeyValueStoreAssociations": {
          "Quantity": 1,
          "Items": [
              {
                  "KeyValueStoreARN": "arn:aws:cloudfront::123456789012:key-value-store/revoked-certificates"
              }
          ]
      }
  }' \
  --connection-function-code fileb://revocation-checker.js
```

## 将函数与分配关联
<a name="associate-revocation-function"></a>

创建并发布连接函数后，将其与已启用 mTLS 的 CloudFront 分配相关联，如[关联 CloudFront 连接函数](connection-functions.md)部分中所述。

# 使用连接日志实现可观测性
<a name="connection-logs"></a>

CloudFront 连接日志提供了双向 TLS 身份验证事件的详细信息，让您可监控证书验证、跟踪连接尝试以及解决身份验证问题。

## 什么是连接日志？
<a name="what-are-connection-logs"></a>

连接日志为已启用双向 TLS 的分配捕获有关 TLS 握手和证书验证的详细信息。与记录 HTTP 请求信息的标准访问日志不同，连接日志专注于 TLS 连接建立阶段，包括：
+ 连接状态（成功/失败）
+ 客户端证书详细信息
+ TLS 协议和密码信息
+ 连接计时指标
+ 来自连接函数的自定义数据

通过查看这些日志，您可以全面了解基于证书的身份验证事件，从而更好地监控安全性、解决问题并满足合规性要求。

## 启用连接日志
<a name="enable-connection-logs"></a>

连接日志仅适用于已启用双向 TLS 身份验证的分配。您可以将连接日志发送到多个目标，包括 CloudWatch Logs、Amazon Data Firehose 和 Amazon S3。

### 先决条件
<a name="connection-logs-prerequisites"></a>

在启用连接日志之前：
+ 为 CloudFront 分配配置双向 TLS
+ 为 CloudFront 分配启用连接日志
+ 确保您拥有所选日志记录目标所需的权限
+ 对于跨账户传输，请配置适当的 IAM 策略

### 启用连接日志（控制台）
<a name="enable-connection-logs-console"></a>

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 从分配列表中，选择已启用 mTLS 的分配。

1. 选择**日志记录**选项卡。

1. 选择**添加**。

1. 选择要接收日志的服务：
   + **CloudWatch Logs**
   + **Firehose**
   + **Amazon S3**

1. 对于**目标**，为所选服务选择资源：
   + 对于 CloudWatch Logs，输入**日志组名称**
   + 对于 Firehose，输入 **Firehose 传输流**
   + 对于 Amazon S3，输入**存储桶名称**（可选择附带前缀）

1. （可选）配置其他设置：
   + **字段选择：**选择要包含的特定日志字段。
   + **输出格式：**从 JSON、Plain、w3c、Raw 或 Parquet（仅 S3）中进行选择。
   + **字段分隔符：**指定如何分隔日志字段。

1. 选择**保存更改**

### 启用连接日志（AWS CLI）
<a name="enable-connection-logs-cli"></a>

以下示例演示如何使用 CloudWatch API 启用连接日志：

```
# Step 1: Create a delivery source
aws logs put-delivery-source \
  --name "cf-mtls-connection-logs" \
  --resource-arn "arn:aws:cloudfront::123456789012:distribution/E1A2B3C4D5E6F7" \
  --log-type CONNECTION_LOGS

# Step 2: Create a delivery destination
aws logs put-delivery-destination \
  --name "s3-destination" \
  --delivery-destination-configuration \
  "destinationResourceArn=arn:aws:s3:::amzn-s3-demo-bucket1"

# Step 3: Create the delivery
aws logs create-delivery \
  --delivery-source-name "cf-mtls-connection-logs" \
  --delivery-destination-arn "arn:aws:logs:us-east-1:123456789012:delivery-destination:s3-destination"
```

**注意**  
在使用 CloudWatch API 时，您必须指定美国东部（弗吉尼亚州北部）区域（us-east-1），即使在将日志传输到其他区域时也是如此。

## 连接日志字段
<a name="connection-log-fields"></a>

连接日志包含有关每次 TLS 连接尝试的详细信息：


| 字段 | 说明 | 示例 | 
| --- | --- | --- | 
| eventTimestamp | 连接建立成功或失败时对应的 ISO 8601 时间戳 | 1731620046814 | 
| connectionId | TLS 连接的唯一标识符 | oLHiEKbQSn8lkvJfA3D4gFowK3\$1iZ0g4i5nMUjE1Akod8TuAzn5nzg== | 
| connectionStatus |  mTLS 连接尝试的状态。  | Success 或 Failed | 
| clientIp | 连接客户端的 IP 地址 | 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | 
| clientPort | 客户端使用的端口 | 12137 | 
| serverIp | CloudFront 边缘服务器的 IP 地址 | 99.84.71.136 | 
| distributionId | CloudFront 分配 ID | E2DX1SLDPK0123 | 
| distributionTenantId | CloudFront 分配租户 ID（如果适用） | dt\$12te1Ura9X3R2iCGNjW123 | 
| tlsProtocol | 使用的 TLS 协议版本 | TLSv1.3 | 
| tlsCipher | 用于连接的 TLS 密码套件 | TLS\$1AES\$1128\$1GCM\$1SHA256 | 
| tlsHandshakeDuration | TLS 握手的持续时间（毫秒） | 153 | 
| tlsSni | 来自 TLS 握手的服务器名称指示值 | d111111abcdef8.cloudfront.net | 
| clientLeafCertSerialNumber | 客户端证书的序列号 | 00:b1:43:ed:93:d2:d8:f3:9d | 
| clientLeafCertSubject | 客户端证书的主题字段 | C=US, ST=WA, L=Seattle, O=Amazon.com, OU=CloudFront, CN=client.test.mtls.net | 
| clientLeafCertIssuer | 客户端证书的颁发者字段 | C=US, ST=WA, L=Seattle, O=Amazon.com, OU=CloudFront, CN=test.mtls.net | 
| clientLeafCertValidity | 客户端证书的有效期 | NotBefore=2025-06-05T23:28:21Z;NotAfter=2125-05-12T23:28:21Z | 
| connectionLogCustomData | 通过连接函数添加的自定义数据 | REVOKED:00:b1:43:ed:93:d2:d8:f3:9d | 

## 连接错误代码
<a name="connection-error-codes"></a>

```
Failed:ClientCertMaxChainDepthExceeded
Failed:ClientCertMaxSizeExceeded
Failed:ClientCertUntrusted
Failed:ClientCertNotYetValid
Failed:ClientCertExpired
Failed:ClientCertTypeUnsupported
Failed:ClientCertInvalid
Failed:ClientCertIntentInvalid
Failed:ClientCertRejected
Failed:ClientCertMissing
Failed:TcpError
Failed:TcpTimeout
Failed:ConnectionFunctionError
Failed:ConnectionFunctionDenied
Failed:Internal
Failed:UnmappedConnectionError
```

连接失败时，CloudFront 会记录具体的原因代码：


| 代码 | 说明 | 
| --- | --- | 
| ClientCertMaxChainDepthExceeded | 已超出最大证书链深度 | 
| ClientCertMaxSizeExceeded | 已超出最大证书大小 | 
| ClientCertUntrusted | 证书不可信 | 
| ClientCertNotYetValid | 证书尚未生效 | 
| ClientCertExpired | 证书已过期 | 
| ClientCertTypeUnsupported | 证书类型不受支持 | 
| ClientCertInvalid | 证书无效 | 
| ClientCertIntentInvalid | 证书意图无效 | 
| ClientCertRejected | 证书已被自定义验证拒绝 | 
| ClientCertMissing | 证书缺失 | 
| TcpError |  尝试建立连接时出错  | 
| TcpTimeout |  无法在超时时间内建立连接  | 
| ConnectionFunctionError |  连接函数执行过程中引发了未捕获的异常  | 
| Internal |  出现内部服务错误  | 
| UnmappedConnectionError |  发生了一个无法归入任何其他类别的错误  | 