วิธีตั้งค่า Tailscale subnet router บน VPS อย่างถูกต้อง
เรียนรู้วิธีตั้งค่า Tailscale subnet router บน VPS เพื่อเข้าถึงเครือข่ายส่วนตัว ครอบคลุมการเปิดใช้งาน IP forwarding การตั้งค่า --accept-routes และการอนุมัติเส้นทางให้ใช้งานได้ถาวร
หน้าที่ของ Tailscale subnet router
Tailscale subnet router คือเครื่องคอมพิวเตอร์หนึ่งเครื่องที่ทำหน้าที่ประกาศช่วง IP address ส่วนตัวทั้งหมดให้แก่ tailnet ของคุณ เพื่อให้อุปกรณ์ทุกเครื่องใน tailnet สามารถเข้าถึง IP address ในช่วงดังกล่าวได้ แม้ว่าอุปกรณ์เหล่านั้นจะไม่ได้ติดตั้ง Tailscale ไว้ก็ตาม tailnet คือเครือข่าย Tailscale ส่วนตัวของคุณ ซึ่งประกอบด้วยกลุ่มอุปกรณ์ที่ลงชื่อเข้าใช้ด้วยบัญชีหรือองค์กรเดียวกัน ส่วน exit node เป็นฟีเจอร์ที่มักถูกสับสนกับ subnet router แต่มีหน้าที่ตรงกันข้ามกัน โดย exit node จะส่ง traffic ทั้งหมดของอุปกรณ์ออกผ่าน VPS ทำให้ VPS กลายเป็นเส้นทางออกสู่สาธารณะของอุปกรณ์นั้น
สรุปได้ประโยคละหนึ่งใจความสำคัญดังนี้ subnet router ช่วยให้เครือข่ายส่วนตัวหนึ่งเครือข่ายสามารถเข้าถึงได้จาก tailnet ส่วน exit node ทำหน้าที่เปลี่ยนจุดที่ traffic สาธารณะของคุณออกสู่ภายนอก หากคุณต้องการใช้งาน exit node โปรดอ่าน วิธีการรัน Tailscale exit node บน VPS แทน ทั้งสองฟีเจอร์นี้ใช้ flag ที่แยกจากกัน แม้ว่า VPS หนึ่งเครื่องจะสามารถทำหน้าที่ทั้งสองอย่างพร้อมกันได้ แต่ทั้งสองฟีเจอร์แก้ปัญหาที่แตกต่างกันและมีสาเหตุความล้มเหลวที่ต่างกัน
เมื่อ VPS จำเป็นต้องทำหน้าที่เป็น subnet router
กรณีที่พบบ่อยคือเครือข่ายส่วนตัว (private network) ที่ผู้ให้บริการจัดเตรียมไว้ให้ VPS ของคุณจะมีที่อยู่สาธารณะ (public address) และอินเทอร์เฟซที่สองบนเซกเมนต์ส่วนตัว ในขณะที่เซิร์ฟเวอร์อื่นบนเซกเมนต์นั้นไม่มีที่อยู่สาธารณะเลย เช่น ฐานข้อมูลที่ 10.0.0.20 หรือเป้าหมายสำหรับสำรองข้อมูลที่ 10.0.0.30 ให้ติดตั้ง Tailscale บน VPS หนึ่งเครื่อง ประกาศเส้นทาง 10.0.0.0/24 แล้วแล็ปท็อปของคุณจะสามารถเข้าถึงที่อยู่ส่วนตัวเหล่านั้นได้โดยตรง โดยไม่ต้องเปลี่ยนแปลงค่าใดๆ บนเซกเมนต์นั้น และฐานข้อมูลก็ยังคงไม่มีที่อยู่สาธารณะ หากสิ่งเดียวที่คุณต้องการจากเซกเมนต์นั้นคือเว็บแอปพลิเคชันเดียวบนพอร์ตเดียว การประกาศเส้นทางทั้งช่วงถือว่าเกินความจำเป็น และ Tailscale serve จะช่วยทำ HTTPS บนพอร์ตนั้นพอร์ตเดียวแทน ตรรกะเดียวกันนี้ยังใช้กับ daemon ที่ตั้งใจให้เชื่อมต่อเฉพาะ localhost เท่านั้น เช่น dsh ที่รันแบบ headless ภายใต้ systemd ซึ่งที่อยู่บน tailnet ของ VPS นั้นจะเข้ามาแทนที่ SSH tunnel ที่คุณต้องเปิดค้างไว้เพื่อเข้าถึง UI
อีกกรณีหนึ่งคือเครือข่ายที่อยู่อีกฝั่งของ VPS เช่น LAN (local area network) ที่บ้านหรือที่ทำงานซึ่งอยู่หลังเราเตอร์ของตนเอง หรือกลุ่มอุปกรณ์ที่ไม่สามารถรัน Tailscale ได้เลย เช่น managed switch หรือ NAS รุ่นเก่าที่มีเฟิร์มแวร์แบบล็อกไว้ เครื่อง Linux เครื่องหนึ่งบนเครือข่ายนั้นจะทำหน้าที่เป็น subnet router ให้กับอุปกรณ์อื่นๆ ทั้งหมด สำหรับที่บ้าน เครื่องนั้นมักจะเป็น VM ขนาดเล็กบน hypervisor ที่คุณใช้งานอยู่แล้ว และ การคำนวณความคุ้มค่าระหว่างการใช้ Proxmox host ที่บ้านกับการเช่า VPS คือสิ่งที่คุณต้องตัดสินใจก่อนเลือกฝั่งที่จะวางบริการของคุณ
ทั้งสองกรณีมีข้อกำหนดร่วมกันประการหนึ่ง คือ subnet router ต้องสามารถเข้าถึงช่วงเครือข่ายที่ประกาศไว้ได้อยู่แล้ว โดยใช้ตารางเส้นทาง (routing table) และไฟร์วอลล์ของตนเอง Tailscale ไม่ได้สร้างการเชื่อมต่อนั้นขึ้นมาเอง แต่ทำหน้าที่ส่งผ่านทราฟฟิกไปยังเราเตอร์และส่งต่อให้ kernel เป็นผู้จัดการการส่งต่อข้อมูล (forward) ต่อไป
ติดตั้ง Tailscale และตรวจสอบเส้นทางเครือข่ายภายในก่อน
curl -fsSL https://tailscale.com/install.sh | shสคริปต์จะตรวจหา distribution เพิ่ม package repository ของ Tailscale ติดตั้งคำสั่ง tailscale และ daemon tailscaled จากนั้นจึงเปิดใช้งาน service ให้ยืนยันสถานะด้วย systemctl is-active tailscaled ซึ่งควรแสดงผลเป็น active
ก่อนดำเนินการอื่นใด ให้ตรวจสอบว่า VPS สามารถเข้าถึงเครือข่ายที่คุณต้องการประกาศใช้งานได้จริง
ip route show
ping -c3 10.0.0.20ip route show ต้องแสดงช่วง IP ภายในบนอินเทอร์เฟซจริง เช่น 10.0.0.0/24 dev enp7s0 proto kernel scope link src 10.0.0.5 หากการ ping ล้มเหลวในขั้นตอนนี้บนตัวเราเตอร์เอง จะไม่มี flag ใดของ Tailscale ที่แก้ไขปัญหานี้ได้ ปัญหาเกิดจากการตั้งค่าเครือข่ายของ VPS หรือ firewall บนโฮสต์ปลายทาง ให้แก้ไขส่วนนั้นก่อน เนื่องจากการทดสอบในขั้นตอนถัดไปทั้งหมดขึ้นอยู่กับจุดนี้
เปิดใช้งาน IP forwarding และตั้งค่าให้คงอยู่หลังการรีบูต
เครื่อง Linux จะทิ้งแพ็กเก็ตทั้งหมดที่ไม่ได้ส่งถึงตัวมันเองหากไม่ได้เปิดใช้งานการส่งต่อ (forwarding) การส่งต่อแพ็กเก็ตของเครื่องอื่นเป็นหน้าที่หลักของ subnet router ดังนั้นขั้นตอนนี้จึงเป็นสิ่งที่ขาดไม่ได้
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.confตรวจสอบสถานะด้วย sysctl net.ipv4.ip_forward ซึ่งควรแสดงผลลัพธ์เป็น net.ipv4.ip_forward = 1
ผู้ใช้งานมักทำขั้นตอนนี้สำเร็จเพียงครึ่งเดียว การใช้ sudo sysctl -w net.ipv4.ip_forward=1 จะเห็นผลทันทีแต่จะหายไปเมื่อรีบูตเครื่อง ทำให้ subnet router ทำงานได้ปกติหลายสัปดาห์แล้วหยุดทำงานในเช้าวันถัดไปหลังจากรีบูตเพื่ออัปเกรดเคอร์เนล ส่วนที่น่าสับสนคือไม่มีสิ่งใดแสดงอาการเสีย tailscale status ยังคงแสดงสถานะโหนดว่าออนไลน์, คอนโซลของผู้ดูแลระบบยังคงแสดงว่าเส้นทางได้รับการอนุมัติ และไคลเอนต์ยังคงติดตั้งเส้นทางไว้ แพ็กเก็ตจะเดินทางมาถึง VPS แต่เคอร์เนลจะทิ้งแพ็กเก็ตเหล่านั้นโดยไม่บันทึก log ใดๆ การเขียนค่าลงใน /etc/sysctl.d/99-tailscale.conf คือสิ่งที่ทำให้การตั้งค่านี้คงอยู่หลังการรีบูต
หากคุณประกาศเส้นทาง (advertise routes) ในขณะที่ forwarding ยังปิดอยู่ tailscale up จะแจ้งเตือนคุณในขณะนั้น โดยมีบรรทัดที่ใกล้เคียงกับ Warning: IPv4 forwarding is disabled. Subnet routes and exit nodes may not work correctly. โปรดอ่านผลลัพธ์ของคำสั่งนั้นแทนการเลื่อนผ่านไป
การประกาศเส้นทาง (Advertise the routes)
sudo tailscale up --advertise-routes=10.0.0.0/24บน VPS ที่ลงชื่อเข้าใช้ tailnet อยู่แล้ว ให้เปลี่ยนการตั้งค่าในตำแหน่งเดิมแทน:
sudo tailscale set --advertise-routes=10.0.0.0/24ให้ใช้ tailscale set สำหรับการเปลี่ยนแปลงในภายหลังทุกครั้ง การรัน tailscale up ซ้ำด้วย flag เพียงตัวเดียวจะรีเซ็ต flag อื่นๆ ที่คุณไม่ได้ระบุไว้ และ CLI จะหยุดการทำงานพร้อมแสดงข้อผิดพลาดว่าการเปลี่ยนการตั้งค่าด้วยวิธีนี้จำเป็นต้องระบุ flag ที่ไม่ใช่ค่าเริ่มต้นทั้งหมด ส่วน tailscale set จะเปลี่ยนการตั้งค่าเพียงรายการเดียวและคงค่าอื่นไว้ตามเดิม
คุณสามารถระบุช่วงเครือข่ายหลายรายการในรายการเดียวโดยคั่นด้วยเครื่องหมายจุลภาคและไม่มีช่องว่าง เช่น --advertise-routes=10.0.0.0/24,192.168.50.0/24 แต่ละรายการต้องเป็นที่อยู่เครือข่ายในรูปแบบ CIDR (classless inter-domain routing หรือรูปแบบ 10.0.0.0/24) หากคุณระบุที่อยู่ host ของตนเองโดยผิดพลาด เช่น 10.0.0.5/24 ระบบจะปฏิเสธเนื่องจากบิตหลัง prefix ไม่เป็นศูนย์ และข้อความแสดงข้อผิดพลาดจะระบุ prefix ที่คุณน่าจะต้องการสื่อถึง หากต้องการหยุดการประกาศเส้นทาง ให้ตั้งค่าเป็นรายการว่างด้วย sudo tailscale set --advertise-routes=
อนุมัติเส้นทางในคอนโซลผู้ดูแลระบบ
การประกาศเส้นทาง (advertising a route) เป็นเพียงการส่งคำขอ ไม่ใช่การเปลี่ยนแปลงค่าทันที จนกว่าผู้ดูแลระบบจะอนุมัติ ไคลเอนต์จะยังไม่ได้รับเส้นทางนั้นและไม่สามารถเข้าถึงช่วงเครือข่ายดังกล่าวได้ การออกแบบนี้มีเจตนาเพื่อความปลอดภัย เนื่องจากเครื่องที่สามารถเพิ่มตัวเองเข้าไปในตารางเส้นทางของทุกคนได้นั้น อาจดักจับทราฟฟิกของช่วงเครือข่ายใดก็ได้ตามต้องการ
ให้ดำเนินการอนุมัติที่หน้า Machines ในคอนโซลผู้ดูแลระบบ โดย VPS จะแสดงรายการพร้อมป้ายกำกับ subnet ให้เปิดแถวของเครื่องนั้น ค้นหาส่วน subnets แก้ไขการตั้งค่าเส้นทาง ทำเครื่องหมายถูกที่เส้นทางดังกล่าว แล้วบันทึก
การอนุมัติจะทำแยกตาม prefix หากคุณประกาศ 10.0.0.0/24 ในวันนี้ และประกาศ 192.168.50.0/24 ในเดือนหน้า prefix ใหม่จะเข้ามาในสถานะยังไม่อนุมัติ ในขณะที่ prefix เก่าจะยังคงทำงานได้ตามปกติ เส้นทางที่ได้รับอนุมัติและเส้นทางที่ถูกละเว้นจะมีสถานะเหมือนกันเมื่อดูจากฝั่ง VPS ดังนั้นควรตรวจสอบคอนโซลก่อนเริ่มขั้นตอนการแก้ไขปัญหาอื่น
คุณสามารถข้ามขั้นตอนการทำด้วยตนเองได้โดยใช้บล็อก autoApprovers ในไฟล์นโยบาย tailnet:
{
"autoApprovers": {
"routes": {
"10.0.0.0/24": ["tag:subnet-router"]
}
}
}จากนั้นให้เริ่มการทำงานของโหนดด้วยแท็กดังกล่าว sudo tailscale up --advertise-routes=10.0.0.0/24 --advertise-tags=tag:subnet-router แล้วเส้นทางจะถูกอนุมัติทันทีที่ประกาศออกมา ทั้งนี้ แท็กดังกล่าวจะต้องมีอยู่ในส่วน tagOwners ของไฟล์นโยบายเดียวกันก่อน การตั้งค่านี้มีประโยชน์หากคุณสร้าง VPS ใหม่จากสคริปต์ เนื่องจากโหนดที่ถูกสร้างใหม่จะถือเป็นโหนดใหม่ และเส้นทางของมันจะเริ่มต้นในสถานะยังไม่อนุมัติเสมอ
เหตุใดไคลเอนต์ Linux จึงเพิกเฉยต่อเส้นทางหากไม่มีแฟล็ก --accept-routes
เส้นทางดังกล่าวได้รับการประกาศและอนุมัติแล้ว โทรศัพท์และ Mac ของคุณสามารถเข้าถึง 10.0.0.20 ได้ แต่แล็ปท็อป Linux ของคุณกลับทำไม่ได้ และในคอนโซลผู้ดูแลระบบก็ไม่พบข้อบ่งชี้ถึงปัญหาใดๆ
การยอมรับ subnet route หมายถึงการเขียนรายการลงในตารางเส้นทาง (routing table) ของไคลเอนต์ บน Android, iOS, macOS, tvOS และ Windows ไคลเอนต์ Tailscale จะดำเนินการส่วนนี้ให้คุณโดยอัตโนมัติ แต่บน Linux จะไม่ทำเช่นนั้น เนื่องจากเครื่อง Linux มักเป็นเซิร์ฟเวอร์หรือเราเตอร์ที่มีการตั้งค่าตารางเส้นทางไว้อย่างเจาะจง การแทรก /24 ที่ได้รับมาจากเครือข่ายโดยไม่แจ้งเตือนอาจทำให้การรับส่งข้อมูลที่เครื่องนั้นจัดการอยู่เดิมเกิดปัญหาได้ ดังนั้นบน Linux คุณจึงต้องเลือกเปิดใช้งานด้วยตนเองในไคลเอนต์แต่ละเครื่อง:
sudo tailscale set --accept-routesจากนั้นตรวจสอบว่าเส้นทางถูกเพิ่มเข้าไปที่ใด:
ip route show table 52
ip route get 10.0.0.20Tailscale บน Linux จะไม่นำเส้นทางที่ยอมรับไปใส่ไว้ในตารางเส้นทางหลัก (main routing table) แต่จะนำไปใส่ไว้ในตารางเส้นทางหมายเลข 52 และติดตั้งกฎนโยบาย (policy rules) ซึ่งสามารถดูได้ด้วย ip rule show ในช่วงลำดับความสำคัญ 5210 ถึง 5270 เพื่อส่งแพ็กเก็ตที่ไม่ตรงกับเงื่อนไขไปยังตารางนั้น ดังนั้นการใช้ ip route show เพียงอย่างเดียวจะไม่แสดง 10.0.0.0/24 และผู้ที่ตรวจสอบด้วยคำสั่งนั้นเพียงอย่างเดียวอาจสรุปผิดว่า --accept-routes ไม่ได้ทำงานใดๆ ip route show table 52 คือคำสั่งที่แสดงข้อมูลที่ถูกต้อง และควรแสดงช่วงที่ประกาศไว้บน tailscale0
มีข้อยกเว้นประการหนึ่งที่ควรทราบ หากโหนด Linux นี้ทำหน้าที่เป็น subnet router ตัวที่สองสำหรับเครือข่ายท้องถิ่นของตนเอง การใช้ --accept-routes จะทำให้เครื่องส่งข้อมูลสำหรับ subnet ที่เชื่อมต่อโดยตรงของตนเองผ่านเราเตอร์ตัวอื่นแทนที่จะส่งออกผ่านอินเทอร์เฟซของตนเอง สำหรับเราเตอร์ในโหมดสำรอง (standby) ในระบบที่มีความพร้อมใช้งานสูง (high availability) ให้ปิด --accept-routes ไว้และทำการประกาศเส้นทางเพียงอย่างเดียว
รูปแบบความล้มเหลว: เราเตอร์สองตัวประกาศช่วงเครือข่ายทับซ้อนกัน
เราเตอร์ subnet สองตัวต้องไม่ประกาศช่วงเครือข่ายที่เหมือนกันทุกประการ การประกาศช่วงที่ทับซ้อนกันโดยมี prefix length ต่างกันนั้นสามารถทำได้ โดย Tailscale จะเลือกเส้นทางที่เฉพาะเจาะจงที่สุด หากเราเตอร์ A ประกาศ 10.0.0.0/24 และเราเตอร์ B ประกาศ 10.0.0.0/16 ทราฟฟิกที่มุ่งหน้าไปยัง 10.0.0.20 จะถูกส่งไปยัง A
สิ่งที่มักทำให้ผู้ใช้งานประหลาดใจคือพฤติกรรมเมื่อ A ออฟไลน์ Tailscale จะไม่เปลี่ยนไปใช้เส้นทางที่กว้างกว่าโดยอัตโนมัติ ทราฟฟิกที่มุ่งหน้าไปยัง 10.0.0.20 จะหยุดทำงาน ในขณะที่ทราฟฟิกไปยัง 10.1.0.20 ยังคงทำงานผ่าน B ได้ตามปกติ อาการนี้จะดูเหมือนเครือข่ายส่วนตัวใช้งานได้เพียงบางส่วน โดยมีสาเหตุมาจากโหนดที่ออฟไลน์ไปนั้นถือครอง prefix ที่เฉพาะเจาะจงกว่าอยู่ หากคุณต้องการระบบ failover ให้ตั้งค่าเราเตอร์ตัวที่ครอบคลุมช่วงกว้างกว่าให้ประกาศ prefix ที่แคบกว่าด้วย เพื่อให้ทั้งสองตัวครอบคลุมที่อยู่ชุดเดียวกัน
การทับซ้อนอีกรูปแบบหนึ่งเกิดขึ้นใกล้กับฝั่งไคลเอนต์ การใช้งานเครือข่ายโรงแรมที่ 192.168.1.0/24 ในขณะที่ subnet router ของคุณประกาศ 192.168.1.0/24 หมายความว่าทั้งสองแหล่งกำลังแย่งชิงเส้นทางไปยังปลายทางเดียวกัน ซึ่งผลลัพธ์จะขึ้นอยู่กับแพลตฟอร์มที่ใช้ บน Linux ให้ติดตั้งกฎ (rule) ไว้ก่อนกฎของ Tailscale เพื่อให้ที่อยู่ภายในเครื่องใช้ตารางหลัก (main table):
sudo ip rule add to 192.168.1.0/24 priority 2500 lookup mainกฎดังกล่าวจะไม่คงอยู่ถาวรและจะหายไปเมื่อรีบูตเครื่อง วิธีแก้ไขที่แท้จริงคือการเลือกช่วง IP ส่วนตัวที่คุณจะไม่พบเจอเมื่อใช้งานภายนอก 192.168.0.0/24 และ 192.168.1.0/24 เป็นค่าเริ่มต้นบนเราเตอร์ตามบ้านส่วนใหญ่ ดังนั้นควรเลือกช่วงที่อยู่ภายใน 10.0.0.0/8 ที่คุณกำหนดขึ้นมาเองโดยเฉพาะ การชนกันของ IP ในลักษณะเดียวกันนี้จะทำให้ VPN แบบ WireGuard ที่คุณตั้งค่าเอง ใช้งานไม่ได้ด้วยเหตุผลเดียวกัน คือเส้นทางภายในเครื่องที่เฉพาะเจาะจงกว่าจะเป็นฝ่ายชนะ ทำให้ทราฟฟิกไม่ถูกส่งเข้าอุโมงค์ VPN
รูปแบบความล้มเหลว: DNS แปลงชื่อเป็นที่อยู่ซึ่งไม่มีเส้นทางรองรับ
ปัญหานี้ตรวจสอบได้ยากเนื่องจากไม่มีการรายงานข้อผิดพลาดใดๆ ชื่อโดเมนถูกแปลงเป็น IP ได้สำเร็จ แต่การเชื่อมต่อกลับหมดเวลา (timeout)
สมมติว่า db.internal.example.com ถูกแปลงเป็น 10.0.5.20 ผ่านเนมเซิร์ฟเวอร์ส่วนตัวของคุณ และคุณได้ประกาศเส้นทาง 10.0.0.0/24 ไว้ การค้นหาชื่อจะสำเร็จเพราะขั้นตอนการแปลงชื่อ (DNS - domain name system) และการกำหนดเส้นทาง IP (IP routing) เป็นคนละส่วนกันและไม่มีส่วนใดตรวจสอบความถูกต้องของอีกส่วน จากนั้นแพ็กเก็ตที่ส่งไปยัง 10.0.5.20 จะไม่พบเส้นทางที่ตรงกันใน tailnet จึงหลุดออกไปทาง default gateway ของไคลเอนต์และหายไปในที่สุด
คำสั่งสองชุดนี้จะช่วยแยกแยะปัญหาทั้งสองส่วนออกจากกัน:
nslookup db.internal.example.com
ip route get 10.0.5.20หากการค้นหาชื่อส่งคืนที่อยู่ IP กลับมา แต่ ip route get ไม่ตอบสนองด้วย dev tailscale0 แสดงว่าชื่อโดเมนถูกต้องแต่เส้นทางหายไป ให้ประกาศช่วง IP ที่ครอบคลุมที่อยู่นั้น โดยอาจใช้ 10.0.0.0/16 หรือระบุ prefix เพิ่มเติมอีกชุด จากนั้นอนุมัติ prefix ใหม่ในคอนโซล
มีกับดักที่คล้ายกันบนตัวเนมเซิร์ฟเวอร์เอง หากคุณตั้งค่าเนมเซิร์ฟเวอร์ส่วนกลางใน admin console เป็นที่อยู่ส่วนตัว เช่น 10.0.0.53 ที่อยู่นั้นจะต้องอยู่ภายในเส้นทางที่ได้รับอนุมัติ มิฉะนั้นอุปกรณ์ของคุณจะไม่สามารถเข้าถึงตัวแปลงชื่อ (resolver) ได้เลย หากคุณเปิดตัวเลือกที่บังคับใช้ DNS ส่วนกลางในขณะที่ชี้ไปยัง resolver ที่ไม่มีใครเข้าถึงได้ อุปกรณ์ทุกเครื่องใน tailnet จะสูญเสียความสามารถในการแปลงชื่อทันที รวมถึงเครื่องที่เพิ่งใช้งานได้เมื่อครู่ ให้ประกาศและอนุมัติเส้นทางไปยัง resolver ก่อน แล้วจึงค่อยเปลี่ยนการตั้งค่า DNS หากปัญหา DNS ภายในอุโมงค์ (tunnel) เป็นสิ่งที่คุณยังคงประสบอยู่ วิธีที่ DNS ล้มเหลวผ่านอุโมงค์ WireGuard จะอธิบายกลไกเดียวกันนี้โดยไม่มีเลเยอร์การประสานงานด้านบนมาเกี่ยวข้อง
Source NAT และการเชื่อมต่อแบบ site to site
โดยปกติแล้ว subnet router จะเขียนที่อยู่ต้นทางของทุกแพ็กเก็ตที่ส่งต่อใหม่ให้เป็นที่อยู่ส่วนตัวของตัวมันเอง กระบวนการนี้เรียกว่า SNAT (source network address translation) ซึ่งมีไว้เพื่อให้การตอบกลับทำงานได้โดยไม่ต้องแก้ไขค่าใดๆ บนเครือข่ายส่วนตัว เช่น ฐานข้อมูลที่ 10.0.0.20 จะตอบกลับไปยัง VPS ซึ่งเป็นปลายทางที่ฐานข้อมูลรู้จักวิธีเข้าถึงอยู่แล้ว ข้อเสียคือฐานข้อมูลจะมองเห็นการเชื่อมต่อ tailnet ทุกรายการว่ามาจาก VPS ทำให้กฎไฟร์วอลล์รายต้นทางและ log การเข้าถึงไม่สามารถระบุตัวตนผู้ใช้งานจริงได้
คุณสามารถปิดการทำงานนี้บน Linux ได้หากต้องการคงที่อยู่ tailnet จริงของไคลเอนต์ไว้:
sudo tailscale set --snat-subnet-routes=falseจากนั้นโฮสต์บนเครือข่ายส่วนตัวจำเป็นต้องมีเส้นทาง (route) กลับไปยัง 100.64.0.0/10 ซึ่งเป็นช่วงที่ Tailscale กำหนดให้กับอุปกรณ์ต่างๆ โดยต้องชี้ไปยัง subnet router หากไม่มีเส้นทางขากลับนี้ แพ็กเก็ตตอบกลับจะถูกส่งไปยัง default gateway และไปไม่ถึงปลายทาง ทำให้การเชื่อมต่อค้างหลังจากส่งแพ็กเก็ตแรก คุณต้องเพิ่ม static route บน gateway ของเครือข่ายส่วนตัว หรือเปิดใช้งาน SNAT ไว้ตามเดิม
การเชื่อมต่อแบบ site to site คือการที่ subnet router สองตัวทำงานนี้พร้อมกัน โดยแต่ละตัวจะประกาศเครือข่ายของตนเองและยอมรับเครือข่ายของอีกฝั่ง:
sudo tailscale up --advertise-routes=10.0.0.0/24 --snat-subnet-routes=false --accept-routesให้รันคำสั่งที่สอดคล้องกันบนเราเตอร์อีกตัวโดยใช้ช่วงเครือข่ายของตัวมันเอง ช่วงเครือข่ายทั้งสองต้องไม่ซ้ำกัน หากการถ่ายโอนข้อมูลขนาดใหญ่เกิดการหยุดชะงักในขณะที่ ssh และ ping ยังทำงานได้ปกติ สาเหตุอาจมาจาก MSS (maximum segment size) ซึ่งเป็นขนาดข้อมูลที่ใหญ่ที่สุดที่แพ็กเก็ต TCP สามารถบรรจุได้ ค่า overhead ของอุโมงค์ทำให้แพ็กเก็ตที่ถูกส่งต่อมีขนาดใหญ่เกินกว่าที่ลิงก์ระหว่างทางบางจุดจะรองรับได้ การทำ clamping จะช่วยแก้ไขปัญหานี้:
sudo iptables -t mangle -A FORWARD -o tailscale0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtuบันทึกกฎดังกล่าวด้วย iptables-persistent มิฉะนั้นกฎจะหายไปเมื่อมีการบูตเครื่องใหม่
การดูแลรักษาเพื่อให้ระบบทำงานได้อย่างต่อเนื่อง
โดยค่าเริ่มต้น Node keys จะหมดอายุหลังจาก 180 วัน นับตั้งแต่เดือนสิงหาคม 2026 เป็นต้นไป เมื่อคีย์บน subnet router หมดอายุ โหนดจะออกจากระบบและช่วง IP ที่ประกาศไว้ทั้งหมดจะไม่สามารถเข้าถึงได้ โดยไม่มีการเปลี่ยนแปลงการตั้งค่าใดๆ ที่อธิบายสาเหตุได้ ให้ปิดการใช้งานการหมดอายุของคีย์สำหรับเครื่องนี้ที่หน้า Machines ใน admin console จากนั้นจดบันทึกไว้ว่าคุณได้ดำเนินการดังกล่าวแล้ว
Tailscale จะให้ความสำคัญกับการเชื่อมต่อโดยตรงระหว่าง peer และจะเปลี่ยนไปใช้ relay servers เมื่อไม่สามารถเชื่อมต่อโดยตรงได้ แม้ relay จะทำงานได้ดี แต่ก็จะเพิ่ม latency เข้ามา VPS ที่มี public address เป็นกรณีที่จัดการได้ง่าย: ให้เปิดรับ inbound UDP 41641 แล้ว peer ส่วนใหญ่จะเชื่อมต่อได้โดยตรง หาก ufw เป็นตัวจัดการ firewall อยู่ กฎ ufw ที่ VPS จำเป็นต้องใช้จริงๆ จะครอบคลุมถึงไวยากรณ์ที่ต้องใช้
Access rules คืออีกส่วนที่สำคัญ ใน tailnet ค่าเริ่มต้น อุปกรณ์ทุกเครื่องของคุณสามารถเข้าถึงกันได้ ดังนั้น route ที่ได้รับอนุมัติจึงใช้งานได้ทันที แต่เมื่อคุณเขียน ACL policy ฝั่งปลายทางของกฎจะต้องระบุช่วง private range ให้ชัดเจน เพราะ 10.0.0.20 ไม่ใช่ที่อยู่ของ tailnet และไม่ครอบคลุมโดยกฎที่เขียนขึ้นสำหรับ tailnet IP หรือ tags
สุดท้าย ให้ตัดสินใจว่าคุณต้องการใช้ coordination server ที่คุณไม่ได้ดูแลเองหรือไม่ Tailscale control plane เป็นบริการแบบ hosted คีย์ของคุณจะยังคงอยู่บนเครื่องของคุณ แต่บัญชีและไฟล์นโยบายจะอยู่ที่นั่น สิ่งที่ผู้ไม่หวังดีอาจทำได้หาก control plane ถูกบุกรุกหรือข้อมูลล็อกอินถูกขโมย คือประเด็นที่ควรพิจารณาก่อนที่คุณจะอนุญาตให้เข้าถึงเครือข่ายส่วนตัวของคุณ และ รูปแบบความเชื่อมั่นของ Tailscale จะระบุขอบเขตดังกล่าวไว้ ค่าใช้จ่ายมักไม่ใช่ปัจจัยหลักที่ทำให้คนเลิกใช้งาน เนื่องจาก แผนฟรีรองรับผู้ใช้สูงสุดหกคนพร้อมอุปกรณ์ส่วนตัวไม่จำกัดจำนวน แม้ว่า subnet router ที่คุณตั้งค่าภายใต้ tag จะถูกนับต่างจากเครื่องที่ล็อกอินด้วยบัญชีของคุณก็ตาม หลังจากจุดนั้น ค่าใช้จ่ายจะคิดตามจำนวนผู้ใช้แทนจำนวนเครื่อง ดังนั้น สิ่งที่ครัวเรือนหรือทีมขนาดห้าคนต้องจ่ายจริงเมื่อแผนฟรีหมดลง เป็นสิ่งที่ควรคำนวณก่อนที่คุณจะเพิ่มบัญชีที่ทำให้เกินขีดจำกัด การใช้งาน Headscale ซึ่งเป็น Tailscale control server แบบ self-hosted จะช่วยให้คุณเก็บข้อมูลไว้บน VPS ของคุณเอง โดยแลกกับการที่ต้องดูแลรักษาระบบด้วยตนเอง อีกทางเลือกหนึ่งสำหรับความกังวลเดียวกันคือการเลิกใช้ไคลเอ็นต์ของ Tailscale และ การทำ self-hosting เซิร์ฟเวอร์ NetBird VPN ซึ่งจะนำเลเยอร์การประสานงานและไคลเอ็นต์แบบ mesh มาไว้บนเครื่องที่คุณควบคุมเอง หากคุณยังตัดสินใจไม่ได้ระหว่างโมเดลนี้กับการตั้งค่าด้วยตนเอง การเปรียบเทียบระหว่าง WireGuard และ Tailscale จะอธิบายว่าเลเยอร์การประสานงานมอบอะไรให้คุณและมีต้นทุนอย่างไรบ้าง
FAQ
Subnet router กับ exit node ต่างกันอย่างไร
Subnet router ทำหน้าที่ประกาศช่วงที่อยู่ IP ภายใน เพื่อให้เครื่องใน tailnet สามารถเข้าถึงเครื่องที่ไม่ได้ติดตั้ง Tailscale ได้ ส่วน exit node จะประกาศตัวเองเป็นเส้นทางออกสู่ Internet ทั้งหมด เพื่อให้เครื่องลูกข่ายส่ง traffic ทั้งหมดออกผ่านที่อยู่สาธารณะของ node นั้น VPS หนึ่งเครื่องสามารถเป็นได้ทั้งสองอย่าง โดยใช้ flag แยกกันคือ --advertise-routes และ --advertise-exit-node ซึ่งแต่ละรายการต้องได้รับการอนุมัติใน admin console แยกกัน
ทำไม Linux client ของฉันถึงเพิกเฉยต่อ subnet route ที่ประกาศไว้
Linux client จะไม่ยอมรับ subnet route จนกว่าคุณจะสั่งให้ทำ ให้รันคำสั่ง sudo tailscale set --accept-routes บนเครื่อง client จากนั้นตรวจสอบด้วย ip route show table 52 แทนที่จะใช้ ip route show เนื่องจาก Tailscale จะติดตั้งเส้นทางที่ยอมรับไว้ใน routing table 52 และเข้าถึงผ่าน policy rules ทำให้ตารางหลัก (main table) ไม่แสดงรายการเหล่านี้ และดูเหมือนว่าเส้นทางที่ใช้งานได้จริงนั้นหายไป
ทำไม subnet ถึงหยุดทำงานหลังจาก reboot
สาเหตุที่เป็นไปได้มากที่สุดคือ IP forwarding ค่าที่ตั้งไว้ด้วย sysctl -w จะไม่คงอยู่หลังการ reboot ดังนั้นให้เขียนค่าลงใน /etc/sysctl.d/99-tailscale.conf และยืนยันด้วย sysctl net.ipv4.ip_forward หากเปิด forwarding แล้วแต่ยังเข้าถึงช่วง IP ไม่ได้ ให้ตรวจสอบ node ใน admin console โดยปกติ node keys จะหมดอายุหลังจาก 180 วัน ซึ่ง subnet router ที่หมดอายุจะแสดงอาการเหมือนปัญหาเครือข่ายมากกว่าปัญหาบัญชีผู้ใช้
Subnet router สองตัวสามารถประกาศช่วง IP เดียวกันได้หรือไม่
ไม่สามารถประกาศช่วงที่เหมือนกันทุกประการได้ แต่ช่วงที่ซ้อนทับกันโดยมี prefix length ต่างกันสามารถทำได้ โดยเส้นทางที่เฉพาะเจาะจงที่สุดจะเป็นฝ่ายชนะ การทำ failover ต้องใช้ความระมัดระวัง เพราะเมื่อ router ที่ถือ prefix เฉพาะเจาะจงกว่าออฟไลน์ Tailscale จะไม่สลับไปใช้เส้นทางที่กว้างกว่าโดยอัตโนมัติ ทำให้ traffic หยุดชะงัก สำหรับการทำ standby pair ที่แท้จริง ควรให้ router ทั้งสองตัวประกาศ prefix ที่เฉพาะเจาะจงชุดเดียวกัน
ทำไม hostname ถึง resolve ได้แต่การเชื่อมต่อกลับ timeout
การทำ DNS resolution และการทำ routing เป็นขั้นตอนที่แยกจากกัน ชื่อสามารถ resolve ไปยังที่อยู่ที่ไม่มีเส้นทางที่ได้รับอนุมัติครอบคลุมอยู่ ทำให้ packet หลุดออกไปผ่าน default gateway ของ client ให้รันคำสั่ง ip route get <address> บนเครื่อง client หากคำตอบไม่รวมถึง dev tailscale0 ให้ประกาศช่วง IP ที่ครอบคลุมที่อยู่นั้นและอนุมัติ prefix ใหม่ใน admin console