네트워크 기초 — 리눅스 VM 에서 손으로 · 방화벽과 NAT · 실습
NAT 로 사설망을 인터넷에 내보낸다
이 실습은 VM 에서 돕니다
이번엔 VM 자신이 라우터입니다. 네임스페이스 lan 이 사설망의 호스트이고,
VM 의 uplink(enp1s0, 10.0.2.2)가 인터넷 쪽입니다. 사설 주소 10.30.0.2 는
바깥에서 돌아올 길이 없으므로, VM 이 자기 주소로 바꿔 내보내야 합니다 — 그것이
마스커레이드입니다. 이 VM 은 공인 80/443 과 DNS 에만 닿습니다.
목표
마스커레이드(SNAT)로 사설망 호스트를 인터넷에 내보내고, 패킷의 출발지가 실제로
바뀌는 것을 양쪽 인터페이스에서 잡아 보고, DNAT 로 바깥에서 온 접속을 안쪽
서버로 넘깁니다. 집 공유기와 도커의 -p 가 하는 일이 정확히 이것입니다.
왜 중요한가
사설 주소는 인터넷에서 라우팅되지 않습니다. 그런데 집·회사·클라우드 VPC·
쿠버네티스 파드가 전부 사설 주소입니다. 이들이 바깥과 이야기하는 방법은
하나뿐입니다 — 경계에서 주소를 바꾸고, 응답이 오면 되돌리는 것. 그 되돌림을
가능하게 하는 것이 연결 추적(conntrack)이고, 그래서 NAT 장비가 재시작되면
모든 연결이 끊깁니다. "안에서는 되는데 밖에서 안 된다" 는 신고의 답은 거의
언제나 이 장에 있습니다.
단계
1. 네임스페이스 lan 과 veth lan0(lan, 10.30.0.2/24)↔lan-r(루트, 10.30.0.1/24)을 만들고, lan 의 기본 경로를 10.30.0.1 로, 루트의 net.ipv4.ip_forward 를 1 로 하세요.
2. lan 에서 uplink 게이트웨이 10.0.2.1 로 ping 이 안 되는 결과를 /root/nat/before.txt 에 저장하세요.
3. 테이블 ip labnat 의 postrouting 훅 체인에 10.30.0.0/24 가 uplink 로 나갈 때 counter masquerade 하는 규칙을 넣어 ping 이 되게 하세요.
4. uplink 와 lan-r 에서 동시에 ICMP 를 캡처하며 lan 에서 ping 을 보내, 바깥에서 본 출발지가 바뀐 것을 /root/nat/outside.txt 와 안쪽의 원래 출발지를 /root/nat/inside.txt 에 저장하세요.
5. /etc/netns/lan/resolv.conf 에 상류 DNS 서버를 적어 lan 안에서 getent hosts archive.ubuntu.com 이 되게 하고 그 결과를 /root/nat/dns.txt 에 저장하세요.
6. lan 에서 curl -sI http://archive.ubuntu.com/ 의 응답 머리를 /root/nat/web.txt 에 저장하세요.
7. nft list table ip labnat 을 /root/nat/counter.txt 에 저장하세요. 마스커레이드 규칙의 counter packets 가 0 보다 커야 합니다.
8. lan 안에 10.30.0.2:80 웹 서버를 띄우고, 네임스페이스 guest(veth guest0 10.31.0.2/24 ↔ guest-r 10.31.0.1/24)를 만들어, prerouting 훅 체인의 iifname "guest-r" tcp dport 8080 dnat to 10.30.0.2:80 규칙으로 guest 에서 http://10.31.0.1:8080/ 이 되게 하고 그 응답 첫 줄을 /root/nat/dnat.txt 에 저장하세요.
참고
- uplink 이름은
ip route show default의dev입니다(이 VM 은enp1s0). - 마스커레이드:
nft add table ip labnat; nft 'add chain ip labnat post { type nat hook postrouting priority 100; }'; nft add rule ip labnat post ip saddr 10.30.0.0/24 oifname "enp1s0" counter masquerade. - 네임스페이스는
/etc/resolv.conf도 따로입니다./etc/netns/<이름>/resolv.conf가 있으면ip netns exec가 그것을 덮어 씌워 줍니다. 상류 서버 주소는resolvectl dns enp1s0. - DNAT:
nft 'add chain ip labnat pre { type nat hook prerouting priority -100; }'. - 흔한 실수:
ip_forward를 빼먹는 것. NAT 규칙이 있어도 넘겨 주지 않으면 소용없습니다.
단계 8개
- 사설망 한 대
- NAT 없이는
- 마스커레이드
- 주소가 바뀌는 순간
- 네임스페이스의 resolv.conf
- 인터넷에 닿는다
- 세어 본다
- 포트 포워딩