Hướng dẫn cài đặt và cấu hình Headscale: Tự host Control Server Tailscale cho mạng VPN Zero Trust

Security tutorial - IT technology blog
Security tutorial - IT technology blog

Bối cảnh & Tại sao nên tự host Headscale?

Quản trị máy chủ phân tán giữa AWS, Hetzner và dàn homelab ở nhà luôn khiến nhiều anh em đau đầu. Thói quen mở port 22 rồi gắn IP whitelist rất bất tiện khi cần làm việc từ quán cà phê. Giải pháp dựng OpenVPN truyền thống cũng bộc lộ nhược điểm lớn. Mọi traffic đều phải dồn qua server trung tâm, vô tình biến VPS thành nút thắt cổ chai (bottleneck) và khiến ping tăng vọt.

Tailscale xử lý bài toán này rất thông minh nhờ kiến trúc Mesh VPN trên nền WireGuard. Hai máy kết nối trực tiếp P2P với nhau thay vì trung chuyển qua gateway. Tuy nhiên, bản SaaS miễn phí của Tailscale vẫn có ràng buộc: giới hạn 3 người dùng, phụ thuộc control plane của bên thứ ba và không phù hợp với các dự án đòi hỏi kiểm soát dữ liệu nội bộ nghiêm ngặt.

Đó là lý do Headscale ra đời. Đây là bản triển khai mã nguồn mở của Tailscale coordination server. Bạn tự kiểm soát toàn bộ máy chủ điều phối trên VPS riêng. Toàn bộ routing table, ACL và danh sách node nằm trong tay bạn. Trong khi đó, các thiết bị client vẫn dùng app Tailscale chính thức từ App Store, Google Play hay Linux repository.

Cài đặt Headscale trên máy chủ Linux

Một con VPS giá rẻ với 1 vCPU và 1GB RAM (chạy Ubuntu 22.04/24.04 hoặc Debian 12) là quá đủ. Ở quy mô homelab dưới 100 node, daemon Headscale thực tế chỉ ăn tầm 30MB đến 50MB RAM. Bạn cần chuẩn bị sẵn một subdomain (ví dụ: vpn.itfromzero.com) đã trỏ A record về IP tĩnh của server.

Bước 1: Tải và cài đặt file binary

Truy cập GitHub release của dự án để lấy bản deb mới nhất cho kiến trúc amd64:

export HEADSCALE_VERSION="0.22.3"
wget --output-document=headscale.deb \
  https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_amd64.deb

sudo dpkg -i headscale.deb

Package này sẽ tự động tạo user hệ thống headscale, cấp quyền thư mục dữ liệu tại /var/lib/headscale và đặt file config mẫu tại /etc/headscale/config.yaml.

Bước 2: Dựng Reverse Proxy với Nginx và Let’s Encrypt

Headscale có tính năng tự xin SSL qua ACME. Dù vậy, đặt Nginx phía trước vẫn là phương án an toàn và linh hoạt nhất. Nginx giúp quản lý chứng chỉ tập trung, xử lý WebSocket trơn tru và dễ phân luồng khi bạn chạy chung VPS với các web service khác.

sudo apt update && sudo apt install -y nginx certbot python3-certbot-nginx

Tạo file virtual host mới cho Headscale:

sudo nano /etc/nginx/sites-available/headscale

Dán nội dung cấu hình sau vào:

server {
    listen 80;
    server_name vpn.itfromzero.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name vpn.itfromzero.com;

    ssl_certificate /etc/letsencrypt/live/vpn.itfromzero.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/vpn.itfromzero.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $server_name;
        proxy_redirect http:// https://;
        proxy_buffering off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Mở file /etc/nginx/nginx.conf và đảm bảo đã khai báo block WebSocket bên trong khối http {}:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

Kích hoạt vhost, chạy Certbot cấp SSL và reload service:

sudo ln -s /etc/nginx/sites-available/headscale /etc/nginx/sites-enabled/
sudo certbot --nginx -d vpn.itfromzero.com
sudo nginx -t && sudo systemctl reload nginx

Cấu hình chi tiết Headscale

Thiết lập file config.yaml

Mở file cấu hình chính của Headscale để điều chỉnh các tham số kết nối:

sudo nano /etc/headscale/config.yaml

Kiểm tra và sửa lại các trường thông tin cốt lõi sau:

server_url: https://vpn.itfromzero.com:443
listen_addr: 127.0.0.1:8080
metrics_listen_addr: 127.0.0.1:9090

ip_prefixes:
  - 100.64.0.0/10
  - fd7a:115c:a1e0::/48

derp:
  server:
    enabled: false
  urls:
    - https://controlplane.tailscale.com/derpmap/default
  paths: []
  auto_update_enabled: true
  update_frequency: 24h

database:
  type: sqlite3
  sqlite:
    path: /var/lib/headscale/db.sqlite

Kích hoạt và khởi động service qua systemd:

sudo systemctl enable --now headscale
sudo systemctl status headscale

Khởi tạo User quản trị

Headscale nhóm các thiết bị theo từng User (trước bản 0.23 gọi là Namespace). Hãy tạo tài khoản đầu tiên cho team nội bộ:

sudo headscale users create admin-team

Đăng ký Client vào Headscale Server

Trên máy client (ví dụ một con Ubuntu server khác hoặc laptop cá nhân), cài đặt agent Tailscale chính thức:

curl -fsSL https://tailscale.com/install.sh | sh

# Kết nối tới control server tự host
sudo tailscale up --login-server https://vpn.itfromzero.com

Terminal sẽ trả về một liên kết xác thực có dạng:

To authenticate, visit:
https://vpn.itfromzero.com/register/nodekey:xxxxxxxxxxxxxxxxxxxxxx

Copy chuỗi khóa sau tiền tố nodekey: (hoặc mkey: tùy phiên bản client) rồi quay về server Headscale chạy lệnh phê duyệt:

sudo headscale nodes register --user admin-team --key nodekey:xxxxxxxxxxxxxxxxxxxxxx

Nếu cần bootstrap tự động qua Ansible hoặc Docker entrypoint, bạn hãy tạo sẵn Pre-auth key có thời hạn dùng một lần:

# Tạo key dùng một lần hết hạn sau 24 giờ
sudo headscale preauthkeys create --user admin-team --expiration 24h

Lúc này, phía client chỉ cần chạy một lệnh duy nhất để vào mạng ngay:

sudo tailscale up --login-server https://vpn.itfromzero.com --authkey <YOUR_PREAUTH_KEY>

Kiểm tra & Giám sát mạng VPN

Xác thực kết nối và hiệu năng Mesh

Tại máy chủ Headscale, kiểm tra danh sách thiết bị đang online:

sudo headscale nodes list

Bảng kết quả sẽ liệt kê Node ID, Hostname, User sở hữu, địa chỉ CGNAT (dải 100.64.0.0/10) và trạng thái Online.

Tiếp theo, thử kiểm tra chất lượng kết nối từ máy client:

# Liệt kê các peer trong mạng cùng địa chỉ IP tương ứng
tailscale status

# Ping kiểm tra định tuyến trực tiếp
tailscale ping 100.64.0.2

Dòng phản hồi pong from ... via [public-ip]:port in 14ms (direct) chứng minh hai máy đã bắt tay P2P thành công qua WireGuard. Băng thông lúc này đạt trần tốc độ của đường truyền ISP. Ngược lại, nếu thấy xuất hiện via DERP(syd), kết nối đang bị relay do cả hai đầu đều vướng NAT nghiêm ngặt (Symmetric NAT), khiến ping tăng lên mức 80-150ms.

Thu thập Metrics với Prometheus

Headscale tích hợp sẵn endpoint Prometheus tại cổng 9090. Kiểm tra nhanh bằng lệnh curl từ localhost:

curl -s http://127.0.0.1:9090/metrics | grep -E '^headscale_'

Hai metric cần lưu tâm nhất là headscale_nodes_online_count và headscale_sqlite_queries_total. Với quy mô homelab dưới 150 node, file SQLite mặc định xử lý hoàn toàn trơn tru. Khi mở rộng vượt ngưỡng 200 node với hàng trăm route update liên tục, bạn chỉ cần chuyển database.type sang postgres để tránh hiện tượng database lock.

Share: