NAT(Network Address Translation): 공인 IP 하나를 여럿이 나눠 쓰는 법

NAT(Network Address Translation): 공인 IP 하나를 여럿이 나눠 쓰는 법

집에서 와이파이에 연결된 기기를 한번 세어 볼까요? 노트북, 스마트폰, 태블릿, TV, 어쩌면 로봇청소기까지 십수 대는 우습게 넘어갑니다. 그런데 통신사가 우리 집에 내준 공인 IP 주소는 보통 딱 하나뿐인데요. 어떻게 그 많은 기기가 주소 하나로 동시에 인터넷을 쓰는 걸까요? 🤔

비밀은 집 공유기 안에서 조용히 돌아가는 NAT(Network Address Translation)에 있습니다. 우리말로 옮기면 “네트워크 주소 변환”인데, 이름 그대로 오가는 패킷의 주소를 바꿔치기하는 기술이에요. 이 글에서는 NAT가 무엇을 바꾸는지, 어떻게 IP 하나로 수십 대를 감당하는지, 그리고 그 대가로 어떤 불편이 따라오는지까지 차근차근 살펴보겠습니다.

NAT가 왜 필요할까요

이야기는 IPv4 주소가 모자란다는 사실에서 출발합니다. IPv4 주소는 32비트라서 전부 합쳐도 약 43억 개뿐인데, 전 세계 기기 수는 이미 그 숫자를 한참 넘어섰어요. 그래서 등장한 절충안이 사설 IP입니다. 192.168.x.x10.x.x.x 같은 대역을 집이나 회사 같은 내부망에서 자유롭게 재사용하도록 떼어 둔 거죠.

문제는 사설 IP가 정의상 외부 인터넷에서는 보이지 않는다는 점입니다. 우리 집 노트북의 192.168.0.10이라는 주소는 전 세계에 수억 개나 똑같이 존재하니, 인터넷 어딘가의 서버가 그 주소로 응답을 돌려보낼 방법이 없어요. 그래서 사설망 안의 기기가 바깥으로 나갈 때는 누군가 공인 IP로 주소를 바꿔줘야 합니다. 그 역할을 맡는 것이 NAT입니다.

참고로 이 주소 부족 문제의 근본적인 해법은 주소 공간을 대폭 넓힌 IPv6인데요. IPv6가 완전히 자리 잡기 전까지 IPv4의 수명을 늘려 준 임시 처방이 사설 IP와 NAT의 조합이었죠.

사설 IP에 공인 IP 가면을 씌운다

가장 기본적인 NAT의 동작은 패킷의 출발지 주소를 바꾸는 것입니다.

집 공유기는 두 개의 얼굴을 가집니다. 안쪽으로는 192.168.0.1 같은 사설 IP를 달고 내부망의 게이트웨이 노릇을 하고, 바깥쪽으로는 통신사가 준 공인 IP를 하나 받아 인터넷과 마주합니다. 노트북이 구글로 패킷을 보내면, 공유기는 그 패킷의 출발지 주소를 노트북의 사설 IP에서 자기 공인 IP로 슬쩍 바꿔치기해서 내보냅니다. 바깥에서 보면 마치 공유기가 직접 보낸 패킷처럼 보이는 거죠.

응답이 공인 IP로 돌아오면 공유기는 다시 주소를 원래 노트북의 사설 IP로 되돌려 전달합니다. 이렇게 출발지 주소를 바꾸는 방식을 출발지 NAT(Source NAT, 이하 SNAT)라고 부릅니다. 집에서 인터넷을 쓸 때 늘 일어나는 일이 바로 이 SNAT예요.

그런데 여기서 한 가지 의문이 생깁니다. 노트북 한 대라면 응답을 그대로 돌려주면 되지만, 스마트폰과 태블릿까지 동시에 구글에 접속했다면 공유기는 돌아온 응답을 셋 중 누구에게 줘야 할지 어떻게 알까요? 공인 IP는 하나뿐인데 말이죠.

포트로 구분하는 마법, PAT

이 문제를 푸는 열쇠가 바로 포트 번호입니다.

공유기는 주소만 바꾸는 게 아니라 출발지 포트 번호까지 함께 바꾸고, 그 대응 관계를 표로 기록해 둡니다. 이 표를 NAT 변환 테이블이라고 부르는데, 대략 이렇게 생겼어요.

내부 (사설 IP:포트)변환 후 (공인 IP:포트)목적지
192.168.0.10:52001203.0.113.7:40001구글 서버:443
192.168.0.11:51999203.0.113.7:40002구글 서버:443
192.168.0.12:60000203.0.113.7:40003네이버 서버:443

노트북과 스마트폰이 똑같이 구글의 443 포트로 접속해도, 공유기는 각각 다른 외부 포트(40001, 40002)를 붙여 내보냅니다. 그래서 응답이 203.0.113.7:40002로 돌아오면, 공유기는 변환 테이블을 뒤져 “아, 이건 192.168.0.11:51999의 스마트폰에게 줄 거구나” 하고 정확히 되돌려줄 수 있죠.

이렇게 IP와 포트를 함께 변환해서 공인 IP 하나 뒤에 여러 기기를 숨기는 방식을 포트 주소 변환(Port Address Translation, 이하 PAT)이라고 부릅니다. NAPT(Network Address Port Translation)나 IP 마스커레이딩(masquerading)이라고도 하는데, 우리가 집이나 사무실에서 쓰는 NAT는 거의 다 이 PAT예요. 포트 번호가 16비트라 이론상 공인 IP 하나로 6만 개가 넘는 연결을 동시에 감당할 수 있으니, IP 하나로 수십 대는 물론이고 수백 대도 거뜬합니다.

패킷이 나갔다 돌아오는 한 번의 왕복을 그림으로 보면 이렇습니다.

sequenceDiagram
    autonumber
    participant P as 스마트폰 (192.168.0.11)
    participant R as 공유기 (NAT)
    participant S as 구글 서버

    P->>R: 출발지 192.168.0.11:51999 → 구글:443
    Note over R: 변환 테이블에 기록 후<br/>출발지를 203.0.113.7:40002로 교체
    R->>S: 출발지 203.0.113.7:40002 → 구글:443
    S-->>R: 목적지 203.0.113.7:40002로 응답
    Note over R: 테이블 조회 →<br/>목적지를 192.168.0.11:51999로 복원
    R-->>P: 스마트폰에게 응답 전달

NAT에도 종류가 있습니다

지금까지 본 PAT 말고도 NAT에는 몇 가지 방식이 더 있는데요.

우선 정적 NAT(Static NAT)는 사설 IP 하나를 공인 IP 하나에 고정으로 1:1 매핑하는 방식입니다. 내부 서버를 외부에 항상 같은 주소로 노출해야 할 때 씁니다. 또한 동적 NAT(Dynamic NAT)는 공인 IP를 여러 개 미리 확보해 두고, 내부 기기가 나갈 때마다 남아 있는 공인 IP를 하나씩 빌려주는 방식이에요. 공인 IP 풀이 바닥나면 새 연결이 막힌다는 한계가 있습니다. 마지막으로 앞에서 본 PAT는 공인 IP 하나에 포트로 여러 기기를 욱여넣는 방식이라, 주소를 가장 알뜰하게 쓴다는 점에서 오늘날 압도적으로 많이 쓰입니다.

내 NAT를 직접 확인해 보기

NAT가 실제로 동작하고 있다는 건 명령어 두 개로 금방 확인할 수 있습니다. 먼저 내 기기가 사설망 안에서 받은 사설 IP를 확인해 볼게요.

사설 IP 확인
# macOS
ipconfig getifaddr en0
# → 192.168.0.10

# Linux
ip addr show

와이파이에 연결돼 있다면 192.168.0.10처럼 사설 IP 대역의 주소가 나옵니다. 이번엔 인터넷 반대편에서 바라본 내 주소, 즉 공인 IP를 확인해 봅니다.

공인 IP 확인
curl ifconfig.me
# → 203.0.113.42  (통신사가 공유기에 내준 공인 IP)

두 값이 서로 다르다는 것 자체가 NAT가 조용히 일하고 있다는 증거입니다. 내부에서는 192.168.0.10으로 통신하지만 인터넷에는 공유기의 공인 IP로 나가고 있는 거죠. 재미있는 건, 같은 와이파이에 연결된 다른 기기에서 curl ifconfig.me를 실행해도 똑같은 공인 IP가 나온다는 점입니다. 여러 기기가 공인 IP 하나를 PAT로 함께 나눠 쓰고 있기 때문이에요.

바깥에서 먼저 연결하려면

NAT는 안에서 밖으로 나가는 통신에는 완벽하게 동작하지만, 방향이 반대가 되면 이야기가 달라집니다.

변환 테이블은 내부 기기가 먼저 패킷을 내보낼 때 비로소 만들어집니다. 그런데 바깥에 있는 누군가가 우리 집 안의 기기로 먼저 연결을 시도하면, 그에 해당하는 항목이 테이블에 아직 없어서 공유기는 이 패킷을 누구에게 전달해야 할지 알 수 없어요. 그래서 그냥 버립니다. 집 안에 웹 서버를 띄워도 밖에서 접속이 안 되는 게 이 때문이에요.

이걸 해결하는 첫 번째 방법이 포트 포워딩(port forwarding)입니다. 공유기에 “공인 IP의 8080 포트로 들어온 요청은 무조건 192.168.0.20의 80 포트로 넘겨라” 같은 규칙을 수동으로 등록해 두는 거예요. 목적지 주소를 바꾼다는 점에서 이건 목적지 NAT(Destination NAT, 이하 DNAT)에 해당합니다. 집에 게임 서버나 홈 카메라를 열어 본 적이 있다면 이미 포트 포워딩을 설정해 보셨을 겁니다.

문제는 화상 통화나 P2P처럼 양쪽 다 NAT 뒤에 있는 경우예요. 서로 상대의 공유기에 포트 포워딩을 걸 수도 없는 노릇이죠. 그래서 등장한 기법이 NAT 통과(NAT traversal)인데요. STUN 같은 서버의 도움을 받아 각자 자기 공인 IP와 포트를 알아낸 뒤, 절묘한 타이밍에 동시에 패킷을 주고받아 양쪽 변환 테이블에 구멍을 뚫는 이른바 홀 펀칭(hole punching)이 대표적입니다. Tailscale로 어디서든 내 기기에 접속하기에서 소개한 것처럼, 요즘 VPN이나 메시 네트워크 도구들은 이 까다로운 NAT 통과를 알아서 처리해 줍니다.

NAT는 보안 장치가 아닙니다

NAT를 쓰다 보면 생기는 재미있는 부수 효과가 하나 있습니다. 방금 봤듯이 바깥에서는 NAT 뒤의 기기로 먼저 연결할 수 없으니, 결과적으로 내부 기기가 인터넷에 직접 노출되지 않는 거예요. 그래서 NAT가 방화벽 역할을 해준다고 생각하기 쉽습니다.

하지만 이건 어디까지나 우연히 따라온 효과일 뿐, NAT는 애초에 보안을 목적으로 설계된 기술이 아닙니다. 포트 포워딩을 잘못 열어 두거나, 내부 기기가 먼저 악성 서버로 연결을 맺어 통로를 열어 버리면 NAT는 아무런 방어도 해 주지 못해요. “우리는 NAT 뒤에 있으니 안전하다”는 착각은 위험합니다. NAT가 만들어 주는 경계는 편의를 위한 부산물이라고 여기고, 보안은 방화벽과 접근 제어로 따로 챙겨야 합니다.

NAT 없는 세상은 올까요

NAT가 IPv4의 수명을 늘려 준 것은 분명하지만, 그만큼 그늘도 깊습니다.

공인 IP가 워낙 귀해지다 보니 이제는 통신사조차 가입자 모두에게 공인 IP를 주지 못하는 지경이 됐어요. 그래서 등장한 게 CGNAT(Carrier-Grade NAT)입니다. 가입자들을 100.64.0.0/10 대역으로 한 번 묶고 통신사 망에서 또 한 번 변환하는, 말하자면 NAT를 이중으로 쌓는 구조인데요. 이렇게 되면 가정에서 포트 포워딩을 걸어도 통신사 쪽 NAT에 막혀 소용이 없어지는 등 불편이 커집니다.

이 모든 번거로움의 근본 원인은 결국 주소가 모자란다는 것이고, 그 해답으로 준비된 것이 IPv6입니다. 주소가 사실상 무한에 가까우니 모든 기기에 공인 주소를 직접 줄 수 있고, 그러면 NAT라는 우회로 자체가 필요 없어지죠. 다만 전 세계 인프라가 IPv6로 완전히 넘어가려면 아직 갈 길이 멀기 때문에, NAT는 앞으로도 꽤 오랫동안 우리 곁에 남아 있을 겁니다.

마치며

NAT는 IP 주소가 부족한 시대에 태어나, 사설 IP에 공인 IP 가면을 씌우고 포트로 여러 기기를 구분하는 방식으로 IPv4의 수명을 크게 늘려 준 기술입니다. 집에서 수십 대의 기기가 IP 하나로 인터넷을 쓰는 것도, 바깥에서 집 안 서버로 접속하려면 포트 포워딩이 필요한 것도, 화상 통화가 가끔 연결에 애를 먹는 것도 모두 이 NAT의 동작으로 설명할 수 있어요.

임시 처방으로 시작했지만 이제는 인터넷을 떠받치는 핵심 인프라가 된 NAT의 원리를 알아두면, 네트워크 설정을 하다 마주치는 여러 현상이 훨씬 선명하게 보일 거예요.

더 깊이 파고들고 싶다면 전통적인 NAT 동작을 정의한 RFC 3022를 직접 읽어보는 것도 추천합니다.

This work is licensed under CC BY 4.0CCBY

개발자를 위한 뉴스레터

달레가 정리한 AI 개발 트렌드와 직접 만든 콘텐츠를 전해드립니다.

Discord