클라이언트가 게이트웨이 주소로 ping을 보낼 수 있어도 그 뒤의 모든 리소스는 도달 불가능한 채로 남는다. 이 두 관찰은 당신과 대화하는 호스트와 라우팅하지 않는 라우터를 설명하며, 이는 같은 장비 위의 서로 다른 역할이다. 포워딩은 그 사이의 스위치다.

두 역할은 독립적이며, 두 주소 패밀리도 마찬가지다.

자기 주소에 응답하는 것은 아무것도 증명하지 않는다

패킷이 게이트웨이 자신에게 지정되면 로컬 스택이 이를 소비하고 포워딩 결정은 일어나지 않는다. 그래서 터널 주소나 관리 인터페이스로의 성공적인 ping은 데몬이 살아 있고 터널이 올라와 있음을 알려 주지만, 상자 뒤 네트워크로 향하는 트래픽에 대해서는 아무것도 말하지 않는다. 커널은 자신에게 지정되지 않은 패킷에 대해서만 포워딩 경로를 참조한다.

요구 사항을 설정이 아니라 역할로 읽어라. 이 호스트는 두 인터페이스 사이에서 패킷을 옮겨야 한다. 원격 네트워크에 도달하기만 하면 되는 노트북은 그 역할을 절대 맡지 않고, 사이트 간 엔드포인트는 항상 맡는다. 그렇게 읽으면 작동하던 클라이언트 구성이 게이트웨이로 옮겼을 때 실패하는 이유가 설명된다.

같은 문장이 무엇을 포워딩해도 되는지에 대한 자체 정책을 가진, 포워딩 결정 앞의 방화벽에도 적용된다.

주소 패밀리별로 따로 확인하라

IPv4 포워딩은 하나의 스위치이고, IPv6 포워딩은 인터페이스별 동작을 가진 또 다른 스위치다. 첫째를 켜는 것은 둘째에 대해 아무것도 말하지 않으며, 이중 스택 클라이언트는 네트워크의 절반에 도달하면서 나머지는 어두운 채로 남을 수 있다. 따라서 서로 다른 패밀리의 두 클라이언트가 같은 게이트웨이에 대해 의견이 다를 수 있다. 어느 설정이든 편집하기 전에 실패한 클라이언트가 어느 패밀리를 썼는지 물어라. 라우팅 설계가 틀렸다고 결론 내리기 전에 둘 다 확인하라.

sysctl net.ipv4.ip_forward
sysctl -a --pattern 'net.ipv6.conf.(all|default).forwarding'
nft list ruleset | head -n 40

많은 배포판에서 런타임에 읽는 값은 서비스나 구성 파일이 넣어 둔 것이므로, 일회성 명령으로 한 변경은 재부팅 시 사라질 수 있다. 런타임 값을 편집하기 전에 그 설정을 소유한 파일을 찾아라.

포워딩은 네 가지 요구 사항 중 하나다

작동하는 포워딩 흐름에는 동시에 네 가지가 필요하다. 클라이언트는 목적지가 터널 뒤에 있음을 알아야 하고, 게이트웨이는 앞으로 갈 경로가 있어야 하며, 응답에는 되돌아올 경로가 있어야 하고, 방화벽은 트래픽을 허용해야 한다. 소스 변환은 규칙이 아니라 선택으로 그 설계에 속한다. 대칭 경로를 가진 사설 라우팅 네트워크에는 필요 없고 비대칭 네트워크에는 보통 필요하기 때문이다. 네 가지는 각각 독립적으로 실패하므로 하나를 고쳐도 증상이 거의 움직이지 않는다. 어느 하나를 바꾸기 전에 네 가지를 모두 적어라.

클라우드 플랫폼은 다섯 번째 고려 사항을 더한다. 일부는 인스턴스에 소스 및 목적지 검사를 강제하며, 이는 게스트 커널이 어떻게 구성되었든 포워딩된 패킷을 버린다. 그곳의 권위는 플랫폼 자체의 네트워킹 문서이지 VM 내부의 sysctl 출력이 아니다.

게이트웨이가 아니라 클라이언트에서 시험하라

게이트웨이 자체의 셸에서 실행한 시험은 방금 활성화한 포워딩 경로를 전혀 지나지 않는다. 문제가 있는 클라이언트에서 트래픽을 만들어 게이트웨이 자체가 아니라 그 뒤의 무언가에 도달하는지 확인하라. 변경한 역할을 실제로 시험하는 유일한 방법이다.

리스너 규칙과 포워딩 규칙을 머릿속에서도 변경 기록에서도 분리해 두라. VPN 포트를 여는 것은 클라이언트를 서비스로 받아들이는 일이다. 그 뒤 네트워크에서는 아무것도 주지 않으며, 수년에 걸쳐 자란 방화벽 목록에서는 둘이 똑같아 보인다.

패킷이 도착했는데 서비스가 사용자를 거부한다면 네트워킹을 넘어선 것이다. 포워딩 정책을 다시 넓히는 대신 애플리케이션 인가로 넘어가라.

관련 글