사설 IP는 왜 인터넷에서 안 통할까? NAT부터 DNS까지
온프레미스 프로젝트를 하다 보면 황당한 순간이 온다. 회사에선 멀쩡히 열리던 주소가 집에서 접속하면 안 열려. 같은 서버, 같은 URL인데 말이지. 이 글은 그 이유를 사설 IP, NAT, DNS 세 가지로 풀어본다.
1. IP에는 두 종류가 있다
세상 모든 기기가 전 세계에서 유일한 주소를 가지려면 IP가 턱없이 부족하다. 그래서 IP 대역을 둘로 나눔. (네트워크 시간에 배움)
공인 IP(Public IP) — 인터넷 전체에서 유일하고 어디서든 도달 가능. 203.0.113.20 같은 주소로 패킷 보내면 전 세계 어디서든 그 서버에 닿는다.
사설 IP(Private IP) — 조직 내부에서만 쓰는 주소. 아래 세 대역이 예약돼 있어.
대역 범위
| 10번대 | 10.0.0.0 ~ 10.255.255.255 |
| 172번대 | 172.16.0.0 ~ 172.31.255.255 |
| 192번대 | 192.168.0.0 ~ 192.168.255.255 |
집 공유기가 노트북에 붙여주는 192.168.0.10 같은 게 사설 IP야. 얘들의 결정적 특징은 인터넷에서 라우팅이 안 된다는 거. 전 세계 수많은 회사가 동시에 192.168.0.10을 쓰고 있으니까, 인터넷 라우터는 이 대역으로 오는 패킷을 그냥 버려. 오직 같은 사설망 안에서만 의미가 있어.
그래서 외부 사용자한테 http://192.168.0.10:8080 같은 사설 주소 알려주면, 그 사람 브라우저는 길을 못 찾고 그냥 실패함.
2. 그럼 집 안의 폰은 어떻게 인터넷을 쓰지? — NAT
여기서 자연스럽게 의문이 든다. 내 폰은 사설 IP인데 어떻게 유튜브를 보냐?
답이 **NAT(Network Address Translation, 네트워크 주소 변환)**이다. 사설 IP랑 공인 IP 사이를 패킷이 오갈 때 주소를 바꿔치기하는 기술.
집을 예로 들어보자. 집 안엔 사설 IP 쓰는 기기들이 있어.
노트북 192.168.0.10
폰 192.168.0.11
TV 192.168.0.12
근데 인터넷에서 우리 집을 보면 통신사가 준 공인 IP 하나(203.0.113.20)로만 보여. 공유기가 NAT를 하는 거지.
- 노트북이 유튜브에 요청 보냄. 출발지: 192.168.0.10
- 공유기가 출발지를 192.168.0.10 → 203.0.113.20으로 바꿔서 내보냄
- 유튜브 응답이 203.0.113.20으로 돌아옴
- 공유기가 "이거 아까 노트북이 보낸 거니까" 192.168.0.10으로 되돌려서 전달
여러 기기 중 어느 거 요청인지는 포트 번호로 구분해. 대표번호 하나로 전화받아서 내선으로 연결해주는 안내데스크랑 똑같음.
3. 반대 방향도 있다 — 포트포워딩(DNAT)
위 예시는 안에서 밖으로 나가는 경우야. 그럼 밖에서 안으로 들어오려면? 예를 들어 집 안 NAS(192.168.0.50:8080)에 외부에서 접속하고 싶다면?
이때 쓰는 게 포트포워딩, 정식 명칭 DNAT(Destination NAT). 공유기에 이렇게 규칙을 걸어.
외부에서 203.0.113.20:8443 으로 들어온 요청
→ 내부 192.168.0.50:8080 으로 전달
이제 외부 사용자는 https://203.0.113.20:8443으로 접속하고, 공유기가 이걸 내부 192.168.0.50:8080으로 변환해줘. 외부에 노출하는 포트(8443)랑 내부 실제 포트(8080)가 다른 이유가 바로 이거야.
여기서 핵심이 드러난다. 같은 서버라도 "어디서 접속하느냐"에 따라 닿을 수 있는 주소가 다르다.
접속 위치 써야 하는 주소
| 같은 사설망 내부 | http://192.168.0.50:8080 (NAT 없이 직접) |
| 인터넷(외부) | https://203.0.113.20:8443 (DNAT 경유) |
맨 앞에서 던진 "회사에선 열리는데 집에선 안 열림"의 정체가 이거다. 응답 본문에 내부 사설 주소가 박혀 있으면, 외부 사용자는 그 주소로 못 닿아.
4. OSI 7계층에서 NAT는 어디 있나
네트워크를 7개 층으로 나눈 OSI 모델을 한 번 보면 NAT 위치가 명확해져. 아래로 갈수록 물리에 가깝고, 위로 갈수록 사람이 쓰는 데이터에 가까움.
계층 이름 다루는 것 예시
| 7 | 응용 | 사람이 쓰는 데이터 | HTTP, DNS |
| 6 | 표현 | 암호화·인코딩 | TLS, JPEG |
| 5 | 세션 | 연결 유지 | 세션 관리 |
| 4 | 전송 | 포트, 신뢰성 | TCP, UDP |
| 3 | 네트워크 | IP 주소, 라우팅 | IP |
| 2 | 데이터링크 | 같은 망 안 전달 | MAC, 이더넷 |
| 1 | 물리 | 전기 신호 | 케이블, 와이파이 |
NAT는 3계층(IP)에서 일어나. IP 주소를 바꿔치기하니까. 다만 포트까지 같이 다루는 경우(아까 그 안내데스크 방식)는 4계층 포트도 건드리니까, 실무에선 3~4계층에 걸쳐 있다고 봐.
그래서 NAT는 "패킷 헤더의 IP/포트"를 바꿔. 7계층의 데이터 본문(예: HTTP 응답에 적힌 URL 문자열)은 안 건드림. 이게 중요해. 만약 서버가 응답 본문에 사설 IP를 그대로 적어서 보내면, NAT는 헤더만 바꿀 뿐 본문 속 그 주소는 손 안 대. 외부 사용자는 본문에 적힌 사설 주소 보고 접속 시도하다가 실패함. 본문 속 주소까지 환경에 맞게 바꾸려면 7계층, 즉 애플리케이션이 직접 처리해야 해.
5. 더 깔끔한 해법 — DNS
지금까진 "주소를 IP로 직접 박는다"는 전제였어. 근데 우리가 youtube.com이라고 치지 142.250.x.x라고 안 치잖아. 보통은 **이름(도메인)**을 써. 이 이름을 IP로 바꿔주는 전화번호부가 **DNS(Domain Name System)**야.
DNS는 한 가지 마법을 부릴 수 있어. 같은 이름인데 누가 묻느냐에 따라 다른 IP를 돌려주기. 이걸 split-horizon DNS(또는 split-brain DNS)라고 해.
"nas.mycompany.com 주소 알려줘"
내부망에서 물으면 → 192.168.0.50 (사설 IP, 직접 도달)
외부망에서 물으면 → 203.0.113.20 (공인 IP, DNAT 경유)
이렇게 해두면 서버 응답에는 IP 대신 도메인 하나(nas.mycompany.com)만 적으면 돼. "어느 IP로 갈지"는 DNS가 접속 위치 보고 알아서 갈라줌. 애플리케이션이 본문 속 주소를 일일이 바꿔치기할 필요가 사라지는 거지.
DNS도 OSI 7계층(응용 계층)에 속해. HTTP랑 같은 층.
정리
- 사설 IP(10.x, 172.16~31.x, 192.168.x)는 조직 내부 전용이라 인터넷에서 안 통함
- NAT는 사설 ↔ 공인 IP를 바꿔치기해서 사설망 기기가 인터넷 쓰게 해줌 (3계층, 포트까지 보면 3~4계층)
- **포트포워딩(DNAT)**은 밖에서 안으로 들어오게 해줌. 그래서 외부 포트랑 내부 포트가 다를 수 있음
- 결국 접속 위치에 따라 써야 하는 주소가 다르다
- NAT는 헤더만 바꾸니까, 응답 본문에 박힌 주소는 애플리케이션(7계층)이 직접 처리하거나 split-horizon DNS로 도메인 하나에 맡기면 깔끔함
맨 앞 질문 — "회사에선 열리는데 집에선 안 열려요" — 답은 이제 한 줄로 끝난다. 그 주소가 사설 IP라서, 외부에서는 NAT 거친 공인 주소나 도메인으로 접속해야 하기 때문.