VPN 클라이언트 둘이 서로 다른 공인 IPv4 주소로 나갈 수 있으며, 그렇게 하는 규칙은 대부분 사람이 생각하는 것보다 짧습니다. 이걸 작동시키는 것은 iptables 문법이 아니라 패킷이 출구 체인에 도달했을 때의 상태이며, 그곳의 소스 주소가 여전히 클라이언트를 구분할 수 있어야 합니다. 앞선 masquerade가 이미 둘을 하나의 주소로 합쳐 버렸다면, 클라이언트별 규칙으로는 그 구분을 되살릴 수 없습니다. 먼저 그 문제를 정리한 다음 변환을 쓰세요.

게이트웨이까지 살아남는 신원

규칙은 패킷의 소스 주소와 일치하며 VPN 사용자 이름이나 클라이언트 앱이 표시하는 이름과는 일치하지 않습니다. 경로에서 패킷을 먼저 변환하는 모든 것이 규칙이 아직 무엇을 볼 수 있는지 결정합니다. nat 테이블을 순서대로 실행하고 소스가 아직 클라이언트별로 남아 있는 지점을 찾으세요.

iptables -t nat -S POSTROUTING

그 목록을 위에서부터 읽으세요. 위쪽의 masquerade 규칙은 일치하는 모든 흐름의 소스를 다시 쓰고, 그 뒤에 놓인 클라이언트별 항목은 더 이상 존재하지 않는 주소와 일치합니다. 두 LAN 장치가 하나의 터널을 공유하며 하나의 내부 주소로 도착하면 방화벽보다 설계가 먼저 바뀌어야 하므로, 소스 범위를 구분해 두거나 각자 고유한 내부 주소를 주세요.

내부 주소 할당을 인증된 클라이언트에 묶으세요. 그 주소를 다른 장치에 넘기면 출구 정책도 함께 넘어가며, 소스 변환만으로는 신원 증명이 되지 않습니다.

변환은 주소를 만들어낼 수 없습니다

각 공인 주소는 이 출구 지점에 할당되거나 이쪽으로 라우팅되어야 하고, 응답은 다시 돌아올 길을 찾아야 합니다. 아무도 되돌려 라우팅하지 않는 주소에서 트래픽을 보내는 규칙은 먼 쪽에서 버려지거나 요청한 적 없는 호스트로 응답됩니다. 클라우드 공급자 인스턴스는 보통 패킷이 나가기 전에 공인 주소를 사설 인터페이스 주소로 변환하므로, SNAT 소스는 공급자가 받아들일 주소여야 하고 콘솔에 보이는 값이 아닙니다. 공급자의 주소 모델을 읽고, 공인 값을 모든 패킷에 복사하는 대신 그것을 따르세요.

실제로는 방화벽을 건드리기 전에 공급자 콘솔에서 라우팅된 프리픽스를 확인하고, 매핑이 일대일이면 사설 인터페이스 주소를 변환 소스로 쓰는 것입니다. 아래 예시의 주소는 문서용 대역에서 가져온 것이므로 가장 먼저 바꿀 것은 주소 텍스트 자체입니다.

일반 masquerade 앞에 삽입

무엇이든 추가하기 전에 출구 인터페이스와 현재 체인을 확인하세요. 전자는 규칙이 어떤 패킷과 일치할 수 있는지 정하고, 후자는 그 앞에 이미 무엇이 서 있는지 보여 줍니다.

ip -4 route show default
iptables -t nat -L POSTROUTING -n -v --line-numbers

첫 명령은 인터넷으로 가는 패킷이 실제로 나가는 인터페이스를 알려 줍니다. 두 번째는 줄 번호와 함께 체인을 출력합니다. 일반 masquerade 항목이 그 위에 있어야 할 줄입니다.

iptables -t nat -I POSTROUTING 1 -s 10.88.4.20/32 -o ens3 -j SNAT --to-source 198.51.100.77
iptables -t nat -I POSTROUTING 1 -s 10.88.4.21/32 -o ens3 -j SNAT --to-source 198.51.100.78

위의 두 규칙은 각각 하나의 내부 주소와 일치하고, 일치를 출구 인터페이스로 제한하며, 소스를 명시적으로 설정합니다. 추가가 아니라 삽입하면 위치 1에서 masquerade 줄보다 먼저 평가되며, 둘 사이의 순서는 소스가 다르므로 상관없습니다. ens3는 route 명령이 보고한 값으로 바꾸세요. 두 도구가 한 테이블을 쓰는 것이 올바른 규칙이 효과가 없는 흔한 이유이므로, 다른 방화벽 관리자를 같은 훅에서 떼어 두세요.

새 흐름으로 소스를 증명하세요

상태 기반 NAT는 흐름이 시작될 때 변환을 묶고 이후 패킷에 재사용하므로, 변경 전에 열린 세션은 변경 후에도 옛 소스를 유지합니다. 새로 시작한 연결만이 규칙을 증명합니다.

conntrack -L -s 10.88.4.20 -p tcp --dport 443

그 항목의 응답 방향을 읽으세요. 목적지가 원격 끝점이 소스로 보는 주소이므로, 의도한 공인 주소와 비교하고, 옛 주소를 담은 항목은 고장 난 규칙이 아니라 너무 일찍 시작된 흐름의 증거로 보세요. 클라이언트에 새 연결을 열게 한 다음 질의를 반복하세요. 테스트를 강제하려고 추적 테이블 전체를 비우면 게이트웨이의 다른 모든 세션이 중단됩니다.

변환은 여전히 경로를 고르지 않고, 필터를 통과시키지 않으며, 인바운드 서비스를 게시하지 않습니다. 잘못된 경로와 빠진 허용 규칙은 완벽한 SNAT 규칙 뒤에도 계속 실패합니다. IPv6와 모든 보조 출구 경로도 확인한 뒤, 다음 변경이 규칙 문구가 아니라 매핑에서 시작하도록 내부-공인 쌍을 방화벽 문서에 적어 두세요.

관련 글