SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-11-01

Headscale: tự host control server Tailscale trên VPS

Tự chạy control server Tailscale trên VPS với Headscale: cài gói .deb chính thức, đặt server_url, restart service bằng systemd rồi join node đầu tiên.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Headscale là gì

Headscale là phiên bản tự host của Tailscale control server. Vì vậy, máy điều phối private network của bạn là một VPS do bạn sở hữu. Đây là một dự án cộng đồng và không do Tailscale Inc. vận hành. Mỗi máy vẫn chạy client tailscale chính thức, trỏ đến server của bạn bằng một flag là --login-server.

Control server là thành phần biết những máy nào thuộc network. Nó cấp cho mỗi node một địa chỉ trong dải 100.64.0.0/10, phân phối public key và cho các node biết cách tìm thấy nhau. Các tunnel vẫn dùng WireGuard và được thiết lập trực tiếp giữa các node. Traffic giữa hai máy của bạn không đi qua máy headscale, trừ khi không thể tạo đường truyền trực tiếp và các node phải chuyển sang dùng relay. Tự vận hành vai trò điều phối này chỉ thay đổi bên nắm giữ nó, không thay đổi khả năng của nó. Vì vậy, trước khi coi việc chuyển đổi này tự nó là một cải thiện bảo mật, bạn nên hiểu control server có thể và không thể truy cập gì trong mô hình này.

Headscale phục vụ một tailnet (một mạng Tailscale) cho mỗi instance. Dự án mô tả mô hình này phù hợp với nhu cầu cá nhân hoặc tổ chức nhỏ. Với ba hoặc bốn máy, một VPN WireGuard đơn giản trên VPS do bạn sở hữu sẽ cần ít phần mềm hơn và ít thứ có thể hỏng hơn. Headscale trở nên đáng dùng khi bạn không còn muốn tự viết một block [Peer] cho mỗi laptop mới. Chi phí thường là lý do đầu tiên khiến mọi người tìm hiểu, vì vậy bạn nên đọc gói miễn phí hosted thực sự bao gồm những gì trước khi quản lý một server, vì một vài máy cá nhân thường vẫn nằm trong giới hạn của gói này. Nếu bạn đã vượt giới hạn đó, hãy tính toán dựa trên chi phí của các gói trả phí theo user và resource được gắn tag, vì số thiết bị của user là không giới hạn, còn resource được gắn tag có hạn mức và khoản phí riêng. Nếu muốn có một control plane tự host nhưng thích dùng client riêng và web interface để quản lý peer hơn là một bản thay thế trực tiếp cho Tailscale, NetBird trên một VPS duy nhất là lựa chọn thay thế đáng cân nhắc. Cả hai đều truyền traffic qua WireGuard, nên lựa chọn phụ thuộc vào cách bạn viết access rule và relay hoạt động như thế nào. Bạn nên so sánh NetBird với Tailscale về các điểm này trước khi cài một trong hai. Để xem so sánh rộng hơn giữa hai mô hình, hãy đọc WireGuard và Tailscale khác nhau như thế nào.

Các điều kiện cần có trước khi cài đặt

  • Một VPS chạy Ubuntu 24.04, có địa chỉ IPv4 public và quyền sudo. Nếu server còn mới, trước tiên hãy làm theo 10 phút đầu tiên trên một VPS mới.
  • Một bản ghi DNS A trỏ đến địa chỉ đó. Hướng dẫn này sử dụng headscale.example.com.
  • Một domain hoặc subdomain thứ hai cho MagicDNS. Hướng dẫn này sử dụng tailnet.example.net. Domain hoặc subdomain này không được trùng với domain trong server_url.
  • Một máy client để tham gia mạng, chạy Linux, macOS, Windows, Android hoặc iOS. Headscale 0.29.6 yêu cầu Tailscale client phiên bản 1.80.0 trở lên.

Cài đặt headscale từ gói .deb chính thức

Dự án phát hành các gói .deb trên trang GitHub releases. Tính đến ngày 27 tháng 10 năm 2026, bản stable mới nhất là 0.29.6, được phát hành ngày 24 tháng 10 năm 2026. Trước tiên, hãy kiểm tra architecture của bạn vì tên file có chứa thông tin này.

sudo apt update
sudo apt install -y wget
dpkg --print-architecture

Lệnh này in ra amd64 trên VPS x86 thông thường và arm64 trên plan kiểu Ampere hoặc Graviton. Gán kết quả vào biến bên dưới.

HEADSCALE_VERSION="0.29.6"
HEADSCALE_ARCH="amd64"
wget --output-document=headscale.deb \\
  "https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb"
sudo apt install -y ./headscale.deb
headscale version

./ ở trước tên file là bắt buộc. Nếu thiếu nó, apt sẽ tìm một package tên headscale.deb trong các repository của bạn rồi báo lỗi.

Package tạo một system user headscale, ghi file cấu hình mặc định /etc/headscale/config.yaml, cài systemd unit rồi khởi động service. Vì vậy, headscale đã chạy khi apt trả về và sudo systemctl is-active headscale in ra active. Tuy nhiên, package không enable unit khi cài mới. Service sẽ không tự chạy lại sau reboot cho đến khi bạn enable nó; bước restart bên dưới sẽ thực hiện việc này. Service cũng đang chạy với cấu hình được cung cấp sẵn. Cấu hình đó trỏ server_url đến http://127.0.0.1:8080, đây không phải địa chỉ mà bất kỳ client nào của bạn có thể truy cập. Hiện chưa có gì được expose vì listen_addr được cung cấp sẵn cũng bind trên loopback. Tuy nhiên, đừng join bất kỳ client nào trước khi bạn đặt server_url và restart service; hai bước tiếp theo sẽ thực hiện việc đó.

Cấu hình server_url trước khi bất kỳ client nào tham gia

Chỉnh sửa /etc/headscale/config.yaml bằng sudo nano /etc/headscale/config.yaml, hoặc áp dụng cùng ba thay đổi đó bằng sed. Giữ lại một bản sao của file gốc, vì file này dài và có nhiều chú thích. Đây là tài liệu tham chiếu tốt nhất cho các setting còn lại.

sudo cp /etc/headscale/config.yaml /etc/headscale/config.yaml.orig
sudo sed -i 's|^server_url:.*|server_url: https://headscale.example.com|' /etc/headscale/config.yaml
sudo sed -i 's|^listen_addr:.*|listen_addr: 127.0.0.1:8080|' /etc/headscale/config.yaml
sudo sed -i 's|^  base_domain:.*|  base_domain: tailnet.example.net|' /etc/headscale/config.yaml
sudo grep -E '^(server_url|listen_addr):|^  base_domain:' /etc/headscale/config.yaml

server_url là địa chỉ public mà headscale dùng khi tạo registration URL. Client sử dụng địa chỉ control được cấu hình bằng --login-server, vì vậy hãy dùng cùng một tên public với https:// ở cả hai nơi, không dùng 127.0.0.1. Tài liệu headscale cho biết có thể dùng HTTP thuần hoặc HTTPS trên cổng khác 443, nhưng khuyến nghị mạnh mẽ HTTPS trên cổng 443 cho production. Phần còn lại của hướng dẫn này giả định cấu hình đó.

listen_addr là địa chỉ bind của process. Hãy giữ nó trên loopback. Reverse proxy trên cùng máy sẽ thực hiện TLS termination và chuyển tiếp request đến đó, nên không có gì bên ngoài server cần truy cập cổng 8080.

base_domain là hậu tố MagicDNS, tức domain dùng để đặt tên cho các node. Nó phải là một fully qualified domain name không có dấu chấm ở cuối và phải khác domain trong server_url, vì nếu không hai namespace sẽ bị trùng.

Giữ nguyên phần database. Cấu hình mặc định dùng SQLite tại /var/lib/headscale/db.sqlite, trong một thư mục do package tạo và sở hữu. SQLite đủ dùng cho tailnet có quy mô như vậy.

Khởi động lại headscale và xác nhận service đang chạy

sudo systemctl restart headscale
sudo systemctl enable headscale
sudo systemctl is-active headscale
sudo systemctl is-enabled headscale
curl -sS -o /dev/null -w '%{http_code}\\n' http://127.0.0.1:8080/health

is-active in active, is-enabled in enabled, còn curl in 200. Lệnh restart là bước nạp các chỉnh sửa của bạn. Headscale chỉ đọc cấu hình một lần khi khởi động, nên process do package khởi chạy vẫn tiếp tục dùng server_url được package cung cấp cho đến khi bạn restart service. sudo systemctl enable --now headscale không thực hiện được việc này: service đã chạy, nên lệnh --now không thay đổi gì và giá trị cũ vẫn đang được áp dụng. Việc khởi động service cùng hệ thống là nhiệm vụ của enable, và package không tự làm việc đó: trong một lần cài mới, package khởi động service nhưng không enable nó, nên bạn phải chạy sudo systemctl enable headscale một lần như ở trên.

Nếu is-active in ra bất kỳ giá trị nào khác active, hoặc curl không in ra 200, hãy đọc journal bằng sudo journalctl -u headscale -n 50 --no-pager. Lỗi ở bước này gần như luôn nằm trong file cấu hình, vì headscale phân tích toàn bộ file trước khi mở socket. Do đó, một lỗi thụt dòng hoặc một thiết lập bắt buộc không hợp lệ sẽ dừng process trước khi process bắt đầu listen. Sửa file, sau đó chạy sudo systemctl restart headscale. Mọi thay đổi cấu hình sau này cũng cần restart tương tự. Các client sẽ tự reconnect sau đó. Nếu bạn chưa quen với systemd unit, chạy service và timer của riêng bạn bằng systemd giải thích các command được dùng ở đây.

Kiểm tra các file state khi bạn đang ở trong shell:

stat -c '%U %n' /var/lib/headscale/db.sqlite /var/lib/headscale/noise_private.key

Cả hai dòng đều bắt đầu bằng headscale, user không có quyền đặc biệt do package tạo. noise_private.key là identity của server đối với các client. Hãy giữ file này. Nếu xóa file, headscale sẽ tạo identity mới và các client phải lấy server key mới trước khi reconnect; các registration hiện có vẫn nằm trong database.

Đặt TLS trước headscale

Client phải truy cập server_url qua HTTPS. Caddy là cách ngắn gọn nhất vì nó tự yêu cầu và gia hạn certificate.

sudo apt install -y caddy

Thay /etc/caddy/Caddyfile bằng block trong tài liệu headscale:

headscale.example.com {
    reverse_proxy 127.0.0.1:8080 {
        header_up True-Client-IP {remote_host}
        header_up X-Real-IP {remote_host}
    }
}
sudo caddy validate --adapter caddyfile --config /etc/caddy/Caddyfile
sudo systemctl restart caddy
sudo systemctl is-active caddy

validate in adapted config to JSON khi file được parse thành công. Cảnh báo cho biết file chưa được format chỉ mang tính hình thức. Từ laptop, curl -sS -o /dev/null -w '%{http_code}\\n' https://headscale.example.com/health cũng phải in 200. Kiểm tra này xác nhận DNS, firewall, certificate và proxy đang hoạt động cùng nhau.

Có một chi tiết về proxy khiến nhiều người mất cả buổi tối để xử lý. Kết nối control của Tailscale là một HTTP upgrade. Nó được khởi tạo bằng POST thay vì GET, và giá trị của header Upgrade là tailscale-control-protocol. Caddy chuyển tiếp phần này mà không cần cấu hình thêm. nginx thì không, nên front end nginx phải chuyển tiếp rõ ràng các header Upgrade và Connection. Tài liệu headscale thực hiện việc này bằng một upgrade map:

map $http_upgrade $connection_upgrade {
    default keep-alive;
    ''      close;
}

server {
    listen 443 ssl;
    server_name headscale.example.com;
    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_buffering off;
        proxy_pass http://127.0.0.1:8080;
    }
}

Nếu bỏ các dòng đó, các request thông thường vẫn thành công. Vì vậy /health trả về 200 và mọi thứ có vẻ bình thường, nhưng kết nối control không bao giờ được thiết lập: node mới không thể register, còn node hiện có không thể reconnect và báo trạng thái online. Nếu chọn nginx, Certbot trên Ubuntu 24.04 với nginx hướng dẫn phần certificate.

Các cổng cần mở trong UFW

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Cổng 443 mang toàn bộ kết nối điều khiển của client đến headscale. Nếu sau này bật DERP relay tích hợp, bạn cũng cần mở cổng 3478/udp, được đề cập bên dưới. Cổng 80 dùng cho HTTP challenge của ACME (automatic certificate management environment) và chuyển hướng sang HTTPS. Caddy vẫn có thể lấy chứng chỉ khi đóng cổng 80, vì có thể dùng TLS-ALPN challenge trên cổng 443. Tuy nhiên, khi mở cổng 80, cả hai challenge đều khả dụng và các request http:// dạng HTTP sẽ được chuyển hướng.

Cổng 8080 vẫn đóng. listen_addr là 127.0.0.1:8080, nên proxy kết nối đến headscale qua loopback interface và không cần firewall rule. Mở cổng 8080 trong UFW cũng không expose thêm gì, vì từ bên ngoài không có tiến trình nào listening trên cổng này. Việc đó cũng không mang lại lợi ích nào. Lưu ý rằng hầu hết nhà cung cấp còn có một firewall thứ hai trong control panel, tách biệt với UFW. Vì vậy, một cổng có thể mở trên máy chủ nhưng vẫn đóng ở edge. Kiến thức cơ bản về firewall UFW trên VPS trình bày chi tiết hơn về cú pháp rule.

Tạo user và preauth key

sudo headscale users create alice
sudo headscale users list

Lệnh headscale là một client. Lệnh này giao tiếp với daemon đang chạy qua unix socket tại /var/run/headscale/headscale.sock. Socket này có mode 0770 và thuộc group headscale. Từ đó có 2 điểm cần lưu ý. Lệnh sẽ fail khi service đang dừng. Đây cũng là lý do thứ hai khiến thứ tự trong hướng dẫn này quan trọng. Ngoài ra, lệnh cần sudo, trừ khi bạn thêm account của mình vào group headscale.

users list in một ID bên cạnh mỗi tên. Bạn cần số này vì lệnh tạo key nhận user ID dạng số, không nhận tên.

sudo headscale preauthkeys create --user 1 --expiration 24h

Key chỉ được in một lần. Hãy copy ngay. Preauth key chỉ dùng được 1 lần và có hiệu lực trong 1 giờ, trừ khi bạn chỉ định khác. Vì vậy, nên đặt --expiration 24h trong lúc vẫn đang testing. Thêm --reusable để tạo key dùng enroll nhiều máy. Hãy bảo vệ key đó như password vì bất kỳ ai có key đều có thể join vào network của bạn.

Kết nối client đầu tiên bằng --login-server

Trên máy bạn muốn tham gia:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --login-server https://headscale.example.com --auth-key 'hskey-auth-PASTE-YOUR-KEY-HERE'
tailscale status
tailscale ip -4

tailscale ip -4 in ra địa chỉ mà headscale đã gán, ví dụ như 100.64.0.1. Quay lại server và chạy sudo headscale nodes list để xem node cùng ID, user và trạng thái online.

Dùng địa chỉ HTTPS public từ server_url cho --login-server. Client tự loại bỏ dấu gạch chéo ở cuối control URL; không có phép so sánh chuỗi chính xác nào buộc bạn phải bỏ dấu này.

Máy trước đây đã đăng nhập vào dịch vụ hosted của Tailscale sẽ giữ phiên đăng nhập đó. Trước tiên, chạy sudo tailscale logout trên máy này, sau đó chạy tailscale up với --login-server.

Nếu bỏ qua --auth-key, client sẽ in ra một URL. Mở URL đó để xem identifier của lần đăng ký; sau đó approve trên server:

sudo headscale auth register --user alice --auth-id PASTE-THE-ID-FROM-THE-PAGE

Cách này thuận tiện hơn cho laptop cá nhân. Preauth key phù hợp hơn với các tác vụ được script hóa vì không cần có người theo dõi. Khi chính VPS đã là một node, nó cũng có thể chuyển tiếp traffic Internet của các máy khác, tức cấu hình exit node, với điểm khác là bạn approve route được quảng bá trên server bằng lệnh headscale thay vì trong hosted admin console. Nếu bạn muốn truy cập vào một private network nằm phía sau VPS thay vì tạo đường ra Internet, cùng bước approve này áp dụng cho việc quảng bá subnet đó đến phần còn lại của tailnet. Public một ứng dụng từ node, thay vì định tuyến toàn bộ network qua node đó, lại là một tác vụ khác; serve và funnel là hai cách để thực hiện, nhưng cả hai đều dựa vào certificate và ingress machinery của Tailscale. Vì vậy, hãy xem chúng là các tính năng của hosted tailnet, không phải tính năng do headscale cung cấp.

DERP và thành phần chuyển tiếp lưu lượng khi đường kết nối trực tiếp bị lỗi

DERP (designated encrypted relay for packets) là đường dự phòng. Khi hai node không thể mở kết nối WireGuard trực tiếp, thường vì cả hai đều nằm sau NAT (network address translation) nghiêm ngặt, chúng sẽ gửi packet qua relay. Relay không giữ key nên không thể đọc lưu lượng của bạn. Tuy nhiên, relay biết những node nào đang trao đổi dữ liệu và lưu lượng trao đổi có dung lượng bao nhiêu.

Cần hiểu rõ cấu hình mặc định hoạt động như thế nào. Headscale được phát hành với cấu hình trỏ đến https://controlplane.tailscale.com/derpmap/default cùng auto_update_enabled: true và update_frequency: 3h, vì vậy control plane thuộc về bạn còn relay thuộc về Tailscale. Với đa số người dùng, đây là một đánh đổi hợp lý. Nếu không muốn như vậy, hãy tự vận hành relay.

Để tự vận hành relay, đặt enabled: true bên dưới derp.server trong config.yaml, thay ipv4: 198.51.100.1 và ipv6: 2001:db8::1 được cung cấp sẵn bằng địa chỉ public của relay, hoặc xóa cả hai thiết lập để dùng DNS, sau đó restart headscale và mở cổng STUN (session traversal utilities for NAT) bằng sudo ufw allow 3478/udp. Các thiết lập địa chỉ này ghi đè DNS, vì vậy nếu để lại một placeholder thì client sẽ được trỏ đến địa chỉ không thể truy cập. File cấu hình nêu rõ yêu cầu này: server_url phải dùng https vì DERP yêu cầu TLS. Xóa danh sách derp.urls sẽ loại relay của Tailscale khỏi map; hãy bảo đảm còn một relay embedded hoặc relay tự cấu hình hoạt động trước khi làm vậy. Headscale từ chối khởi động khi relay map trống. Nếu map chỉ chứa một relay không thể truy cập, các node không thể kết nối trực tiếp cũng sẽ không thể giao tiếp.

Từ client, tailscale netcheck in ra độ trễ đến từng vùng relay mà client nhận biết. tailscale status hiển thị direct kèm địa chỉ hoặc relay kèm mã vùng cho các kết nối peer đang hoạt động. Peer bị kẹt ở relay cần được kiểm tra đường kết nối trực tiếp, bao gồm NAT và rule của firewall. Peer đang ở direct nhưng vẫn chậm là một vấn đề khác; câu trả lời thường là MTU chứ không phải chính tunnel.

Vì sao một node hiển thị là offline?

Proxy đang loại bỏ yêu cầu upgrade. Dấu hiệu là /health trả về 200, trong khi việc đăng ký node mới thất bại hoặc các node hiện có không thể kết nối lại. Kết nối điều khiển là một POST mang theo Upgrade: tailscale-control-protocol. Nếu proxy không chuyển tiếp yêu cầu này, cả việc đăng ký lẫn channel báo trạng thái node đều bị chặn. Hãy so sánh cấu hình nginx với các dòng upgrade ở trên, hoặc chuyển sang Caddy để loại trừ proxy.

Địa chỉ điều khiển public đã thay đổi. Các node vẫn kết nối đến địa chỉ được cấu hình bằng --login-server. Việc thay đổi server_url không cập nhật cấu hình phía client đó. Nếu địa chỉ cũ không còn trỏ đến server, hãy chạy sudo tailscale up --login-server https://headscale.example.com --force-reauth trên từng node.

Client không chạy. Trên node, hãy chạy sudo systemctl is-active tailscaled và sudo journalctl -u tailscaled -n 50 --no-pager. Client không thể phân giải hoặc kết nối đến domain của bạn sẽ ghi log các lần thử lại tại đó.

Key đã hết hạn. Nội dung này được trình bày trong phần tiếp theo.

Để theo dõi phía server trong lúc kiểm tra, hãy chạy sudo journalctl -u headscale -f trên VPS và restart tailscaled trên client. Đồng thời kiểm tra journal của client. Một request đến được headscale không đảm bảo sẽ tạo ra một dòng log ở log level mặc định. Vì vậy, chỉ riêng việc server không có log không đủ để kết luận lỗi nằm ở DNS, firewall hoặc proxy.

Hết hạn key và node ngừng hoạt động vài tuần sau

Có hai loại thời hạn riêng biệt. Nhầm lẫn giữa chúng sẽ làm mất thời gian.

Preauth key hết hạn nhanh theo thiết kế. Mặc định là 1 giờ và chỉ dùng được 1 lần. Nếu tailscale up từ chối key, hãy tạo key mới trên server thay vì chỉnh sửa bất kỳ thứ gì trên client.

Node key là phần có thời hạn dài hơn. Phần node của config.yaml đặt expiry: 0, còn 0 nghĩa là không có thời hạn mặc định; thời hạn do client chỉ định hoặc thời hạn OIDC vẫn có thể được áp dụng. Node đã gắn tag không bị hết hạn tự động, nhưng administrator vẫn có thể cho hết hạn thủ công. Đặt expiry: 180d nếu muốn thời hạn mặc định là 180 ngày cho các lần đăng ký không có tag. Tuy nhiên, thời hạn do client yêu cầu sẽ được ưu tiên và OIDC có thể ghi đè giá trị mặc định. Thay đổi setting này không thay đổi ngược thời hạn của các lần đăng ký hiện có. Node có thời hạn phải xác thực lại trước thời điểm đó bằng sudo tailscale up --login-server https://headscale.example.com --force-reauth. Nếu không ai xác thực lại một headless server, server đó sẽ bị ngắt khỏi network khi registration hết hạn.

Hãy thực hiện thủ công khi ai đó làm mất laptop. sudo headscale nodes list cung cấp ID, sau đó sudo headscale nodes expire -i 3 đăng xuất node đó, còn sudo headscale nodes delete -i 3 xóa hoàn toàn node khỏi network.

Bản sao lưu và nâng cấp

/var/lib/headscale và /etc/headscale cùng nhau tạo thành toàn bộ máy chủ. Hãy dừng service trước khi sao chép chúng, vì SQLite có thể đang ghi dữ liệu và bản sao cơ sở dữ liệu được tạo khi đang tải có thể không nhất quán.

sudo systemctl stop headscale
sudo tar czf /root/headscale-state.tgz -C /var/lib headscale
sudo tar czf /root/headscale-config.tgz -C /etc headscale
sudo systemctl start headscale
sudo chmod 600 /root/headscale-*.tgz

Chuyển cả hai file ra khỏi máy chủ. Chúng chứa private key và toàn bộ thông tin đăng ký, nên cần được bảo vệ như chính máy chủ. bản sao lưu restic từ VPS trình bày cách thực hiện việc này theo lịch và có mã hóa.

Nâng cấp cũng lặp lại quy trình cài đặt: tải .deb, sudo apt install ./headscale.deb mới, sau đó khởi động lại và chạy lại các bước kiểm tra is-active và /health. Từ phiên bản 0.29, quy trình nâng cấp được kiểm soát chặt chẽ. Không thể bỏ qua một phiên bản minor, và cũng không thể hạ cấp xuống phiên bản minor cũ hơn. Hãy nâng cấp từng phiên bản minor một, tạo bản sao lưu trước mỗi bước và đọc release notes của phiên bản đó trước, vì release này đã thay đổi hành vi của chính sách ACL và di chuyển một số configuration key. Version 0.29.6 cũng bao gồm các bản cập nhật bảo mật cho việc xác thực chứng chỉ và các dependency, vì vậy các hệ thống đang chạy 0.29 nên cài bản patch release này.

FAQ

headscale đã chạy ngay sau khi tôi cài .deb chưa?

Có. Package khởi động service ngay sau khi cài, với /etc/headscale/config.yaml được cung cấp, chỉ lắng nghe trên loopback và đặt server_url thành http://127.0.0.1:8080. Khi cài mới, package không enable service, nên service sẽ không khởi động lúc boot cho đến khi bạn chạy sudo systemctl enable headscale. Địa chỉ được cung cấp không dùng được cho client, nên hãy sửa server_url, listen_addr và base_domain, sau đó chạy sudo systemctl restart headscale và xác nhận bằng sudo systemctl is-active headscale. Giá trị này phải là restart: headscale chỉ đọc file khi khởi động, còn enable --now trên một service đang chạy sẽ enable service để khởi động cùng boot nhưng không restart service, nên các giá trị cũ vẫn đang được dùng. Nếu service fail sau khi restart, sudo journalctl -u headscale -n 50 --no-pager sẽ chỉ ra vấn đề. Ở giai đoạn này, nguyên nhân gần như luôn là lỗi YAML, vì headscale phân tích toàn bộ file trước khi bind vào một cổng.

Tôi vẫn cài Tailscale client thông thường trên các máy của mình chứ?

Có. Headscale chỉ thay thế control server. Mỗi node chạy client chính thức của Tailscale, và bạn trỏ client đến server bằng sudo tailscale up --login-server https://headscale.example.com. Flag đó có trong client tiêu chuẩn, nên không cần patch hoặc build lại gì cả.

Traffic của tôi có đi qua headscale server không?

Thông thường là không. Headscale điều phối network, đồng thời cấp key và địa chỉ, còn data path là WireGuard kết nối trực tiếp giữa các node. Traffic chỉ đi đường vòng khi hai node không thể kết nối trực tiếp và phải fallback sang một DERP relay. Với configuration được cung cấp, các relay đó là relay public của Tailscale. Chạy tailscale status trên một node để xem một peer cụ thể đang direct hay đang dùng relay.

Vì sao node của tôi vẫn offline sau khi register?

Một node xuất hiện trong headscale nodes list nhưng không bao giờ online cần được kiểm tra control connection, bao gồm cả reverse proxy. Đây là một HTTP upgrade được gửi dưới dạng POST với header Upgrade: tailscale-control-protocol. nginx sẽ loại bỏ connection này nếu bạn không forward rõ ràng các header Upgrade và Connection bằng proxy_set_header. Configuration ở trên thực hiện việc đó trong block map $http_upgrade $connection_upgrade. Việc loại bỏ các header này cũng ngăn node mới register. Caddy forward connection này mà không cần configuration bổ sung, nên đây là cách nhanh để kiểm tra proxy có phải nguyên nhân hay không.

Tôi có cần domain name và TLS cho headscale không?

Có, với setup này: hãy dùng domain name và HTTPS. Certificate cũng có thể bao phủ địa chỉ IP thuần, nhưng configuration file nêu rõ rằng DERP yêu cầu TLS. Domain kết hợp với Caddy thường mất khoảng 5 phút để thiết lập và cung cấp một HTTPS endpoint có thể tự gia hạn. HTTP thuần vẫn dùng được, nhưng tài liệu headscale khuyến nghị mạnh HTTPS trên port 443 cho production, đồng thời lưu ý rằng Tailscale client giả định HTTPS trên port 443 trong một số tình huống.

Bài viết này có hữu ích không?