LabHub
배우기 러닝패스 코스

주소·서브넷·게이트웨이 · 헤어핀 NAT · 실습

헤어핀을 재현하고 두 가지 방법으로 푼다

LabHub 에서 이어서 보기

목표

집 안 노트북·공유기·서버 세 자리를 한 파드 안에 만들고, 목적지만 바꿨을 때
응답이 돌아오지 못하는 것을 실제로 재현합니다. 그다음 출발지까지 바꿔
통하게 만들고, 같은 문제를 이름 해석 쪽에서 푸는 방법과 비교합니다.

왜 중요한가

"밖에서는 되는데 집 안에서만 안 된다" 는 신고는 원인을 짐작하기가 어렵습니다.
연결이 안 되는 것도 아니고 이름이 안 풀리는 것도 아니며, 응답이 오기는 오는데
받는 쪽이 버리기 때문입니다. 버려지는 일은 로그에 아무것도 남기지 않습니다.

이 실습은 그 버려지는 순간을 눈으로 보게 만듭니다. connect() 한 UDP 소켓은
연결한 상대에서 온 것만 받고 나머지는 커널이 조용히 버리는데, 그것이 노트북이
공유기 주소에서 올 응답을 기다리다가 서버의 사설 주소에서 온 응답을 버리는
상황과 정확히 같습니다.

이 파드에서 되는 것과 안 되는 것

실습 파드에는 커널 권한이 없어 ip netnsnfttcpdump 도 동작하지
않습니다. 대신 127.0.0.0/8대역 전체가 자기 자신이라, 권한 없이도
127.0.0.10·127.0.0.20·127.0.0.99 를 한 대에서 함께 쓸 수 있습니다.
세 자리를 그 세 주소로 나눠 씁니다. 6단계의 nftables 규칙은 글로만 쓰고
적용하지 않습니다.

단계

1. 세 자리의 주소와 하는 일을 /root/hairpin/01-map.txt 에 적으세요. laptop 127.0.0.10, router 127.0.0.99, server 127.0.0.20 이고, 주소 셋을 한 대에서 쓸 수 있는 이유도 한 줄 적습니다.
2. /root/hairpin/site/index.htmlhairpin-lab-server 한 줄을 넣고, 그 디렉터리를 127.0.0.20:9000 으로 내보내세요. 사설 주소로 붙은 결과와 127.0.0.99:9000 으로 붙은 결과를 /root/hairpin/02-direct.txt 에 함께 담습니다.
3. 목적지만 바꿨을 때(DNAT 만) 패킷의 출발지와 목적지가 어떻게 변하는지를 /root/hairpin/03-tuple.txt 에 다섯 줄로 적으세요. 줄머리는 각각 request-out, after-dnat, reply, expected, mismatch= 입니다.
4. /root/hairpin/nat.py 를 만드세요. python3 nat.py dnat-only 가 세 소켓으로 그 상황을 재현하고 마지막 줄에 result=dropped 를 출력해야 합니다. 돌린 결과를 /root/hairpin/04-dnat-only.txt 에 저장하세요.
5. 같은 도구의 python3 nat.py dnat-snat 이 출발지까지 바꿔 result=delivered 를 내게 하고, 결과를 /root/hairpin/05-dnat-snat.txt 에 저장하세요.
6. 진짜 공유기에 걸 규칙을 /root/hairpin/06-rules.nft 에 쓰세요. 서버는 192.168.0.20, 집 안 대역은 192.168.0.0/24, 포트는 80 입니다. prerouting 과 postrouting 두 체인이 필요하고, 출발지를 바꾸는 규칙은 집 안에서 온 것만 걸려야 합니다.
7. 같은 문제를 이름 쪽에서 푸세요. /root/hairpin/hosts.internalhome.example.test 의 내부 답을 적고, curl --resolve 로 내부 답과 바깥 답을 각각 흉내 내 /root/hairpin/07-split.txt 에 담으세요.
8. 두 해법을 /root/hairpin/08-compare.md 에 비교하세요. ## 헤어핀, ## 스플릿, ## 무엇을 고르나 세 절이 필요합니다.

참고

단계 8개

  1. 세 자리의 지도를 그린다
  2. 사설 주소로는 되고 바깥 주소로는 안 된다
  3. 네 개의 튜플을 추적한다
  4. 목적지만 바꾸면 응답이 버려진다
  5. 출발지까지 바꾸면 통한다
  6. 공유기에 걸 규칙을 쓴다
  7. 같은 문제를 이름 쪽에서 푼다
  8. 두 해법을 비교한다