우선 Turn 서버에 알아보기 전에 NAT 개념부터 잡고 가야한다.
cmd
에 ipconfig
를 쳐보면 구글에서 내 ip 찾기
해서 나온 결과와 다르다는 것을 알 수 있다.
ipconfig 로 나온 결과는 사설IP 일명 "사피" 내 ip 찾기 해서 나온 결과는 공인IP 흔히 "공피" 라고 불린다.
그럼 내 ipconfig 로 나온 사피가 어떻게 데이터가 공피를 타고 내 사피까지 들어올 수 있을까?
여기서 바로 NAT
가 사피를 공피로 1대 1 대응시켜 변환해주는 장비가 있기 때문에 가능하다.
추가적으로 IP 주소를 재기록하면서 라우터를 통해 네트워크 트래픽을 주고받는 매커니즘도 갖고있다.
공피는 인터넷에 접글할 때 부여되고 만약 사용하지 않는다면 다른 사람에게 다시 공유되는 방식으로 동작한다.
따라서 수 많은 사람들이 이제는 인터넷을 사용하기 때문에 IPv4 -> IPv6 도 함께 부여된다.
자, 이제 NAT 의 개념을 알았으니 본격적으로 TURN 서버를 알기위해 차근차근 나아가보자.
TURN 서버는 WebRTC 에서 P2P conn 을 해주기위해 존재한다.
그리고 WebRTC 에 대해 알아보자.
Web Real Time Communtcation 의 약자로 실시간 화상통화를 할 수 있도록 도와주는 Google 에서 개발한 JS 를 기반으로 서비스를 제공하는 API 이다.
특징으로는 Latency 가 짧지만 STUN, 혹은 TURN 서버에 연결을 해야한다는 것이다. 왜냐하면 P2P 로 연결해야하기 때문이다.
하지만 여기서 IP 주소(사피->공피)를 바꿔버리는 NAT 이 여기서는 문제를 일으킨다.
즉, NAT 과 WebRTC 를 종합하여 정리하자면 중간에 방화벽이 존재하거나 NAT 환경에 놓여 있는 경우에는 각 Peer에 대한 직접적인 시그널링이 불가능하다.
따라서 시그널링을 하고 연결을 하기 위해서는 무언가 다른 방법이 필요하다.
이러한 방식을 UDP Hole Punching
방식이라고 하는데 중간에 무언가 중개해줘야할 누군가가 필요하다.
이때 필요한게 앞서 말한 STUN, TURN 서버이다.
Session Traversal Uilities for NAT의 약자이다.
아까 위에서 설명했듯이 NAT환경에서는 Private IP를 별도로 가지고 있기 때문에 Peer to Peer(이하 P2P) 통신이 불가능 하다. 따라서 클라이언트는 자신의 Public IP를 확인하기 위해 STUN 서버로 요청을 보내고 서버로 부터 자신의 Public IP를 받는다. 그래서 이때부터 클라이언트는 자신이 받은 Public IP를 이용하여 시그널링을 할때 받은 그 정보를 이용해서 시그널링을 하게 한다.
즉, 해당 Peer 의 Public 주소를 보내느 역할을 하는 것이다.
다만 이 STUN으로 모든걸 해결할 수는 없는데 바로 두 Client가 같은 네트워크에 존재하고 있을때는 이것으로는 해결이 되지 않는다. 또한, NAT 환경에서는 Symmetirc NAT의 경우는 어플리케이션이 달라지면 NAT의 매핑테이블이 바뀔 수 있기 때문이다.
그래서 존재하는 것이 바로 TURN 서버이다.
TURN 서버는 클라이언트들이 통신할 때 Public 망에 존재하는 TURN 서버를 경유하여 통신하게 된다. 즉, NAT 보안 정책이 너무 엄격하거나 NAT 순회를 하기 위해 필요한 NAT 바인딩을 성공적으로 할 수 없는 경우에 TURN 을 사용한다.
클라이언트는 자신의 Private IP가 포함된 TURN 메세지를 턴서버로 보낸다. 그러면 TURN 서버는 메세지에 포함된 Network Layer IP 주소와 Transport Layer의 UDP 포트 넘버와의 차이를 확인하고 클라이언트의 Public IP로 응답하게 된다. 이때 NAT는 NAT 매핑테이블에 기록되어 있는 정보에 따라서 내부 네트워크에 있는 클라이언트의 Private IP 로 메세지를 전송한다.
TURN 서버는 ICE의 일부로 사용될 수 있도록 디자인 되었다. ICE는 무엇일까?
Interactive Connectivity Establishment 의 약자이다.
ICE는 쉽게 말해 두 단말이 통신을 할 수 있도록 최적의 경로를 찾을 수 있도록 도와주는 기술이다.
정확히 말하면 ICE는 Client가 통신 가능한 모든 주소를 식별하는 것을 의미하는데, 원래는 P2P 가 이루어지기 위해서는 방화벽 통과 -> 공피 할당 -> 데이터 릴레이 등의 과정을 거쳐야하는데 이를 모든 포트를 열어두고 두 엔드 포인트 모두 다 연결할 수 있는 IP 주소, 포트에 대한 정보까지 갖게된다. 이를 위해 클라이언트는 STUN 메세지를 TURN 서버로 요청 및 응답과정에서 다음 3가지의 주소를 확인 하게 된다.
Candidate라는 개념이 추가로 존재하는데 이것은 IP와 포트의 조합으로 표시된 주소이며 이제 이 확보된것을 통해서 연결을 해야한다.
3가지 연결을 지원한다.
Connection을 체크한 후 Connection이 완료되면 RTP 및 RTCP 패킷을 전송하여 통화가 가능하게 된다.
RTP란 실시간 전송 프로토콜(Real-time Transport Protocol, RTP)은 IP 네트워크 상에서 오디오와 비디오를 전달하기 위한 통신 프로토콜이다.
TURN서버는 STUN서버의 개념을 포함하고 있는 Super Set이며 STUN서버 처럼 단순히 라우팅 테이블을 통해서 private ip와 public ip를 연결하는데에서 그치지 않는다.
WebRTC를 예로 들면 미디어 데이터를 1:1로 보내준다고 했을때 그 모든 데이터는 TURN 서버를 Relay 서버로 하여 데이터를 원하는 Peer에게 전달해주게 된다.
하지만, 만약 1:N 통신으로 스트리밍하는 서비스라면 중간에 Media 서버를 두어 중계하지 않으면 모든 Peer가 매쉬 구조로 연결되게 되어 각 Peer에 엄청난 부담을 주게 되고 네트워크 자원도 너무 많이 사용하게 된다.
따라서 네트구성과 ICE 연결상태에 따라 되도록이면 STUN 을 사용할 수 있도록 하자.
여기서는 방법에 대한 부분만 설명하고 있습니다.
사실 TURN 서버를 구축하는 가장 편리한 방법은 coturn 이미지를 사용하는 방법이다.
따라서 Window 보단 Linux 환경이 훨씬 편한데 안타깝게도 현장 서버는 window 라서 별의 별 짓을 다 해보았다.
이 wls, docker, vm, eturnal 등을 사용한 방법들에 대해선 차근차근 포스팅하겠다.
chrome://webrtc-internals/
doc-kurento.readthedocs.io/en/stable/glossary.html#term-nat
developer.mozilla.org/ko/docs/Web/API/WebRTC_API/Protocols
brunch.co.kr/@linecard/156
ko.wikipedia.org/wiki/TURN
https://m.blog.naver.com/arumizz/221399298672