2장의 MAC 주소는 같은 링크 안에서만 통하는 주소였습니다. 이번 장은 링크를 넘어 최종 목적지까지 찾아가는 계층입니다.
3.1 IPv4 주소
- 32비트, 점으로 구분한 4개의 옥텟:
192.168.10.25 - 약 43억 개 → 이미 고갈 → 사설 IP와 NAT, 그리고 IPv6 등장
3.2 서브넷과 CIDR
IP 주소는 네트워크 부분과 호스트 부분으로 나뉩니다. 그 경계를 표시하는 것이 서브넷 마스크, 이를 줄여 쓰는 것이 CIDR 표기법입니다.
192.168.10.25/24
→ 앞 24비트가 네트워크: 192.168.10.0
→ 뒤 8비트가 호스트: 0 ~ 255
→ 서브넷 마스크: 255.255.255.0| CIDR | 서브넷 마스크 | 전체 주소 수 | 사용 가능 호스트 |
|---|---|---|---|
| /32 | 255.255.255.255 | 1 | 단일 호스트 지정 |
| /30 | 255.255.255.252 | 4 | 2 |
| /28 | 255.255.255.240 | 16 | 14 |
| /24 | 255.255.255.0 | 256 | 254 |
| /16 | 255.255.0.0 | 65,536 | 65,534 |
| /8 | 255.0.0.0 | 16,777,216 | 16,777,214 |
사용 가능 호스트가 2개 적은 이유는 네트워크 주소(맨 앞) 와 브로드캐스트 주소(맨 뒤) 를 제외하기 때문입니다. (클라우드 VPC는 추가로 몇 개를 예약합니다. AWS는 서브넷마다 5개.)
계산 예시: 10.0.4.130/26은 어떤 네트워크에 속할까?
/26 → 블록 크기 = 2^(32-26) = 64
4번째 옥텟: 0, 64, 128, 192 단위로 나뉨
130은 128~191 구간 → 네트워크 10.0.4.128, 브로드캐스트 10.0.4.191
사용 가능: 10.0.4.129 ~ 10.0.4.190개발자에게 중요한 이유: 방화벽 허용 규칙(
10.10.0.0/16 허용), 클라우드 보안 그룹, Docker 네트워크 대역, Kubernetes Pod CIDR, Nginxallow/deny, DB의pg_hba.conf가 모두 CIDR로 작성됩니다.
3.3 공인 IP와 사설 IP
RFC 1918에 정의된 사설 대역은 인터넷에서 라우팅되지 않습니다.
| 대역 | CIDR |
|---|---|
| 10.0.0.0 ~ 10.255.255.255 | 10.0.0.0/8 |
| 172.16.0.0 ~ 172.31.255.255 | 172.16.0.0/12 |
| 192.168.0.0 ~ 192.168.255.255 | 192.168.0.0/16 |
그 외 알아둘 특수 주소:
127.0.0.0/8— 루프백.127.0.0.1= 자기 자신0.0.0.0— 서버 바인딩 시 "모든 인터페이스"169.254.0.0/16— 링크 로컬. DHCP 실패 시 자동 할당, 클라우드 메타데이터 서버(169.254.169.254)100.64.0.0/10— 통신사 NAT(CGNAT) 용도
자주 겪는 함정 —
127.0.0.1vs0.0.0.0바인딩 개발 서버를127.0.0.1에 바인딩하면 같은 머신에서만 접근됩니다. 컨테이너 안에서 서버를127.0.0.1로 띄우면 포트를 publish해도 외부에서 접근할 수 없습니다. 컨테이너 안의 서버는0.0.0.0으로 바인딩해야 합니다. (Vite의--host, Next.js의-H 0.0.0.0이 필요한 이유)
3.4 NAT (Network Address Translation)
사설 IP를 가진 장비가 인터넷에 나갈 때, 라우터가 출발지 주소를 공인 IP로 바꿔줍니다.
[내 PC 192.168.0.10:52000] → [공유기 NAT] → [공인 IP 203.0.113.5:40001] → 서버- SNAT(Source NAT): 출발지 변환. 내부 → 외부 통신 시.
- DNAT(Destination NAT): 목적지 변환. 포트 포워딩. 외부 → 내부 서비스 노출 시.
- PAT/NAPT: 포트까지 변환해 공인 IP 하나를 여럿이 공유.
개발자에게 미치는 영향:
- 서버는 클라이언트의 진짜 IP를 모른다. 같은 회사 직원 수백 명이 서버 입장에선 하나의 IP로 보입니다. IP 기반 Rate Limit을 걸 때 주의해야 합니다.
- 외부에서 먼저 내부로 연결할 수 없다. 이것이 WebRTC에 STUN/TURN이 필요한 이유입니다(9장).
- Docker의 포트 매핑(
-p 8080:80)도 내부적으로 iptables DNAT입니다.
3.5 라우팅
라우터는 라우팅 테이블을 보고 "이 목적지로 가려면 다음에 어디로 보내야 하는가"를 결정합니다. 가장 구체적인(prefix가 긴) 규칙이 우선합니다(Longest Prefix Match).
ip route
# default via 192.168.0.1 dev eth0 ← 나머지는 전부 게이트웨이로
# 192.168.0.0/24 dev eth0 scope link ← 같은 대역은 직접 전달
# 172.17.0.0/16 dev docker0 ← Docker 브리지 대역실무 사례 — Docker 대역 충돌: Docker 기본 브리지는
172.17.0.0/16을 사용합니다. 사내망에172.17.x.x대역 서버가 있으면, 서버의 라우팅 테이블이 해당 트래픽을 docker0으로 보내버려 특정 사내 서버에만 접속이 안 되는 기이한 현상이 생깁니다. 폐쇄망/사내 서버에 Docker를 설치할 때는/etc/docker/daemon.json의bip,default-address-pools로 대역을 미리 지정하는 것이 안전합니다.
{
"bip": "10.200.0.1/24",
"default-address-pools": [
{ "base": "10.201.0.0/16", "size": 24 }
]
}3.6 ICMP, TTL, traceroute
- ICMP: IP 계층의 제어/오류 메시지 프로토콜.
ping이 사용. - TTL(Time To Live): 패킷이 거칠 수 있는 최대 라우터 수. 라우터를 지날 때마다 1씩 감소, 0이 되면 폐기하고 ICMP Time Exceeded를 돌려보냄.
- traceroute: TTL을 1, 2, 3...으로 늘려가며 경로상의 라우터를 찾아냄.
주의: 많은 기업망/클라우드는 ICMP를 차단합니다. ping이 안 된다고 서버가 죽은 것이 아닙니다. 포트 단위로 확인해야 합니다(14장).
3.7 MTU와 단편화
- MTU: 링크 계층이 한 번에 보낼 수 있는 최대 크기. 이더넷 기본 1500바이트.
- MSS: TCP 페이로드 최대 크기. 보통 1500 − IP 헤더 20 − TCP 헤더 20 = 1460.
- VPN, 터널(VXLAN, IPsec), PPPoE를 거치면 헤더가 추가되어 실제 MTU가 줄어듭니다.
증상: "작은 요청은 잘 되는데 큰 응답(또는 TLS 핸드셰이크의 긴 인증서)에서 멈춘다", "VPN 붙이면 특정 사이트만 안 열린다" → MTU 문제(PMTU 블랙홀) 를 의심하세요. ICMP 차단 때문에 "패킷이 너무 크다"는 신호가 발신자에게 돌아오지 못해 생깁니다.
3.8 IPv6 간단 정리
- 128비트:
2001:0db8:0000:0000:0000:ff00:0042:8329→2001:db8::ff00:42:8329 - NAT 없이 모든 장비에 공인 주소 부여 가능
- 루프백은
::1, 모든 인터페이스는:: - 개발 시 주의: Node.js 17+부터
localhost해석 시 OS 설정 순서를 따르면서::1이 먼저 나올 수 있습니다. 서버는127.0.0.1(IPv4)에만 떠 있는데 클라이언트가::1로 붙어ECONNREFUSED가 나는 사례가 흔합니다. 이럴 땐127.0.0.1을 명시하세요.