
Tailscale — 포트포워딩 없이 어디서든 내 인프라에 접속하기
홈랩을 운영하거나 원격 서버를 관리하다 보면 반드시 한 번쯤 마주치는 문제가 있습니다. 집 밖에서 집 안의 서버에 어떻게 접속할 것인가입니다.
흔히 사용하는 방법은 공유기 포트포워딩에 DDNS를 붙이거나, OpenVPN 서버를 직접 구성하는 식입니다. 기술적으로는 모두 잘 작동합니다. 다만 포트를 외부에 직접 노출하면 brute-force 공격에 취약하고, OpenVPN은 인증서 관리와 서버 유지 비용이 따라옵니다. WireGuard를 직접 구성하는 것도 좋은 선택이지만, 기기가 늘어날수록 피어 설정을 매번 손으로 관리해야 하는 번거로움이 있습니다.
Tailscale은 이 문제를 다른 방식으로 접근합니다. 각 기기에 클라이언트를 설치하고 같은 계정으로 로그인하면, 나머지는 알아서 처리됩니다.
Tailscale이란
Tailscale은 WireGuard 기반의 Mesh VPN 서비스입니다. 기기들을 하나의 가상 사설망으로 묶어주고, 각 기기에는 100.x.x.x 대역의 고정 IP를 자동으로 부여합니다. 포트포워딩도, 공인 IP도, 인증서도 필요하지 않습니다.
일반적인 VPN과 결정적으로 다른 점은 트래픽이 중앙 서버를 거치지 않는다는 것입니다. Tailscale의 서버는 키 교환과 정책 배포만 담당하고, 실제 데이터는 기기 간 직접 P2P로 전송됩니다.
왜 WireGuard인가
Tailscale의 기반이 되는 WireGuard는 기존 VPN 프로토콜들의 복잡성을 걷어내기 위해 설계된 프로토콜입니다. 전체 코드베이스가 약 4,000줄 수준으로, OpenVPN의 수십만 줄과 비교하면 감사(audit)와 유지 관리가 훨씬 수월합니다.
암호화 알고리즘을 협상하는 과정 자체가 없습니다. Curve25519, ChaCha20, Poly1305 등 검증된 알고리즘을 고정 사용하기 때문에, 협상 과정에서 발생하는 다운그레이드 공격이나 잘못된 설정으로 인한 취약점이 원천 차단됩니다.
Tailscale은 WireGuard 위에 NAT 통과, 자동 키 배포, 접근 제어 정책 등을 얹어서 WireGuard를 직접 운용할 때 손으로 해야 했던 부분들을 자동화합니다.
아키텍처
Tailscale의 설계에서 가장 중요한 개념은 Control Plane과 Data Plane의 분리입니다.
Control Plane (Hub-and-Spoke)
└─ Tailscale Coordination Server
└─ 역할: WireGuard 공개키 교환, 정책 배포
└─ 트래픽: 거의 없음 (키와 메타데이터만)
Data Plane (Mesh)
└─ Device A ←──── WireGuard 암호화 터널 ────→ Device B
└─ Device A ←──── WireGuard 암호화 터널 ────→ Device C
└─ 트래픽: 기기 간 직접 P2P
Control Plane은 Hub-and-Spoke 구조이지만, 실질적인 트래픽을 처리하지 않습니다. 소수의 공개키와 정책 정보만 오갑니다. 실제 데이터는 전부 기기 간 직접 암호화 터널로 전송됩니다.
덕분에 Tailscale의 Coordination Server가 일시적으로 중단되더라도, 이미 연결된 기기 간 통신은 끊어지지 않습니다. 새로운 기기를 추가하거나 정책을 변경하는 작업만 불가능해질 뿐입니다.
NAT Traversal
포트포워딩 없이 연결이 되는 이유가 여기 있습니다.
Tailscale은 STUN 서버를 활용해 각 기기의 공인 IP와 포트 매핑 정보를 수집합니다. Coordination Server가 이 정보를 양쪽에 전달하면, 두 기기가 동시에 서로의 엔드포인트로 UDP 패킷을 전송합니다. 양쪽 NAT 라우터가 아웃바운드 패킷을 보고 인바운드 허용 규칙을 자동 생성하는 이른바 UDP Hole Punching입니다.
이 방식은 약 94%의 NAT 환경에서 직접 연결에 성공합니다. Symmetric NAT나 기업 방화벽처럼 UDP Hole Punching이 막힌 나머지 6% 환경에서는 DERP(Designated Encrypted Relay for Packets) 서버로 자동 전환됩니다. DERP는 전 세계 20개 이상 도시에 배포된 릴레이 서버로, 암호화된 WireGuard 패킷만 중계합니다. 릴레이 서버 자체는 패킷 내용을 볼 수 없습니다.
사용자 입장에서는 이 과정이 완전히 투명하게 처리됩니다.
주요 기능
MagicDNS
Tailscale로 연결된 기기 집합을 Tailnet이라고 부릅니다. MagicDNS는 각 기기에 hostname.tailnet-name.ts.net 형태의 DNS 이름을 자동 부여하는 기능입니다. IP를 외울 필요 없이 호스트명으로 바로 접근할 수 있습니다.
ssh my-homelab
curl http://nas-box:8096
Subnet Router
Tailscale 클라이언트가 설치되지 않은 기기에도 접근이 필요한 경우 사용합니다. 내부망에서 게이트웨이 역할을 할 노드 하나에만 Tailscale을 설치하고, 해당 서브넷 전체를 Tailnet에 노출시킵니다.
# 서브넷 라우터 활성화
sudo tailscale up --advertise-routes=192.168.1.0/24
이후 Admin 콘솔에서 라우트를 승인하면, 다른 Tailscale 노드에서 192.168.1.x 대역 전체에 접근할 수 있습니다.
Tailscale SSH
SSH 키 없이 Tailscale 계정 인증만으로 SSH 접속을 허용하는 기능입니다. 여러 서버를 관리하거나 팀원에게 접근 권한을 부여할 때 키 배포와 관리 부담이 줄어듭니다.
# 노드에서 활성화
sudo tailscale up --ssh
# 접속
tailscale ssh user@my-server
ACL
어떤 기기 또는 사용자 그룹이 어떤 기기에 접근할 수 있는지를 정책으로 정의합니다. HuJSON 형식으로 작성하며, Admin 콘솔에서 관리합니다.
{
"groups": {
"group:dev": ["dev1@company.com", "dev2@company.com"],
"group:ops": ["admin@company.com"]
},
"acls": [
{
"action": "accept",
"src": ["group:ops"],
"dst": ["tag:server:*"]
},
{
"action": "accept",
"src": ["group:dev"],
"dst": ["tag:server:22", "tag:server:8080"]
}
]
}
설치
Linux
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
# 출력된 URL로 브라우저 인증
tailscale status
# 100.64.0.1 my-laptop user@ linux -
# 100.64.0.2 home-server user@ linux online
# 100.64.0.3 raspberry-pi user@ linux online
Docker Compose
services:
tailscale:
image: tailscale/tailscale:latest
hostname: my-node
environment:
- TS_AUTHKEY=tskey-auth-xxxxxxxxxx
- TS_STATE_DIR=/var/lib/tailscale
volumes:
- tailscale-state:/var/lib/tailscale
- /dev/net/tun:/dev/net/tun
cap_add:
- NET_ADMIN
- SYS_MODULE
restart: unless-stopped
volumes:
tailscale-state:
WireGuard 직접 구성과의 비교
WireGuard를 직접 구성하면 각 피어 쌍마다 수동으로 키를 교환하고 설정 파일을 작성해야 합니다. 기기가 N대일 때 완전히 연결하려면 설정 항목 수가 N²에 비례해 증가합니다. 기기 하나를 추가할 때마다 기존 모든 피어의 설정을 수정해야 합니다.
Tailscale은 이 과정을 전부 자동화합니다. 단, Coordination Server를 Tailscale 클라우드에 의존하게 됩니다.
항목 WireGuard 직접 구성 Tailscale
| 초기 설정 | 피어마다 수동 키 교환 | 설치 후 로그인 |
| 기기 추가 | 기존 피어 설정 전체 수정 | 새 기기에서 로그인만 |
| NAT 통과 | 수동 포트포워딩 | 자동 |
| 키 관리 | 직접 | 자동 |
| Control Plane 주권 | 완전 자체 보유 | Tailscale 클라우드 의존 |
Self-hosted: Headscale
Coordination Server까지 직접 운영하고 싶다면 오픈소스 대안인 Headscale을 사용할 수 있습니다. Tailscale 클라이언트는 그대로 사용하면서 Control Plane만 자체 서버로 교체하는 방식입니다.
docker run -d \
--name headscale \
-p 8080:8080 \
-v ./config:/etc/headscale \
headscale/headscale:latest serve
# 클라이언트에서 자체 서버 지정
sudo tailscale up --login-server=https://headscale.yourdomain.com
외부 서비스 의존도를 낮춰야 하는 기업 환경이나, 완전한 데이터 주권이 필요한 경우에 적합합니다.
요금
플랜 가격 노드 수 주요 기능
| Personal | 무료 | 100대 | MagicDNS, ACL, SSH, Subnet Router |
| Plus | $6/월 | 100대 | 우선 지원 + 추가 기능 |
| Business | $18/월/user | 무제한 | 감사 로그, SAML SSO |
개인 홈랩이나 소규모 프로젝트는 무료 플랜으로 충분합니다.
마치며
Tailscale은 VPN 운용에서 반복적으로 발생하는 작업들, 키 배포, NAT 통과, 피어 설정 갱신을 자동화한 도구입니다. WireGuard의 보안과 성능을 그대로 사용하면서, 운용 복잡도를 낮추는 데 집중한 설계입니다.
포트포워딩 없이 어디서든 내 인프라에 붙고 싶다면, Tailscale은 나쁘지 않은 선택이네요.
참고 자료
- Tailscale 공식 문서: https://tailscale.com/kb
- Tailscale 아키텍처 블로그: https://tailscale.com/blog/how-tailscale-works
- Headscale GitHub: https://github.com/juanfont/headscale
- WireGuard 백서: https://www.wireguard.com/papers/wireguard.pdf
'Computer Science > CS 지식' 카테고리의 다른 글
| Supabase란 무엇인가 — PostgreSQL 위에 쌓은 풀스택 백엔드 (0) | 2026.03.27 |
|---|---|
| .env 파일 - 환경 변수로 설정 관리하기 (0) | 2025.10.29 |
| Kafka에 대해 간략하게 알아보기 (0) | 2025.08.22 |
| TLS 암호화 프로토콜 (2) | 2025.07.31 |
| 정보처리기사 실기에 나오는 네트워크 관련 용어 (0) | 2025.07.16 |