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

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à một bản triển khai tự host của control server Tailscale. 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 community project 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 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. Tunnel vẫn dùng WireGuard và được tạo 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 kết nối 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 quyền điều phối, không thay đổi những gì hệ thống có thể thực hiện. Vì vậy, trước khi xem việc chuyển đổi 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.

Mỗi instance Headscale phục vụ một tailnet (một Tailscale network). Project mô tả mô hình này là phù hợp cho mục đích cá nhân hoặc một tổ chức nhỏ. Với ba hoặc bốn máy, một WireGuard VPN đơn giản trên VPS do bạn sở hữu sẽ có ít phần mềm cần vận hành hơn và ít thứ có thể hỏng hơn. Headscale hữu ích khi bạn không còn muốn tự viết một block [Peer] cho từng laptop mới. Chi phí thường là lý do đầu tiên khiến mọi người tìm đến giải pháp này. Vì vậy, bạn nên đọc gói miễn phí được host thực sự bao gồm những gì trước khi tự vận hành 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ếu bạn đã vượt giới hạn này, hãy tính toán dựa trên chi phí các gói trả phí, được tính theo user thay vì theo device, vì một gia đình dùng chung một account có thể vẫn trả ít tiền ngay cả khi số lượng device tăng cao. Nếu bạn muốn tự host control plane nhưng muốn dùng client riêng và web interface để quản lý peer, thay vì một bản thay thế drop-in cho Tailscale, thì NetBird trên một VPS duy nhất là lựa chọn đáng cân nhắc. Để 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.

Bạn cần chuẩn bị gì 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 mới, trước tiên hãy làm theo 10 phút đầu tiên trên 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 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.

Cài 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 tháng 7 năm 2026, bản phát hành hiện tại là 0.29.3. Kiểm tra architecture trước vì tên file chứa thông tin này.

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

Lệnh này in 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.3"
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, apt sẽ tìm gói có tên headscale.deb trong các repository của bạn rồi fail.

Gói này tạo system user headscale, ghi file cấu hình mặc định /etc/headscale/config.yaml, cài systemd unit, sau đó enable và start service. Vì vậy, headscale đã chạy khi apt trả về, và sudo systemctl is-active headscale in active. Tuy nhiên, service đang chạy với cấu hình được đóng gói sẵn. Cấu hình đó trỏ server_url đến http://127.0.0.1:8080, đây không phải địa chỉ mà client của bạn có thể truy cập. Hiện chưa có gì được expose vì listen_addr được bind vào loopback, nhưng không được join bất kỳ client nào cho đến khi bạn thiết lập 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 có 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 3 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, đồng thời là tài liệu tham khảo tốt nhất cho các thiết lập 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ỉ mà headscale ghi vào mọi lần đăng ký client. Sau đó, client luôn kết nối đến đúng chuỗi này, vì vậy giá trị này phải là tên public có https:// ở phía trước, không bao giờ là 127.0.0.1.

listen_addr là địa chỉ process bind vào. Giữ nguyên trên loopback. Reverse proxy trên cùng máy chủ sẽ thực hiện TLS termination (transport layer security) và chuyển tiếp đến địa chỉ này, vì vậy không cần cho phép kết nối từ bên ngoài máy chủ đến port 8080.

base_domain là hậu tố MagicDNS, tức domain mà các node được cấp tên bên dưới. Giá trị này phải là một fully qualified domain name không có dấu chấm ở cuối, đồng thời phải khác domain trong server_url, vì nếu không hai namespace sẽ xung đột.

Giữ nguyên phần database. Giá trị mặc định là 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 dịch vụ đang chạy

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

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

Nếu is-active in bất kỳ giá trị nào khác active, hoặc curl không in 200, hãy đọc journal bằng sudo journalctl -u headscale -n 50 --no-pager. Ở bước này, lỗi 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 đó, indent sai hoặc key không xác định sẽ dừng tiến trình trước khi có bất kỳ tiến trình nào listening. Sửa file, rồi sudo systemctl restart headscale. Mọi thay đổi cấu hình sau đó cũng cần khởi động lại như vậy. Client sẽ tự kết nối lại sau đó. Nếu bạn chưa quen với systemd unit, chạy các service và timer của riêng bạn bằng systemd giải thích các lệnh được dùng ở đây.

Kiểm tra các file trạng thái 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 mà package đã tạo. noise_private.key là identity của server đối với các client. Giữ lại file này. Nếu bạn xóa nó, headscale sẽ tạo identity mới và mọi node phải đăng ký lại.

Đặt TLS phía trước headscale

Client phải truy cập server_url qua HTTPS. Caddy là cách ngắn gọn nhất vì 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 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.

Đây là chi tiết về proxy khiến nhiều người mất cả buổi tối. Kết nối control của Tailscale là một HTTP upgrade, đượ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 header này mà không cần cấu hình thêm. nginx thì không, nên front end nginx cần 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 đó, 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 duy trì lâu không bao giờ được thiết lập, khiến các node đăng ký xong rồi chuyển sang offline. Nếu chọn nginx, Thiết lập 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 xử lý toàn bộ kết nối của client. Cổng 80 chỉ dùng cho HTTP challenge của ACME (môi trường quản lý certificate tự động) và redirect sang HTTPS. Caddy cần cổng này để lấy certificate.

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 nào. Mở cổng 8080 ra Internet sẽ cho client một control channel không mã hóa nhưng không mang lại lợi ích gì. Lưu ý rằng hầu hết provider có thêm một firewall 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 bị đóng ở edge. Kiến thức cơ bản về UFW firewall 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 đã cấp, chẳng hạn 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.

Giá trị của --login-server phải khớp chính xác với server_url, bao gồm scheme và không có dấu gạch chéo ở cuối. Chúng được so sánh dưới dạng chuỗi. Nếu không khớp, client sẽ đăng ký với một địa chỉ rồi được yêu cầu kết nối đến địa chỉ khác.

Máy trước đó đã đăng nhập vào hosted service của Tailscale vẫn giữ phiên đăng nhập đó. Trước tiên hãy chạy sudo tailscale logout trên má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ý, rồi 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 mọi thứ được script hóa vì không cần người ngồi theo dõi. Sau khi chính VPS trở thành một node, VPS cũng có thể chuyển tiếp lưu lượng Internet của các máy khác, tức cấu hình exit node. Đ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ì dùng VPS làm đường ra Internet, cùng bước approval đó sẽ áp dụng cho việc quảng bá subnet đó đến phần còn lại của tailnet. Publish một ứng dụng từ node, thay vì định tuyến toàn bộ network qua node đó, là một việc khác; serve và funnel là 2 cách để thực hiện, nhưng cả 2 đề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 truyền trực tiếp không hoạt động

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 nghiêm ngặt (network address translation), chúng sẽ gửi packet qua một 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 node nào đang liên lạc với nhau và lượng dữ liệu được truyền.

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, nên 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 phù hợp, hãy tự chạy relay.

Để chạy relay riêng, đặt enabled: true bên dưới derp.server trong config.yaml, khởi động lại headscale và mở cổng STUN (session traversal utilities for NAT) bằng sudo ufw allow 3478/udp. 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 toàn bộ danh sách derp.urls sẽ loại relay của Tailscale khỏi map. Nếu làm vậy mà không có embedded relay hoạt động, mọi cặp node không thể kết nối trực tiếp sẽ hoàn toàn không thể kết nối.

Từ client, tailscale netcheck in độ trễ đến từng relay region mà client biết. tailscale status đánh dấu mỗi peer là direct kèm địa chỉ hoặc relay kèm mã region. Peer bị kẹt ở relay là vấn đề NAT, không phải vấn đề của headscale. Peer ở trạng thái direct nhưng vẫn chậm là một vấn đề khác; câu trả lời thường là MTU, không phải tunnel.

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

Proxy đang loại bỏ upgrade. Đây là nguyên nhân thường gặp nhất. Dấu hiệu là mọi thứ khác đều bình thường: /health trả về 200, headscale nodes list hiển thị node, nhưng node không bao giờ online. Kết nối điều khiển là một POST chứa Upgrade: tailscale-control-protocol. Proxy không forward kết nối này sẽ làm mất kênh duy nhất báo trạng thái node. So sánh cấu hình nginx của bạn với block map ở trên, hoặc chuyển sang Caddy để loại trừ proxy.

server_url đã thay đổi sau khi các node đăng ký. Node tiếp tục kết nối đến giá trị được cấp khi đăng ký. Nếu bạn đã sửa giá trị này, 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, chạy sudo systemctl is-active tailscaled và sudo journalctl -u tailscaled -n 50 --no-pager. Client không thể resolve hoặc kết nối đến domain của bạn sẽ ghi log các lần retry tại đó.

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

Để monitor phía server trong khi kiểm tra, chạy sudo journalctl -u headscale -f trên VPS rồi restart tailscaled trên client. Node kết nối được đến headscale sẽ tạo log ngay lập tức. Nếu không có log, request chưa đến server. Khi đó hãy kiểm tra DNS, firewall và proxy trước khi kiểm tra headscale.

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

Có 2 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à 1 lần sử dụng. 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 thiết lập expiry: 0, còn 0 có nghĩa là không có thời hạn mặc định: node đã đăng ký sẽ tiếp tục hợp lệ cho đến khi bạn cho hết hạn. Node đã gắn tag thì không bao giờ hết hạn. Hãy đặt expiry: 180d nếu bạn muốn các đăng ký tự hết hạn theo thời gian, và cần hiểu rõ hệ quả: khi đó mọi node không có tag đều cần sudo tailscale up --login-server https://headscale.example.com --force-reauth theo lịch đó, còn một server headless không có ai xác thực lại sẽ tự bị loại khỏi network.

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.

Sao lưu và nâng cấp

/var/lib/headscale và /etc/headscale cùng nhau tạo thành toàn bộ server. Hãy dừng service trước khi sao chép chúng, vì SQLite có thể vẫn đang ghi dữ liệu và bản sao database được tạo khi đang chịu 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

Hãy chuyển cả hai file ra khỏi máy. Chúng chứa private key và toàn bộ registration, nên cần được bảo vệ cẩn thận như chính server. sao lưu bằng 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 đó restart 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 rất nghiêm ngặt. Không thể bỏ qua một minor version, và cũng không thể downgrade xuống minor version cũ hơn. Hãy nâng từng minor version một, sao lưu trước mỗi bước, đồng thời đọc release notes của phiên bản đó trước, vì bản release tương ứng đã thay đổi cách hoạt động của ACL policy và di chuyển một số configuration key.

FAQ

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

Có. Package sẽ enable và start service ngay sau khi cài, với /etc/headscale/config.yaml được phát hành kèm package. Service này chỉ listen trên loopback và đặt server_url thành http://127.0.0.1:8080. Địa chỉ đó không dùng được cho client, vì vậy 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 start, còn chạy enable --now trên service đã chạy thì không thay đổi gì. 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 parse toàn bộ file trước khi bind port.

Tôi vẫn phải 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 official client của Tailscale, và bạn trỏ client đến server bằng sudo tailscale up --login-server https://headscale.example.com. Flag đó có sẵn trong client chuẩn, nên không cần patch hoặc build lại.

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, cấp key và address, còn data path dùng WireGuard kết nối trực tiếp giữa các node. Traffic chỉ đi vòng khi 2 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 phát hành kèm package, các relay đó là relay public của Tailscale. Chạy tailscale status trên một node để xem peer cụ thể đang ở trạng thái direct hay đang dùng relay.

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

Node xuất hiện trong headscale nodes list nhưng không bao giờ online thường đã mất control connection tại reverse proxy. Đây là một HTTP upgrade được gửi bằng POST với header Upgrade: tailscale-control-protocol. nginx sẽ drop request này trừ khi bạn thêm block map $http_upgrade $connection_upgrade và các dòng proxy_set_header tương ứng. Caddy forward request này mà không cần configuration bổ sung, nên có thể dùng Caddy để kiểm tra nhanh proxy có phải là nguyên nhân hay không.

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

Về thực tế là có. Client kết nối đến chuỗi bạn đặt trong server_url. Certificate được cấp cho name, không phải bare IP address, và configuration file nêu rõ DERP yêu cầu TLS. Một domain kết hợp với Caddy thường chỉ mất khoảng 5 phút để thiết lập và cung cấp HTTPS endpoint tự renew. Chạy control server bằng plain HTTP nghĩa là mọi trao đổi giữa client và server đều đi qua internet dưới dạng plain text.