Tailscale คืออะไรและมีหลักการทำงานอย่างไร
ทำความเข้าใจการทำงานของ Tailscale ในฐานะ Mesh VPN ที่ใช้โปรโตคอล WireGuard โดยเน้นการเชื่อมต่อแบบ Peer to Peer พร้อมอธิบายกลไก Coordination Server และการทำ NAT Traversal
Tailscale คืออะไร
Tailscale คือ VPN ที่เชื่อมต่อเครื่องของคุณเข้าหากันโดยตรง แทนที่จะส่งผ่านทราฟฟิกทั้งหมดผ่านเกตเวย์ที่คุณดูแลเพียงจุดเดียว ทุกโหนดจะรัน WireGuard ดังนั้นแพ็กเก็ตข้อมูลจะถูกเข้ารหัสจากเซิร์ฟเวอร์หนึ่งไปยังอีกเซิร์ฟเวอร์หนึ่ง และไม่มีสิ่งใดในเส้นทางที่สามารถอ่านข้อมูลเหล่านั้นได้ โดยจะมีเซิร์ฟเวอร์ประสานงาน (coordination server) ที่โฮสต์ไว้ทำหน้าที่แนะนำโหนดต่างๆ ให้รู้จักกัน ซึ่งเซิร์ฟเวอร์นี้จะจัดเก็บและแจกจ่าย public key พร้อมทั้งระบุตำแหน่งของโหนดแต่ละโหนดให้ทราบ รวมถึงส่งกฎการเข้าถึงที่คุณกำหนดไว้ลงไปยังโหนดต่างๆ ด้วย
การแบ่งหน้าที่เช่นนี้คือหัวใจสำคัญของการออกแบบทั้งหมด โดย data plane จะทำงานแบบ peer to peer และมีการเข้ารหัสระหว่างโหนด ส่วน control plane จะเป็นบริการที่ Tailscale ดูแลให้คุณ คำถามที่น่าสนใจทุกประการเกี่ยวกับ Tailscale รวมถึงประเด็นที่ละเอียดอ่อนเรื่องความน่าเชื่อถือ ล้วนมีที่มาจากข้อเท็จจริงสองประการนี้ หากคุณเคย สร้าง WireGuard VPN ด้วยตนเองบน VPS มาก่อน Tailscale ก็คืออุโมงค์เชื่อมต่อแบบเดียวกันนั้น เพียงแต่มีการจัดการเรื่องการแจกจ่ายคีย์และการทะลุผ่านไฟร์วอลล์ไว้ให้คุณเรียบร้อยแล้ว
Tailscale ทำงานอย่างไร
เครือข่ายส่วนตัวของโหนดต่างๆ ของคุณเรียกว่า tailnet เมื่อเครื่องใดเครื่องหนึ่งเข้าร่วมเครือข่าย จะมีกระบวนการ 4 อย่างเกิดขึ้นดังนี้
- daemon
tailscaledจะเริ่มทำงาน สร้างคู่กุญแจ WireGuard และเก็บสถานะไว้ใน/var/lib/tailscale/tailscaled.stateโดยกุญแจส่วนตัว (private key) จะอยู่บนเครื่องนั้นเสมอ Tailscale ระบุไว้อย่างชัดเจนว่า "กุญแจส่วนตัวจะไม่ถูกส่งออกจากโหนดของมันโดยเด็ดขาด" - โหนดจะล็อกอินเข้าสู่ coordination server และอัปโหลดกุญแจสาธารณะ (public key) รวมถึงที่อยู่ที่เครื่องนั้นเชื่อว่าสามารถติดต่อได้ Tailscale อธิบายเซิร์ฟเวอร์นี้ว่าเป็น "กล่องรับฝากกุญแจสาธารณะที่ใช้ร่วมกัน"
- coordination server จะส่งแผนผังเครือข่ายกลับมา ซึ่งประกอบด้วยกุญแจสาธารณะ, ที่อยู่ tailnet, ชื่อเครื่อง และจุดเชื่อมต่อที่เป็นไปได้ของทุกโหนดที่โหนดนี้ได้รับอนุญาตให้ติดต่อ
- จากนั้นโหนดแต่ละคู่จะพยายามสร้างอุโมงค์ WireGuard เชื่อมต่อกันโดยตรง หากไม่สำเร็จ ระบบจะส่งแพ็กเก็ตผ่าน relay แทน
โหนดแต่ละโหนดจะได้รับที่อยู่ที่เสถียรจาก 100.64.0.0/10 ซึ่งเป็นช่วงที่อยู่แบบ carrier-grade NAT ตั้งแต่ 100.64.0.0 ถึง 100.127.255.255 Tailscale ใช้ช่วงที่อยู่นี้เนื่องจากถูกสงวนไว้สำหรับโครงสร้างพื้นฐานของผู้ให้บริการ จึงแทบไม่เกิดการซ้ำซ้อนกับที่อยู่ส่วนตัวที่เซิร์ฟเวอร์ของคุณใช้งานอยู่แล้ว บน Linux อุโมงค์นี้จะปรากฏเป็นอินเทอร์เฟซชื่อ tailscale0
การทำงานของ WireGuard จะอยู่ใน tailscaled ในระดับ userspace ไม่ใช่ kernel module นี่คือเหตุผลที่ Tailscale สามารถเริ่มทำงานบนระบบ container virtualization ที่ sudo modprobe wireguard ไม่สามารถทำงานได้เนื่องจาก Operation not supported นอกจากนี้ยังหมายความว่าขีดจำกัดของปริมาณข้อมูล (throughput) บนเครื่องนั้นจะต่ำกว่าการใช้ WireGuard ในระดับ kernel ซึ่งเป็นหนึ่งในข้อแลกเปลี่ยนที่อธิบายไว้ใน Tailscale เทียบกับ WireGuard แบบปกติ
มีคำสั่ง 2 คำสั่งที่ช่วยให้คุณทราบสถานะปัจจุบัน
tailscale ip -4
tailscale statustailscale status จะแสดงผลลัพธ์บรรทัดละหนึ่งโหนด โดยคอลัมน์สุดท้ายคือข้อมูลที่สำคัญที่สุด
100.101.102.103 web-1 you@ linux -
100.101.102.104 db-1 you@ linux active; direct 198.51.100.24:41641
100.101.102.105 ci-runner you@ linux active; relay "fra"direct ตามด้วยที่อยู่และพอร์ต หมายความว่าเครื่องทั้งสองพบเส้นทางถึงกันและรับส่งข้อมูลแบบ peer to peer ส่วน relay "fra" หมายความว่าข้อมูลกำลังผ่าน Tailscale relay ใน Frankfurt และ - หมายความว่าไม่มีเซสชันที่ใช้งานอยู่กับโหนดนั้นในขณะนี้ ซึ่งถือเป็นเรื่องปกติ
สิ่งที่ coordination server สามารถมองเห็นและไม่สามารถมองเห็นได้
coordination server จะเก็บ public key และ metadata ไว้ โดยเซิร์ฟเวอร์จะทราบชื่อเครื่องของคุณ, ผู้ใช้หรือ tag ที่เป็นเจ้าของแต่ละ node, tailnet address ของแต่ละ node, public address ที่สามารถติดต่อ node ของคุณได้, เวลาที่แต่ละ node ออนไลน์ครั้งล่าสุด และ policy file ที่คุณเขียนขึ้น ข้อมูลเหล่านี้ถือเป็นแผนผังที่สมบูรณ์ของโครงสร้างเครือข่ายทั้งหมดของคุณ
เซิร์ฟเวอร์นี้ไม่มี private key จึงไม่สามารถถอดรหัส traffic ระหว่าง node สองจุดได้ การเข้ารหัสจะเป็นแบบ end-to-end ระหว่าง WireGuard peer โดยที่ coordination server ไม่ได้เป็นส่วนหนึ่งของ peer เหล่านั้น
สิ่งที่เซิร์ฟเวอร์ทำได้คือการแจกจ่าย key ไม่ว่าจะเป็น coordination server แบบโฮสต์หรือแบบที่คุณรันเอง จะได้รับความไว้วางใจให้แจ้งแก่ node ของคุณว่า public key ใดบ้างที่อยู่ใน tailnet นี่คือจุดสำคัญของแบบจำลองภัยคุกคามที่จะกล่าวถึงต่อไป และเป็นเหตุผลว่าทำไม Headscale ซึ่งเป็น coordination server แบบโอเพนซอร์สที่คุณสามารถโฮสต์ได้ด้วยตนเอง จึงถูกสร้างขึ้นมา
วิธีที่เซิร์ฟเวอร์สองเครื่องหลังไฟร์วอลล์ต่างกันสื่อสารกันโดยตรง
NAT (network address translation) คือสิ่งที่ช่วยให้เครื่องหลายเครื่องใช้ที่อยู่สาธารณะร่วมกันได้ โดยปกติแล้ว VPS ของคุณจะมีที่อยู่สาธารณะเป็นของตัวเอง แต่เครื่องอื่นที่คุณต้องการให้เข้ามาอยู่ใน tailnet มักจะไม่มี เช่น เซิร์ฟเวอร์ที่บ้าน, build runner ในเครือข่ายสำนักงาน หรือเครื่องที่อยู่หลังไฟร์วอลล์ของผู้ให้บริการที่คุณไม่สามารถแก้ไขได้
Tailscale ค้นหาเส้นทางโดยใช้เทคนิคที่สร้างขึ้นบนมาตรฐาน STUN (session traversal utilities for NAT) และ ICE โดยแต่ละโหนดจะส่งแพ็กเก็ต UDP ขนาดเล็กไปยังเซิร์ฟเวอร์ STUN และเรียนรู้ที่อยู่สาธารณะรวมถึงพอร์ตที่เร้าเตอร์กำหนดให้กับซ็อกเก็ตนั้น ทั้งสองโหนดจะรายงาน candidate เหล่านั้นไปยังเซิร์ฟเวอร์ประสานงาน ซึ่งจะส่งต่อข้อมูลไปยังอีกฝั่ง จากนั้นทั้งสองโหนดจะเริ่มส่งแพ็กเก็ตหากันในเวลาเดียวกัน เร้าเตอร์ของแต่ละฝั่งจะเห็นแพ็กเก็ตขาออกก่อน จึงสร้างการแมปและยอมรับการตอบกลับที่มาจากที่อยู่เดียวกันนั้น โดยที่ทั้งสองฝั่งไม่จำเป็นต้องมีกฎไฟร์วอลล์ขาเข้า นี่คือเหตุผลที่ NAS หรือ Pi ที่บ้านสามารถเข้าถึงได้โดยไม่ต้องทำ port forwarding บนเร้าเตอร์ของคุณ และ การใช้ Tailscale แทนการทำ port forwarding จะอธิบายขั้นตอนการตั้งค่าดังกล่าว รวมถึงข้อจำกัดที่ทำไม่ได้
พอร์ตที่ใช้มีความเฉพาะเจาะจง อุโมงค์ WireGuard แบบตรงใช้ UDP โดยมีพอร์ตต้นทางเริ่มต้นที่ 41641 ส่วน STUN ทำงานผ่าน UDP 3478 ไปยังเซิร์ฟเวอร์ relay ของ Tailscale การเชื่อมต่อควบคุมจะเลือกใช้ HTTP ปกติบน TCP 80 ซึ่งห่อหุ้มด้วยการขนส่งที่เข้ารหัสของ Tailscale เอง และจะเปลี่ยนไปใช้ HTTPS บน TCP 443 หากพอร์ต 80 ไม่ตอบสนอง ข้อมูลที่ส่งผ่านเซิร์ฟเวอร์ DERP ของ Tailscale จะใช้ HTTPS บน TCP 443 ในขณะที่ peer relay ที่คุณรันภายใน tailnet ของคุณเองจะส่งข้อมูลผ่าน UDP โดยส่วนใหญ่แล้วคุณไม่จำเป็นต้องเปิดพอร์ตขาเข้าใดๆ แม้ว่าในเครือข่ายที่มี NAT ซับซ้อน การอนุญาตให้ UDP 41641 เข้ามาได้จะช่วยให้การเชื่อมต่อโดยตรงมีโอกาสสำเร็จมากขึ้น
tailscale netcheckอ่านสองบรรทัดจากรายงานนั้น UDP: true หมายความว่าเครื่องนี้สามารถส่ง UDP ไปยังอินเทอร์เน็ตได้ และ UDP: false หมายความว่าเครื่องนี้ไม่สามารถทำได้ ดังนั้นทุกการเชื่อมต่อจากโหนดนี้จะถูกส่งผ่าน relay MappingVariesByDestIP: true หมายความว่าเร้าเตอร์กำหนดพอร์ตสาธารณะที่แตกต่างกันสำหรับแต่ละปลายทาง ดังนั้นการคาดการณ์ที่อยู่ข้างต้นจึงใช้งานไม่ได้ และโหนดเหล่านั้นมักจะถูกส่งผ่าน relay เป็นส่วนใหญ่
เมื่อ Tailscale ใช้ DERP relay แทน
DERP (designated encrypted relay for packets) คือกลไกสำรอง Tailscale มี relay ให้บริการในหลายภูมิภาคซึ่งเข้าถึงได้ผ่าน TCP 443 โดยโหนดที่ไม่สามารถสร้างเส้นทางเชื่อมต่อโดยตรงได้จะส่งแพ็กเก็ต WireGuard ผ่าน relay เหล่านี้ ยกเว้นในกรณี tailnet ที่คุณกำหนด peer relay ไว้ ซึ่งก็คืออุปกรณ์ของคุณเองที่ทำหน้าที่ส่งต่อทราฟฟิกผ่าน UDP โดย Tailscale จะพยายามใช้ช่องทางเหล่านั้นก่อน และจะใช้ DERP เป็นลำดับสุดท้ายเมื่อไม่มีช่องทางอื่นใช้งานได้ และ tailscale status จะแสดงสถานะการเชื่อมต่อเป็น peer-relay
แพ็กเก็ตข้อมูลจะยังคงถูกเข้ารหัสไว้ Tailscale ระบุไว้อย่างชัดเจนว่า "ไม่มีวิธีใดที่เซิร์ฟเวอร์ DERP จะถอดรหัสทราฟฟิกของคุณได้ มันเพียงแค่ส่งต่อทราฟฟิกที่เข้ารหัสไว้แล้วจากโหนดหนึ่งไปยังอีกโหนดหนึ่งโดยไม่ทราบเนื้อหาภายใน" เซิร์ฟเวอร์ relay จะเห็นเพียง ciphertext และทราบว่าโหนดใดกำลังสื่อสารกับโหนดใดเท่านั้น
นอกจากนี้ relay ยังทำหน้าที่ส่งแพ็กเก็ตชุดแรกของการเชื่อมต่อส่วนใหญ่ การค้นหาเส้นทางโดยตรงต้องใช้เวลา ดังนั้นเซสชันมักจะเริ่มต้นด้วยการส่งผ่าน relay และจะอัปเกรดเป็นการเชื่อมต่อโดยตรงทันทีที่โหนดทั้งสองพบกัน คุณสามารถตรวจสอบกระบวนการนี้ได้
tailscale ping db-1การตอบกลับชุดแรกจะแสดงเป็น via DERP(fra) จากนั้นบรรทัดถัดมาจะรายงานผลในลักษณะ via 198.51.100.24:41641 การเปลี่ยนแปลงนี้คือการอัปเกรดไปสู่ tunnel แบบโดยตรง หากสถานะไม่เปลี่ยนแปลงเลย ให้รันคำสั่ง tailscale netcheck ที่ปลายทางทั้งสองฝั่ง การเชื่อมต่อผ่าน relay ยังคงใช้งานได้ตามปกติ แต่จะมีค่า latency เพิ่มขึ้นเนื่องจากทุกแพ็กเก็ตต้องอ้อมผ่านเครื่องที่สาม หากสิ่งที่คุณพบคือการถ่ายโอนข้อมูลที่ช้าแทนที่จะเป็นการเชื่อมต่อที่ขาดหายไป เหตุใดการเชื่อมต่อ Tailscale ผ่าน relay จึงช้ากว่าการเชื่อมต่อโดยตรงมาก จะอธิบายถึงความแตกต่างและวิธีนำ VPS เข้าสู่เส้นทางเชื่อมต่อโดยตรง
การเชื่อมต่อ VPS เข้ากับ tailnet ของคุณ
สคริปต์ติดตั้งรองรับ Ubuntu และ Debian
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale upsudo tailscale up จะแสดง URL ขึ้นมา ให้เปิด URL นั้นแล้วยืนยันตัวตน จากนั้นโหนดจะปรากฏใน admin console ของคุณ จากนั้นให้ตรวจสอบว่า daemon กลับมาทำงานหลังการรีบูต เพราะนี่คือขั้นตอนที่ผู้ใช้มักมองข้าม
sudo systemctl is-enabled tailscaled
tailscale statusis-enabled ควรแสดงผลเป็น enabled และ tailscale status ควรแสดงรายการโหนดใหม่พร้อมที่อยู่ IP ในช่วง 100.x สำหรับเซิร์ฟเวอร์ที่สร้างจากสคริปต์ การใช้ URL แบบโต้ตอบนั้นไม่สะดวก ให้สร้าง auth key ใน admin console แล้วส่งค่านั้นพร้อมกับ tag เพื่อระบุประเภทของเครื่องนี้
sudo tailscale up --auth-key=tskey-auth-REPLACE-ME --advertise-tags=tag:serverโหนดที่ติด tag จะถูกเป็นเจ้าของโดย tag นั้นแทนที่จะเป็นบุคคลที่รันคำสั่ง ทำให้โหนดทำงานต่อไปได้แม้บัญชีของผู้รันคำสั่งจะถูกลบไปแล้ว tag จะต้องถูกประกาศไว้ในไฟล์ policy ภายใต้ tagOwners ก่อน มิฉะนั้นคำสั่งจะถูกปฏิเสธ การติด tag ยังส่งผลต่อการนับจำนวนอุปกรณ์ในแผนการใช้งานของคุณ เนื่องจากทรัพยากรที่ติด tag จะถูกคิดราคาแยกจากอุปกรณ์ส่วนตัวของผู้ใช้ โดย สิ่งที่แผนบริการฟรีครอบคลุม จะระบุรายละเอียดเกี่ยวกับขีดจำกัดดังกล่าวไว้
การตั้งค่าสองอย่างมีความสำคัญสำหรับการจัดการกลุ่มเครื่องเซิร์ฟเวอร์ โดยปกติ node key จะหมดอายุหลังจาก 180 วัน (ข้อมูล ณ เดือนตุลาคม 2026) และเมื่อ key หมดอายุ "การเชื่อมต่อจาก/ไปยัง endpoint ดังกล่าวจะหยุดทำงาน" จนกว่าอุปกรณ์จะยืนยันตัวตนใหม่ ผู้ดูแลระบบสามารถเลือก Temporarily extend key บนเครื่องที่หมดอายุใน admin console เพื่อขยายเวลา 30 นาทีสำหรับการล็อกอินใหม่หรือปิดการหมดอายุของ key โหนดที่ยืนยันตัวตนด้วย tag เช่นตัวอย่างข้างต้น จะถูกปิดการหมดอายุของ key ไว้โดยค่าเริ่มต้น สำหรับเซิร์ฟเวอร์ที่ไม่มีผู้ดูแลเครื่องอื่นๆ ให้เปิดแถวของเครื่องนั้นใน admin console แล้วเลือก Disable Key Expiry ส่วน MagicDNS ซึ่งเปิดใช้งานโดยค่าเริ่มต้นสำหรับ tailnet ที่สร้างขึ้นในหรือหลังวันที่ 20 ตุลาคม 2022 จะกำหนดชื่อให้กับแต่ละโหนด เช่น db-1.yak-bebop.ts.net ซึ่งจะถูก resolve โดย stub resolver ที่ 100.100.100.100 ควรใช้ชื่อแทนการใช้ที่อยู่ IP เนื่องจากโหนดที่ถูกสร้างใหม่จะได้รับที่อยู่ใหม่แต่ยังคงใช้ชื่อเดิม
หากการติดตั้งล้มเหลวที่ apt หรือที่ repository ข้อผิดพลาดทั่วไปในการติดตั้ง Tailscale บน Ubuntu ได้รวบรวมวิธีแก้ไขไว้แล้ว
การเข้าถึงบริการที่ผูกไว้กับ localhost
นี่คือจุดที่ tailnet มีประโยชน์และเป็นจุดที่ผู้ใช้งานมักติดปัญหา การเข้าร่วม tailnet ไม่ได้ทำให้บริการที่ผูกกับ loopback สามารถเข้าถึงได้จากภายนอก
ss -tlnp | grep 3000หากคำสั่งดังกล่าวแสดงผลเป็น 127.0.0.1:3000 หมายความว่า socket จะยอมรับเฉพาะแพ็กเกจที่มีปลายทางเป็น 127.0.0.1 เท่านั้น คำขอจากโหนดอื่นจะส่งมายังที่อยู่ 100.x ของโหนดนี้ ทำให้ kernel ไม่มีบริการใดรอรับคำขอและตอบกลับด้วย TCP reset ส่งผลให้ฝั่งไคลเอนต์รายงานข้อผิดพลาด Connection refused ตัวอุโมงค์เครือข่ายทำงานปกติ แต่ปัญหาอยู่ที่ตัว listener
มีวิธีแก้ไขที่ตรงไปตรงมาสองวิธี วิธีแรกคือการผูกบริการเข้ากับที่อยู่ tailnet ของโหนด ซึ่งจะช่วยให้บริการไม่เปิดเผยบนอินเทอร์เฟซสาธารณะโดยไม่ต้องมี proxy มาคั่นกลาง: ให้ส่งค่า --bind 100.101.102.104 หรือตัวเลือกที่เทียบเท่ากันในไฟล์ config ของคุณ และหากเป็น container ให้ publish พอร์ตเป็น -p 100.101.102.104:3000:3000 หรืออีกวิธีคือปล่อยให้บริการทำงานบน loopback แล้วใช้ Tailscale วางไว้ด้านหน้า
tailscale serve 3000วิธีนี้จะทำหน้าที่ proxy คำขอไปยัง http://127.0.0.1:3000 และให้บริการภายใน tailnet ของคุณผ่านชื่อ ts.net ด้วยโปรโตคอล HTTPS เมื่อมีการเปิดใช้งานใบรับรอง HTTPS สำหรับ tailnet แล้ว บริการจะยังคงเป็นส่วนตัวสำหรับโหนดของคุณเท่านั้น สำหรับแนวคิดเดียวกันในรูปแบบสาธารณะเรียกว่า Funnel โดยคุณสามารถดูรายละเอียดว่าควรเลือกใช้วิธีใดได้ที่ Tailscale serve กับ funnel
งานที่เกี่ยวข้องอีกสองอย่างมีหน้าอธิบายแยกต่างหาก การเข้าถึงเครือข่ายส่วนตัวทั้งหมดที่ไม่ได้ติดตั้ง Tailscale จำเป็นต้องใช้ subnet router บน VPS และการส่งทราฟฟิกอินเทอร์เน็ตขาออกของโหนดผ่านโหนดอื่นจำเป็นต้องใช้ exit node
การปิดพอร์ตที่ไม่จำเป็นอีกต่อไป
เมื่อผู้ดูแลระบบสามารถเข้าถึงเซิร์ฟเวอร์ผ่าน tailnet ได้แล้ว พอร์ต 22 ที่เปิดสาธารณะก็ไม่มีความจำเป็นอีกต่อไป นี่คือผลลัพธ์ที่สำคัญในทางปฏิบัติ พอร์ตที่ปิดอยู่จะไม่สามารถถูกโจมตีแบบ brute force ได้ และ log ของคุณจะไม่เต็มไปด้วยความพยายามในการล็อกอินที่ไม่พึงประสงค์อีกต่อไป
ลำดับขั้นตอนมีความสำคัญ ให้เพิ่มการเข้าถึงผ่าน tailnet ทดสอบจนมั่นใจว่าสามารถล็อกอินผ่านช่องทางนั้นได้จากเซสชันที่สอง แล้วจึงค่อยลบกฎการเข้าถึงแบบสาธารณะออก
sudo ufw allow in on tailscale0
sudo ufw status verboseหลังจากนั้น ให้ลบกฎ SSH สาธารณะออกและเชื่อมต่อใหม่โดยใช้ชื่อ MagicDNS โปรดสังเกตว่า ufw allow in on tailscale0 ทำงานอย่างไร มันจะเชื่อถือทุกอย่างที่เข้ามาผ่าน tunnel ดังนั้นไฟล์นโยบายของ Tailscale จึงกลายเป็นตัวควบคุมการเข้าถึงแทนที่ ufw คุณควรเขียนนโยบายโดยคำนึงถึงจุดนี้
คำเตือนสำหรับผู้ที่รันคอนเทนเนอร์ การเผยแพร่พอร์ตผ่าน Docker จะติดตั้งกฎ NAT ของตัวเองและข้ามการทำงานของ ufw ดังนั้นการใช้ ufw deny จึงไม่สามารถปิดพอร์ตเหล่านั้นได้ พอร์ตที่เผยแพร่ผ่าน Docker ข้ามการทำงานของ ufw อธิบายกลไกดังกล่าวไว้ การเผยแพร่พอร์ตไปยังที่อยู่ tailnet ตามที่กล่าวข้างต้นจะช่วยเลี่ยงปัญหานี้ได้ หากแอปพลิเคชันรันภายใต้ Docker Compose การใช้ Tailscale sidecar ในสแต็กของ Compose จะช่วยเพิ่มความปลอดภัยขึ้นอีกขั้นด้วยการลบพอร์ตที่เผยแพร่ออกไปทั้งหมด ทำให้คอนเทนเนอร์สามารถเข้าถึงได้ผ่านชื่อ tailnet เท่านั้น
สิ่งที่ Tailscale ปกป้องและสิ่งที่ไม่ปกป้อง
ควรระบุให้ชัดเจน เพราะเนื้อหาทางการตลาดมักทำให้ประเด็นนี้คลุมเครือ
สิ่งที่ได้รับการปกป้อง: การรับส่งข้อมูลระหว่างโหนดสองโหนดจะถูกเข้ารหัสแบบ end-to-end ด้วย WireGuard และไม่มี relay ตัวกลางใดสามารถอ่านข้อมูลได้ private key จะไม่ถูกส่งออกจากเครื่องที่สร้างมันขึ้นมา โหนดไม่จำเป็นต้องเปิดพอร์ตสาธารณะขาเข้า ดังนั้นจึงไม่มีพอร์ตอย่าง 22 หรือ 5432 ให้ Internet สแกนพบ การเข้าถึงระหว่างโหนดถูกกำหนดโดยไฟล์นโยบาย (policy file) แทนที่จะขึ้นอยู่กับว่าใครทราบที่อยู่ของโหนดนั้น
สิ่งที่ไม่ได้ปกป้อง: coordination server จะเห็นแผนผังอุปกรณ์ (device graph) ของคุณ ข้อมูล metadata เหล่านี้มีความละเอียดอ่อนในตัวเอง เนื่องจากชื่อเครื่อง, เจ้าของ, ที่อยู่ และเวลาที่ออนไลน์สามารถบ่งบอกถึงโครงสร้างพื้นฐานของคุณได้ นอกจากนี้ server ยังเป็นตัวแจกจ่ายกุญแจ ซึ่งถือเป็นความเสี่ยงที่สำคัญกว่า Tailscale ระบุไว้โดยตรงว่า "หาก Tailscale มีเจตนาร้ายและแอบเพิ่มโหนดใหม่เข้าไปในเครือข่ายของคุณ Tailscale ก็สามารถส่งหรือรับข้อมูลไปยังโหนดที่มีอยู่เดิมของคุณในรูปแบบ plaintext ได้" ผู้ให้บริการ single sign-on ของคุณก็อยู่ในเส้นทางความเชื่อถือเดียวกัน เพราะใครก็ตามที่สามารถสร้างตัวตนในระบบนั้นได้ ก็สามารถเพิ่มโหนดเข้าไปได้เช่นกัน และหากโหนดใดถูกบุกรุก โหนดนั้นก็จะเป็น peer ภายใน tailnet ซึ่งจะเข้าถึงสิ่งใดได้บ้างนั้นขึ้นอยู่กับนโยบายที่คุณกำหนดไว้ ความเสี่ยงนี้จะยอมรับได้หรือไม่ขึ้นอยู่กับว่าคุณกำลังป้องกันตัวจากใคร และ รูปแบบความเชื่อถือฉบับเต็ม จะอธิบายรายละเอียดในแต่ละกรณี รวมถึงสิ่งที่บัญชีตัวตนที่ถูกขโมยไปสามารถทำได้จริง
มีสองคำตอบสำหรับความเสี่ยงในการแจกจ่ายกุญแจ คำตอบแรกคือ tailnet lock ซึ่งกำหนดให้โหนดที่เชื่อถือได้ที่มีอยู่เดิมต้องลงนามทาง cryptographically ให้กับโหนดใหม่ก่อนที่โหนดอื่นของคุณจะยอมรับมัน control plane ใดที่เพิ่มโหนดโดยไม่มีลายเซ็นที่ถูกต้องจะถูกเพิกเฉย admin console จะสร้างบรรทัด tailscale lock init ที่ถูกต้องสำหรับโหนดที่ทำหน้าที่ลงนามของคุณ และทุกโหนดสามารถตรวจสอบสิ่งที่ตนเองเห็นได้
tailscale lock statusโหนดทั้งหมดควรรายงานชุดกุญแจลงนามที่เชื่อถือได้ชุดเดียวกัน คำตอบที่สองคือการรัน control plane ด้วยตนเอง การใช้ Headscale coordination server แบบ self-hosted ซึ่งใช้โปรโตคอลเดียวกันกับ client ชุดเดียวกัน ทำให้แผนผังอุปกรณ์และการแจกจ่ายกุญแจย้ายมาอยู่บนฮาร์ดแวร์ที่คุณเป็นเจ้าของเอง ซึ่งคุณจะต้องรับผิดชอบเรื่อง uptime ของ server นั้นด้วย หากคุณยังคงเปรียบเทียบ control plane แบบ self-hosted อื่นๆ แทนที่จะเลือกตัวนี้ NetBird เป็นอีกหนึ่ง mesh VPN ที่คุณสามารถรัน server ได้เองทั้งหมดบน VPS เพียงเครื่องเดียว
ค่าเริ่มต้นหนึ่งอย่างที่ควรแก้ไขตั้งแต่วันแรก: tailnet ใหม่ที่เพิ่งติดตั้งจะมาพร้อมกับค่าเริ่มต้นที่อนุญาตทุกอย่าง: "นโยบายเริ่มต้นของ tailnet จะเปิดใช้งานการสื่อสารระหว่างอุปกรณ์ทั้งหมดภายใน tailnet" ทันทีที่คุณเพิ่มส่วน acls เข้าไป รูปแบบความปลอดภัยจะเปลี่ยนเป็นปฏิเสธการเข้าถึงโดยอัตโนมัติ (deny by default) และจะมีเพียงกฎที่คุณกำหนดเท่านั้นที่ผ่านได้
{
"tagOwners": {
"tag:server": ["autogroup:admin"]
},
"acls": [
{"action": "accept", "src": ["autogroup:member"], "dst": ["tag:server:22"]}
]
}นโยบายดังกล่าวอนุญาตให้สมาชิก tailnet เชื่อมต่อ SSH ไปยังเซิร์ฟเวอร์ที่ติด tag ได้เท่านั้น และไม่อนุญาตการเข้าถึงอย่างอื่น ควรเพิ่ม rule แยกตามแต่ละบริการ แทนการคง wildcard ไว้ เพราะ wildcard อาจทำให้ laptop ที่มี key ถูกขโมยเพียงเครื่องเดียวเข้าถึง database ของคุณได้ หากคุณยังอยู่ระหว่างเลือก mesh VPN วิธีเขียน rule ลักษณะนี้เป็นหนึ่งในจุดที่ตัวเลือกแต่ละแบบแตกต่างกันอย่างมีนัยสำคัญ และ การเปรียบเทียบ NetBird กับ Tailscale จะเปรียบเทียบ policy model ของทั้งสองระบบ รวมถึงผู้ที่ดูแล control planeด้วย
รูปแบบความล้มเหลวและข้อความที่คุณจะพบ
tailscale status แจ้งว่า relay เสมอ โหนดทั้งสองไม่สามารถสร้างเส้นทางเชื่อมต่อโดยตรงได้ ให้รันคำสั่ง tailscale netcheck ที่ปลายทางทั้งสองฝั่ง หากขึ้น UDP: false แสดงว่า UDP ถูกบล็อกขาออก ทำให้ใช้งานได้ผ่าน relay เท่านั้น หากขึ้น MappingVariesByDestIP: true แสดงว่ามี hard NAT ขวางอยู่ การอนุญาตให้ UDP พอร์ต 41641 เข้ามาในฝั่งที่คุณควบคุมมักจะช่วยแก้ไขปัญหานี้ได้
โหนดที่เคยใช้งานได้ปกติหลายเดือนกลับหายไป สาเหตุที่พบบ่อยคือ node key หมดอายุตามค่าเริ่มต้นที่ 180 วัน ให้ตรวจสอบเครื่องใน admin console ก่อน หากสถานะแสดงว่าหมดอายุ การรัน sudo tailscale up บนเครื่องนั้นจะทำให้กลับมาใช้งานได้อีกครั้ง และการปิดการตั้งค่า key expiry บนเซิร์ฟเวอร์จะช่วยป้องกันไม่ให้เกิดปัญหานี้ซ้ำ หาก key ยังไม่หมดอายุ ให้ตรวจสอบ policy file เนื่องจากคำแนะนำของ Tailscale สำหรับอุปกรณ์ที่หายไปจาก tailscale status คือให้ตรวจสอบ access rules ที่อาจขัดขวางการเชื่อมต่อ
รายชื่อ peer ปรากฏขึ้นแต่การเชื่อมต่อหมดเวลา (timeout) หาก tailscale ping ได้รับการตอบกลับ แสดงว่าการเชื่อมต่อทำงานปกติและสาเหตุที่เป็นไปได้คือ policy ปฏิเสธ traffic นั้น ให้ตรวจสอบส่วน acls เพื่อหา rule ที่ครอบคลุม source, destination และพอร์ตดังกล่าว แพ็กเก็ตที่ถูกปฏิเสธจะถูกทิ้ง (drop) แทนที่จะถูกตอบกลับ จึงเป็นเหตุผลว่าทำไมคุณถึงได้รับ timeout แทนที่จะเป็น Connection refused
ชื่อ MagicDNS ไม่สามารถ resolve ได้ ping db-1 ล้มเหลวในขณะที่ ping 100.101.102.104 ทำงานได้ปกติ ขั้นแรกให้ยืนยันว่าไคลเอนต์ยอมรับการตั้งค่า DNS ของ Tailscale: โหนดที่เริ่มทำงานด้วย --accept-dns=false จะไม่ส่ง query ไปยัง stub resolver ที่ 100.100.100.100 จากนั้นให้ดูที่ cat /etc/resolv.conf และสิ่งที่เขียนไฟล์นั้นบนเครื่อง ในระบบที่ใช้ systemd-resolved โดยปกติไฟล์จะเป็น symlink ไปยัง /run/systemd/resolve/stub-resolv.conf และการไม่พบ 100.100.100.100 ในนั้นถือเป็นเรื่องปกติ ในกรณีที่ tailscaled เขียนไฟล์โดยตรง DHCP client หรือเครื่องมืออื่นที่เขียนทับไฟล์จะทำให้ MagicDNS ใช้งานไม่ได้ หากไม่มีสาเหตุใดอธิบายได้ ปัญหาอาจเกิดจากการตั้งค่า DNS ในเครื่องหรือในเครือข่าย ซึ่งเป็นปัญหาประเภทเดียวกับ DNS ขัดข้องภายใน WireGuard tunnel
tailscale up ปฏิเสธ tag ของคุณ tag ดังกล่าวไม่ได้ถูกประกาศไว้ภายใต้ tagOwners ใน policy file ให้เพิ่ม tag นั้นเข้าไปแล้วรันคำสั่งอีกครั้ง
FAQ
Tailscale เป็น VPN หรือ mesh network?
ทั้งสองคำมีความถูกต้องและอธิบายคนละเลเยอร์กัน อุโมงค์เชื่อมต่อใช้ WireGuard ซึ่งทำให้มันเป็น VPN ส่วนโทโพโลยีเป็นแบบ mesh เพราะแต่ละโหนดจะสร้างอุโมงค์เชื่อมต่อโดยตรงไปยังโหนดอื่นที่สื่อสารด้วย แทนที่จะส่งแพ็กเก็ตทั้งหมดผ่านเซิร์ฟเวอร์กลางเพียงจุดเดียว coordination server จะอยู่บน control path ไม่ใช่ data path ดังนั้นหากเซิร์ฟเวอร์นี้ไม่สามารถเข้าถึงได้ อุโมงค์เชื่อมต่อเดิมของคุณจะยังคงรับส่งข้อมูลได้ตามปกติ สิ่งที่จะหยุดทำงานระหว่างระบบขัดข้องคือการเพิ่มโหนดใหม่ และการเปลี่ยนแปลงคีย์หรือนโยบายใหม่ อย่างไรก็ตาม โดยค่าเริ่มต้นแล้วมันไม่ใช่ privacy VPN: เว็บไซต์ต่างๆ จะยังคงเห็นที่อยู่สาธารณะของคุณจนกว่าคุณจะส่งข้อมูลผ่าน exit node และ สิ่งที่ Tailscale ปิดบังจากเว็บไซต์และ ISP ของคุณ จะขึ้นอยู่กับการตั้งค่าแต่ละแบบ
Tailscale สามารถอ่านข้อมูลการรับส่งข้อมูลของฉันได้หรือไม่?
ไม่สามารถอ่านเนื้อหาได้ ข้อมูลจะถูกเข้ารหัสแบบ end-to-end ระหว่างโหนดด้วย WireGuard โดย private key จะไม่ถูกส่งออกจากโหนด และ DERP relay จะทำหน้าที่ส่งต่อแพ็กเก็ตโดยไม่มีวิธีถอดรหัสข้อมูลเหล่านั้น Tailscale จะเห็นเพียง metadata เท่านั้น เช่น ชื่อเครื่อง, เจ้าของ, public key, ที่อยู่ของ endpoint และสถานะออนไลน์ของแต่ละโหนด นอกจากนี้ยังทำหน้าที่แจกจ่ายคีย์ ดังนั้นหาก coordination server ถูกบุกรุก อาจมีความพยายามแทรกโหนดที่กลุ่มอุปกรณ์ของคุณจะเชื่อถือได้ ฟีเจอร์ tailnet lock จะป้องกันปัญหานี้โดยกำหนดให้ต้องมีการลงนามจากโหนดที่คุณเชื่อถือเอง และการใช้ Headscale จะช่วยตัดปัญหาเรื่องการพึ่งพา control plane ที่โฮสต์โดยผู้ให้บริการออกไป
ฉันจำเป็นต้องเปิดพอร์ตไฟร์วอลล์สำหรับ Tailscale หรือไม่?
แทบไม่จำเป็นต้องเปิดขาเข้าเลย คำแนะนำของ Tailscale ระบุว่า "โดยส่วนใหญ่แล้ว คุณไม่จำเป็นต้องเปิดพอร์ตไฟร์วอลล์ใดๆ" สำหรับขาออก โหนดจำเป็นต้องใช้ TCP 443 เพื่อเชื่อมต่อไปยัง coordination server และ relay รวมถึง UDP 3478 สำหรับ STUN อุโมงค์เชื่อมต่อโดยตรงจะใช้ UDP โดยมี source port เริ่มต้นที่ 41641 การอนุญาตให้ UDP 41641 ขาเข้าเป็นทางเลือกเสริม และจะช่วยให้การเชื่อมต่อโดยตรงสำเร็จได้ง่ายขึ้นในเครือข่ายที่มีข้อจำกัด
ทำไมโหนดอื่นถึงเข้าถึงบริการของฉันบนพอร์ต 3000 ไม่ได้?
ให้ตรวจสอบ bind address ก่อนด้วย ss -tlnp หาก listener ทำงานบน 127.0.0.1:3000 จะปฏิเสธการเชื่อมต่อที่ส่งมายังที่อยู่ 100.x ของ tailnet เพราะ socket นั้นยอมรับเฉพาะจุดหมายที่เป็น loopback เท่านั้น และไคลเอนต์จะได้รับข้อความ Connection refused ให้ตั้งค่าบริการให้ bind กับที่อยู่ของ tailnet หรือรัน tailscale serve 3000 เพื่อทำ proxy หาก listener ทำงานบน 0.0.0.0 อยู่แล้วแต่การเชื่อมต่อหมดเวลาแทนที่จะถูกปฏิเสธ แสดงว่าปัญหาไม่ได้อยู่ที่ bind address ให้ตรวจสอบกฎนโยบายและไฟร์วอลล์ของโฮสต์ก่อน จากนั้นจึงตรวจสอบไฟร์วอลล์เครือข่ายและดูว่าการยืนยันตัวตนของอุปกรณ์ใดอุปกรณ์หนึ่งหมดอายุหรือไม่
ฉันควรใช้ Headscale แทน coordination server ของ Tailscale หรือไม่?
ควรใช้ Headscale เมื่อกราฟของอุปกรณ์หรือการแจกจ่ายคีย์จำเป็นต้องอยู่บนโครงสร้างพื้นฐานที่คุณควบคุมเอง หรือเมื่อ tailnet จำเป็นต้องทำงานโดยไม่มีการพึ่งพาบริการภายนอก ไคลเอนต์และโปรโตคอลที่ใช้จะเหมือนกันทุกประการ สิ่งที่ต้องแลกคือคุณต้องเป็นผู้ดูแล coordination server เอง และหากเซิร์ฟเวอร์ขัดข้องจะทำให้ไม่สามารถเพิ่มโหนดใหม่หรือปรับใช้นโยบายใหม่ได้ สำหรับกลุ่มอุปกรณ์ขนาดเล็ก การใช้ control plane ที่โฮสต์โดยผู้ให้บริการพร้อมเปิดใช้งาน tailnet lock มักจะเป็นทางเลือกที่คุ้มค่ากว่า