Tailscale Funnel URL이 열리지 않을 때 backend와 공개 조건을 나누는 법

공개 URL보다 로컬 backend를 먼저 확인한다

Funnel URL이 timeout 또는 gateway 오류를 보일 때 외부 방화벽부터 열면 로컬 애플리케이션 장애를 놓칠 수 있습니다. Funnel은 로컬 service를 인터넷에 공개하는 계층이므로, 해당 node에서 backend가 같은 target으로 응답하는지가 첫 번째 경계입니다. backend가 죽어 있으면 Funnel 설정을 다시 만들어도 결과는 달라지지 않습니다.

Serve와 Funnel도 구분해야 합니다. Serve는 tailnet 내부 공유에 사용하고 Funnel은 인터넷 공개에 사용합니다. 둘의 status를 따로 기록하지 않으면 내부에서는 열리지만 외부에서는 닫힌 상태를 backend 문제로 오인할 수 있습니다.

외부 요청이 backend까지 가는 다섯 조건

경계확인 값실패 시 의미
로컬 servicetarget 주소의 응답과 listen addressFunnel 이전의 애플리케이션 문제입니다.
Tailscale node로그인 상태와 client versioncontrol plane 설정을 받지 못할 수 있습니다.
Funnel 구성status에 나온 target과 public URL이전 Serve/Funnel 구성이 남았을 수 있습니다.
tailnet 조건MagicDNS, HTTPS, funnel node attribute공개 조건이 충족되지 않았습니다.
public listener443, 8443, 10000 중 선택지원하지 않는 외부 port를 요청했습니다.
tailscale version
tailscale status
tailscale serve status
tailscale funnel status
curl -sS -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1:3000/health

마지막 경로는 실제 backend health endpoint에 맞게 바꿉니다. 127.0.0.1:3000에서 응답하지 않으면 먼저 service의 process, container port, listen address를 수정합니다. Funnel을 위해 backend를 LAN 전체에 공개할 필요는 없습니다.

Funnel 요구 조건을 설정과 대조한다

공식 문서는 Funnel에 Tailscale 1.38.3 이상, MagicDNS, tailnet HTTPS, funnel node attribute가 필요하다고 설명합니다. Funnel은 tailnet의 *.ts.net 이름만 사용하며 TLS 연결로 동작합니다. 공개 listener는 443, 8443, 10000으로 제한됩니다.

예전 명령을 그대로 복사한 경우 client 1.52 전후의 Serve/Funnel CLI 변경도 확인해야 합니다. 현재 설치된 client가 보여 주는 help와 공식 CLI 문서를 기준으로 target을 다시 구성합니다.

아래 세 명령은 조회입니다. status에는 공개 URL과 내부 target이 표시될 수 있으므로 원본을 공개 로그에 붙이지 않습니다.

tailscale funnel --help
tailscale serve status
tailscale funnel status

실제로 인터넷 공개를 의도하고, backend의 인증·데이터 범위와 기존 443 listener 충돌 여부를 확인한 경우에만 다음 변경 예를 사용합니다. 기존 Serve/Funnel URL·target·옵션을 private 기록으로 먼저 남깁니다. --bg는 같은 터미널에서 status를 이어 실행할 수 있게 하지만 종료·로그아웃 후에도 공개가 유지될 수 있으므로 명시적으로 끌 때까지 관리해야 합니다.

tailscale funnel --bg --https=443 http://127.0.0.1:3000
tailscale funnel status

--bg 없이 실행하면 포그라운드 명령이 터미널을 점유합니다. 다른 터미널에서 status를 조회하며, Ctrl+C로 해당 포그라운드 실행을 끝낼 수 있습니다. 개발 호스트 Tailscale 1.102.4의 help에서 --bg와 기본값 false를 확인했으며 인터넷 공개 자체는 시험하지 않았습니다.

증상별 다음 분기

  • 로컬 curl도 실패: Funnel을 건드리지 않고 backend service와 container 상태를 고칩니다.
  • 로컬은 성공하지만 Funnel status가 비어 있음: Funnel 구성이 저장되지 않았거나 Serve만 활성일 수 있습니다. 사용한 command와 권한 prompt 결과를 확인합니다.
  • status는 있으나 지원하지 않는 public port: 허용된 listener로 옮기고 backend port와 public port를 구분합니다. backend는 다른 port를 사용해도 됩니다.
  • tailnet 안에서는 열리고 인터넷에서는 실패: Serve와 Funnel 상태, funnel node attribute, HTTPS 조건을 다시 봅니다. 일반 ACL만 수정해 해결된다고 단정하지 않습니다.
  • 간헐적으로 느리거나 끊김: Funnel에는 비구성형 bandwidth 제한이 있습니다. backend latency와 Tailscale 경로를 함께 기록하되, 제한 값을 임의로 추정하지 않습니다.

검증과 되돌리기

수정 후에는 node 내부에서 backend를 먼저 확인하고, tailnet 외부 연결에서 public URL을 별도로 시험합니다. 같은 Wi-Fi의 Tailscale 연결 기기만 사용하면 인터넷 공개 경로를 실제로 시험하지 못할 수 있습니다. 응답 header와 시각을 남겨 local 응답과 비교합니다.

이번에 새로 켠 HTTPS 443 listener가 잘못된 target을 공개한다면 설치 CLI가 지원하는 tailscale funnel --https=443 off로 그 listener를 끄고 status를 다시 확인합니다. 기존 listener를 바꾼 경우에는 저장한 이전 target·옵션을 복원해야 하며 off만으로 원복이 끝나지 않습니다. reset은 전체 Funnel 설정을 지우는 더 넓은 작업이므로, 모든 공개를 중단해야 하는 경우에만 영향 범위를 확인하고 사용합니다. 다른 listener가 남아 있다면 status 전체가 비어야 한다고 판단하지 않습니다.

운영 기록에는 public URL, target, 변경 시각, local health 결과를 함께 남깁니다. 이 네 값이 있어야 다음 장애에서 인증서 문제와 backend 변경을 같은 사건으로 잘못 묶지 않을 수 있습니다.

공식 문서 및 확인 기준

이 글에 남아 있던 이전 검증 기록

검증 수준: 공식 문서 대조

Funnel 요구 조건과 현재 CLI 범위를 Tailscale 문서로 확인했습니다. 특정 tailnet의 public 경로는 재현하지 않았으므로 bandwidth나 중계 경로의 원인을 확정하지 않습니다.

작성 방식과 수정 정책 · 오류 제보