Hướng dẫn self-hosting VPN kiểu Tailscale: Dùng Tailscale Client + Headscale
Bạn đang tìm cách xây dựng một mạng VPN mesh siêu dễ dùng, giống hệt Tailscale, nhưng hoàn toàn tự host, không phụ thuộc cloud của Tailscale Inc.?
Giải pháp hoàn hảo chính là combo Tailscale Client (chính thức) + Headscale – phiên bản open-source của Tailscale Control Server.
Bạn vẫn dùng đúng app Tailscale trên Windows, macOS, Linux, iOS, Android… nhưng toàn bộ traffic coordination và key exchange diễn ra trên server riêng của bạn.
Lợi ích lớn nhất:
- 100% private (không ai biết thiết bị nào kết nối với ai).
- Miễn phí (không giới hạn thiết bị).
- Giống hệt trải nghiệm Tailscale: auto NAT traversal, MagicDNS, ACL, Exit Node, Subnet Router…
- Dễ scale cho homelab, công ty nhỏ, team remote.
Bài viết này sẽ hướng dẫn ae từng bước để setup combo này, dùng cách hiện đại và ổn định nhất: Docker Compose + Caddy (auto HTTPS).
1. Yêu cầu trước khi bắt đầu
- Server: VPS Ubuntu 22.04/24.04 (khuyến nghị DigitalOcean, Vultr). Ít nhất 1 CPU – 2GB RAM (dùng thoải mái).
- Domain/Subdomain: Ví dụ
headscale.vnrom.nettrỏ A record về IP public của VPS. - Port mở: 80 (cho Let’s Encrypt) và 443 (HTTPS). Nếu dùng firewall ufw:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable- Docker & Docker Compose đã cài (nếu chưa:
sudo apt install docker.io docker-compose-plugin -y). - Kiến thức cơ bản về terminal.
2. Cài đặt Headscale với Docker Compose (Khuyến nghị mạnh)
Tạo thư mục dự án:
mkdir ~/headscale && cd ~/headscale
mkdir config libTạo file docker-compose.yml
services:
headscale:
image: headscale/headscale:stable
container_name: headscale
volumes:
- ./config:/etc/headscale
- ./lib:/var/lib/headscale
restart: unless-stopped
command: serve
healthcheck:
test: ["CMD", "headscale", "health"]
interval: 30s
timeout: 5s
retries: 3
caddy:
image: caddy:latest
container_name: caddy
ports:
- "80:80"
- "443:443"
- "443:443/udp" # QUIC cho Tailscale
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
restart: unless-stopped
depends_on:
- headscale
volumes:
caddy_data:
caddy_config:Tạo file Caddyfile
https://headscale.vnrom.net {
reverse_proxy * http://headscale:8080
}Tải và chỉnh config.yaml
cd ~/headscale/config
curl -o config.yaml https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml
nano config.yamlCác thay đổi quan trọng nhất (chỉ sửa những dòng mình đánh dấu):
server_url: https://headscale.vnrom.net # ← Quan trọng nhất
listen_addr: 0.0.0.0:8080
grpc_listen_addr: 0.0.0.0:50443
# TLS tự động bằng Let's Encrypt
tls_letsencrypt_hostname: headscale.vnrom.net # ← Đổi thành tên miền của bạn
tls_letsencrypt_cache_dir: /var/lib/headscale/cache
tls_letsencrypt_challenge_type: HTTP-01
# Database (sqlite đủ mạnh cho hầu hết trường hợp)
database:
type: sqlite
sqlite:
path: /var/lib/headscale/db.sqlite
write_ahead_log: true
# MagicDNS (rất hay dùng)
dns:
magic_dns: true
base_domain: ts.vnrom.net # ← Khác với server_url
nameservers:
global:
- 1.1.1.1
- 1.0.0.1
# ACL (bắt buộc nếu muốn kiểm soát quyền)
policy:
mode: file
path: /etc/headscale/acl.hujsonLưu lại và khởi động:
cd ~/headscale
docker compose up -dKiểm tra:
docker compose ps
docker compose logs -f headscale # xem log
curl -I https://headscale.vnrom.net/health # phải trả về 200 OK3. Tạo User & Pre-auth Key
Vào container:
docker exec -it headscale shTạo user (ví dụ tên bạn):
headscale users create duyTạo pre-auth key (dùng 1 lần, hết hạn 1 giờ):
headscale preauthkeys create --user duy --expiration 24h # có thể 24hCopy key (dạng hskey-auth-xxx...) ra ngoài.
Thoát container bằng exit.
4. Kết nối các thiết bị (Tailscale Client chính thức)
Linux (Ubuntu/Debian):
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up \
--login-server https://headscale.vnrom.net \
--authkey hskey-auth-xxx... \
--advertise-exit-node # nếu muốn làm Exit NodeWindows:
- Tải Tailscale từ tailscale.com/download
- Mở CMD/PowerShell với quyền Admin:
tailscale login --login-server https://headscale.vnrom.netHoặc dùng --authkey như trên.
macOS / iOS / Android:
- Cài app Tailscale từ App Store / Play Store / tailscale.com
- Vào Settings → Use custom control server → nhập
https://headscale.vnrom.net
Sau khi connect thành công, kiểm tra trên server:
docker exec headscale headscale nodes listBạn sẽ thấy thiết bị hiện xanh, có IP 100.64.x.x.
5. ACL (Access Control List) – Kiểm soát quyền
Tạo file ~/headscale/config/acl.hujson:
{
"acls": [
{ "action": "accept", "src": ["*"], "dst": ["*:*"] } // allow all (test)
],
"ssh": [
{
"action": "accept",
"src": ["autogroup:member"],
"dst": ["autogroup:member"],
"users": ["root", "duy"]
}
]
}Sau khi lưu, Headscale tự reload. Muốn chặt chẽ hơn thì thay * bằng group cụ thể (ví dụ group:admin).
6. Tính năng nâng cao (giống Tailscale 100%)
- Exit Node: Trên máy muốn làm exit node:
tailscale up --advertise-exit-node→ trên máy khác:tailscale set --exit-node=ten-may - Subnet Router:
tailscale up --advertise-routes=192.168.1.0/24→ approve trên Headscale:headscale nodes approve-routes --id <node-id> - MagicDNS: Truy cập máy khác bằng tên:
duy-macbook.ts.vnrom.net - Tailscale SSH: Bật trong app hoặc
--advertise-tags=tag:sshvà dùng ACL ssh.
7. Web UI (tùy chọn nhưng cực tiện)
Thêm vào docker-compose.yml service headscale-ui:
headscale-ui:
image: ghcr.io/gurucomputing/headscale-ui:latest
container_name: headscale-ui
restart: unless-stoppedSửa Caddyfile thêm dòng:
reverse_proxy /web* http://headscale-ui:8080Truy cập: https://headscale.vnrom.net/web
8. Một vài lỗi thường gặp
- Không connect được: Kiểm tra
server_urlcó đúng HTTPS không? Port 443 mở? DNS A record đúng? - Key hết hạn: Tạo key mới.
- Node không online:
tailscale statustrên client, kiểm tra firewall client. - MagicDNS không hoạt động: Đảm bảo
base_domainkhácserver_url. - Cập nhật Headscale:
docker compose pull && docker compose up -d
Với Tailscale Client + Headscale, bạn đã có một hệ thống VPN mesh mạnh mẽ, riêng tư và miễn phí hoàn toàn. Không còn lo lắng về giới hạn thiết bị hay privacy của Tailscale cloud nữa.
Một vài tài liệu chính chủ cho anh em tham khảo thêm:
- Headscale docs: https://headscale.net
- GitHub: https://github.com/juanfont/headscale
- Tailscale clients: https://tailscale.com/download








