Headscale로 셀프호스팅 VPN 만들기 — Tailscale 없이 내 네트워크 구축
Tailscale은 좋은데, 개인 서버에서 더 좋은 방법이 있네?
Tailscale을 써본 분이라면 아실 겁니다. 설치 한 번이면 어디서든 집 네트워크에 접근할 수 있죠. 그런데 몇 가지 아쉬운 점이 있었습니다.
- 무료 플랜은 기기 수 제한이 있습니다.
- 컨트롤 서버가 Tailscale 클라우드에 있어서, 서비스가 죽으면 내 VPN도 죽습니다.
- 내 네트워크 정보가 외부 서버에 저장됩니다.
Headscale은 Tailscale의 컨트롤 서버를 셀프호스팅할 수 있게 만든 오픈소스 프로젝트입니다. Tailscale 클라이언트를 그대로 쓰면서, 컨트롤 플레인만 내 서버에서 돌립니다.
구성 요소
| 컴포넌트 | 역할 |
|---|---|
| Headscale | 컨트롤 서버 (Tailscale 대체) |
| Headplane | 웹 관리 UI |
| Tailscale Router | 서브넷 라우터 (홈 네트워크 광고) |
| Tailscale 클라이언트 | 각 기기에 설치 |
Docker Compose
services:
headscale:
image: headscale/headscale:0.28.0
container_name: headscale-server
command: serve
ports:
- "8089:8080"
- "3478:3478/udp"
volumes:
- "./headscale-data:/var/lib/headscale"
- "./headscale-config:/etc/headscale"
healthcheck:
test: ["CMD", "headscale", "version"]
interval: 30s
headplane:
image: ghcr.io/tale/headplane:0.6.2
container_name: headscale-headplane
depends_on:
- headscale
ports:
- "3009:3000"
volumes:
- "./config.yaml:/etc/headplane/config.yaml"
- "./headscale-config/config.yaml:/etc/headscale/config.yaml"
- "./headscale-config/acl.hujson:/etc/headscale/acl.hujson"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
tailscale-router:
image: tailscale/tailscale:v1.96.5
container_name: tailscale-router
hostname: subnet-router
network_mode: host
cap_add:
- NET_ADMIN
- NET_RAW
volumes:
- ./tailscale-state:/var/lib/tailscale
environment:
TS_AUTHKEY: ${TS_AUTHKEY}
TS_EXTRA_ARGS: "--advertise-routes=192.168.0.0/23 --login-server=http://127.0.0.1:8089 --accept-dns=false"
TS_STATE_DIR: /var/lib/tailscale
Headscale 설정
# headscale-config/config.yaml
server_url: https://headscale.example.com
listen_addr: 0.0.0.0:8080
prefixes:
v4: 100.64.0.0/10
v6: fd7a:115c:a1e0::/48
dns:
magic_dns: true
base_domain: ts.example.com
nameservers:
global:
- 192.168.1.100 # 내부 DNS (AdGuard 등)
- 1.1.1.1
override_local_dns: true
database:
type: sqlite
sqlite:
path: /var/lib/headscale/db.sqlite
핵심 설정:
- server_url: 외부에서 접근 가능한 Headscale 주소. 리버스 프록시 뒤에 놓으면 됩니다.
- prefixes: Tailscale 네트워크에서 사용할 IP 대역. 기본값 그대로 쓰면 됩니다.
- magic_dns:
기기명.ts.example.com으로 접근 가능하게 해줍니다.
ACL (접근 제어)
{
"groups": {
"group:admin": ["myuser@"]
},
"tagOwners": {
"tag:server": ["group:admin"],
"tag:vpn": ["group:admin"]
},
"acls": [
{
"action": "accept",
"src": ["group:admin"],
"dst": ["*:*"]
},
{
"action": "accept",
"src": ["tag:server", "tag:vpn"],
"dst": ["*:*"]
}
]
}
admin 그룹은 모든 곳에 접근 가능하고, 서버/VPN 태그가 붙은 노드끼리도 자유롭게 통신합니다.
서브넷 라우터: 홈 네트워크 전체 접근
tailscale-router가 192.168.0.0/23을 광고합니다. 이렇게 하면 VPN에 연결된 기기에서 홈 네트워크의 모든 장비에 접근할 수 있습니다.
TS_EXTRA_ARGS: "--advertise-routes=192.168.0.0/23 --login-server=http://127.0.0.1:8089"
--advertise-routes: 이 서브넷을 VPN 네트워크에 광고--login-server: 로컬 Headscale 서버 주소 (같은 호스트니까 localhost)
Headplane UI에서 해당 라우트를 승인하면 활성화됩니다.
클라이언트 연결
각 기기에서 Tailscale 클라이언트를 설치하고, login server만 바꿔주면 됩니다.
# macOS / Linux
tailscale up --login-server=https://headscale.example.com
# iOS / Android
# Tailscale 앱 설정에서 "Custom control server" 입력
실제 사용 예시
제 네트워크 구성입니다:
| 노드 | Tailscale IP | 역할 |
|---|---|---|
| 홈서버 라우터 | 100.64.0.11 | 서브넷 라우터 + Exit Node |
| 해외 VPS | 100.64.0.23 | Exit Node (해외 IP) |
| 노트북 | 100.64.0.35 | 클라이언트 |
| 스마트폰 | 100.64.0.42 | 클라이언트 |
카페에서 노트북으로 192.168.1.100:3060에 바로 접근할 수 있고, 해외 IP가 필요하면 VPS를 Exit Node로 쓰면 됩니다.
Exit Node 활용: 해외 VPS로 VPN 대체하기
유료 VPN 서비스를 쓰는 대신, 해외 클라우드에 무료 VPS를 하나 띄워서 Exit Node로 쓰고 있습니다. Oracle Cloud 프리 티어로 일본 리전에 인스턴스를 만들고, Tailscale 클라이언트를 설치한 뒤 Headscale에 연결했습니다.
이렇게 하면:
- 지역 제한 우회: 일본 IP로 인터넷 접속 (일본 전용 서비스 이용)
- 홈서버 Exit Node: 해외에서 한국 IP가 필요할 때 집을 통해 나감
- 비용 0원: Oracle Cloud 프리 티어는 평생 무료
VPS에서 할 일은 Tailscale 설치 + Exit Node 광고뿐입니다.
# 해외 VPS에서
tailscale up --advertise-exit-node --login-server=https://headscale.example.com
Headplane UI에서 Exit Node를 승인하면, 클라이언트에서 바로 사용할 수 있습니다.
# 클라이언트에서 (일본 IP로 나가고 싶을 때)
tailscale up --exit-node=100.64.0.23
기존에 쓰던 유료 VPN을 완전히 대체했습니다. 속도도 더 빠르고, 내 트래픽이 제3자 VPN 업체를 거치지 않으니 프라이버시도 낫습니다.
Tailscale vs Headscale 비교
| Tailscale (클라우드) | Headscale (셀프호스팅) | |
|---|---|---|
| 설정 난이도 | 매우 쉬움 | 중간 |
| 기기 수 제한 | 무료 3대 (2025 기준) | 무제한 |
| 컨트롤 서버 | Tailscale 클라우드 | 내 서버 |
| 데이터 주권 | 외부 | 완전 내부 |
| 안정성 | 높음 | 내 서버 의존 |
| 관리 UI | 엔터프라이즈급 | Headplane |
소수 기기만 쓴다면 Tailscale 클라우드가 편합니다. 하지만 기기가 많거나, 데이터를 외부에 두기 싫거나, 인프라를 직접 통제하고 싶다면 Headscale이 좋은 선택입니다.
마무리
Headscale + Tailscale 클라이언트 조합은 "WireGuard의 성능 + Tailscale의 편의성 + 셀프호스팅의 자유"를 동시에 얻을 수 있는 방법입니다.
한 번 세팅해두면 어디서든 집 네트워크에 접근할 수 있고, Exit Node로 VPN 용도로도 쓸 수 있습니다. Docker Compose 하나면 끝이니 홈서버 운영자라면 꼭 시도해보시길 추천합니다.