Tailscale은 무엇인가: 내 기기들만의 사설망을 5분 만에
TL;DR
- Tailscale은 내 기기들을 하나의 사설망(tailnet)으로 묶어 준다. 어디에 있든 기기끼리 사설 IP로 바로 통신한다.
- 공유기 설정도, VPN 서버도 필요 없다. 로그인만 하면 된다.
- serve는 tailnet 안에만, Funnel은 인터넷에 서비스를 연다. Funnel은 열 경로를 최소한으로 좁혀서 쓴다.
들어가며
집에 서버를 하나 두면 바로 이런 고민이 생긴다. "밖에서 이 서버에 SSH로 들어가려면? 관리 화면은 나만 보고 싶은데?"
전통적인 답은 공유기 포트 포워딩이나 직접 VPN 서버를 세우는 것이다. 둘 다 번거롭고, 잘못 설정하면 위험하다. Tailscale은 이 문제를 "로그인하면 끝" 수준으로 줄여 준다.
1. Tailscale이 하는 일
Tailscale을 기기마다 설치하고 같은 계정으로 로그인하면, 그 기기들은 tailnet이라는 사설망에 들어간다.
[내 Mac] ─────┐
├── tailnet (100.x.y.z 대역의 사설 IP)
[내 휴대폰] ────┤
│
[집 서버] ────┘- 각 기기는
100.x.y.z형태의 고정 사설 IP를 받는다. 카페 와이파이에 있든 LTE에 있든 그대로다. - 기기끼리 직접 연결(peer-to-peer)한다. 중앙 서버를 거치지 않아서 빠르다. 직접 연결이 안 되는 네트워크에서는 Tailscale의 중계 서버(DERP)를 거친다.
- 통신은 WireGuard로 암호화된다. WireGuard는 코드가 짧고 빠른 최신 VPN 프로토콜이다.
왜 포트를 안 열어도 되나
공유기 뒤에 있는 기기들은 바깥에서 먼저 들어오는 연결을 받을 수 없다. Tailscale은 양쪽 기기가 동시에 바깥으로 연결을 시도하게 해서 공유기의 NAT를 통과한다(NAT traversal). 그래서 포트 포워딩 없이도 기기끼리 만날 수 있다.
2. 자주 쓰는 기능
MagicDNS
IP 대신 기기 이름으로 접속할 수 있다. ssh my-server처럼 쓰면 된다. tailnet 안에서만 풀리는 이름이다.
ACL (접근 제어)
tailnet 안에서도 "어떤 기기가 어떤 기기의 어느 포트에 접속할 수 있나"를 JSON으로 정할 수 있다. 예를 들어 "CI용 임시 노드는 서버의 SSH에만 접속 가능"처럼 좁힐 수 있다.
serve: tailnet 안에서만 HTTPS로
서버에서 돌고 있는 웹 앱을 tailnet 안에서만 HTTPS 주소로 열어 준다.
tailscale serve --bg 8080
# → https://my-server.<tailnet 이름>.ts.net 으로 접속 가능 (tailnet 안에서만)인증서도 Tailscale이 알아서 발급한다. 관리 화면처럼 나만 보면 되는 서비스에 딱 맞다. 인터넷에서는 아예 보이지 않으니 로그인 화면이 공격받을 일도 없다.
Funnel: 인터넷에 공개
Funnel은 serve로 연 서비스를 인터넷 전체에 공개한다. 외부 서비스가 내 서버의 파일을 가져가야 할 때(예: 소셜 API가 이미지 URL을 직접 내려받는 경우) 쓸 수 있다.
Funnel은 편한 만큼 조심해서 쓴다.
- 경로 단위로 좁게 연다. 서비스 전체가 아니라 꼭 필요한 경로만 연다.
- 앱에서도 한 번 더 막는다. Funnel로 들어온 요청에는 Tailscale이 표시 헤더를 붙여 준다. 앱이 이 헤더를 보고 허용한 경로가 아니면 거절하면, 설정 실수가 있어도 나머지가 드러나지 않는다.
- 오래 열어 두지 않는다. 필요한 순간에만 쓰는 주소라면 일회용 토큰과 함께 쓴다.
3. CI에서 tailnet에 들어가기
GitHub Actions 같은 CI가 집 서버에 배포하려면, CI 러너가 서버에 닿아야 한다. 서버 포트를 인터넷에 여는 대신 CI 러너를 잠깐 tailnet에 넣는 방법이 있다.
- name: Connect to Tailscale
uses: tailscale/github-action@v3
with:
authkey: ${{ secrets.TS_AUTHKEY }} # 임시(ephemeral) 키- 임시(ephemeral) 키를 쓰면 작업이 끝난 러너는 tailnet에서 자동으로 사라진다.
- 키에 태그를 붙이고 ACL로 그 태그가 닿을 수 있는 곳을 좁혀 두면, 키가 새도 할 수 있는 일이 제한된다.
- 서버의 SSH는 tailnet 안에서만 열려 있으면 된다.
4. Cloudflare Tunnel과 무엇이 다른가
둘 다 "포트를 열지 않고 집 서버에 닿게" 해 주지만 목적이 다르다.
| Tailscale | Cloudflare Tunnel | |
|---|---|---|
| 기본 대상 | 나와 내 기기 | 인터넷의 방문자 |
| 잘 맞는 일 | SSH, 관리 화면, 기기 간 통신, CI 배포 | 공개 웹 서비스 |
| 공개 범위 | 기본은 비공개, Funnel로 일부만 공개 | 기본이 공개, Access로 제한 가능 |
| 도메인 | tailnet 전용 주소 | 내 도메인 |
그래서 둘을 같이 쓰는 경우가 많다. 방문자가 쓰는 서비스는 Cloudflare Tunnel로, 나만 쓰는 통로는 Tailscale로 나누는 식이다. 실제로 어떻게 나눴는지는 개인 프로젝트 인프라 설계에 정리했다.
정리
- Tailscale은 로그인만으로 만드는 개인 사설망이다.
- serve는 나만, Funnel은 모두에게. Funnel은 좁게, 짧게, 두 겹으로.
- CI는 임시 키로 잠깐 tailnet에 들어왔다 나간다.
무료 플랜으로 개인 기기 수십 대까지 쓸 수 있어서, 집 서버를 하나라도 운영한다면 가장 먼저 깔아 둘 만한 도구다.