[외워서 끝내는 네트워크 핵심이론 - 응용] NAT 기반의 인터넷 공유기, 포트포워딩
들어가기 앞서
해당 글은 널널한 개발자님의 인프런 강의 '외워서 끝내는 네트워크 핵심이론 - 응용'의 section 1을 보고 공부한 내용을 정리한 글입니다.
인터넷 공유기
인터넷 공유기 또는 간단히 공유기(共有器)는 가정이나 소기업 등에서 사용하는 소용량의 라우터를 가리키는 말이다. 기술적으로는 홈 라우터(Home Router)라고 한다. 오늘날의 인터넷 공유기는 무선 통신 시대에 걸맞게 Wi-Fi 칩셋과 안테나를 갖추고 무선 단말(access point) 기능을 지원하는 경우가 대부분이며, 스마트폰이 대중화되면서 가정마다 하나씩은 설치하는 필수적인 네트워크 장비가 되었다.
- 인터넷 공유기, 나무위키
오늘날의 인터넷 공유기는 일반적으로 NAT(Network Address Translation) 기술이 적용된 장치로, NAT 기술이란 공인 IP를 사설 IP로 변환해 하나의 공유기에 연결된 다수의 호스트가 하나의 공인 IP를 공유하는 기술을 일컫는다. IPv4 체계에서는 스마트폰, 테블릿 등의 사용에 따른 인터넷 사용량의 급증으로 호스트에게 제공할 공인 IP의 갯수가 턱없이 모자라는 경우가 왕왕 있는데, NAT 기술이 적용된 공유기 덕분에 우리는 공인 IP를 각각의 호스트에게 남발하는 낭비 없이 공인 IP의 발행수를 현격히 줄일 수 있다.
NAT 기술이 적용된 인터넷 공유기는 사설 IP를 제어하는 방식에 따라 Symmetric NAT와 Core NAT로 나눌 수 있는데 일반적으로 Symmetric NAT는 Core NAT 방식에 비해 보안성이 강하다는 특징을 갖는다.
공유기는 L3 라우터에 해당하므로 로컬 네트워크와 광역 네트워크를 연결하는 게이트웨이 역할을 한다. 따라서 공유기를 기준으로 인터넷을 향해 열려 있는 외부망과 공유기에 의해 사설 IP로 관리되는 내부망이 구별되는 것이다. 이러한 상황에서 공유기는 인터넷으로 열려 있는 외부망에 대해서는 공인 IP를, 자신이 관리하는 내부망에서는 사설 IP를 사용한다.
위의 그림으로 예를 들어보면, 인터넷 상에서 그림상에 특정되어진 공유기의 공인 IP는 3.3.3.3이다. 만약 특정 호스트가 해당 공유기 내부에 있는 호스트와 통신하고 싶다면 패킷 전송 시 도착 IP를 3.3.3.3으로 두면 된다.
그러나 위와 같은 방식으로는 원하는 호스트에 원하는 패킷을 전송할 수 없다. 그 이유는 사실 3.3.3.3의 IP를 사용하는 호스트는 공유기 내부의 호스트가 아닌 공유기 자신이기 때문인데 공유기는 단순히 공유기일 뿐 실제 패킷의 전송자가 원하는 호스트는 사설 네트워크 안쪽에 사설 IP를 사용하며 존재하고 있기 때문이다. 따라서 공유기는 자신에게 들어온 패킷을 전송자가 원하는 실제 호스트에게 보내줄 수 있는 기전을 필요로 하는데, 이러한 기전을 어떻게 설계하는가에 따라 NAT 방식이 Symmetric NAT가 될 수도, Core NAT가 될 수도 있다. 참고로 NAT 방식의 공유기는 내부망과 외부망에서 패킷이 들어오면 사설 IP를 공인 IP로 변조하고, 공인 IP를 사설 IP로 변조하는 방식으로 동작한다.
Symmetric NAT 방식의 공유기
Symmetric NAT 방식의 공유기는 Core NAT 방식의 공유기보다 보안성이 뛰어난 방식의 NAT로 모든 TCP 세션의 패킷을 변조하는 방식으로 동작한다. 말이 매우 추상적이고 어렵기 때문에 우선 Symmetric NAT가 동작하는 과정을 클라이언트 호스트와 서버 호스트가 한차례 HTTP 통신하는 방식으로 단계별로 살펴보도록 하자.
자, 여기 192.168.0.10을 사설 IP로 사용하는 클라이언트 호스트가 있다. 이 클라이언트 호스트는 공인 IP로 3.3.3.3을 사용하는 Symmetric NAT 방식의 공유기를 인터넷 게이트웨이로 사용하고 있다. 그림에는 표현하지 않았지만 우리의 클라이언트 호스트는 15.15.15.15:80의 IP와 포트번호를 사용하는 웹 서버를 이용하고자 한다. 이제 이러한 정보를 바탕으로 클라이언트 호스트와 서버 호스트가 어떻게 통신을 주고 받는지 살펴보자.
식별자 | IP | 포트번호 |
클라이언트 호스트 | 사설 IP 192.168.0.10 | 3000 (운영체제가 자동으로 부여) |
Symmetric NAT 공유기 | 공인 IP 3.3.3.3 | |
서버 호스트 | 공인 IP 15.15.15.15 | 80 (웹서버) |
- 클라이언트 호스트가 패킷을 생성하며 출발지 IP/포트번호와 도착지 IP/포트번호를 패킷에 적어 해당 패킷을 공유기로 전송한다.
- 패킷 (클라이언트 호스트 -> 서버 호스트)
- 출발지 IP/포트번호 : 192.168.0.10:3000
- 도착지 IP/포트번호 : 15.15.15.15:80
- Symmetric NAT 공유기에 도착한 패킷이 공유기에 의해 변조된다. 변조의 대상은 출발지 IP와 포트번호이며 해당 정보를 각각 공인 IP와 자신이 식별할 수 있는 랜덤한 외부 포트번호로 교체한다.
- 패킷 (클라이언트 호스트 -> 서버 호스트)
- 출발지 IP/포트번호 :
192.168.0.10:3000-> 3.3.3.3:23000 - 도착지 IP/포트번호 : 15.15.15.15:80
- 공유기는 해당 패킷을 인터넷으로 흘려 보내며(Out-bound), 메모리 상에 위치한 NAT 테이블에 자신이 조작한 정보와 도착지 정보를 기입한다. 해당 데이터는 이후 서버로부터 응답 패킷이 왔을 때, 해당 패킷을 클라이언트 호스트에게 정확히 전달하기 위해 사용된다.
Local IP | Local Port | External Port | Remote IP | Remote Port | Protocol |
192.168.0.10 | 3000 | 23000 | 15.15.15.15 | 80 | TCP |
- 인터넷 상으로 흘러 들어간 패킷은 라우터들을 이동하며 목표한 15.15.15.15:80의 서버 호스트에 도착하고, 서버 호스트는 요청에 대한 응답 패킷을 전송한다.
- 패킷 (서버 호스트 -> 클라이언트 호스트)
- 출발지 IP/포트번호 : 15.15.15.15:80
- 도착지 IP/포트번호 : 3.3.3.3:23000
- 서버 호스트의 응답 패킷이 NAT 공유기에 도착한다. NAT 공유기는 자신이 작성한 NAT 테이블을 조회해 패킷의 도착지 IP/포트번호를 공인 IP 체계에서 사설 IP 체계로 변조한다. 이 때, 조회의 식별자로 사용되는 정보는 응답 패킷의 출발지 IP와 포트번호, 그리고 도착지의 외부 포트번호이다.
- 패킷 (서버 호스트 -> 클라이언트 호스트)
- 출발지 IP/포트번호 : 15.15.15.15:80
- 도착지 IP/포트번호 :
3.3.3.3:23000-> 192.168.0.10:3000
- NAT 공유기는 변조된 패킷을 사설 네트워크 상으로 흘려보낸다. (In-bound)
위의 일련 과정을 통해 Symmetric NAT 기반의 공유기를 사이에 둔 클라이언트와 서버 호스트간의 통신이 1회 완료된다.
유의해야 할 부분은 Symmetric NAT 기반의 공유기는 이러한 과정을 매번, 통신이 이루어지는 모든 세션마다 진행한다는 부분이다. 이 부분이 Cone NAT와 Symmetric NAT의 가장 두드러지는 차이점인데, Symmetric NAT는 모든 통신마다 패킷을 조작하는 행위를 수행하기 때문에 보안상 Cone NAT보다 안전하다는 특징을 갖는다. 이 부분은 Symmetric NAT이 모든 세션마다 패킷을 변조하며, 변조 시에 외부 포트 번호를 랜덤하게 변경하기 때문인데 서버 호스트가 클라이언트 호스트에게 직접 접근하려고 하는 아래의 경우를 살펴보며 해당 부분을 조금 더 자세하게 이해해보도록 하자.
- 서버 호스트가 무슨 이유에서인지 클라이언트 호스트를 호출하고 싶다. 그래서 아래와 같이 출발지, 도착지 IP/포트번호를 적어 패킷을 인터넷 상으로 흘려보낸다.
- 패킷 (서버 호스트 -> 클라이언트 호스트)
- 출발지 IP/포트번호 : 15.15.15.15:80
- 도착지 IP/포트번호 : 3.3.3.3:34
- 서버 호스트의 패킷이 클라이언트 호스트의 공유기로 흘러 들어온다. Symmetric NAT 기반의 공유기는 해당 패킷을 내부망의 호스트에게 인바운드 시키기 위해 자신의 NAT 테이블을 들여다 본다.
Local IP | Local Port | External Port | Remote IP | Remote Port | Protocol |
192.168.0.10 | 3000 | 23000 | 15.15.15.15 | 80 | TCP |
- 그런데 어라, NAT 테이블에 매핑되는 데이터가 존재하지 않는다. 당연하다. Symmetric NAT는 모든 세션에 대해 외부 포트번호를 생성하는데, 외부 포트번호가 생성되는 유일한 구간은 내부망의 패킷이 외부망으로 빠져나가는 아웃바운드 때일 뿐이기 때문이다. 지금의 경우는 서버 호스트가 먼저 클라이언트 호스트에 접근하는 경우이다. 34라는 도착지 외부 포트번호는 존재하지 않는다. 따라서 Symmetric NAT 기반의 공유기는 해당 패킷을 인바운드 시킬 수 없다.
- 서버의 패킷이 인바운드 되지 못하고 소멸된다.
Symmetric NAT 기반의 공유기는 이러한 이유 때문에 좋던 싫던 요청되지 않은 트래픽이 내부망으로 들어오는 모든 행위를 차단시킨다. 따라서 Symmetric NAT 기반의 공유기는 방화벽으로 쓰이기도 하는데, 이는 1. Symmetric NAT가 모든 TCP 세션에 대해 패킷 변조를 수행하기 때문, 2. NAT 테이블에 변조된 데이터 정보는 아웃바운드 때에만 기입되기 때문이다.
Symmetric NAT는 이러한 관점에서 보안적으로 뛰어나지만 요청되지 않은 트래픽이 내부망으로 들어올 수 없기 때문에 p2p 통신(서버를 중간에 거치지 않고 피어peer와 피어간에 이루어지는 통신) 등이 불가능하다. 이러한 제약을 해소하기 위해 사용되는 NAT가 Symmetric NAT와 대조되는 Cone NAT이다.
Cone NAT
위의 Symmetric NAT를 제대로 이해했다면 NAT가 동작하는 과정에 대해서는 어느정도 파악이 가능할 것이다. Cone NAT도 Symmetric NAT와 마찬가지로 패킷을 조작하는 방식은 유사하나, 모든 TCP 세션을 대상으로 패킷을 변조하는 Symmetric NAT와는 달리 Cone NAT는 호스트를 단위로 패킷을 변조하며, 호스트에 따라 고정된 외부 포트번호를 지정한다. Symmetric NAT는 TCP 세션마다 패킷이 변조되고 외부 포트번호는 랜덤 지정, Cone NAT는 호스트를 단위로 패킷을 변조하며 외부 포트번호는 호스트마다 고정된다는 점이 가장 큰 차이점이다. 기억해두도록 하자.
Symmetric NAT는 TCP 세션마다 패킷이 변조되고 외부 포트번호는 랜덤 지정, Cone NAT는 호스트를 단위로 패킷을 변조하며 외부 포트번호는 호스트마다 고정된다는 점이 가장 큰 차이점이다. 기억해두도록 하자.
Cone NAT는 조금 더 세부화해서 Full Cone NAT, Restricted Cone NAT, Port Restricted NAT로 구분할 수 있는데 Full Cone NAT만 제대로 이해하면 나머지 두개는 이해하기에 크게 어렵지 않다. Full Cone NAT의 NAT 테이블을 한번 살펴보자.
Full Cone NAT의 NAT 테이블
Local IP | Local Port | External Port | Remote IP | Remote Port | Protocol |
192.168.0.10 | 3000 | 8080 (고정) | Any | Any | TCP |
Full Cone NAT는 외부망에서 들어오는 패킷의 IP와 포트번호를 조회하지 않는다. 조금 더 이해하기 좋은 표현으로 이야기하자면, '상관하지 않는다'. 어떤 IP/포트번호가 들어오던 상관없다는 의미이다.
유의해야 할 부분은 External Port, 외부 포트번호가 고정되어 있다는 것이다. 내부 사설 IP를 192.168.0.10으로 사용하고 포트번호를 3000으로 사용하는 호스트는 모두 8080의 외부 포트번호를 사용하게 된다.
자 그러면, 만약 요청하지 않은 외부 패킷이 트래픽으로 들어오는 경우, Full Cone NAT에서는 어떻게 동작하게 될까? 아래와 같은 정보로 외부 패킷이 들어왔다고 가정해보자.
- 패킷 (알 수 없는 외부망의 피어 -> 내부망의 피어)
- 출발지 IP/포트번호 : 15.15.15.15:80
- 도착지 IP/포트번호 : 3.3.3.3:8080
Full Cone NAT는 해당 패킷을 조회하기 위해 외부 포트번호라는 하나의 식별자를 사용한다. 8080이라는 포트번호에 해당하는 데이터가 NAT 테이블에 있는가? 있다. Full Cone NAT는 해당 패킷을 내부망에서 사설 IP로 192.168.0.10 포트번호로 3000을 사용하는 호스트(피어)로 해당 패킷을 전송한다. 통신이 성공적으로 이루어지는 것이다.
Full Cone NAT는 Symmetric NAT에 비해 매우 유연하다. 만약 외부에서 공유기의 공인 IP와 포트번호만을 알고 있다면, 누구든 내부망에 접근할 수 있기 때문이다. 따라서 p2p 통신이 원활하게 진행될 수 있다. 하지만 보안성은 상당 부분 희생해야 한다.
Restricted Cone NAT와 Port Restricted Cone NAT는 이러한 Full Cone NAT의 낮은 보안성을 보완하기 위해 존재한다. Full Cone NAT가 외부망의 IP와 포트번호를 조회하지 않는다는 특징을 가지고 있었다면, Restricted Cone NAT는 IP를 확인한다는 점, Port Restricted Cone NAT는 IP와 포트번호를 모두 확인한다는 점에서 차이점이 있다. 아래의 NAT 테이블을 살펴보며 각각을 이해해보자. 앞서 주지한 바와 같이, Full Cone NAT를 제대로 이해했다면, 나머지 둘은 이해하기 크게 어렵지 않을 것이다.
Restricted Cone NAT의 NAT 테이블
Local IP | Local Port | External Port | Remote IP | Remote Port | Protocol |
192.168.0.10 | 3000 | 8080 (고정) | 15.15.15.15 | Any | TCP |
Port Restricted Cone NAT의 NAT 테이블
Local IP | Local Port | External Port | Remote IP | Remote Port | Protocol |
192.168.0.10 | 3000 | 8080 (고정) | 15.15.15.15 | 5555 | TCP |
포트 포워딩
포트 포워딩은 NAT 테이블을 프로그래머 혹은 호스트를 사용하는 사람이 직접(수동으로) 수정하는 것을 말한다. 앞서 주지한 바와 같이 NAT 테이블에 데이터가 쓰여지기 위해서는 최소 1회 이상 패킷이 아웃바운드 되어야 할 필요가 있는데, 포트포워딩은 이러한 과정 없이도 NAT 테이블에 데이터를 추가하는 것을 가능하게 한다.
포트 포워딩은 Full Cone NAT의 형태 즉, 외부망 호스트의 IP와 포트번호를 식별하지 않는 방식으로 동작한다. 따라서 Symmetric NAT 기반의 공유기를 사용하더라도 특정 호스트의 프로세스를 포트 포워딩 해 등록하게 된다면, 해당 프로세스는 Full Cone NAT를 사용하는 것처럼 외부에서 접근 가능하게 된다.
아래는 80번 포트를 내부망 포트로 사용하는 웹서버 호스트의 프로세스를 포트 포워딩으로 등록해 외부에서 접근 가능하도록 열어두는 설정이다. 아래처럼 포트 포워딩을 등록하면, 외부망에서 3.3.3.3:80과 같이 내부망으로 접근하고자 할 때, 자동으로 192.168.0.10 호스트의 80번 포트로 접근하게 된다.
Local IP | Local Port | External Port | Remote IP | Remote Port | Protocol |
192.168.0.10 | 80 | 80 (직접 설정) | Any | Any | TCP |
끝마치며
텍스트로 정보를 전달하기 어려운 주제인 것 같다. 글 쓰는 게 너무 어려웠다. ㅜㅜ