

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 透過輪換用戶端存取字符解決 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 或 [describe-tunnel](https://docs.aws.amazon.com/cli/latest/reference/iotsecuretunneling/describe-tunnel.html) AWS CLI。

裝置可能會因多種原因而中斷連線。要解決連線問題，如果裝置由於以下可能原因而中斷連線，可以在輪換目的地的 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"
}
```