Tự chạy Tailscale (Self-Hosting): Hướng dẫn triển khai Headscale trên Docker

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

Sáu tháng không cần đám mây: Hành trình sử dụng Headscale của tôi

Tôi đã dành nhiều năm xây dựng HomeLab trước khi vấp phải một rào cản: CGNAT. Mặc dù Tailscale giải quyết vấn đề kết nối ngay lập tức, tôi không thích việc metadata của mạng mình nằm trên máy chủ của một công ty. Tôi cũng muốn vượt qua giới hạn 100 thiết bị (node) của gói miễn phí mà không cần nâng cấp lên gói doanh nghiệp. Đó là lúc tôi chuyển toàn bộ mạng mesh của mình sang Headscale.

Headscale là một bản thực thi mã nguồn mở, tự lưu trữ (self-hosted) của máy chủ điều khiển Tailscale. Nó cung cấp các tính năng tương tự—NAT traversal, bảo mật WireGuard và kết nối P2P liền mạch—nhưng giữ “bộ não” điều hành trên phần cứng của chính bạn. Sau nửa năm vận hành trên 25 thiết bị tại ba địa điểm khác nhau, nó đã trở thành phần ổn định nhất trong hệ thống của tôi.

Bắt đầu nhanh: Vận hành chỉ trong 5 phút

Bạn có thể đưa Headscale vào hoạt động trên một VPS giá 5 USD/tháng hoặc một máy tính cũ tại nhà chỉ trong vài phút. Tất cả những gì bạn cần là một máy chủ Linux có IP công cộng hoặc đã được chuyển tiếp cổng (forward port) đúng cách.

1. Chuẩn bị cấu trúc thư mục

Bắt đầu bằng cách tạo một không gian riêng cho các tệp cấu hình và cơ sở dữ liệu.

mkdir -p ~/headscale/config
cd ~/headscale
touch config/config.yaml

2. Tệp Docker Compose

Tạo một tệp docker-compose.yml. Tôi khuyên dùng image chính thức vì nó nhẹ và nhận các bản vá bảo mật nhanh chóng.

services:
  headscale:
    image: headscale/headscale:latest
    container_name: headscale
    volumes:
      - ./config:/etc/headscale
      - ./data:/var/lib/headscale
    ports:
      - "8080:8080"
      - "9090:9090"
    command: headscale serve
    restart: always

3. Cấu hình cơ bản

Tệp config.yaml mặc định khá dài, nhưng bạn chỉ cần kiểm tra một vài trường chính để bắt đầu. Hãy đảm bảo đường dẫn cơ sở dữ liệu khớp với volume Docker của bạn.

server_url: http://<YOUR_SERVER_IP>:8080
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090
db_type: sqlite3
db_path: /var/lib/headscale/db.sqlite

derp:
  urls:
    - https://controlplane.tailscale.com/derpmap/default

Chạy lệnh docker-compose up -d. Máy chủ điều khiển riêng tư của bạn hiện đã sẵn sàng.

Kiến trúc hoạt động như thế nào

Tailscale sử dụng kiến trúc tách biệt (split-plane). **Data Plane** xử lý lưu lượng truy cập thực tế, được mã hóa đầu cuối và thường di chuyển trực tiếp giữa các thiết bị. **Control Plane** (Headscale) chỉ quản lý việc đăng ký node và trao đổi khóa.

Thiết lập này rất mạnh mẽ vì nó tách biệt bảo mật của bạn khỏi thời gian hoạt động (uptime) của bên thứ ba. Khi một thiết bị tham gia, nó sẽ kết nối với container Docker của bạn để tìm các thiết bị ngang hàng (peers). Nếu internet công cộng gặp sự cố nhưng các thiết bị nội bộ vẫn có thể kết nối tới instance Headscale của bạn, mạng mesh nội bộ vẫn sẽ hoạt động bình thường.

Tạo người dùng đầu tiên

Headscale sử dụng “users” để nhóm các node. Bạn phải tạo ít nhất một người dùng trước khi có thể kết nối laptop hoặc điện thoại đầu tiên:

docker exec headscale headscale users create mynetwork

Sử dụng nâng cao: Lấp đầy các khoảng trống

Sau khi các bước cơ bản đã xong, bạn có thể mở khóa các tính năng giúp Headscale hoạt động như một công cụ mạng chuyên nghiệp.

Subnet Routers: Truy cập các phần cứng cũ

Tôi có vài camera IP 1080p và một máy in Brother cũ không thể chạy Tailscale. Để khắc phục, tôi đã biến một chiếc Raspberry Pi 4 thành một **Subnet Router**. Điều này cho phép tôi truy cập toàn bộ dải IP 192.168.1.0/24 từ điện thoại khi đang ở quán cà phê.

Trên thiết bị client, hãy chạy:

tailscale up --login-server http://<YOUR_IP>:8080 --advertise-routes=192.168.1.0/24

Sau đó, kích hoạt route trên máy chủ Headscale:

docker exec headscale headscale nodes list
docker exec headscale headscale routes enable -r <ID>

Tự động hóa với Pre-Auth Keys

Việc đăng nhập thủ công rất phiền phức khi bạn khởi tạo các container Docker tạm thời hoặc các CI/CD runner. Tôi sử dụng các khóa Pre-Auth có thể tái sử dụng để cho phép các node mới tham gia mạng mesh tự động mà không cần can thiệp thủ công:

docker exec headscale headscale preauthkeys create -u mynetwork --reusable --expiration 24h

Những bài học sau 6 tháng vận hành thực tế

Sử dụng hệ thống này trong nửa năm đã dạy tôi một vài điều về việc duy trì một mạng mesh ổn định.

  • Sử dụng Reverse Proxy: Việc để lộ cổng 8080 trực tiếp là rất rủi ro. Hãy sử dụng Nginx Proxy Manager hoặc Caddy để xử lý HTTPS. Các ứng dụng di động kết nối ổn định hơn nhiều qua cổng 443 với chứng chỉ SSL hợp lệ.
  • Bảo vệ cơ sở dữ liệu: Tệp db.sqlite là trái tim của mạng. Nếu nó bị hỏng, bạn sẽ phải xác thực lại thủ công từng node một. Tôi sử dụng một cron job đơn giản để sao lưu tệp này vào NAS hàng đêm.
  • Bật MagicDNS: Headscale hỗ trợ DNS nội bộ. Việc gõ ssh proxmox.mynetwork.mesh dễ dàng hơn nhiều so với việc phải nhớ hàng tá địa chỉ IP 100.64.x.x.
  • Bí mật trên iOS: Việc thay đổi máy chủ trên iPhone hơi khó khăn. Hãy mở ứng dụng Tailscale, vào phần cài đặt, và nhấn vào logo “Tailscale” ở phía trên khoảng mười lần. Thao tác này sẽ làm hiện ra trường ẩn để bạn nhập URL Headscale của mình.

Chuyển sang Headscale là quyết định sáng suốt nhất cho HomeLab của tôi. Nó loại bỏ nỗi lo về việc thay đổi giá cả trong tương lai và cho phép tôi kiểm soát hoàn toàn sơ đồ mạng của mình. Nếu bạn muốn một VPN riêng tư, hiệu năng cao mà không bị ràng buộc bởi đám mây, thì đây chính là giải pháp.

Share: