공인 IP는 게이트웨이 한 대뿐인데 내부 여러 서버로 트래픽을 나눠야 하거나, 80번으로 들어온 요청을 내부 8080 컨테이너로 넘기고 싶을 때가 있습니다. 이때 쓰는 것이 NAT 포트포워딩(DNAT)입니다. 패킷의 목적지 주소를 커널이 바꿔치기합니다.
증상 — 왜 그냥은 안 닿나
외부에서 게이트웨이의 특정 포트로 보낸 패킷은, 명시적으로 전달 규칙이 없으면 내부 호스트로 가지 않습니다. 또 리눅스는 기본적으로 받은 패킷을 다른 인터페이스로 넘기지 않습니다(IP 포워딩 비활성).
진단 — 포워딩이 켜져 있나
로컬 터미널
sysctl net.ipv4.ip_forward # 0이면 포워딩 꺼짐
iptables -t nat -L -n -v # 현재 NAT 규칙
ip_forward가 0이면 라우팅 자체가 안 되므로 먼저 켭니다.
로컬 터미널
sysctl -w net.ipv4.ip_forward=1
영구 반영은 /etc/sysctl.conf에 net.ipv4.ip_forward = 1을 적고 sysctl -p를 실행합니다.
단계 — DNAT 규칙 설정
들어온 요청 목적지를 내부 주소로 바꾸는 것은 PREROUTING 체인의 DNAT, 돌아가는 경로를 위한 주소 변환은 POSTROUTING의 MASQUERADE입니다.
- 외부 8080 요청을 내부 192.168.1.10:80으로 전달
로컬 터미널
iptables -t nat -A PREROUTING -p tcp --dport 8080 \
-j DNAT --to-destination 192.168.1.10:80
- 응답이 게이트웨이를 거쳐 돌아오도록 마스커레이드
로컬 터미널
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.10 --dport 80 \
-j MASQUERADE
| 체인 | 시점 | 역할 |
|---|---|---|
| PREROUTING | 라우팅 결정 전 | 목적지 주소 변경(DNAT) |
| POSTROUTING | 인터페이스로 나가기 직전 | 출발지 주소 변경(SNAT/MASQUERADE) |
규칙의 목적지·포트 표기에서 부등호 같은 특수문자는 쓰지 않으며, --to-destination은 IP:포트 형식입니다.
확인 체크리스트
로컬 터미널
sysctl net.ipv4.ip_forward # 1인지
iptables -t nat -L PREROUTING -n -v # DNAT 규칙·패킷 카운터
curl http://게이트웨이IP:8080/ # 외부에서 실제 도달 테스트
conntrack -L | grep 192.168.1.10 # 변환된 연결 추적(있으면)
규칙은 넣었는데 안 닿는다면 십중팔구 ip_forward가 꺼졌거나, 내부 서버의 응답이 게이트웨이로 돌아오는 경로(라우팅·SNAT)가 없는 경우입니다. -L -n -v의 패킷 카운터가 0이면 규칙에 트래픽이 아예 안 걸린 것입니다.
NAT·iptables 체인을 직접 만들고 패킷이 어떻게 변환되는지 추적하는 실습은 네트워크 트랙에서 회원가입 없이 무료로 할 수 있습니다.