라우터 VPN은 작동하지만 LAN 클라이언트에는 인터넷이 없다
라우터는 자체 터널을 통해 인터넷에 도달하지만 그 뒤의 장치는 그렇지 않다. 포워딩, 변환, 반환 경로는 각각 별도의 권한이다.
상태 표시는 터널이 올라와 있다고 하고, 라우터 자체의 브라우저는 페이지를 불러오지만, 그 뒤의 모든 장치는 여전히 시간 초과가 난다. 이 조합은 대부분의 VPN 안내서가 언급하지 않는 계층으로 문제를 좁힌다. 즉, 터널을 통과해야 할 패킷을 가진 호스트는 라우터뿐이 아니다. 로컬에서 생성된 트래픽과 전달되는 트래픽은 같은 상자 안에서 서로 다른 경로를 탄다. 클라이언트에서 시험해 보면 그 차이는 이론이 아니게 된다.
LAN 호스트에서 장애를 읽는다
실패하는 장치에서 시작하라. 라우터에서 진단을 돌리면 다른 질문에 답하기 때문이다. 클라이언트의 기본 게이트웨이가 이 라우터인지 확인하고, 소스 주소와 서브넷을 기록한 다음, 라우터의 터널 인터페이스에서 무엇이 나가는지 살펴보라.
클라이언트 주소가 변환되면 원격 측은 터널 주소를 보게 되고, 그쪽에서는 모든 것이 정상으로 보이지만 클라이언트는 여전히 실패한다. 변환되지 않으면 원격 측은 클라이언트 서브넷으로 돌아가는 경로를 알아야 하며, 많은 게이트웨이에는 기본적으로 그런 경로가 없다. 어느 쪽이든 라우터 자체의 성공은 무관하다. 그 패킷은 로컬에서 생성되어 전달 경로를 한 번도 지나지 않았기 때문이다.
로컬 트래픽과 전달 트래픽은 다르다
Linux와 대부분의 라우터 펌웨어는 상자 자체가 생성한 패킷을 상자를 통과하는 패킷과 다르게 처리한다. 출력 체인은 전자를 보고, 포워드 체인은 후자를 본다. 그리고 라우터 자체 트래픽에 맞춘 정책은 포워딩을 그대로 둘 수 있다.
sysctl net.ipv4.ip_forward
ip -4 address show br-lan
ip route get 203.0.113.9
nft list ruleset | grep -A 6 'chain forward'
포워딩이 아예 활성화되어 있는지 확인한 다음, 출력 체인이 아니라 포워드 체인을 읽어라. 암호화된 외부 연결을 허용하는 규칙은 복호화된 패킷의 전달을 허용하는 규칙이 아니며, 둘을 혼동하면 정확히 이 증상이 생긴다. 터널이 올라와 있다는 것은 첫 번째만 증명한다.
반환 경로도 존재해야 한다
소스 변환은 반환 경로가 필요한지를 결정한다. 터널 인터페이스에 마스커레이딩이 있으면 응답은 터널 주소로 돌아오고 라우터가 이를 다시 변환한다. 없으면 원격 게이트웨이에 클라이언트 서브넷으로 가는 명시적 경로가 필요하고, 그 자체 정책도 그 방향을 허용해야 한다.
무엇이든 바꾸기 전에 배포가 두 설계 중 어느 것을 쓰는지 기록하라. 수정 방향이 서로 반대이기 때문이다. 변환을 추가하면 빠진 반환 경로가 가려지고 원래 소스 주소가 필요한 애플리케이션이 깨진다. 변환 없이 반환 경로를 추가하면 원격 방화벽이 낯선 소스를 버릴 때 조용히 실패한다. 하나를 고르고 문서화한 뒤 다른 쪽을 맞춰라.
클라이언트 DNS도 같은 검토에 속한다. 라우터의 리졸버는 응답할 수 있지만 다른 서버를 가리키는 클라이언트는 아무것도 받지 못한다.
허용된 흐름 하나와 거부된 흐름 하나를 검증한다
수정 후에는 기존 라우터 세션이 아니라 클라이언트에서 새 연결을 시험하라. 그런 다음 터널을 쓰지 말아야 할 세그먼트가 여전히 쓰지 않는지 확인하라.
curl -sS --max-time 8 https://api.ipify.org
ip route get 203.0.113.9
dig +short intranet.example.net
원격 끝에서 관찰된 소스 주소를 확인하라. 어느 설계가 실제로 돌아가는지 알려 주기 때문이다. 주소와 함께 이름 조회도 검증하라. 리졸버 동작은 같은 상자를 지나는 별도의 경로이기 때문이다.
규칙은 터널이 필요한 클라이언트 네트워크로 범위를 좁혀 유지하고, 시험 하나를 통과시키려고 포워딩 필터를 끄지 말라. 그 변경은 시험을 고치지만 터널이 제공해야 했던 경계를 없앤다. 소스 주소, 변환 결정, 반환 경로를 날짜와 함께 한 메모에 적어라.