

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

# 使用手动设置打开隧道并连接到远程设备
<a name="tunneling-tutorial-manual-setup"></a>

当您打开隧道时，可以选择快速设置方法或手动设置方法来打开通往远程设备的隧道。本教程介绍如何使用手动设置方法打开隧道，以及如何配置和启动本地代理以连接到远程设备。

使用手动设置方法时，必须在创建隧道时手动指定隧道配置。创建隧道后，您可以在浏览器中使用 SSH 或在 AWS IoT 控制台之外打开终端。本教程说明如何使用控制台外部的终端访问远程设备。您还将学习如何配置本地代理，然后连接到本地代理以与远程设备进行交互。要连接到本地代理，必须在创建隧道时下载源访问令牌。

通过此设置方法，可以使用 SSH 以外的服务（例如 FTP）连接到远程设备。有关不同设置方法的信息，请参阅[隧道设置方法](secure-tunneling-tutorial-open-tunnel.md#tunneling-tutorial-setup-methods)。

## 手动设置方法的先决条件
<a name="tunneling-tutorial-manual-prerequisites"></a>
+ 位于远程设备前面的防火墙必须允许端口 443 上的出站流量。您创建的隧道将使用此端口连接到远程设备。
+ 您在远程设备上运行物联网设备代理（参见[IoT 代理代码段](configure-remote-device.md#agent-snippet)），该设备连接到 AWS IoT 设备网关，并配置了 MQTT 主题订阅。有关更多信息，请参阅[将设备连接到 AWS IoT 设备网关](https://docs.aws.amazon.com/iot/latest/developerguide/sdk-tutorials.html)。
+ 您必须在远程设备上运行 SSH 守护进程。
+ 您已经从中下载了本地代理源代码，[GitHub](https://github.com/aws-samples/aws-iot-securetunneling-localproxy)并针对您选择的平台进行了构建。在本教程中，我们将构建的本地代理可执行文件称为 `localproxy`。

## 打开隧道
<a name="open-tunnel"></a>

您可以使用、 AWS IoT API 参考或 AWS 管理控制台，打开安全隧道 AWS CLI。您可以选择配置目标名称，但本教程不要求这样做。如果您配置了目标，安全隧道将使用 MQTT 自动将访问令牌传送到远程设备。有关更多信息，请参阅 [AWS IoT 控制台中的隧道创建方法](secure-tunneling-tutorial-open-tunnel.md#tunneling-tutorial-flows)。

**在控制台中打开隧道**

1. 转至 [AWS IoT 控制台的隧道中心](https://console.aws.amazon.com/iot/home#/tunnelhub)，然后选择**创建隧道**。  
![\[AWS IoT 控制台显示空白的隧道列表，其中包含创建、关闭或删除隧道的选项。\]](http://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/images/tunnels-page.png)

1. 在本教程中，选择 **Manual setup**（手动设置）作为隧道创建方法，然后选择 **Next**（下一步）。有关使用**快速设置功能**方法创建隧道的信息，请参阅 [打开隧道并使用基于浏览器的 SSH 访问远程设备](tunneling-tutorial-quick-setup.md)。
**注意**  
如果您从事物详细信息页面创建安全隧道，则可以选择是创建新隧道还是使用现有隧道。有关更多信息，请参阅 [为远程设备打开隧道并使用基于浏览器的 SSH](tunneling-tutorial-existing-tunnel.md)。  
![\[设置隧道连接的两个选项：快速设置（SSH）或手动设置，后者需要配置本地代理并管理访问令牌。\]](http://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/images/tunnels-choose-manual.PNG)

1. （可选）输入隧道的配置设置。您也可以跳过此步骤，继续下一步以创建隧道。

   请以键-值对的形式输入隧道描述、隧道超时持续时间和资源标记，以帮助您识别资源。对于本教程，您可以跳过目标配置。
**注意**  
不会根据您保持隧道打开的持续时间向您收取费用。只有在创建新隧道时才会产生费用。有关定价的信息，请参阅 [AWS IoT Device Management 定价](https://aws.amazon.com/iot-device-management/pricing/)中的**安全隧道**。

1. 下载客户端访问令牌，然后选择 **Done**（完成）。选择 **Done**（完成）之后，令牌将无法下载。

   这些令牌在连接到隧道时只能使用一次。如果您放错了令牌或隧道断开连接，则可以生成新令牌并将其发送到远程设备以重新连接到隧道。  
![\[用于创建安全隧道连接的源和目标访问令牌，以及有关轮换和重新发送令牌（如果需要）的说明。\]](http://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/images/tunnel-success.png)

**使用 API 打开隧道**  
要打开新隧道，可以使用 [OpenTunnel](https://docs.aws.amazon.com/iot/latest/apireference/API_iot-secure-tunneling_OpenTunnel.html)API 操作。您还可以使用 API 指定其他配置，例如隧道持续时间和目标配置。

```
aws iotsecuretunneling open-tunnel \ 
    --region us-east-1 \ 
    --endpoint https://api.us-east-1.tunneling.iot.amazonaws.com
```

运行此命令将创建新隧道，并为您提供源和目标访问令牌。

```
{
    "tunnelId": "01234567-89ab-0123-4c56-789a01234bcd",
    "tunnelArn": "arn:aws:iot:us-east-1:123456789012:tunnel/01234567-89ab-0123-4c56-789a01234bcd",
    "sourceAccessToken": "<SOURCE_ACCESS_TOKEN>",
    "destinationAccessToken": "<DESTINATION_ACCESS_TOKEN>"
}
```

## 重新发送隧道访问令牌
<a name="resend-access-tokens"></a>

创建隧道时获得的令牌只能用于连接到隧道一次。如果您放错了访问令牌或隧道断开连接，则可以使用 MQTT 向远程设备重新发送新的访问令牌，无需支付额外费用。 AWS IoT 安全隧道将撤消当前令牌并返回新的访问令牌以重新连接到隧道。

**从控制台轮换令牌**

1. 前往[AWS IoT 控制台的 Tunnels 中心](https://console.aws.amazon.com/iot/home#/tunnels)并选择您创建的隧道。

1. 在隧道详细信息页面中，选择 **Generate new access tokens**（生成新访问令牌），然后选择 **Next**（下一步）。

1. 为您的隧道下载新访问令牌，然后选择 **Done**（完成）。这些令牌只能使用一次。如果放错了令牌或隧道断开连接，可以发送新访问令牌。  
![\[源设备和目标设备的访问令牌，以及复制或下载选项。说明轮换令牌会撤消当前令牌并生成新一次性令牌用于重新连接断开的隧道的文本。\]](http://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/images/tunnel-token-rotated.PNG)

**使用 API 轮换访问令牌**  
要轮换隧道访问令牌，您可以使用 [RotateTunnelAccessToken](https://docs.aws.amazon.com/iot/latest/apireference/API_iot-secure-tunneling_RotateTunnelAccessToken.html)API 操作撤消当前令牌并返回新的访问令牌以重新连接到隧道。例如，以下命令可轮换目标设备 *`RemoteThing1`* 的访问令牌。

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

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

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

有关说明如何以及何时轮换访问令牌的示例，请参阅 [通过轮换客户端访问令牌来解决 AWS IoT 安全隧道连接问题](iot-secure-tunneling-troubleshooting.md)。

## 配置和启动本地代理
<a name="start-local-proxy"></a>

要连接到远程设备，请在笔记本电脑上打开终端，然后配置并启动本地代理。本地代理通过安全连接使用安全隧道传输源设备上运行的应用程序发送的数据。 WebSocket 您可以从中下载本地代理源[GitHub](https://github.com/aws-samples/aws-iot-securetunneling-localproxy)。

配置本地代理后，复制源客户端访问令牌，然后在源模式下使用它来启动本地代理。以下显示了启动本地代理的示例命令。在以下命令中，本地代理配置用以侦听端口 5555 上的新连接。在此命令中：
+ `-r`指定 AWS 区域，该区域必须与创建隧道的区域相同。
+ `-s` 指定代理应连接到的端口。
+ `-t` 指定客户端令牌文本。

```
./localproxy -r us-east-1 -s 5555 -t source-client-access-token
```

运行此命令将在源模式下启动本地代理。如果在运行此命令后收到以下错误，请设置 CA 路径。有关信息，请参阅上的[安全隧道本地代理](https://github.com/aws-samples/aws-iot-securetunneling-localproxy)。 GitHub

```
Could not perform SSL handshake with proxy server: certificate verify failed
```

以下显示了在 `source` 模式下运行本地代理的示例输出。

```
...
...

Starting proxy in source mode
Attempting to establish web socket connection with endpoint wss://data.tunneling.iot.us-east-1.amazonaws.com:443
Resolved proxy  server IP: 10.10.0.11
Connected successfully with proxy server
Performing SSL handshake with proxy server	
Successfully completed SSL handshake with proxy server
HTTP/1.1 101 Switching Protocols

...

Connection: upgrade
channel-id: 01234567890abc23-00001234-0005678a-b1234c5de677a001-2bc3d456
upgrade: websocket

...

Web socket session ID: 01234567890abc23-00001234-0005678a-b1234c5de677a001-2bc3d456
Web socket subprotocol selected: aws.iot.securetunneling-2.0
Successfully established websocket connection with proxy server: wss://data.tunneling.iot.us-east-1.amazonaws.com:443
Setting up web socket pings for every 5000 milliseconds
Scheduled next read:

...

Starting web socket read loop continue reading...
Resolved bind IP: 127.0.0.1
Listening for new connection on port 5555
```

## 启动 SSH 会话
<a name="start-ssh-session"></a>

打开另一个终端并使用以下命令通过连接到端口 5555 上的本地代理来启动新的 SSH 会话。

```
ssh username@localhost -p 5555
```

系统可能会提示您输入 SSH 会话的密码。完成 SSH 会话后，键入 **exit** 以关闭会话。

## 清理
<a name="tunnel-cleanup-manual"></a>
+ 

**关闭隧道**  
我们建议您在使用完隧道后将其关闭。如果隧道的打开时间超过指定的隧道持续时间，隧道也可能会关闭。隧道一旦关闭就无法重新打开。您仍然可以通过打开关闭的隧道，然后选择**复制隧道**来复制隧道。指定要使用的隧道持续时间，然后创建新隧道。
  + 要从 AWS IoT 控制台关闭单条隧道或多条隧道，请转到[隧道中心](https://console.aws.amazon.com/iot/home#/tunnels)，选择要关闭的隧道，然后选择**关闭隧道**。
  + 要使用 AWS IoT API 参考 API 关闭单个或多个隧道，请使用 [CloseTunnel](https://docs.aws.amazon.com/iot/latest/apireference/API_iot-secure-tunneling_CloseTunnel.html)API 操作。

    ```
    aws iotsecuretunneling close-tunnel \ 
        --tunnel-id "01234567-89ab-0123-4c56-789a01234bcd"
    ```
+ 

**删除隧道**  
您可以从中永久删除隧道 AWS 账户。
**警告**  
删除是永久性操作，无法撤消。
  + 要从 AWS IoT 控制台删除单条隧道或多条隧道，请转到[隧道中心](https://console.aws.amazon.com/iot/home#/tunnels)，选择要删除的隧道，然后选择**删除隧道**。
  + 要使用 AWS IoT API 参考 API 删除单个或多个隧道，请使用 [CloseTunnel](https://docs.aws.amazon.com/iot/latest/apireference/API_iot-secure-tunneling_CloseTunnel.html)API 操作。使用 API 时，将 `delete` 标志设置为 `true`。

    ```
    aws iotsecuretunneling close-tunnel \ 
        --tunnel-id "01234567-89ab-0123-4c56-789a01234bcd"
        --delete true
    ```