라우터 자체의 VPN 클라이언트 뒤에 있는 호스트로 포트를 포워딩하면 요청은 분명히 도착하는데도 방화벽 문제처럼 보이는 방식으로 실패합니다. 서비스는 연결을 기록하고, 클라이언트는 기다리며, 아무것도 돌아오지 않습니다. 목적지 변환은 제 일을 했고, 사라진 것은 반환 패킷 쪽입니다. 라우터의 선택적 소스 NAT 규칙 하나가 이를 고치며, 흥미로운 부분은 그 규칙을 얼마나 좁게 만들 수 있는지 결정하는 것입니다.

응답이 다른 길을 가는 이유

포트 포워딩은 패킷이 어디로 가는지를 다시 쓰고, 어디서 왔는지는 결코 쓰지 않습니다. 인터넷 클라이언트의 주소는 터널을 지나는 동안 내내 소스 필드에 남으므로, 원격 서비스는 낯선 사람을 보고 자기가 아는 유일한 방법, 즉 자신의 기본 게이트웨이를 통해 응답합니다. 그 게이트웨이는 반대편의 VPN 집중 장치이며, 임의의 공인 주소로 돌아갈 경로가 없습니다.

터널 인터페이스에서 캡처를 보면 요청 패킷은 나가고 들어오는 것은 없다는 비대칭이 분명합니다. 포워딩 체인이 흐름을 허용했고 터널이 그것을 실어 날랐으므로, 폐기는 원격 호스트가 이미 반환 경로를 고른 뒤에 일어납니다.

믿을 만큼 좁은 소스 규칙

라우터를 원격 호스트가 응답하는 소스로 만드세요. 이 구성에서 WAN 주소는 203.0.113.24이고, LAN은 192.168.88.0/24이며, 라우터의 터널 주소는 172.20.5.1이고, 서비스는 172.20.5.40:8443에서 응답합니다. 아래 규칙은 목적지 변환 이후의 패킷과 일치하므로 공인 주소가 아니라 변환된 주소를 지정합니다. 클라이언트 주소에 의존하는 것은 아무것도 없으며, 바로 그 점이 핵심입니다.

iptables -t nat -A POSTROUTING -o tun0 -p tcp -d 172.20.5.40 --dport 8443 -j SNAT --to-source 172.20.5.1

그 줄의 모든 일치는 재작성을 한 터널의 한 서비스로 국한하기 위해 존재합니다. 인터페이스나 포트를 빼면 문제가 요구하는 것보다 더 많은 트래픽을 재작성하게 되고, 이렇게 표적 수정이 다음 사람에게 수수께끼가 됩니다.

전면 마스커레이드가 정직한 선택일 때

라우터가 많은 서비스를 같은 VPN 서브넷으로 포워딩한다면 서비스별 규칙은 아무도 관리하지 않는 목록이 됩니다. 터널 인터페이스를 떠나는 모든 것을 마스커레이드하는 편이 더 단순하고 예측 가능하지만, 그 대가는 반대편의 모든 호스트에서 원래 클라이언트를 숨기는 것입니다. 그쪽 로그를 귀속에 쓰지 않는다면 그것을 선택하고, 쓴다면 좁은 규칙을 유지하세요.

두 선택지는 실패 방식도 다릅니다. 좁은 규칙이 없으면 서비스 하나가 깨지고, 너무 많이 일치하는 넓은 마스커레이드는 이미 작동하던 트래픽을 조용히 재작성할 수 있으며 라우터 자체의 아웃바운드 연결도 포함됩니다.

게시하기 전에 카운터를 확인하세요

절대 일치하지 않는 규칙은 패킷을 세기 전까지 작동하는 규칙과 똑같아 보입니다. 어떤 클라이언트도 연결하기 전에 바이트 카운터와 함께 테이블을 다시 읽고, 그다음 LAN이 아닌 네트워크에서 연결해 다시 읽으세요. 추측을 사실로 바꾸는 것은 이 두 번의 읽기입니다. 두 번째가 움직인 뒤에만 포워딩을 게시하세요.

iptables -t nat -L POSTROUTING -v -n --line-numbers

실제 연결 후 소스 규칙의 카운터가 영이면 일치가 잘못된 것이며, 보통 목적지나 포트가 변환 후 패킷과 맞지 않기 때문입니다. 카운터가 올라가는데 클라이언트가 여전히 시간 초과라면 반환 경로는 고쳐졌고 다른 무언가가 응답을 떨어뜨리는 것이므로, 다음으로 반대편의 포워딩 정책을 보세요. LAN 내부에서의 헤어핀 접근은 별개의 문제이며 이 규칙의 더 넓은 버전이 아니라 자체 규칙이 필요합니다.

관련 글