Tailscale은 WireGuard 위에 만든 메시 VPN(mesh Virtual Private Network)으로, 내 기기들을 하나의 사설망(tailnet)으로 묶는다. tailscale serve는 내 기기의 로컬 서비스를 tailnet 안에서만 HTTPS로 열어 주고, tailscale funnel은 같은 서비스를 공개 인터넷에 연다.
왜 쓰나
집이나 노트북에서 도는 서비스를 휴대폰에서 쓰고 싶을 때, 포트 포워딩(port forwarding)이나 공개 터널 없이 내 기기끼리만 닿게 할 수 있다. 공유기 설정도, 공인 IP(public IP address)도 필요 없다.
- MagicDNS: 기기마다
<기기>.<tailnet>.ts.net같은 이름이 붙는다(DNS와 CNAME, hosts 파일을 손댈 필요가 없다) - Serve: 로컬 포트 앞에 TLS(Transport Layer Security)를 붙여 tailnet 안에
https://로 노출한다. 인증서는 Tailscale이 발급·갱신한다 - Funnel: Serve와 같은 방식이지만 tailnet 밖 누구나 접근할 수 있다. 인증이 없는 서비스라면 쓰지 않는다
tailscale serve --bg 8080 # 로컬 8080을 tailnet 안에 HTTPS로
tailscale serve status
tailscale serve --https=443 off # 끄기wss가 필요한 이유
HTTPS로 연 웹 페이지는 평문 ws:// 연결을 혼합 콘텐츠(mixed content)로 막는다. 그래서 WebSocket 서버를 브라우저에서 쓰려면 Serve로 TLS를 붙여 wss://로 접속한다. 네이티브 앱은 이 제약이 없어 평문 연결도 열 수 있지만, 그만큼 보안을 직접 챙겨야 한다.
주의
- tailnet 안이라도 서비스 자체 인증(토큰 등)은 따로 둔다. 접근 제어(ACL)를 좁히지 않았다면 기기 하나가 털렸을 때 tailnet의 다른 서비스에도 닿을 수 있다
- Serve와 Funnel을 헷갈리지 않는다. 공개가 필요 없으면 Funnel은 끈 채로 둔다
- 같은 문제를 Cloudflare Tunnel 같은 공개 터널로도 풀 수 있는데, 그쪽은 기본이 공개라 접근 제어를 별도로 건다
상주 프로세스를 띄우는 쪽은 macOS launchd로 상주 프로세스 띄우기, 출처가 다른 요청을 브라우저가 어떻게 다루는지는 동일 출처 정책를 본다.