티스토리 뷰
반응형
참고 링크
docs.aws.amazon.com/ko_kr/iot/latest/developerguide/secure-tunneling.html
github.com/aws-samples/aws-iot-securetunneling-localproxy
github.com/aws-samples/iot-secure-tunneling-demo
0. 용어설명
- CAT(Client Access Token)
- 터널 생성시 반환되는 서로 다른 토큰 쌍
- 각 토큰은 출발지 토큰 및 목적지 토큰으로 구분되며, AWS IoT Tunnels에 연결하는데에 사용된다.
- 목적지 애플리케이션
- 터널링 대상이 되는 디바이스에서 실행되는 애플리케이션
- 예를 들어, AWS IoT Tunnels을 SSH 세션 수립 용도로 사용하고자 한다면 대상 애플리케이션은 SSH 데몬일 수 있다.
- 목적지 디바이스
- 터널을 통해 연결하고자 하는 원격지의 디바이스.
- 이하 '목적지'로 표현
- 출발지 디바이스
- 터널을 통해 연결을 시도하고자 하는 작업자의 로컬 PC.
- 이하 '출발지'로 표현
- localproxy
- 출발지 및 목적지가 터널로 연결되기 위해 반드시 실행되어야 하는 애플리케이션
- device-agent(가칭)
- 목적지에서 실행되며 예약된 AWS MQTT 토픽을 구독하는 애플리케이션.
- 구독한 MQTT 토픽을 통해 신규 터널 생성 결과로 반환된 CAT를 수신하여 localproxy를 실행하는 역할.
- 터널
- 출발지와 목적지 간의 양방향 통신을 가능하게 하는 논리적 경로이며, AWS IoT가 관리하는 리소스.
1. AWS IoT Tunnels란?
- 로컬 네트워크에 위치한 호스트로부터 원격 네트워크에 위치한 디바이스 사이에 AWS IoT가 관리하는 안전한 연결을 통해 원격 디바이스에 양방향 통신을 제공하는 서비스.
- AWS IoT 개발자 안내서의 예시 :
예를 들어, 몇 백 마일 떨어진 공장에 위치한 센서 디바이스에서 공장 온도를 측정하는 데 문제가 있는 경우 보안 터널링을 사용하여 이 센서 디바이스에 대한 세션을 열고 신속하게 시작할 수 있습니다.
문제를 확인한 후(예: 잘못된 구성 파일) 파일을 재설정하고 동일한 세션을 통해 센서 디바이스를 다시 시작할 수 있습니다.
보다 일반적인 문제 해결(예: 센서 디바이스 조사를 위해 공장에 기술자 파견)에 비해 보안 터널링은 사고 대응 및 복구 시간 및 운영 비용을 줄여줍니다.
2. AWS IoT Tunnels로 무엇을 할 수 있는가?
- 임의의 포트를 사용하는 로컬 PC의 서비스와 원격 네트워크에 위치한 디바이스의 임의의 포트를 사용하는 서비스를 보안 터널을 통해 연결할 수 있음.
- SSH를 예로 들면, 대상 디바이스 측에 목적지 모드로 실행된 localproxy가 터널로부터 수신받은 모든 data stream을 대상 디바이스의 22번 포트로 포워딩하도록 설정하여 SSH 터널링 효과를 얻을 수 있음.
- 이 과정에서 디바이스가 위치한 원격 네트워크의 방화벽을 업데이트하지 않고 디바이스와 연결할 수 있음.
- 원격 네트워크의 방화벽 규칙이 제공하는 보안 수준을 동일하게 유지할 수 있음.
3. AWS IoT Tunnels는 왜 사용해야하는가?
- 디바이스가 위치한 네트워크가 방화벽의 엄격한 인바운드 규칙에 의해 보호받는 경우, 디바이스에 직접 SSH 연결이 불가능할 수 있음.
- AWS IoT Tunnels를 이용하면 방화벽을 수정하지 않고도 원격에서 간단한 트러블슈팅을 시도할 수 있음.
- AWS 블로그에서의 소개 문구 :
디바이스가 방화벽 뒤에 위치할 때의 장치 관리는 특히 까다로울 수 있다.
일반적인 데스크탑 컴퓨터에서는 원격 관리 애플리케이션이나 VNC와 같은 도구를 설치할 수 있기 때문에 사소한 문제일 수 있지만,
현재까지의 IoT 기기에서는 이러한 기능을 구현하기가 어렵기 때문이다.
4. AWS IoT Tunnels 전제조건
로컬 PC 제약 사항
- SW 최소 조건
- localproxy : localproxy 애플리케이션이 설치되어 있어야 함
- localproxy 빌드 : localproxy를 빌드하기 위한 도구가 설치되어 있어야 함
- Docker
- 또는 CMake
- 서비스 정의 : AWS IoT Tunnels를 통해 터널링할 서비스가 사전 정의되어 있어야 함
- 서비스 설치 : 사전 정의된 서비스가 설치되어 있어야 함
- 예시 : AWS IoT Tunnels를 통해 대상 디바이스에 SSH 터널링을 연결하고자 하는 경우, SSH가 설치되어 있어야 한다.
디바이스 제약 사항
- 디바이스가 위치한 네트워크의 방화벽 아웃바운드 규칙이 최소한 TCP 지원 포트(일반적으로 443)를 제한하지 않도록 구성되어 있어야 함
- SW 최소 조건
- localproxy : localproxy 애플리케이션이 설치되어 있어야 함.
- localproxy 빌드 : localproxy를 빌드하기 위한 도구가 설치되어 있어야 함
- Docker
- 또는 CMake
- device-agent : 예약된 MQTT 토픽을 구독하고, 토픽으로부터 목적지 CAT를 수신하였을 때 localproxy 애플리케이션을 실행하는 device-agent(가칭)이 구현되어 있어야 함
- 예약된 AWS 토픽 : $aws/things/[DEVICE_NAME]/tunnels/notify
- 대상 서비스 정의 : AWS IoT Tunnels이 포워딩할 대상 서비스가 사전 정의되어 있어야 함
- 대상 서비스 설치 : 사전 정의된 대상 서비스가 설치되어 구동되어 있어야 함
- 예시 : AWS IoT Tunnels를 통해 SSH 터널링을 구현하고자 하는 경우, 대상 서비스는 SSH 데몬이 된다.
- HW 최소 조건
- 작성 필요
참고. localproxy란?
- AWS가 제공하는 프록시 애플리케이션
- 소스 및 대상 디바이스에서 실행되어야 하며, 양 종단간 데이터 스트림을 전달하는 역할을 수행
- localproxy는 출발지 모드 또는 대상 모드로 실행이 가능
- 출발지 모드 : 특정 포트로 들어오는 모든 통신을 터널로 전달
- 목적지 모드 : 터널로부터 들어오는 모든 통신을 특정 포트로 전달
- localproxy는 실행 모드 별 CAT와 함께 실행되어 터널 양 종단에 웹소켓으로 연결하기 위한 프록시 엔드포인트인 wss://data.tunneling.iot.ap-northeast-2.amazonaws.com:443 를 사용한다.
- 예시 :
5. AWS IoT Tunnels 동작 원리
i). 동작 원리 요약
- 디바이스에서 실행되는 agent 애플리케이션은 미리 예약된 MQTT 토픽을 구독하도록 설정되어 있어야 함.
- 예약된 토픽 : $aws/things/[DEVICE_NAME]/tunnels/notify
- 터널은 AWS IoT Core로부터 생성됨
- 터널 생성시 사용자는 출발지 / 목적지 액세스 토큰 쌍을 전달받음
- 각 토큰은 터널 양 종단에 대해 접근을 인증하기 위해 사용하며, 유효 기간이 설정되어 일정 시간 이후에는 더 이상 사용할 수 없게 됨.
- 유효 기간은 값 미설정시 디폴트 12시간이며, 1분에서 12시간(= 720분)까지 설정이 가능.
- 사용자는 출발지 액세스 토큰을 이용하여 localproxy 애플리케이션을 출발지 모드로 실행해야 함
- 터널 생성시 예약된 MQTT 토픽에 목적지 액세스 토큰이 전달됨
- 디바이스는 목적지 agent 애플리케이션이 액세스 토큰을 수신하면 localproxy 애플리케이션을 대상 모드로 실행
- 이를 통해 양 종단이 연결됨
ii). localproxy <-> tunnel <-> localproxy 통신 원리
- 터널 양 종단의 localproxy와 터널간의 연결은 웹소켓을 사용한다.
- AWS IoT Tunnels는 코어가 관리하는 터널을 통한 연결이 수립될 뿐, 연결 자체에 MQTT 토픽을 사용하지는 않는다.
- 연결에 사용되는 웹소켓 엔드포인트는 AWS 리전 별로 사전 정의되어 있으며, 엔드포인트 리전과 OpenTunnel API에 사용한 리전은 같아야 한다.
- 웹소켓 엔드포인트 : wss://data.tunneling.iot.ap-northeast-2.amazonaws.com:443
- 웹소켓으로 연결된 터널과 localproxy는 ProtocolBuffer 메시지를 통해 제어 메시지(Control Message) 또는 Data를 직렬화한 바이너리 스트림 형태로 주고받는다.
- Step 1. 터널 연결 수립 및 validation
- localproxy는 터널과 연결하기 위해 웹소켓 handshake를 시도하고, 터널은 해당 웹소켓 요청의 CAT를 검증하여 요청을 수락할지 결정한다.
- 터널은 웹소켓 handshake에 포함된 CAT의 인증과 validation을 마친 후에 해당 요청을 허용하고, 이 시점에서 논리적 경로인 AWS IoT Tunnels가 수립된다.
- Step 2. Stream 시작 및 데이터 스트림 수행
- 터널 연결이 수립된 후, 출발지 localproxy는 실행시 설정되었던 포트로 수신되는 연결을 대기한다.(-s 5555 옵션으로 실행되었다면, 포트 5555를 listen한다.)
- 출발지 localproxy에서, 대기 중인 포트에 서비스(SSH 등)가 연결될 경우, 출발지 localproxy와 해당 서비스는 TCP 연결을 수립한다.
- 출발지 localproxy는 서비스의 TCP 연결을 수락했을 때 StreamStart 제어 메시지와 출발지 localproxy의 서비스 ID를 함께 터널로 송신한다.
- 목적지 localproxy는 ProtocolBuffer 제어 메시지에 포함된 StreamStart Flag를 수신할 때까지 대기한다.
- 목적지 localproxy가 StreamStart가 포함된 메시지를 수신하면, 목적지 localproxy는 서비스 ID에 명시된 목적지 서비스(SSH 데몬 등)에 TCP 연결을 요청한다.
- 목적지 localproxy와 서비스(SSH 데몬 등)의 TCP 연결이 수립된 시점에서 Tunnel 양 종단은 연결된 서비스로부터의 incoming message를 송 / 수신할 수 있게 된다.
- Data Stream은 터널이 명시적으로 닫히거나, localproxy에서의 TCP close 또는 TCP 소켓 I/O 에러 등 에러 상황이 발생한 경우 'StreamReset' 제어 메시지를 서비스 ID와 함께 터널로 전송하였을 때 종료된다.
- Step 1. 터널 연결 수립 및 validation
iii). localproxy <-> App. 통신 원리
- 출발지 모드
- 출발지 모드의 localproxy는 TCP 연결을 수립하는 client처럼 동작한다.
- 출발지 모드로 localproxy가 실행되고 나면, 우선 AWS IoT Secure Tunnel과 연결되고 localproxy는 실행시에 명시된 포트(위의 경우, 5555)로부터 listening을 시작한다.
- 이후 연결에 사용할 서비스가 해당 port로 TCP 연결을 요청하도록 한다.
- 예시 : ssh -p 5555 ubuntu@localhost
- localproxy와 연결에 사용될 서비스가 TCP 연결이 수립되고나면, localproxy는 연결 요청을 포함한 이후의 데이터를 로컬에 수립된 TCP 연결로부터 터널로 전송한다.
- 목적지 모드
- 목적지 모드의 localproxy는 TCP 연결을 수신하는 server처럼 동작한다.
- 목적지 모드로 localproxy가 실행되고 나면, 우선 AWS IoT Secure Tunnel과 연결되고 localproxy는 터널을 통해 들어오는 연결 요청에 대비하여 listening을 시작한다.
- 요청을 수신한 경우, localproxy는 사전에 설정된 목적지와 포트에 TCP 연결을 시도한다.
- 연결이 성공되면 로컬에 수립된 TCP 연결 과 터널 사이에서 data 전송을 시작한다.
iv). device-agent(가칭)의 역할
- 디바이스에서 항상 실행되고 있어야 한다.
- 예약된 AWS MQTT 토픽인 $aws/things/[DEVICE_NAME]/tunnels/notify를 구독하고 있어야 한다.
- 해당 MQTT 토픽을 통해 CAT가 수신되었을 경우, localproxy를 목적지 모드로 실행할 수 있어야 한다.
참고. 예약된 토픽으로부터 수신 Payload 예시
- 디바이스 상에서 동작하는 agent App.은 터널 생성시 목적지 CAT를 $aws/things/[DEVICE_NAME]/tunnels/notify로부터 다음의 형식으로 전달받는다.
{
"clientAccessToken": "목적지 CAT",
"clientMode": "destination",
"region": "ap-northeast-2",
"services": ["SSH1"]
}
6. AWS IoT Tunnels IAM
- 터널 열기 / 터널 닫기 / 터널 상세 보기 / 터널 목록 보기를 수행하기 위해서는 작업자의 IAM 역할에 최소한 다음의 정책이 포함되어 있어야만 한다.
- 터널 자체의 양 종단점을 이용하기 위한 별도의 IAM 정책은 없으며, 이 경우 작업자와 디바이스 각각이 사용할 CAT만이 필요함.
{
"Effect": "Allow",
"Action": [
"iot:OpenTunnel",
"iot:CloseTunnel",
"iot:DescribeTunnel",
"iot:ListTunnels"
],
"Resource": [
"arn:aws:iot:aws-region:aws-account-id:tunnel/*"
]
}
7. AWS IoT Tunnels 과금정책 및 제약사항
i). 과금정책
- 열린 터널 1개 기준 6$ 과금(ap-northeast-2 리전 기준)
- 열린 터널을 통해 여러 클라이언트로부터 단일 디바이스에 연결하는 경우, 추가 요금은 부과되지 않음
- 연결이 끊긴 후 이미 열려 있는 터널에 재연결하는 데에는 요금이 부과되지 않음
ii). 제약사항
- 터널당 최대 대역폭 : 800kbps
- 터널당 최대 서비스 : 3
- 최대 연결 속도 : 10TPS
- 최대 터널 수명 : 12시간
- API 별 TPS : 하단 테이블 참조
CloseTunnel | 1 |
DescribeTunnel | 10 |
ListTagsForResource | 10 |
ListTunnels | 10 |
OpenTunnel | 1 |
TagResource | 10 |
UntagResource | 10 |
8. AWS IoT Tunnels의 한계
- 기기마다 localproxy App.이 포함되어 있어야만 한다.
- 기기마다 터널 수립 용도로 사용되는 목적지 CAT을 수신하기 위해 예약된 AWS MQTT 토픽을 구독하고, 토큰을 수신했을 경우 localproxy App.을 실행하는 역할을 수행할 agent App.이 포함되어 있어야만 한다.
- 터널 생성시 대상 기기로 설정할 수 있는 것은 터널 당 1대이므로, 트러블 슈팅 기기가 많아질수록 터널 요금도 크게 증가할 수 있다.(기기 개수 X 6$)
- 열린 터널의 목적지 토큰을 여러 대상 기기의 localproxy(목적지 모드)가 공유할 경우, 가장 최근에 실행된 localproxy만 정상 동작함.
9. Furthermore
- Greengrass에서 활용 가능한가?
- 기본적으로 AWS IoT Core와 연결된 코어 디바이스만 AWS IoT Secure Tunneling이 가능
- Greengrass Group에 연결된 디바이스들은 Greengrass 코어 기기를 통해 보안 터널을 수립할 수 있는지 레퍼런스를 찾지 못함
- Job으로 완전히 대체될 수 있지는 않은가?
- 재부팅, 설정 수정 등 AWS IoT Tunnels를 통해 진행하는 간단한 일회성 작업은 은 Job으로 완전히 대체될 수 있을 것으로 보임
- 그러나 AWS IoT Tunnels이 제공하는 안전한 양방향 통신은 Job으로 대체할 수 없음
- AWS IoT Tunnels가 요구하는 agent 애플리케이션(토큰을 수신하여 localproxy를 실행) 역할을 Job이 대체할 수 있을 것으로 보임
'Cloud. > aws' 카테고리의 다른 글
[Chime] Eventbridge로 chime event 수신이 안된다면 (0) | 2021.10.06 |
---|---|
[AWS] 인터넷 게이트웨이 (0) | 2021.04.12 |
[AWS IoT] macOS에서 aws iot tunnel localproxy 빌드하기 (0) | 2021.02.19 |
[AWS] AMI 리눅스 배포판별 기본 사용자 (0) | 2020.11.25 |
[AWS] aws configure (0) | 2020.11.25 |
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- JPA
- AWS IoT
- eureka
- spring boot
- pgloader
- dev
- kotlin
- Linux
- Puppeteer
- Git
- IntelliJ
- jQuery
- react
- Database
- 코딩테스트
- hashicorp
- shell
- Docker
- JEST
- Gradle
- Java
- Spring Cloud Config
- javascript
- etc
- postgresql
- AWS
- terraform
- Vault
- mysql
- Node.js
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함