

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 通过轮换客户端访问令牌来解决 AWS IoT 安全隧道连接问题
<a name="iot-secure-tunneling-troubleshooting"></a>

使用 AWS IoT 安全隧道时，即使隧道已打开，也可能会遇到连接问题。以下各节显示了一些可能的问题，以及如何通过轮换客户端访问令牌来解决这些问题。要轮换客户端访问令牌 (CAT)，请使用 [RotateTunnelAccessToken](https://docs.aws.amazon.com/iot/latest/apireference/API_iot-secure-tunneling_RotateTunnelAccessToken.html)API 或[rotate-tunnel-access-token](https://docs.aws.amazon.com/cli/latest/reference/iotsecuretunneling/rotate-tunnel-access-token.html) AWS CLI。根据是在源模式还是目标模式下使用客户端时遇到错误，您可以在源模式和/或目标模式下轮换 CAT。

**注意**  
如果您不确定是否需要在源或目标上轮换 CAT，则可以在使用 `RotateTunnelAccessToken` API 时通过将 `ClientMode` 设置为 ALL，这样就能同时在源和目标上轮换 CAT。
轮换 CAT 不会延长隧道持续时间。例如，假设隧道持续时间为 12 小时，隧道已经打开了 4 个小时。轮换访问令牌时，生成的新令牌只能在剩余的 8 小时内使用。

**Topics**
+ [

## 客户端访问令牌错误无效
](#invalid-access-token)
+ [

## 客户端令牌不匹配错误
](#client-token-mismatch)
+ [

## 远程设备连接问题
](#tunnel-open-device-error)

## 客户端访问令牌错误无效
<a name="invalid-access-token"></a>

使用 AWS IoT 安全隧道时，使用相同的客户端访问令牌 (CAT) 重新连接到同一隧道时，可能会遇到连接错误。在这种情况下，本地代理无法连接到安全隧道代理服务器。如果您在源模式下使用客户端，您可能会看到以下错误消息：

```
Invalid access token: The access token was previously used and cannot be used again
```

出现此错误的原因是，本地代理只能使用一次客户端访问令牌（CAT），然后它变为无效。要纠正此错误，请在 `SOURCE` 模式下轮换客户端访问令牌以便为源生成新的 CAT。有关演示如何轮换源 CAT 的示例，请参阅 [轮换源 CAT 示例](#rotate-token-source-example)。

## 客户端令牌不匹配错误
<a name="client-token-mismatch"></a>

**注意**  
不建议通过客户端令牌来重复使用 CAT。我们建议您改用 `RotateTunnelAccessToken` API 来轮换客户端访问令牌，以重新连接到隧道。

如果您使用的是客户端令牌，则可以重复使用 CAT 以重新连接到隧道。要重复使用 CAT，您必须在首次连接到安全隧道时向 CAT 提供客户端令牌。安全隧道存储客户端令牌，因此，对于使用相同令牌的后续连接尝试，还必须提供客户端令牌。有关使用客户端令牌的更多信息，请参阅[中的本地代理参考实现 GitHub](https://github.com/aws-samples/aws-iot-securetunneling-localproxy/blob/master/V2WebSocketProtocolGuide.md)。

使用客户端令牌时，如果在源模式下使用客户端，则可能会看到以下错误：

```
Invalid client token: The provided client token does not match the client token 
				that was previously set.
```

出现此错误的原因是提供的客户端令牌与访问隧道时随 CAT 提供的客户端令牌不匹配。要纠正此错误，请在 `SOURCE` 模式下轮换 CAT 以便为源生成新的 CAT。下面是一个示例：

### 轮换源 CAT 示例
<a name="rotate-token-source-example"></a>

以下示例显示如何在 `SOURCE` 模式下运行 `RotateTunnelAccessToken` API，以便为源码生成新的 CAT：

```
aws iotsecuretunneling rotate-tunnel-access-token \ 
    --region <region> \ 
    --tunnel-id <tunnel-id> \ 
    --client-mode SOURCE
```

运行此命令将生成一个新的源访问令牌并返回隧道的 ARN。

```
{
    "sourceAccessToken": "<source-access-token>", 
    "tunnelArn": "arn:aws:iot:<region>:<account-id>:tunnel/<tunnel-id>"
}
```

您现在可以使用新的源令牌在源模式下连接本地代理。

```
export AWSIOT_TUNNEL_ACCESS_TOKEN=<source-access-token>
./localproxy -r <region> -s <port>
```

下面的内容显示运行本地代理的示例输出。

```
...

[info]    Starting proxy in source mode
...
[info]    Successfully established websocket connection with proxy server ...
[info]    Listening for new connection on port <port>
...
```

## 远程设备连接问题
<a name="tunnel-open-device-error"></a>

使用 AWS IoT 安全隧道时，即使隧道已打开，设备也可能会意外断开连接。要确定设备是否仍连接到隧道，您可以使用 [DescribeTunnel](https://docs.aws.amazon.com/iot/latest/apireference/API_iot-secure-tunneling_DescribeTunnel.html)API 或 desc [ribe](https://docs.aws.amazon.com/cli/latest/reference/iotsecuretunneling/describe-tunnel.html) AWS CLI-tunnel。

设备可能由于多种原因而断开连接。要解决连接问题，如果设备由于以下可能的原因断开连接，则可以在目标上轮换 CAT：
+ 目标上的 CAT 变为无效。
+ 令牌未通过安全隧道保留的 MQTT 主题传送到设备：

  `$aws/things/<thing-name>/tunnels/notify`

下面的示例演示了如何解决此问题：

### 轮换目标 CAT 示例
<a name="rotate-token-dest-example"></a>

考虑远程设备 `<RemoteThing1>`。要为该事物打开隧道，您可以使用以下命令：

```
aws iotsecuretunneling open-tunnel \ 
    --region <region> \ 
    --destination-config thingName=<RemoteThing1>,services=SSH
```

运行此命令将为源和目标生成隧道详细信息和 CAT。

```
{
    "sourceAccessToken": "<source-access-token>", 
    "destinationAccessToken": "<destination-access-token>", 
    "tunnelId": "<tunnel-id>", 
    "tunnelArn": "arn:aws:iot:<region>:<account-id>:tunnel/tunnel-id"
}
```

但是，当您使用 [DescribeTunnel](https://docs.aws.amazon.com/iot/latest/apireference/API_iot-secure-tunneling_DescribeTunnel.html)API 时，输出表明设备已断开连接，如下图所示：

```
aws iotsecuretunneling describe-tunnel \ 
    --tunnel-id <tunnel-id> \ 
    --region <region>
```

运行此命令将显示设备仍未连接。

```
{
    "tunnel": {
        ...
        "destinationConnectionState": {
            "status": "DISCONNECTED"
        },
        ...
    }
}
```

要解决此错误，请在客户端处于 `DESTINATION` 模式下运行 `RotateTunnelAccessToken` API，并为目标运行配置。运行此命令将撤销旧的访问令牌，生成新令牌，并将此令牌重新发送到 MQTT 主题：

`$aws/things/<thing-name>/tunnels/notify`

```
aws iotsecuretunneling rotate-tunnel-access-token \ 
    --tunnel-id <tunnel-id> \ 
    --client-mode DESTINATION \ 
    --destination-config thingName=<RemoteThing1>,services=SSH \ 
    --region <region>
```

运行此命令将生成新的访问令牌，如下所示。然后，如果设备代理设置正确，令牌将传送到设备以连接到隧道。

```
{
    "destinationAccessToken": "destination-access-token", 
    "tunnelArn": "arn:aws:iot:region:account-id:tunnel/tunnel-id"
}
```