NAT 뒤의 두 컴퓨터는 어떻게 연결되나 — STUN과 홀펀칭
집이나 사무실 컴퓨터에는 바깥에서 부를 수 있는 주소가 없다. 공유기 뒤에 숨어 있기 때문이다. 그래서 공유기 뒤의 두 컴퓨터는 서로에게 먼저 연결할 수 없다.
이 글은 그 문제를 어떻게 푸는지 정리한다. 순서는 NAT → STUN → 홀펀칭 → 중계 서버다.
공유기는 나간 것만 기억한다
집에 컴퓨터가 여러 대 있어도 바깥에 보이는 주소는 하나뿐이다. 공유기가 주소를 바꿔치기해서 내보낸다.
내 컴퓨터가 보냄: 192.168.0.5 의 40000번 → 구글
공유기가 바꿔서: 1.2.3.4 의 54321번 → 구글
공유기가 적어둠: 54321번으로 오는 답장 = 192.168.0.5 의 40000번
답장이 오면 이 메모를 보고 내 컴퓨터로 넘겨준다.
메모는 나갈 때만 만들어진다. 그래서 바깥에서 갑자기 뭔가 들어오면 공유기는 집 안 누구에게 줘야 할지 모른다. 그냥 버린다.
이것이 “바깥에서 먼저 연결할 수 없다”의 전부다. 메모를 만드는 방법은 내가 먼저 나가는 것 하나뿐이다.
메모를 관리하는 건 공유기 자신이다. 바깥에서는 그 메모에 손댈 수 없다.
내 바깥 주소는 내가 모른다
공유기가 54321번을 골랐다는 걸 내 컴퓨터는 모른다. 공유기가 알려주지 않기 때문이다.
그래서 바깥에 있는 서버에 물어본다. 아무 메시지나 하나 보내면 이렇게 답해준다.
너는 나한테
1.2.3.4의54321번으로 보인다.
이 역할을 하는 서버를 STUN이라고 부른다. 하는 일은 이것뿐이다. 거울 같은 것이다.
주의할 점이 하나 있다. STUN은 물어본 사람에게만 답한다. 상대에게 알려주지 않는다. 알아낸 주소를 상대에게 전달하는 건 다른 일이다.
서로 동시에 두드린다
이제 A와 B가 각자의 바깥 주소를 알았다. 서로 알려주고 연결을 시도한다.
A가 B에게 보낸다.
A쪽 공유기를 나갈 때 → 메모 생김 → A쪽 문 열림
B쪽 공유기에 도착 → 메모 없음 → 버려짐
A가 보낸 것은 B에게 도착하지 못한다. 하지만 A쪽 공유기에 메모가 생겼다.
B가 A에게 보낸다.
B쪽 공유기를 나갈 때 → 메모 생김 → B쪽 문 열림
A쪽 공유기에 도착 → 아까 만든 메모 있음 → 통과
이제 서로 통한다.
첫 번째 메시지는 상대에게 닿으려고 보내는 것이 아니다. 내 쪽 문을 열려고 보내는 것이다. 그래서 양쪽이 다 보내야 한다. 한쪽만 보내면 영원히 안 된다.
이 방식을 홀펀칭(구멍 뚫기)이라고 부른다.
안 되는 경우도 있다
공유기 중에는 보내는 상대가 바뀔 때마다 번호를 새로 고르는 것이 있다.
그러면 STUN에게 물어봤을 때 들은 번호(54321)와, 실제로 상대에게 보낼 때 쓰는 번호가 다르다. 상대에게 알려준 번호가 틀린 번호가 되는 것이다. 이런 공유기 뒤에서는 홀펀칭이 실패한다.
처음 만나는 자리가 필요하다
여기서 문제가 하나 더 있다. A와 B는 서로의 주소를 어떻게 주고받나? 아직 연결이 없는데 주소를 알려줄 방법이 없다.
그래서 양쪽이 다 접속할 수 있는 중계 서버를 하나 둔다. 둘 다 그곳으로 먼저 나간다. 나가는 연결이니까 공유기가 막지 않는다.
- A가 중계 서버에 접속해 기다린다
- B도 접속해서 “A에게 이 주소를 전해달라”고 부탁한다
- 중계 서버가 전달한다
- 둘이 동시에 두드린다 (홀펀칭)
성공하면 이제 직접 통신한다. 실패하면 계속 중계 서버를 거쳐서 통신한다.
뚫고 나서도 중계 서버는 남는다
여기가 흔히 오해하는 부분이다. 직접 연결이 되면 중계 서버가 필요 없어질 것 같지만 그렇지 않다. 세 가지 이유가 있다.
기다리는 쪽은 계속 접속해 있어야 한다. A의 주소를 아무도 모르기 때문에, 누군가 A를 찾으려면 중계 서버를 통할 수밖에 없다. A가 중계 서버와의 연결을 끊으면 아무도 A를 찾을 수 없다.
뚫어놓은 구멍은 저절로 막힌다. 공유기의 메모에는 유효기간이 있다. 보통 30초에서 몇 분 사이다. 조용하면 지워진다. 그래서 양쪽이 주기적으로 아무 메시지나 보내서 메모를 새로 고쳐야 한다.
여기서 방향을 헷갈리기 쉽다. 내 쪽 메모는 내가 보내야 갱신된다. 상대가 보내주는 걸 받는 것으로는 안 된다. 그래서 양쪽이 각자 보낸다.
주소가 바뀌면 다시 알려야 한다. 노트북을 와이파이에서 휴대폰 테더링으로 바꾸면 바깥 주소가 달라진다. 새 주소를 알리는 통로가 또 중계 서버다.
정리
- 공유기는 나가는 연결만 기억한다. 그래서 바깥에서 먼저 들어올 수 없다.
- 내 바깥 주소는 내가 모른다. STUN 서버에 물어봐야 안다.
- 양쪽이 동시에 보내야 뚫린다. 첫 메시지는 내 쪽 문을 여는 용도다.
- 상대가 바뀔 때마다 번호를 바꾸는 공유기 뒤에서는 뚫리지 않는다.
- 뚫려도 중계 서버는 계속 필요하다. 기다리는 쪽의 주소이자, 구멍을 다시 여는 통로이기 때문이다.
중계 서버를 직접 운영한다면 이 마지막 항목이 사양을 정한다. 트래픽이 직접 경로로 빠져도 접속 수는 줄지 않는다. 대역폭이 아니라 동시 접속 수를 기준으로 잡아야 한다.