개발 일지

TURN Protocol (+ STUN Message)

북극곰은콜라 2024. 3. 18. 19:48
반응형


TURN 이란?

정의

Traversal Using Relays around NAT의 약자이다.
TURN protocol은 STUN 프로토콜의 확장으로 Direct Communication이 불가 한 상황에서, relay를 통해 두 연결을 제공해주는 역할을 가진다.

배경

NAT 뒤의 HOST로 hole punching을 통해 통신이 가능하다. 하지만, 두 host 모두 NAT 뒤에 있으며, 적절한 설정이 없으면 이 또한 불가 하다.
또는 엔터프라이즈 환경에서 UDP 통신 자체가 불가 할 수 도 있다.
이를 해결하기 위해, TURN 서버에서 두 client의 통신을 relay 해주며, 통신이 가능하게 한다.

 


Overview

                                    Peer A
                                    Server-Reflexive    +---------+
                                    Transport Address   |         |
                                    192.0.2.150:32102   |         |
                                        |              /|         |
                      TURN              |            / ^|  Peer A |
   Client's           Server            |           /  ||         |
   Host Transport     Transport         |         //   ||         |
   Address            Address           |       //     |+---------+
198.51.100.2:49721  192.0.2.15:3478     |+-+  //     Peer A
           |            |               ||N| /       Host Transport
           |   +-+      |               ||A|/        Address
           |   | |      |               v|T|     203.0.113.2:49582
           |   | |      |               /+-+
+---------+|   | |      |+---------+   /              +---------+
|         ||   |N|      ||         | //               |         |
| TURN    |v   | |      v| TURN    |/                 |         |
| Client  |----|A|-------| Server  |------------------|  Peer B |
|         |    | |^      |         |^                ^|         |
|         |    |T||      |         ||                ||         |
+---------+    | ||      +---------+|                |+---------+
               | ||                 |                |
               | ||                 |                |
               +-+|                 |                |
                  |                 |                |
                  |                 |                |
         Client's                   |             Peer B
         Server-Reflexive     Relayed             Transport
         Transport Address    Transport Address   Address
         192.0.2.1:7000       192.0.2.15:50000    192.0.2.210:49191
위 그림은 TURN Server를 통한 Client들 간의 communication을 그린 것 이다.
TURN Client는 Peer A 또는 Peer B와 통신이 하고 싶은 상황이다.
TURN Server는 Public 망에 있다.

 


STUN Message

STUN Message는 STUN Protocol에서 사용되는 message이다.
TURN은 STUN Message를 확장한 프로토콜이기에, 기본적으로 STUN Message 구조를 따른다.

STUN Header

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0|     STUN Message Type     |         Message Length        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Magic Cookie                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                     Transaction ID (96 bits)                  |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
STUN Message의 Header는 20 Byte로 구성된다.
STUN Message Type: message의 class 정보이며 request, success response, failuser response, indication 등 있으며, TURN 등 확장 프로토콜에서 추가되기도 한다.
Message Length: Header를 제외한 Message의 size
Transaction ID: STUN은 request ↔︎ response간 transaction을 지원한다. 해당 ID를 올릴 수 있는 부분

STUN Message Type

 0                 1
 2  3  4 5 6 7 8 9 0 1 2 3 4 5
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
Stun의 MessageType은 14bit로 표현된다.
앞 두 bit는 무조건 00이며(prefix, not message Type), Class + Method로 구성되어 있다.
Class는 8, 12 번째 bit이며, 나머지는 Method이다.
Class: 0b00=request, 0b01=indication, 0b10=successResponse, 0b11=errorResponse
EX) 
TURN Protocol Create Permission
Class: request(0b00) or successResponse(0b10) or errorResponse(0b11)
Method: 0x008

request: 0000 0000 0000 1000 = 0x0008
sucessResponse: 0000 0001 0000 1000 = 0x0108
errorResponse: 0000 0001 0001 1000 = 0x0118
Protocol Method Bytes Support Class
STUN (Reserved) 0x000 -
STUN Binding 0x001 -
STUN (Reserved; was SharedSecret) 0x002 -
TURN Allocate 0x003 req / res
TURN Refresh 0x004 req / res
TURN Send 0x006 indication
TURN Data 0x007 indication
TURN CreatePermission 0x008 req / res
TURN ChannelBind 0x009 req / res

STUN Attributes

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Type                  |            Length             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Value (variable)                ....
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Type: Attribute의 구분으로 16bit이다.
Length: value의 length in bytes로 16bit 이다.
value: Attribute의 값
Protocol Type Bytes Desc
STUN MAPPED-ADDRESS 0x0001 reflexive transport address of the client
STUN USERNAME 0x0006 identifies the username and password combination used in the message-integrity
STUN MESSAGE-INTEGRITY 0x0008 contains an HMAC-SHA1 [RFC2104] of the STUN message
STUN ERROR-CODE 0x0009 errorCode: 300 ~ 699 + α
300: Try Alternate
400: Bad Request
401: Unauthorized
420: Unknown Attribute
438: Stale Nonce
500: Server Error
STUN UNKNOWN-ATTRIBUTES 0x000A errorResponse에서만 사용되는 type으로, 서버가 이해하지 못한 attribute를 뜻함
STUN REALM 0x0014 Attribute request에 있는 경우 long-term credential이 사용되고 있음을 나타내며
error response에 있다면 client에게 long-term credential이 필요함을 나타냄
STUN NONCE 0x0015 128 character보다 적은 임의의 값
STUN XOR-MAPPED-ADDRESS 0x0020 MAPPED-ADDRESS와 동일하며, 난독화 됨
STUN SOFTWARE 0x8022 textual description of the software
STUN ALTERNATE-SERVER 0x8023 alternate transport address identifying a different STUN server that the STUN client should try
STUN FINGERPRINT 0x8028 use for identifier
TURN CHANNEL-NUMBER 0x000C channel을 지정하기 위한 값
TURN LIFETIME 0x000D duration of allocation
TURN XOR-PEER-ADDRESS 0x0012 난독화된 상대의 address를 의미
TURN DATA 0x0013 data
TURN XOR-RELAYED-ADDRESS 0x0016 Allocate Response로 전달되는 allocated address
TURN REQUESTED-ADDRESS-FAMILY 0x0017 IPv4: 0x01
IPv6: 0x02
TURN EVEN-PORT 0x0018 relay port even으로 요청
TURN REQUESTED-TRANSPORT 0x0019 protocol을 지정하는 attribute
(https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)
17 (User Datagram Protocol)로 고정
TURN DONT-FRAGMENT 0x001A Allocate시 보내는 attribute peer로 데이터 전달 시 fragment를 하지 말라는 의미
value는 없음
TURN RESERVATION-TOKEN 0x0022 Server에서 예비로 남긴 relay address를 식별하는 토큰
allocation에서 사용될 수 있음
TURN ADDITIONAL-ADDRESS-FAMILY 0x8000 REQUESTED-ADDRESS-FAMILY의 확장, allocate에서 사용될 수 있음
TURN ADDRESS-ERROR-CODE 0x8001 address관련 error code
TURN ICMP 0x8004 UDP Packets이 사라진 이유를 서버에서 알리기 위한 Attribute
STUN (Reserved) 0x0000 -
STUN (Reserved; was RESPONSE-ADDRESS) 0x0002 for legacy protocol
STUN (Reserved; was CHANGE-ADDRESS) 0x0003 for legacy protocol
STUN (Reserved; was SOURCE-ADDRESS) 0x0004 for legacy protocol
STUN (Reserved; was CHANGED-ADDRESS) 0x0005 for legacy protocol
STUN (Reserved; was PASSWORD) 0x0007 for legacy protocol
STUN (Reserved; was REFLECTED-FROM) 0x000B for legacy protocol
TURN Reserved (was BANDWIDTH) 0x0010 for legacy protocol
TURN Reserved (was TIMER-VAL) 0x0021 for legacy protocol

 


Sample TURN Sequence Diagram

Client는 TURN Server로 Allocate를 진행하는 참여자이며 Peer는 TURN 서버에서 메시지 전송이 가능한 참여자이다.
따라서 Peer는 public 망에 있거나, 이전에 Allocate 된 상태로 보면 된다.
allocate를 포함하여 대부분의 메시지에 적용되는 인증은 같은 방식으로 진행한다.
일반적인 Flow는 Allocate → (Permission) → Send data 이며 Send data는 indicate와 channel 방식이 있다.
Client는 Allocate를 통해 자신에게 udp 전송이 가능하도록 할당을 받는다.
이후 peer등 다른 참여자는 allocate된 해당 address로 data를 전송하면 TURN Server에서 allocate 된 정보를 바탕으로 Client에게 메시지를 전송한다.
indicate는 메시지마다 peer에 대한 정보를 같이 보내는 방식
channel은 사전에 channel number와 peer를 mapping하여, channel number로만 data를 전송하는 방식이다.

 


Appendix: UDP Hole Punching

Hole Pubching은 NAT 뒤의 client들의 peer to peer가 가능하도록 하는 방법 중 하나이다.
이는 NAT 뒤의 client끼리 p2p 통신을 시작할 수 없기 때문에 필요하다.
Hole Pubching 를 위해서는 NAT 방식이 EIM(Endpoint-Independent Mapping)일 때 이상적으로 동작한다.

Under EIM-NAT

                                 Server S
                             192.0.2.128:20001
                                     |
        +----------------------------+----------------------------+
        | ^ Registry Session(A-S) ^     ^ Registry Session(B-S) ^ |
        | | 192.0.2.128:20001     |     |  192.0.2.128:20001    | |
        | | 192.0.2.1:62000       |     |  192.0.2.254:31000    | |
        |                                                         |
        | ^ P2P Session (A-B)     ^     ^  P2P Session (B-A)    ^ |
        | | 192.0.2.254:31000     |     |  192.0.2.1:62000      | |
        | | 192.0.2.1:62000       |     |  192.0.2.254:31000    | |
        |                                                         |
      +--------------+                                 +--------------+
      | 192.0.2.1    |                                 | 192.0.2.254  |
      |              |                                 |              |
      | EIM-NAT A    |                                 | EIM-NAT B    |
      +--------------+                                 +--------------+
        |                                                         |
        | ^ Registry Session(A-S) ^     ^ Registry Session(B-S) ^ |
        | |  192.0.2.128:20001    |     |  192.0.2.128:20001    | |
        | |     10.0.0.1:1234     |     |     10.1.1.3:1234     | |
        |                                                         |
        | ^ P2P Session (A-B)     ^     ^  P2P Session (B-A)    ^ |
        | |  192.0.2.254:31000    |     |  192.0.2.1:62000      | |
        | |     10.0.0.1:1234     |     |     10.1.1.3:1234     | |
        |                                                         |
     Client A                                                 Client B
     10.0.0.1:1234                                        10.1.1.3:1234
두 Client가 서로 다른 EIM-NAT 뒤에 있다.
ClientA ↔︎ ClientB는 직접통신은 불가하며, NAT를 거쳐 통신을 하고자 한다.
1. ClientA, B 모두 Server로 Session을 등록하는 과정을 갖는다.
2. EIM-NAT는 Endpoint와 상관없이 각각 192.0.2.1:62000, 192.0.2.254:31000을 ClientA, B와 매핑한다.
3. ClientA, B 모두 Server에게 상대의 NAT public IP를 쿼리한다.
4. ClientA, B 서로 Server를 통해 만든 NAT Table의 포트로 UDP 통신을 한다.

 


REFERENCE

https://datatracker.ietf.org/doc/html/rfc8656

https://datatracker.ietf.org/doc/html/rfc5389

https://datatracker.ietf.org/doc/html/rfc5128#section-3.3

https://www.netmanias.com/ko/post/blog/5833/nat-network-protocol/nat-behavior-requirements-for-unicast-udp-rfc-4787-part-1-mapping-behavior

 

 

 

반응형