ติดตั้ง Headscale บน VPS — Tailscale Server ส่วนตัว
Headscale คือ open-source implementation ของ Tailscale control server ที่รันบน VPS ของคุณเองได้เลย แทนที่จะใช้ cloud ของ Tailscale คุณควบคุม node ทุกตัวในเครือข่าย mesh VPN ผ่าน server ส่วนตัว — ข้อมูลไม่ผ่านบริษัทใดทั้งนั้น เหมาะมากสำหรับนักพัฒนา, ทีม DevOps, และใครก็ตามที่ต้องการ VPN คุณภาพสูงในราคาถูก
Headscale vs Tailscale Cloud ต่างกันอย่างไร?
| หัวข้อ | Tailscale Cloud | Headscale (Self-hosted) |
|---|---|---|
| Control server | ของ Tailscale Inc. | VPS ของคุณเอง |
| ราคา | Free tier / $6+/เดือน | ค่า VPS เท่านั้น |
| Node สูงสุด | 3 (free) / ไม่จำกัด (paid) | ไม่จำกัด |
| Privacy | metadata ผ่าน Tailscale | คุณควบคุมทั้งหมด |
| MagicDNS / ACL | ครบ | มี (บางฟีเจอร์ยังพัฒนาอยู่) |
| Data plane (WireGuard) | peer-to-peer โดยตรง | peer-to-peer โดยตรงเหมือนกัน |
ความต้องการระบบ
- VPS Ubuntu 22.04 / 24.04 หรือ Debian 12
- RAM 512 MB ขึ้นไป (1 GB แนะนำ)
- Domain หรือ subdomain ที่ชี้มายัง VPS (เช่น
hs.example.com) - Port 80, 443 (HTTPS) และ 41641/UDP เปิดอยู่
- Root หรือ sudo access
ขั้นตอนที่ 1: ติดตั้ง Headscale
ดาวน์โหลด binary เวอร์ชันล่าสุดจาก GitHub releases:
# ตรวจสอบเวอร์ชันล่าสุดที่ https://github.com/juanfont/headscale/releases
HEADSCALE_VERSION="0.25.1"
ARCH="amd64"
wget "https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${ARCH}.deb" \
-O /tmp/headscale.deb
sudo dpkg -i /tmp/headscale.deb
dpkg --print-architecture — ถ้าเป็น ARM ให้เปลี่ยน amd64 เป็น arm64ขั้นตอนที่ 2: ตั้งค่า config.yaml
สร้างไดเรกทอรีและแก้ไข config:
sudo mkdir -p /etc/headscale /var/lib/headscale /var/run/headscale
sudo cp /etc/headscale/config.yaml.example /etc/headscale/config.yaml 2>/dev/null || true
sudo nano /etc/headscale/config.yaml
ค่าสำคัญที่ต้องแก้ใน config.yaml:
server_url: https://hs.example.com:443
listen_addr: 0.0.0.0:8080
tls_letsencrypt_hostname: hs.example.com # ให้ Headscale จัดการ TLS เอง
tls_letsencrypt_challenge_type: HTTP-01
ip_prefixes:
- 100.64.0.0/10 # Tailscale CGNAT range
dns_config:
magic_dns: true
base_domain: mesh.internal
nameservers:
- 1.1.1.1
- 8.8.8.8
db_type: sqlite3
db_path: /var/lib/headscale/db.sqlite
private_key_path: /var/lib/headscale/private.key
noise:
private_key_path: /var/lib/headscale/noise_private.key
ขั้นตอนที่ 3: เปิด Port และเริ่ม Service
# เปิด port ที่จำเป็น
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 41641/udp # WireGuard DERP relay
# เริ่ม service
sudo systemctl enable --now headscale
sudo systemctl status headscale
sudo journalctl -u headscale -fขั้นตอนที่ 4: สร้าง Namespace (User)
Headscale จัดการ node ผ่าน "user" (เดิมเรียก namespace):
# สร้าง user สำหรับเครือข่ายของคุณ
sudo headscale users create mynetwork
# ดู user ทั้งหมด
sudo headscale users list
ขั้นตอนที่ 5: เชื่อม Tailscale Client เข้า Headscale
บน device ที่ต้องการเข้าร่วม (Linux, macOS, Windows, iOS, Android):
# Linux — ติดตั้ง Tailscale client ก่อน
curl -fsSL https://tailscale.com/install.sh | sh
# เชื่อมต่อโดยชี้ไปยัง Headscale server ของคุณ
sudo tailscale up \
--login-server https://hs.example.com \
--authkey=YOUR_AUTH_KEY
สร้าง auth key ล่วงหน้าบน server:
# สร้าง pre-auth key (ใช้ได้ 1 ครั้ง)
sudo headscale preauthkeys create --user mynetwork --expiration 24h
# สร้าง reusable key (หลาย device)
sudo headscale preauthkeys create --user mynetwork --reusable --expiration 72h
# ดู key ทั้งหมด
sudo headscale preauthkeys list --user mynetwork
ขั้นตอนที่ 6: จัดการ Node
# ดู node ที่เชื่อมต่ออยู่
sudo headscale nodes list
# Approve node ที่รอการยืนยัน
sudo headscale nodes register --user mynetwork --key MACHINE_KEY
# ตั้งชื่อ node
sudo headscale nodes rename --identifier 1 my-laptop
# ลบ node
sudo headscale nodes delete --identifier 2
ขั้นตอนที่ 7: ตั้งค่า ACL (Access Control)
สร้างไฟล์ /etc/headscale/acls.yaml เพื่อควบคุมการเข้าถึง:
acls:
- action: accept
src:
- mynetwork
dst:
- mynetwork:*
โหลด ACL ใหม่:
sudo headscale acls -o yaml get
# แก้ไขแล้ว reload
sudo systemctl reload headscale
tag:prod เข้าถึงได้เฉพาะ port 443ขั้นตอนที่ 8: ตั้งค่า Nginx Reverse Proxy (ทางเลือก)
ถ้าต้องการรัน Headscale หลัง Nginx แทนที่จะให้ Headscale จัดการ TLS เอง:
sudo nano /etc/nginx/sites-available/headscale
server {
listen 80;
server_name hs.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name hs.example.com;
ssl_certificate /etc/letsencrypt/live/hs.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hs.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
sudo ln -s /etc/nginx/sites-available/headscale /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
ตรวจสอบว่า Headscale ทำงานถูกต้อง
# ดูสถานะ service
sudo systemctl status headscale
# ดู log แบบ real-time
sudo journalctl -u headscale -f --since "5 min ago"
# ตรวจสอบ API ทำงาน
curl -s https://hs.example.com/api/v1/node \
-H "Authorization: Bearer YOUR_API_KEY" | python3 -m json.tool
# ดูรายการ node
sudo headscale nodes list
# ทดสอบ ping ระหว่าง node
ping 100.64.0.2 # IP ของ node ในเครือข่าย mesh
แก้ปัญหาที่พบบ่อย
Error: "failed to fetch noise key from control"
ปัญหานี้เกิดเมื่อ Tailscale client เชื่อมต่อ Headscale server ไม่ได้ มักมาจาก URL ผิดหรือ TLS certificate ไม่ถูกต้อง
# ตรวจสอบ URL server และ certificate
curl -v https://hs.example.com/key
# ต้องได้ response เป็น JSON ที่มี public key
# ดู log ของ Headscale
sudo journalctl -u headscale -n 50 --no-pager
Error: "tls: failed to verify certificate"
Certificate ของ Headscale server ไม่ valid — มักเกิดเมื่อ Let's Encrypt renewal ล้มเหลวหรือ domain ยังไม่ชี้มายัง IP ของ VPS
# ตรวจสอบ certificate
sudo certbot certificates 2>/dev/null || \
openssl s_client -connect hs.example.com:443 -servername hs.example.com &1 | grep -E "subject|expire"
# ถ้าใช้ built-in TLS ของ Headscale
sudo ls -la /var/lib/headscale/cache/
Error: "machine is not registered"
Node ที่เชื่อมต่อยังไม่ได้รับการ approve — ต้อง register ด้วยมือหรือใช้ pre-auth key
# ดู node ที่รอ approval
sudo headscale nodes list
# Register node ที่รอ
sudo headscale nodes register \
--user mynetwork \
--key mkey:MACHINE_KEY_HERE
Error: "database is locked"
SQLite database ถูก lock เพราะ process อื่นใช้อยู่ หรือ disk เต็ม
# ตรวจสอบ disk
df -h /var/lib/headscale
# ตรวจสอบ process ที่ใช้ db
sudo fuser /var/lib/headscale/db.sqlite
# Restart service
sudo systemctl restart headscale
Node เชื่อมต่อได้แต่ ping กันไม่ผ่าน
ปัญหา firewall หรือ routing บน node ปลายทาง — ตรวจสอบ iptables และ IP forwarding
# ตรวจสอบ IP forwarding บน VPS
sysctl net.ipv4.ip_forward
# เปิด IP forwarding ถ้ายังไม่ได้เปิด
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# ดู route table บน node ที่มีปัญหา
ip route show table 52
คำถามที่พบบ่อย
Headscale รองรับกี่ node?
ทฤษฎีไม่จำกัด เพราะเป็น open-source ที่รันบน VPS ของคุณ แต่ในทางปฏิบัติ SQLite เริ่มช้าเมื่อมี node หลายร้อย — แนะนำให้ migrate ไป PostgreSQL เมื่อมีมากกว่า 50 node โดยเปลี่ยน db_type: postgres ใน config
ถ้า VPS ล่ม node ที่เชื่อมกันอยู่จะยังคุยกันได้ไหม?
ได้ เพราะ WireGuard วิ่ง peer-to-peer โดยตรง — control plane (Headscale) ใช้แค่สำหรับ authenticate และแจก IP ครั้งแรก หลังจาก node เชื่อมกันแล้ว communication ดำเนินต่อได้แม้ server จะ offline ชั่วคราว (แต่ node ใหม่จะ join ไม่ได้ระหว่างนั้น)
ใช้ Headscale กับ iOS/Android ได้ไหม?
ได้ ใช้ Tailscale official app บน iOS/Android แล้วเลือก "Use custom login server" ใส่ URL ของ Headscale — ทำงานได้ทุก platform ที่ Tailscale รองรับ เพราะ Headscale implements Tailscale protocol เต็มรูปแบบ
ถ้าคุณกำลังมองหา VPS ที่มีประสิทธิภาพดีสำหรับรัน Headscale หรือ workload อื่นๆ ในเอเชีย บริการ VPS สิงคโปร์ของ asiagb เป็นตัวเลือกที่น่าสนใจ — latency ต่ำจากไทย เหมาะกับ control server ที่ต้องการความเสถียร