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

Tailscale thay port forwarding cho NAS, Pi, game server

Truy cập NAS, Raspberry Pi hoặc Minecraft server mà không mở port router. Xem Tailscale vượt NAT, khi dùng relay và giới hạn với người ngoài tailnet.

Tailscale có cần port forwarding không?

Tailscale không cần port forwarding. Với việc truy cập các máy của chính bạn, Tailscale thay thế hoàn toàn port forwarding. Mỗi thiết bị trong tailnet của bạn (mạng riêng mà Tailscale tạo giữa các thiết bị) tự mở các kết nối outbound. Bạn không cần thay đổi gì trên router gia đình: không cần forward port, không cần máy chủ DMZ (demilitarized zone), không cần bản ghi dynamic DNS và không cần public IP. NAS (thiết bị lưu trữ nối mạng), Raspberry Pi hoặc game server nằm sau router ipTIME hoặc Fritz!Box có thể được truy cập từ laptop của bạn ở bất kỳ đâu bằng private address riêng, trong khi phía inbound của router vẫn đóng.

Phạm vi những việc Tailscale không làm cũng rất rõ ràng. Tailscale kết nối các thiết bị đã đăng nhập vào tailnet của bạn hoặc đã được chia sẻ vào tailnet đó. Người lạ trên Internet hoặc bạn bè chưa tham gia không thể truy cập bất kỳ thứ gì thông qua Tailscale. Việc public một service cho toàn bộ Internet là một công việc khác và được trình bày gần cuối.

Cách Tailscale vượt qua NAT mà không cần forward port

Port forwarding tồn tại vì NAT (network address translation). Trong hầu hết kết nối gia đình, router của bạn giữ một địa chỉ IPv4 public, còn mọi thiết bị phía sau nó dùng địa chỉ private. Gói tin inbound đến router không cho biết thiết bị private nào muốn nhận gói tin, nên router sẽ drop gói tin đó. Port forward là rule thủ công cho biết “port 25565 thuộc về 192.168.0.20”. Tailscale đạt được kết quả tương tự mà không cần rule này, qua 4 bước.

Đầu tiên, mọi node đều chủ động kết nối ra ngoài. Khi khởi động, tailscaled kết nối đến coordination server. Nó ưu tiên HTTP thuần trên TCP 80, được bọc trong transport đã mã hóa riêng, và chuyển sang HTTPS trên TCP 443 khi port 80 không phản hồi. Nó gửi public key của WireGuard và nhận public key cùng địa chỉ của mọi node khác trong tailnet. Coordination server không truyền traffic của bạn; nó chỉ cung cấp key và address book.

Thứ hai, mỗi node xác định router đang ánh xạ nó ra bên ngoài như thế nào. Node gửi yêu cầu STUN (session traversal utilities for NAT) qua UDP đến port 3478 trên relay server của Tailscale. Phản hồi chứa public IP và port mà router đã gán cho gói tin outbound đó. Đây là mapping mà port forward lẽ ra phải tạo thủ công, nhưng router tự tạo mapping này cho một outbound flow. Nếu router hỗ trợ UPnP hoặc NAT-PMP, Tailscale cũng tự động yêu cầu router tạo mapping, việc này có thể hữu ích nhưng không bắt buộc.

Thứ ba, hai phía thực hiện hole punching. Node A và node B nhận public endpoint của nhau thông qua coordination server. Cả hai đồng thời gửi gói UDP từ listener của mình, mặc định là port 41641, đến public endpoint của phía còn lại. Router của mỗi phía đã có outbound mapping cho node tương ứng, nên gói tin từ phía kia khớp với mapping đó và được cho phép đi vào. Từ thời điểm này, hai node giao tiếp trực tiếp qua WireGuard, trong khi router vẫn không có rule nào.

Thứ tư, khi hole punching thất bại, traffic tiếp tục đi qua relay. Mọi connection thực tế ban đầu đều đi qua một DERP (designated encrypted relay for packets) server. DERP truyền các gói WireGuard đã mã hóa qua HTTPS trên TCP 443, sau đó Tailscale cố nâng cấp connection lên đường UDP trực tiếp ở bước 3. CGNAT (carrier-grade NAT, trong đó ISP đặt bạn phía sau một lớp NAT thứ hai do ISP kiểm soát) và symmetric NAT (trong đó router chọn port mới cho từng destination, khiến phản hồi STUN không còn hữu ích) đều ngăn việc nâng cấp này. Corporate firewall chặn UDP cũng có tác dụng tương tự. Khi việc nâng cấp thất bại, Tailscale trước tiên thử peer relay, tức một thiết bị trong tailnet của bạn đã được cấu hình để relay traffic qua UDP. Nếu không có peer relay, connection tiếp tục đi qua DERP. Relay chỉ nhìn thấy ciphertext. Cách này cũng làm tăng latency và giảm throughput. vì sao connection Tailscale qua relay chậm và cách chuyển sang kết nối trực tiếp giải thích cách xác định path hiện tại và những gì cần thay đổi.

Không bước nào trong 4 bước trên tạo inbound connection đến router của bạn. Đó là toàn bộ lý do bạn không cần port forward.

Cài client và kiểm tra đường kết nối

Quá trình cài đặt gồm một script và một lần đăng nhập trên mỗi thiết bị.

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
tailscale ip -4

tailscale up in ra một URL đăng nhập. Mở URL đó, đăng nhập, rồi thiết bị sẽ tham gia tailnet. tailscale ip -4 in ra địa chỉ tailnet của thiết bị trong dải 100.64.0.0/10. Địa chỉ này không đổi sau khi reboot hoặc khi chuyển sang mạng khác, nên đây là địa chỉ cần ghi vào cấu hình SSH và các game client.

Từ thiết bị thứ hai trong tailnet, kiểm tra đường kết nối đến thiết bị thứ nhất:

tailscale ping nas

Dùng hostname hoặc địa chỉ tailnet. Phản hồi đầu tiên thường hiển thị via DERP, vì mọi kết nối đều bắt đầu qua relay trong khi đường kết nối trực tiếp vẫn đang được thương lượng. Sau vài giây, phản hồi sẽ chuyển sang IP public và port, nghĩa là hole punching đã thành công. Nếu sau một phút phản hồi vẫn hiển thị via DERP, quá trình hole punching không hoàn tất. Nguyên nhân thường là một phía nằm sau NAT mà hole punching không thể vượt qua, hoặc mạng chặn UDP. Khi đó, kết nối đang đi qua relay.

Quy tắc firewall đáng thêm

Tailscale hoạt động mà không cần thay đổi firewall trên hầu hết mạng, vì lưu lượng UDP outbound thường được cho phép. Một quy tắc tùy chọn có thể tăng khả năng thiết lập đường truyền trực tiếp: cho phép UDP outbound từ port 41641.

Trên router gia đình hoặc firewall của nơi làm việc có hạn chế UDP outbound, điều này có nghĩa là cho phép các thiết bị gửi UDP với source port 41641 đến mọi địa chỉ và mọi destination port, đồng thời cho phép UDP outbound đến destination port 3478 để dùng STUN. Chỉ cho phép destination port 41641 là chưa đủ, vì NAT hoặc cấu hình của peer có thể đặt đầu kết nối của peer trên bất kỳ port nào. Hầu hết router gia đình đã cho phép toàn bộ UDP outbound, nên không cần làm gì thêm.

Trên VPS, hướng hữu ích là inbound. VPS thường có public IP trên network interface riêng, hoặc nhiều nhất là một one-to-one NAT cố định như NAT do AWS internet gateway thực hiện. Vì vậy, quy tắc cho phép UDP inbound trên port 41641 sẽ cung cấp cho mọi peer một đích ổn định và có thể truy cập. Khi đó, một peer phía sau NAT khó vượt qua thường vẫn có thể kết nối trực tiếp, miễn là mạng của peer đó cho phép UDP outbound. Peer trên mạng chặn UDP vẫn dùng relay, bất kể VPS cho phép gì. Với ufw:

sudo ufw allow 41641/udp
sudo ufw status

ufw status phải liệt kê 41641/udp là ALLOW từ Anywhere. Nhà cung cấp có network firewall riêng trong control panel cũng cần thêm quy tắc tương tự tại đó, vì packet bị chặn ở biên của nhà cung cấp sẽ không bao giờ đến được ufw. Quy tắc này chỉ giúp việc kết nối thuận tiện hơn, không bắt buộc. Khi port bị đóng, VPS vẫn tham gia tailnet và các peer vẫn truy cập được VPS; một số peer sẽ đi qua relay thay vì kết nối trực tiếp.

Truy cập NAS gia đình hoặc Raspberry Pi từ bên ngoài

Trường hợp đầu tiên là đơn giản nhất. Đây cũng là điều hầu hết mọi người muốn nói khi nói “port forwarding với Tailscale”: truy cập một thiết bị ở nhà từ laptop hoặc điện thoại không ở nhà.

Cài client trên thiết bị ở nhà và trên laptop. Toàn bộ cấu hình chỉ có vậy. NAS hoặc Pi sẽ nhận kết nối trên địa chỉ tailnet cho mọi service đang listen trên tất cả interface, mà không cần forward cổng nào. Service chỉ bind vào 127.0.0.1 hoặc địa chỉ LAN vẫn không hiển thị trên tailnet cho đến khi bạn thay đổi địa chỉ mà service listen.

ssh pi@100.101.102.103
curl -I http://100.101.102.103:8080/

Thay địa chỉ bằng kết quả của tailscale ip -4 trên thiết bị ở nhà. Đăng nhập SSH phải hoạt động giống hệt như khi laptop kết nối vào Wi-Fi ở nhà. curl -I phải in ra dòng trạng thái HTTP của web app đang chạy trên thiết bị. Vì kết nối được xác thực bằng các WireGuard key gắn với thiết bị đã đăng nhập, những service vốn nguy hiểm nếu mở qua một cổng được forward, chẳng hạn SMB (server message block) share hoặc web admin panel, vẫn có thể dùng an toàn trong trường hợp này: chỉ các thiết bị của bạn mới có thể gửi packet đến service. Router ipTIME hoặc Fritz!Box ở giữa không bao giờ thấy kết nối inbound và không cần thay đổi cấu hình. Nếu ISP đặt bạn sau CGNAT, cách này vẫn hoạt động vì thiết bị ở nhà chỉ tạo kết nối outbound. Trong trường hợp xấu nhất, đường truyền sẽ đi qua relay.

MagicDNS, được bật mặc định trên các tailnet mới, cũng cấp cho mỗi node một hostname. Vì vậy, ssh pi@nas sẽ hoạt động ngay khi laptop tham gia tailnet.

Khi thiết bị không chạy được Tailscale: subnet router

Một số thiết bị không thể chạy client: máy in, camera IP, NAS cũ dùng hệ điều hành bị khóa, hoặc smart TV. Subnet router giải quyết trường hợp này. Một máy trong mạng gia đình có thể chạy Tailscale (một Pi là đủ) sẽ quảng bá toàn bộ subnet gia đình. Các thiết bị khác trong tailnet sẽ định tuyến đến subnet đó thông qua máy này.

echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-tailscale.conf
sudo sysctl --system
sudo tailscale up --advertise-routes=192.168.0.0/24

Sử dụng subnet gia đình thực tế của bạn. Sau đó, route cần được phê duyệt trong admin console, tại phần cài đặt route của máy. Các client Linux phải opt in bằng sudo tailscale set --accept-routes. Sau đó, ping 192.168.0.50 từ laptop có thể truy cập camera ở nhà. sysctl bật forwarding rất quan trọng. Nếu không bật, Pi sẽ loại bỏ mọi packet không gửi đến chính nó. Khi đó, route vẫn hiển thị là đã được phê duyệt nhưng không thiết bị nào phía sau route phản hồi. Bước phê duyệt, tùy chọn opt in phía client và các nguyên nhân khác khiến route đã được phê duyệt nhưng không thể truy cập được được trình bày trong chạy Tailscale subnet router. Phần đó dùng VPS làm router nhưng áp dụng không thay đổi cho Pi đặt trong phòng khách.

Cho bạn bè tham gia Minecraft server mà không cần mở router

Trường hợp thứ hai: Minecraft server chạy trên một PC ở nhà và bạn bè muốn tham gia. Cách cũ là forward TCP 25565 trên router rồi cung cấp public IP cho bạn bè. Cách này cũng để mọi scanner trên Internet thấy địa chỉ đó. Tailscale thay thế cách này bằng tính năng chia sẻ.

Có 2 tùy chọn. Tùy chọn đầu tiên là mời bạn bè vào tailnet của bạn dưới dạng user. Cách này hoạt động, nhưng số user seat trong free plan có giới hạn, và theo mặc định, user được mời có thể truy cập mọi thiết bị trong tailnet của bạn. Quyền này rộng hơn mức cần thiết cho một game, trừ khi bạn viết access rule để giới hạn lại. Tùy chọn thứ hai và đơn giản hơn là node sharing. Trong admin console, mở trang Machines, tìm game PC, mở menu của máy rồi chọn Share. Tailscale tạo một invitation link. Mỗi người bạn cần có free Tailscale account riêng. Account đó là owner của một tailnet nhỏ riêng, và người bạn phải accept link bằng account đó. Sau đó, máy được chia sẻ xuất hiện trong danh sách máy của họ, và chỉ máy đó xuất hiện. Tính năng sharing cấp cho người nhận quyền truy cập vào máy được chia sẻ, không cấp quyền truy cập vào bất kỳ máy nào khác trong tailnet của bạn. Máy được chia sẻ cũng bị quarantine theo mặc định: máy này có thể nhận connection từ tailnet của người bạn nhưng không thể tự khởi tạo connection nào.

Bạn bè thêm server trong Minecraft bằng địa chỉ tailnet của máy, 100.101.102.103:25565, hoặc chỉ dùng địa chỉ này nếu port là port mặc định. Game PC không cần forward port nào, và router không phải thay đổi cấu hình. Máy được chia sẻ không advertise subnet route, nên sharing phù hợp với service chạy ngay trên máy được chia sẻ. Đây chính xác là trường hợp của game server.

Giới hạn là mọi người chơi đều phải chạy Tailscale và accept share. Với một nhóm bạn, điều này không thành vấn đề. Với public server cho phép bất kỳ ai tham gia thì không phù hợp. Hai section tiếp theo sẽ trình bày cách xử lý trường hợp đó.

Chạy game server trên VPS và giữ RCON trong tailnet

Cách khác để không phải port forwarding là ngừng host game ở nhà. VPS có public IP và có thể nhận kết nối trực tiếp, nên game port có thể mở ra Internet mà không cần router ở nhà. Chạy Minecraft server trên VPS trình bày cách chọn cấu hình, các Java flag, backup và systemd unit. Phần quan trọng ở đây là những port nào được mở ra Internet.

Minecraft server mở 2 port. TCP 25565 là port của game và người chơi cần port này. TCP 25575 là RCON (remote console), nhận password rồi chạy mọi server command, bao gồm op và stop. RCON port mở ra Internet sẽ trở thành mục tiêu để đoán password. Đưa VPS vào tailnet và đặt rule khác nhau cho 2 port:

sudo ufw allow OpenSSH
sudo ufw allow 25565/tcp
sudo ufw allow in on tailscale0 to any port 25575 proto tcp
sudo ufw enable
sudo ufw status

Rule thứ hai mở game cho mọi nguồn. Rule thứ ba chỉ mở RCON cho các packet đến từ interface tailscale0, tức là chỉ từ các thiết bị trong tailnet và những người bạn đã share VPS. Nếu share VPS, hãy dùng access rule trong tailnet policy để ngăn người dùng được share truy cập port 25575, vì chỉ dùng interface rule thì không thể phân biệt họ với thiết bị của bạn. Public IP vẫn trả lời trên port 25565, còn kết nối đến port 25575 từ phía public sẽ bị ufw drop theo default deny policy. Hãy kiểm tra cả 2 port từ laptop của bạn, thiết bị đang ở trong tailnet:

nc -zv 100.101.102.103 25575
nc -zv <vps-public-ip> 25575

Lệnh đầu tiên phải in ra succeeded. Lệnh thứ hai sẽ treo rồi timeout, vì packet đến từ public interface và không khớp với allow rule nào. Cùng mô hình này áp dụng được cho SSH, web map, database hoặc metrics dashboard: public port trên public IP, còn admin port chỉ mở trên tailscale0.

Expose một dịch vụ ra toàn bộ Internet: Funnel hoặc reverse tunnel qua VPS

Trường hợp thứ ba là điều mà riêng Tailscale không giải quyết được. Blog, public API, public game server, status page: khách truy cập không nằm trong tailnet của bạn và sẽ không bao giờ nằm trong đó. Có 2 công cụ xử lý việc này, và mỗi công cụ có một bài viết riêng.

Tailscale Funnel publish một dịch vụ HTTPS từ một node ra public Internet thông qua các relay của Tailscale. Công cụ này chỉ hoạt động qua TLS (transport layer security) và chỉ trên các cổng 443, 8443 và 10000. Vì vậy, nó phù hợp với web app nhưng không phù hợp với raw game protocol trên cổng 25565. Tailscale Serve và Funnel giải thích mỗi công cụ publish dịch vụ nào và cho những ai.

VPS reverse tunnel xử lý mọi trường hợp còn lại. Máy chủ ở nhà mở một tunnel outbound đến VPS có public IP. VPS chuyển tiếp một public port ngược qua tunnel, bằng TCP hoặc UDP, trên bất kỳ số cổng nào. Đây là công cụ phù hợp cho public Minecraft server chạy tại nhà phía sau CGNAT. Bài reverse tunnel qua VPS cho máy chủ gia đình phía sau CGNAT hướng dẫn chi tiết cách triển khai. Hãy chọn một trong 2 cách này và đừng tiếp tục tìm một thiết lập Tailscale để mở cổng ra toàn bộ Internet. Không có thiết lập như vậy.

Tailscale không làm được gì

  • Tailscale không chuyển tiếp một cổng cho các client public tùy ý. Packet từ bên ngoài tailnet không bao giờ đến được node của bạn vì không có WireGuard key tương ứng. WireGuard packet không có key hợp lệ sẽ bị drop mà không có phản hồi.
  • Tailscale không cung cấp cách để người dùng public truy cập vào. Người dùng phải là thành viên của tailnet hoặc đã chấp nhận một node được chia sẻ.
  • Tailscale không đảm bảo có đường kết nối trực tiếp. Khi gặp NAT khó, kết nối sẽ được relay nên chậm hơn.
  • Tailscale không mở router. Router vẫn đóng, và đó chính là mục đích.

FAQ

Tailscale có cần port forwarding không?

Không. Mọi node Tailscale chỉ thực hiện các kết nối outbound. Nó kết nối đến coordination server qua TCP 80, chuyển sang HTTPS trên TCP 443 nếu cổng 80 không phản hồi, và xác định địa chỉ public của nó bằng STUN trên UDP 3478. Mọi kết nối giữa các peer ban đầu được chuyển tiếp qua DERP trên TCP 443 (vẫn là outbound), sau đó được nâng cấp lên đường truyền trực tiếp bằng kỹ thuật UDP hole punching từ cổng 41641. Khi hole punching thất bại, lưu lượng sẽ chuyển sang peer relay nếu bạn đã cấu hình, hoặc tiếp tục chạy qua DERP. Router tại nhà không bao giờ cần mở port hay thiết lập DMZ, và thiết bị nằm sau CGNAT cũng tham gia mạng theo cách tương tự.

Tailscale có thể thay thế port forwarding cho server Minecraft không?

Có, đối với server mà bạn bè của bạn tham gia. Hãy cài đặt Tailscale trên máy tính chạy game, chia sẻ máy đó với từng người bạn từ trang Machines trong admin console, và họ sẽ kết nối đến địa chỉ tailnet của máy đó trên cổng 25565 mà không cần mở port nào. Nó không thay thế được port forwarding cho một server public, vì những người chơi bên ngoài tailnet của bạn không thể truy cập vào node đó. Với trường hợp đó, hãy host game trên VPS có public IP và giữ RCON trên tailnet, hoặc dùng reverse tunnel từ máy ở nhà đến VPS.

Tailscale sử dụng những cổng nào?

Bốn cổng. TCP 80 outbound là kết nối ưu tiên đến coordination server, được truyền tải trong giao thức mã hóa riêng của Tailscale. TCP 443 outbound là kết nối dự phòng khi cổng 80 không phản hồi, và nó luôn truyền tải lưu lượng DERP relay. UDP 3478 outbound là STUN, dùng để phát hiện địa chỉ public. UDP 41641 là cổng WireGuard mặc định để kết nối trực tiếp: các gói tin đi từ cổng này đến bất kỳ cổng nào mà phía peer sử dụng, và có thể thay đổi nếu cổng 41641 đã bị chiếm. Không cổng nào trong số này cần mở inbound, và việc chặn TCP 80 cũng không sao vì client sẽ tự chuyển sang 443. Việc cho phép inbound UDP 41641 trên VPS là tùy chọn và giúp các peer có đường truyền trực tiếp thường xuyên hơn.

Tại sao kết nối Tailscale của tôi bị relay thay vì kết nối trực tiếp?

tailscale ping liên tục phản hồi via DERP khi quá trình UDP hole punch không thể hoàn tất. Các nguyên nhân thường gặp là NAT không thể xuyên qua (CGNAT, hoặc symmetric NAT gán cổng mới cho mỗi đích đến) và firewall chặn outbound UDP. Hãy khắc phục những gì bạn kiểm soát được: cho phép outbound UDP đi từ cổng 41641 đến bất kỳ cổng đích nào, cho phép outbound UDP đến cổng 3478, hoặc đặt một peer trên VPS với inbound UDP 41641 đã mở, để quá trình hole punch của phía bên kia có một đích đến cố định và có thể truy cập được. Một peer mà mạng của chính nó chặn UDP thì dù thế nào vẫn sẽ bị relay.