Tailscale 서브넷 SNAT를 비활성화한 뒤의 단방향 트래픽
Tailscale 서브넷 라우터에서 SNAT를 끄면 응답이 더 이상 도착하지 않습니다. 실제 원본 주소는 유지되므로 LAN에는 100.64.0.0/10으로 돌아가는 경로가 필요합니다.
Tailscale 서브넷 라우터에서 원본 NAT를 끄면 터널은 계속 작동하지만 그 안을 지나는 연결은 멈춥니다. 요청은 원격 클라이언트 자신의 오버레이 주소를 지닌 채 목적지에 도착하며, 이것이 바로 이 변경의 요점이고, 응답에는 이제 LAN이 알 필요가 없었던 경로가 필요합니다. 그 경로가 없으면 패킷은 도착하지만 응답은 일반 게이트웨이로 나가고, 장애는 어떤 방화벽 규칙으로도 설명되지 않는 방화벽 문제처럼 보입니다. 터널은 건강하고, 돌아오는 구간만 빠져 있습니다.
SNAT이 가리던 것
SNAT이 켜져 있으면 라우터는 서브넷으로 전달하기 전에 원본 주소를 자신의 LAN 주소로 다시 쓰므로, 목적지는 이미 도달 방법을 아는 호스트로 응답하고 다른 것은 구성할 필요가 없습니다. 이를 끄면 원래 원본이 유지되고, 목적지는 자신의 회선 위 이웃이 아니라 오버레이 범위 안의 주소를 보게 됩니다. 그 주소는 실제이며 tailnet 전체에서 라우팅할 수 있지만, LAN에서는 기본 게이트웨이를 통해 도달할 수 없습니다. 문서화된 스위치는 --snat-subnet-routes=false이며 Linux 서브넷 라우터 자체에 적용됩니다.
이것은 패킷별 토글이 아니라 상시 설정이므로, 그 라우터가 서비스하는 모든 목적지 네트워크에 반환 경로가 있어야 합니다. 그래서 이 변경은 체크박스가 아니라 배포 결정이 됩니다. 그 라우터가 서비스하는 모든 것은 같은 순간에 이 요구 사항을 물려받습니다.
반환 경로가 있을 수 있는 곳
세 가지 배치가 흔하며, 차이는 정확성이 아니라 도달 범위에 있습니다. 목적지 호스트의 정적 경로는 가장 직접적이고 가장 확장성이 낮으며, 모든 장치가 자기 사본을 필요로 합니다. VPC나 사이트 라우터의 경로 테이블은 네트워크 전체를 한 번에 덮고, 클래스 없는 정적 경로를 실은 DHCP 옵션은 클라이언트에 자동으로 도달하지만 이를 무시하는 장치에서는 조용히 실패합니다.
ip route add 100.64.0.0/10 via 192.168.1.10
ip route get 100.64.0.5
어떤 배치를 택하든 다음 홉은 라우터의 LAN 주소이며 결코 tailnet 주소가 아닙니다. LAN 호스트는 이 경로가 없으면 오버레이에 도달할 수 없으므로, 오버레이 내부를 다음 홉으로 삼으면 순환하여 패킷이 어디에도 가지 않습니다. 이 한 가지 실수가 올바르게 보이면서도 실패하는 대부분의 구성을 설명하며, 라우터 자체의 테이블만 읽는 모든 점검을 통과합니다. 다음 사람이 틀린 쪽을 시험하지 않도록 어떤 배치를 썼는지 적어 두십시오.
장애를 단방향 트래픽으로 읽기
증상은 원인보다 알아보기 쉬운데, 서비스는 라우터 자체에서는 응답하지만 원격 클라이언트에서는 침묵합니다. 목적지에서 캡처하면 요청이 들어오고 응답이 나가는 것이 보이며, 그 응답이 어디로 가는지 알아차리기 전까지는 성공처럼 보입니다. 응답은 기본 게이트웨이로 향하며, 이는 들어오는 구간은 작동했고 돌아오는 구간은 그렇지 않았다는 뜻입니다.
한 번의 교환에서 양방향을 보고 응답이 애초에 도착했는지 보여 주는 라우터에서 대신 캡처하십시오. 응답이 목적지에는 나타나지만 라우터에는 결코 나타나지 않는다면 목적지 쪽 경로가 없거나 틀린 것입니다. 라우터에 나타나 거기서 멈춘다면 문제는 더 앞에 있으며 다른 조사에 속합니다.
sudo tcpdump -ni any host 100.64.0.5
ip route get 100.64.0.5
실제 주소가 경로를 받을 가치가 있는가
목적지 네트워크를 다시 구성할 수 없을 때마다 SNAT을 유지하는 것이 더 간단한 답으로 남고, 대가는 모든 클라이언트가 목적지의 로그와 정책에서 라우터처럼 보인다는 것입니다. 애플리케이션이 실제 원본 주소를 필요로 하거나 네트워크 정책이 같은 라우터를 공유하는 클라이언트를 구분해야 할 때 끄는 것이 정당합니다. 둘 다 정당한 이유이며 어느 것도 무료가 아닙니다. 이점은 모든 목적지 네트워크에서 경로를 유지하는 수고와 아래에 설명된 방화벽 검토를 감수할 만해야 합니다.
작은 LAN 하나에는 이 교환이 대개 이득이지만, 정적 경로를 받아들일 수 없는 기기들이 널려 있는 경우에는 대개 이득이 아닙니다. 결정과 이유를 라우터 구성 옆에 기록하여 다음 관리자가 어떤 동작이 의도된 것인지 알게 하십시오. 아무도 적지 않은 기본값은 실수와 구별되지 않습니다.
방화벽, 로깅, 이중 역할
라우터의 LAN 주소와 일치하던 모든 규칙이 이제 다른 원본과 일치하며, 여기에는 허용 규칙과 라우터를 클라이언트로 기록하던 모든 로그 필드가 포함됩니다. 라우터 주소만 허용하는 규칙은 새 원본을 완전히 차단하므로 첫 실패 후가 아니라 첫 시험 전에 그 규칙들을 읽으십시오. 교체 범위를 필요한 클라이언트와 포트로 좁힌 뒤, tailnet 전체를 조용히 허용하지 않는지 확인하십시오.
sudo nft list ruleset | grep -n '100\.64'
sudo iptables-save | grep -n '100\.64'
한 노드가 출구 노드와 서브넷 라우터를 겸하는 것은 문서화된 조합이며, 서브넷 SNAT을 비활성화하면 업스트림 트래픽을 떨어뜨릴 수 있습니다. 그 역할을 서로 다른 노드로 분리하면 이 주의 사항이 사라지고 각 경로와 방화벽 정책에 소유자가 하나씩 생깁니다. 역할을 함께 유지해야 한다면 그 동작을 예상하고 클라이언트를 탓하기 전에 시험하십시오. 다음 연결이 실패할 때 함께 읽히므로 경로, 스위치 설정, 역할 할당을 한 메모에 보관하십시오.