VPN 게이트웨이 양쪽에서 캡처를 뜨면 하나의 흐름이 서로 다른 주소 네 개를 보여 줄 수 있습니다. 출발지 NAT는 패킷이 어디서 왔다고 주장하는지를 다시 쓰고, 목적지 NAT는 어디로 가는지를 다시 씁니다. Masquerade는 세 번째 방향이 아니라 고정값 대신 나가는 인터페이스의 주소를 쓰는 출발지 NAT 규칙입니다. 셋 중 무엇이 정말 필요한지 이름 붙이면 “VPN이 고장 났다”는 티켓 대부분이 되돌아오는 경로에 대한 질문으로 줄어듭니다.

각 규칙이 다시 쓰는 것

출발지 NAT는 보통 SNAT로 쓰며, 흐름이 라우터나 게이트웨이를 떠날 때 출발지 주소를 바꿉니다. 받는 쪽 서비스는 번역된 주소로 응답하고, 번역하는 상자는 그 연결을 위해 보관한 상태로 변경을 되돌립니다. Linux에서는 그 상태가 conntrack에 살기 때문에 conntrack -L가 원래 튜플과 응답 튜플을 나란히 출력합니다.

목적지 NAT인 DNAT는 대신 목적지를 바꿉니다. UDP 51820의 공인 주소로 보낸 패킷은 10.8.0.2:51820의 내부 WireGuard 서버로 다시 쓸 수 있습니다. 가정용 라우터나 클라우드 로드 밸런서가 VPN 리스너를 게시하는 방식이 이것이며, 터널이 그 뒤에 무엇을 실을 수 있는지는 말해 주지 않습니다.

Masquerade는 SNAT 계열입니다. 규칙은 주소를 지정하지 않고, 패킷이 나갈 때 나가는 인터페이스가 가진 주소를 씁니다. Linux는 여기에 자체 타깃을 주며, DHCP나 PPPoE로 주소를 받는 WAN 인터페이스에서 흔한 선택입니다.

매핑이 어디에 사는지가 실패를 결정한다

모든 경계에서 튜플을 기록하십시오. 대상은 터널 앞, 터널 안, 공인 인터페이스 위이며, 터널 안의 캡처가 바깥과 다른 것은 정당한 일이고 번역이 어디서 일어나는지 모른 채 둘을 비교하는 사람은 잘못된 호스트를 쫓게 됩니다.

돌아오는 트래픽은 매핑을 들고 있는 장치를 지나야 합니다. 응답이 다른 경로, 두 번째 업링크, 정책 라우트, 혹은 당신의 사설 대역을 들어본 적 없는 사업자를 지나면 상태 기반 역번역이 일어나지 않고 클라이언트는 단방향 트래픽을 봅니다. 출발지 NAT를 더 넣는 것으로 빠진 반환 경로가 고쳐지는 일은 드물고, 한 흐름에서 증상을 숨기면서 다른 모든 곳의 주소 기반 정책을 깨뜨릴 수 있습니다.

또 하나 흔한 실수는 터널이 라우팅 가능성을 만든다고 기대하는 것입니다. 패킷이 인터넷으로 나가는 사설 클라이언트에는 유효한 출구 구성이 필요합니다. 즉 기본 라우트, 전달하는 게이트웨이, 보통은 공인 주소로의 출발지 번역이며, 암호화만으로는 사설 주소가 도달 가능해지지 않습니다.

Masquerade 아니면 명시적 SNAT

무엇을 약속하는지로 둘을 비교하십시오. Masquerade는 출구 주소를 고르고, 명시적 SNAT는 그것을 고정합니다. 공인 주소가 안정적인 게이트웨이에서는 고정이 로그와 파트너 허용 목록에 예측 가능한 값 하나를 줍니다. 동적 WAN 링크에서는 고정한 SNAT 주소가 임대가 바뀌는 순간 틀린 값이 되며, Masquerade는 바로 그 경우를 위해 만들어졌습니다.

범위는 선택만큼 중요합니다. 게이트웨이를 떠나는 모든 패킷과 일치하고 출발지나 목적지 제한이 없는 Masquerade 규칙은 그대로 두려던 트래픽까지 번역합니다. 다른 사설 네트워크로 가는 트래픽도 포함되므로 규칙은 클라이언트 대역, 의도한 목적지, 인터페이스로 제한하십시오.

정책 기반 IPsec에서 이것이 가장 아프게 물립니다. strongSwan의 전달 안내서는 IP 전달을 켜고 클라이언트용 출발지 NAT 규칙을 추가하는 과정을 짚으며, 같은 문서가 원래 주소를 유지해야 하는 트래픽을 제외하는 방법도 다룹니다. 보안 정책이 일치하기 전에 출발지를 번역하면 패킷이 더는 협상된 선택자처럼 보이지 않아 터널은 올라오지만 트래픽은 계속 떨어집니다.

먼 쪽이 무엇을 봐야 하는지도 정하십시오. 번역 뒤에 서비스는 게이트웨이를 보지 개별 클라이언트를 보지 않습니다. 이는 반환 라우팅을 단순하게 만들고 동시에 로그를 평평하게 하며 클라이언트별 허용 목록을 무력화합니다. 클라이언트 주소 보존이 중요하다면 테스트를 통과시키려고 숨기는 대신 라우팅된 반환 경로를 설계하십시오.

Linux 게이트웨이에서 규칙 읽기

10.8.0.0/24에 클라이언트를 두고 WAN 인터페이스 이름이 eth0인 원격 접속 게이트웨이는 전달이 켜져 있고 흐름을 허용하는 필터 정책이 있어야 어떤 NAT 규칙도 도움이 되며, iptables 버전은 양방향을 nat 테이블에 둡니다.

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 51820 \
  -j DNAT --to-destination 10.8.0.2:51820

nftables 형태는 같은 두 훅을 이름 있는 인터페이스와 명시적 체인으로 씁니다:

nft add rule ip nat postrouting ip saddr 10.8.0.0/24 oifname "eth0" masquerade
nft add rule ip nat prerouting iifname "eth0" udp dport 51820 dnat to 10.8.0.2:51820

두 예시 모두 필터 체인이 전달된 흐름을 이미 받아들인다고 가정합니다. NAT는 허용 규칙이 아니며 올바로 번역된 패킷도 한 테이블 뒤에서 버려질 수 있습니다. conntrack -L로 실제 매핑을 확인하고, nft list ruleset나 iptables-save -t nat로 무엇이 적재되었는지 확인한 뒤, 두 인터페이스에서 캡처해 주소가 정말 바뀌는지 보십시오.

나쁜 규칙처럼 보이는 실패 모드

헤어핀 트래픽이 고전입니다. 서버의 공인 주소로 내부 서버에 닿는 내부 클라이언트에는 들어오는 길에 DNAT, 되돌아 나가는 길에 출발지 번역이 필요하며, 없으면 서버가 클라이언트에 곧바로 응답하고 그 응답은 거부됩니다. 해법은 그 내부에서 공인으로 가는 경우를 위한 더 좁은 두 번째 규칙이며, 모든 것에 대한 넓은 Masquerade 규칙이 아닙니다.

이중 번역은 조용한 쪽입니다. 이미 통신사급 NAT 뒤에 있는 클라이언트는 되돌려 라우팅할 수 없는 주소로 게이트웨이에 오므로 다시 번역합니다. 동작하지만 로그에는 사설 주소 지정의 두 홉이 실리고 어떤 조사든 두 매핑이 모두 필요합니다. 정책 기반 IPsec는 세 번째 꼬임을 더하는데, 정책 일치 전에 번역하면 트래픽이 지나가지 않는 채로 SA만 올라오며 이는 NAT가 아니라 방화벽 버그처럼 읽힙니다.

다음은 통과하는 테스트와 실패하는 배포입니다. NAT 명령을 손으로 돌려 보는 것은 동작 원리를 증명할 뿐 구성은 아닙니다. 실행 중에 추가한 규칙은 재부팅이나 다음 인터페이스 이벤트에서 사라지고, 번호가 바뀌는 인터페이스에 묶인 Masquerade 규칙은 먼 쪽이 보는 주소를 조용히 바꿀 수 있습니다. 규칙은 그것을 소유한 방화벽 구성에 넣고 다시 연결한 뒤 재시험하십시오.

규칙을 저장하기 전 점검 목록

먼저 방향을 이름 붙여 출발지인지, 목적지인지, 둘 다인지 정하십시오. 다음으로 상태를 누가 들고 있어야 하는지, 게이트웨이인지 위쪽 라우터인지 IPsec 피어인지 정하고 응답 경로가 그곳을 통해 돌아오는지 확인하십시오. 규칙은 실제로 의도한 클라이언트 대역, 목적지, 인터페이스로 제한하고, 먼 쪽이 게이트웨이를 봐야 하는지 원래 클라이언트 주소를 봐야 하는지 미리 정하십시오.

게이트웨이에서가 아니라 클라이언트에서 시험하십시오. 게이트웨이 자체의 브라우저는 클라이언트 번역 규칙을 완전히 우회할 수 있으므로 거기서 열리는 페이지는 터널에 대해 아무것도 증명하지 못합니다. 클라이언트에서 시작한 요청 하나를 보내고 카운터와 conntrack 테이블을 보며, 근무지에서 둘 중 하나가 가능하다면 터널 재연결과 WAN 주소 변경 뒤에 반복하십시오.

관련 글