관리 콘솔의 승인은 마지막 단계처럼 보이지만 그렇지 않습니다. 먼저 애플리케이션이 시간 초과되고, 그 뒤에야 라우터가 온라인이고 경로가 승인되었음을 알게 됩니다. 승인은 배포 단계이며, 권한도 아니고 전달 보장도 아닙니다. 패킷이 서브넷 라우터 뒤의 호스트에 도달하려면 네 단계가 맞아야 하며, 각 단계는 다음 단계가 실패하는 동안에도 성공할 수 있습니다. 순서대로 진행하고 지탱되지 않는 첫 단계에서 멈추세요.

네 단계, 하나의 실패

라우터가 프리픽스를 알리고, tailnet이 그 알림을 승인하며, 클라이언트가 받은 경로를 수락하고, 액세스 정책이 특정 연결을 허용합니다. 이는 서로 다른 세 구성 요소가 내리는 네 가지 별개의 결정입니다. 따라서 승인된 경로는 네트워크가 이제 tailnet 라우팅 테이블의 일부라는 것만 의미합니다.

처음 세 단계가 눈에 보이는 상태를 만들기 때문에 네 번째 단계가 가장 자주 빠집니다. 라우터 자체의 tailnet 주소를 포함하는 권한이 그 뒤의 사설 서브넷을 자동으로 포함하지는 않습니다. 서로 다른 대상이며, 정책은 대상별로 평가됩니다.

Linux에서는 세 번째 단계에 사람들을 놀라게 하는 기본값도 있습니다: 서브넷 경로 수락은 선택 사항입니다. 여러 GUI 클라이언트는 알림된 경로를 기본으로 수락하므로, 혼합된 플릿에서 한 머신만 실패하고 나머지는 동작하는 것처럼 보일 수 있습니다.

플랫폼을 가정하지 말고 실패하는 머신에서 설정을 확인하세요. 동작하는 머신에서는 경로가 빠진 조각이었던 적이 없으니, tailnet 쪽이 건강하다는 것을 그 머신들이 증명하게 하세요. Tailscale의 서브넷 라우터 문서는 승인, 클라이언트의 경로 수락, 정책 단계를 다룹니다.

클라이언트가 실행되는 곳에서 경로를 확인하세요

라우터가 아니라 실패하는 클라이언트에서 시작하세요. 경로가 존재하는지, 클라이언트 설정이 경로 수락을 허용하는지 확인하세요.

tailscale status
tailscale debug prefs | grep -i route
ip route get 10.20.0.42

첫 번째 명령은 피어 목록과 서브넷 라우터에 도달할 수 있는지를 보여 주고, 두 번째는 경로 수락 플래그를 포함한 클라이언트 기본 설정을 출력하며, 세 번째는 서브넷의 실제 호스트에 어떤 인터페이스를 쓸지 커널에 묻습니다. 마지막 명령이 Tailscale 인터페이스 대신 물리 인터페이스를 언급한다면 경로가 테이블에 들어가지 않은 것입니다. 경로 누락은 클라이언트 측 문제이며 승인 문제가 아닙니다. 정책을 보기 전에 그것을 고치세요.

Linux에서 경로를 수락하려면 플래그가 설정되어 있다고 가정하지 말고 그 플래그로 다시 연결하세요: tailscale up --accept-routes. 다른 플래그로 가입한 클라이언트는 변경할 때까지 그 플래그를 유지하므로, 다른 플래그를 추가하기 전에 현재 설정을 확인하세요. 변경 후 첫 번째 명령을 다시 실행하면 테이블에 경로가 표시되어야 합니다.

전달과 반환 경로를 증명하세요

승인은 라우터가 패킷을 전달하도록 구성하지 않으며 응답을 마련하지도 않습니다. 둘 다 라우터의 LAN 쪽 호스트 수준 문제입니다. 클라이언트가 아니라 라우터에서 시험하세요.

sysctl net.ipv4.ip_forward
iptables -t nat -L POSTROUTING -n -v
tcpdump -ni any host 10.20.0.42 and port 443

첫 번째 명령은 1을 보고해야 하며, 그렇지 않으면 커널이 전달된 패킷을 버립니다. 두 번째는 서브넷 경로 매스커레이딩이 출발지를 다시 쓰는지 보여 주며, 이는 기본 동작이고 보통 원하는 것입니다. 세 번째는 요청이 대상에 도달하는지 무언가 돌아오는지 보여 주며, 응답이 없는 요청은 반환 경로 문제이고 승인 문제가 아닙니다. 이들 중 무엇이든 바꾸기 전에 세 결과를 함께 읽으세요.

매스커레이딩이 비활성화되어 있다면 대상 네트워크에는 tailnet 주소로 돌아가는 경로가 필요하고, 중간의 모든 홉이 그것을 알아야 합니다. 매스커레이딩을 다시 켜는 것이 단일 서비스에 가장 빠른 수정이지만, 원래 클라이언트 주소가 대상에서 가려진다는 대가가 있습니다. 대상이 감사를 위해 출발지 주소를 기록할 때 이 맞바꿈이 중요하므로, 사고 중에 플래그를 뒤집는 대신 의도적으로 결정하세요. 다음 사람은 두 동작 중 하나만 보게 되므로 어떤 선택을 했는지 문서화하세요.

리소스에 대한 액세스 규칙을 읽으세요

경로가 있고 전달이 증명되었다면 남은 용의자는 정책입니다. 연결을 허용해야 하는 권한을 읽고 출발지만이 아니라 대상을 확인하세요. 클라이언트 자체의 ID도 정책 선택자와 일치해야 하므로 실패하는 같은 머신에서 확인하세요.

tailscale status --json | head -40
tailscale ping <router-name-or-tailnet-ip>
ping -c 3 10.20.0.42

상태 출력은 클라이언트 자체 주소와 그것이 보는 피어를 식별하며, 정책 출발지 선택자는 이와 일치해야 합니다. tailscale ping는 서브넷 라우터 자체까지의 tailnet 경로를 증명하며, 해석하는 것은 피어 이름과 tailnet 주소이고 알림된 서브넷 내부의 호스트가 아닙니다. 세 번째 명령은 서브넷 경로를 통해 일반 ICMP 에코를 보내므로 결과는 라우터가 아니라 대상을 설명합니다. tailnet 수준의 거부는 보통 거부로 돌아오고, 나갔다가 돌아오지 않는 패킷은 시간 초과됩니다.

실패하는 이름은 실패하는 주소와 다른 질문이므로, 경로를 탓하기 전에 호스트를 직접 해석하세요. 권한은 서브넷 전체가 아니라 실제 리소스 요구에 맞춰 작성하세요. 하나의 애플리케이션을 위해 /24 전체를 여는 것이 좁은 요청이 나중에 아무도 제거하지 못하는 넓은 권한이 되는 길입니다.

목표가 사설 서브넷이 아니라 인터넷 송신이었다면, 올바른 구성 요소는 서브넷 라우터가 아니라 출구 노드이고, 정책과 라우팅도 그에 따라 다릅니다. 권한을 넓히기 전에 그 결정을 확인하세요. 출구 노드는 기본 경로를 바꾸지만, 서브넷 라우터는 프리픽스를 알릴 뿐입니다.

관련 글