

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 원격 디바이스 구성 및 IoT 에이전트 사용
<a name="configure-remote-device"></a>

IoT 에이전트는 클라이언트 액세스 토큰을 포함하는 MQTT 메시지를 받고 원격 디바이스에서 로컬 프록시를 시작하는 데 사용됩니다. 보안 터널링에서 MQTT를 사용하여 클라이언트 액세스 토큰을 전달하려면 원격 디바이스에 IoT 에이전트를 설치하고 실행해야 합니다. IoT 에이전트는 다음과 같은 예약된 IoT MQTT 주제를 구독해야 합니다.

**참고**  
예약된 MQTT 주제 구독 이외의 방법을 통해 대상 클라이언트 액세스 토큰을 원격 디바이스에 전달하려는 경우 대상 클라이언트 액세스 토큰(CAT) 리스너와 로컬 프록시가 필요할 수 있습니다. CAT 리스너는 선택한 클라이언트 액세스 토큰 전달 메커니즘과 함께 작동하고 대상 모드에서 로컬 프록시를 시작할 수 있어야 합니다.

## IoT 에이전트 코드 조각
<a name="agent-snippet"></a>

IoT 에이전트는 다음과 같은 예약된 IoT MQTT 주제를 구독해야 MQTT 메시지를 수신하고 로컬 프록시를 시작할 수 있습니다.

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

여기서 `thing-name`는 원격 디바이스와 연결된 AWS IoT 사물의 이름입니다.

다음은 MQTT 메시지 페이로드의 예입니다.

```
{
    "clientAccessToken": "destination-client-access-token",
    "clientMode": "destination",
    "region": "aws-region",
    "services": ["destination-service"]
}
```

IoT 에이전트는 MQTT 메시지를 받은 후 적절한 파라미터를 사용하여 원격 디바이스에서 로컬 프록시를 시작해야 합니다.

다음 Java 코드에서는 Java 라이브러리의 [AWS IoT 디바이스 SDK](https://github.com/aws/aws-iot-device-sdk-java) 및 [ProcessBuilder](https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html)를 사용하여 보안 터널링을 사용하는 간단한 IoT 에이전트를 빌드하는 방법을 보여줍니다.

```
// Find the IoT device endpoint for your AWS 계정
final String endpoint = iotClient.describeEndpoint(new DescribeEndpointRequest().withEndpointType("iot:Data-ATS")).getEndpointAddress();

// Instantiate the IoT Agent with your AWS credentials
final String thingName = "RemoteDeviceA";
final String tunnelNotificationTopic = String.format("$aws/things/%s/tunnels/notify", thingName);
final AWSIotMqttClient mqttClient = new AWSIotMqttClient(endpoint, thingName,
                 "your_aws_access_key", "your_aws_secret_key");

try {
    mqttClient.connect();
    final TunnelNotificationListener listener = new TunnelNotificationListener(tunnelNotificationTopic);
    mqttClient.subscribe(listener, true);
}
finally {
    mqttClient.disconnect();
}

private static class TunnelNotificationListener extends AWSIotTopic {
    public TunnelNotificationListener(String topic) {
        super(topic);
    }

    @Override
    public void onMessage(AWSIotMessage message) {
        try {
            // Deserialize the MQTT message
            final JSONObject json = new JSONObject(message.getStringPayload());
 
            final String accessToken = json.getString("clientAccessToken");
            final String region = json.getString("region");
            
            final String clientMode = json.getString("clientMode");
            if (!clientMode.equals("destination")) {
                throw new RuntimeException("Client mode " + clientMode + " in the MQTT message is not expected");
            }

            final JSONArray servicesArray = json.getJSONArray("services");
            if (servicesArray.length() > 1) {
                throw new RuntimeException("Services in the MQTT message has more than 1 service");
            }
            final String service = servicesArray.get(0).toString();
            if (!service.equals("SSH")) {
                throw new RuntimeException("Service " + service + " is not supported");
            }

            // Start the destination local proxy in a separate process to connect to the SSH Daemon listening port 22
            final ProcessBuilder pb = new ProcessBuilder("localproxy",
                        "-t", accessToken,
                        "-r", region,
                        "-d", "localhost:22");
            pb.start();
        }
        catch (Exception e) {
            log.error("Failed to start the local proxy", e);
        }
    }
}
```