วิธีติดตั้ง NetBird VPN Server บน VPS ด้วยตัวเอง
เรียนรู้วิธีติดตั้ง NetBird บน VPS ของคุณเอง ตั้งแต่การตั้งค่า DNS และ TLS ไปจนถึงการใช้ setup keys สำหรับอุปกรณ์แบบ unattended พร้อมเปรียบเทียบข้อแตกต่างกับ Headscale อย่างละเอียด
ประโยชน์ของการ self-host เซิร์ฟเวอร์ NetBird VPN
การ self-host เซิร์ฟเวอร์ NetBird VPN ช่วยให้คุณนำ control plane มาไว้บน VPS ของคุณเอง ซึ่งเป็นส่วนที่ทำหน้าที่เก็บรายการ peer, ตัดสินใจว่าเครื่องใดสามารถเชื่อมต่อกับเครื่องใดได้ และช่วยให้ peer สองเครื่องค้นหากันและกันได้แม้จะอยู่หลัง NAT (network address translation) สำหรับตัว tunnel นั้นยังคงเป็น WireGuard ซึ่งมีการเข้ารหัสโดยตรงระหว่างเครื่องของคุณ สิ่งที่เปลี่ยนไปคือไม่มีบริษัทภายนอกถือครองรายการอุปกรณ์หรือขั้นตอนการล็อกอินของคุณ
NetBird อยู่กึ่งกลางระหว่างสิ่งที่คุณอาจรู้จักอยู่แล้ว มันเป็น mesh overlay ดังนั้น peer จึงเชื่อมต่อถึงกันโดยตรงแทนที่จะส่งข้อมูลทั้งหมดผ่าน gateway เดียว นอกจากนี้ยังสามารถ self-host ได้แบบ end-to-end ซึ่งเทียบเคียงได้กับ Headscale ซึ่งเป็นเซิร์ฟเวอร์ควบคุม Tailscale แบบ self-hosted หากคุณเคยใช้งานเฉพาะ tunnel แบบ gateway เดียวมาก่อน โปรดอ่าน ความแตกต่างระหว่าง WireGuard แบบปกติกับ mesh overlay ก่อน เนื่องจากแนวคิดดังกล่าวจะช่วยให้เนื้อหาในส่วนที่เหลือของหน้านี้มีประโยชน์ต่อคุณ
หากสิ่งที่คุณต้องการจริงๆ คือเซิร์ฟเวอร์เพียงเครื่องเดียวที่ traffic ทั้งหมดของคุณวิ่งผ่าน การใช้ mesh อาจเป็นระบบที่ซับซ้อนเกินความจำเป็น การใช้ WireGuard VPN แบบปกติบน VPS เครื่องเดียว หรือ การใช้ Tailscale exit node สามารถทำงานดังกล่าวได้โดยใช้ทรัพยากรน้อยกว่ามาก
สิ่งที่ stack ทำงานอยู่จริง
โครงสร้างมีการเปลี่ยนแปลงเมื่อเร็วๆ นี้ และบทความเก่าส่วนใหญ่ยังคงอธิบายโครงสร้างแบบเดิม ณ เดือนสิงหาคม 2026 ใน release v0.76.2 สคริปต์ quickstart จะเขียนไฟล์ Compose ที่มี 3 บริการเป็นค่าเริ่มต้น
netbird-serverทำหน้าที่จัดการ API, บริการ signal, relay พร้อมตัวรับฟัง STUN ในตัว และ identity provider ในตัว ใน release รุ่นเก่า บริการเหล่านี้เป็นคอนเทนเนอร์แยกกัน และ identity provider เป็นการติดตั้ง Zitadel แยกต่างหากที่คุณต้องสร้างขึ้นก่อนdashboardคือคอนโซลเว็บสำหรับผู้ดูแลระบบtraefikทำหน้าที่ terminate TLS (transport layer security) และร้องขอใบรับรองจาก Let's Encrypt ในการเริ่มทำงานครั้งแรก
ยังมีอีก 2 บริการที่คงสถานะปิดไว้จนกว่าคุณจะตอบตกลงที่ prompt บริการ NetBird Proxy จะเผยแพร่บริการภายในบนชื่อโฮสต์สาธารณะ ส่วน CrowdSec จะกรอง traffic ที่ไม่พึงประสงค์ ทั้งสองอย่างไม่จำเป็นสำหรับการสร้าง mesh ที่ใช้งานได้ และทั้งคู่ใช้หน่วยความจำบนเครื่องขนาดเล็ก
หากคุณย้ายมาจาก wg-easy ในคอนเทนเนอร์ Docker เดียว นี่ถือเป็นการเพิ่มจำนวนส่วนประกอบ สิ่งที่คุณได้รับคือการควบคุมนโยบายการเข้าถึง (access policies), บัญชีผู้ใช้รายบุคคล และ peer ที่เชื่อมต่อถึงกันโดยตรงแทนที่จะผ่าน gateway เพียงจุดเดียว
สิ่งที่ต้องเตรียมก่อนเริ่มต้น
ชื่อโดเมนสาธารณะเป็นสิ่งที่จำเป็น หากไม่มีจะไม่สามารถดำเนินการได้ Dashboard, API และ Relay ทั้งหมดทำงานผ่าน HTTPS บนพอร์ต 443 โดย Traefik จะรับใบรับรองจาก Let's Encrypt ผ่านกระบวนการ HTTP challenge ซึ่งต้องใช้ชื่อโดเมนที่ชี้มายัง VPS ของคุณจากอินเทอร์เน็ตสาธารณะ การใช้เพียงหมายเลข IP จะไม่สามารถใช้งานในขั้นตอนการทำงานนี้ได้
ให้สร้าง A record หนึ่งรายการ netbird.example.com โดยชี้ไปยังหมายเลข IPv4 สาธารณะของ VPS และรอให้การตั้งค่ามีผลก่อนที่จะเริ่มดำเนินการใดๆ
dig +short netbird.example.comคำสั่งดังกล่าวต้องแสดงหมายเลข IP ของเซิร์ฟเวอร์คุณ หากรันตัวติดตั้งก่อนที่ DNS จะอัปเดต จะทำให้การขอใบรับรองล้มเหลวในการเริ่มทำงานครั้งแรก และหากมีการตรวจสอบที่ล้มเหลวซ้ำๆ จะทำให้ติดข้อจำกัดด้านอัตราการร้องขอ (rate limits) ของ Let's Encrypt ซึ่งจะทำให้คุณต้องรออีกหนึ่งชั่วโมงจึงจะลองใหม่ได้
พอร์ต 3 พอร์ตต้องสามารถเข้าถึงได้จากอินเทอร์เน็ต ได้แก่ TCP 80 สำหรับการตรวจสอบใบรับรองและการเปลี่ยนเส้นทางไปยัง HTTPS, TCP 443 สำหรับ Dashboard, API, สัญญาณ (signal) และการรับส่งข้อมูลผ่าน Relay และ UDP 3478 สำหรับ STUN
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3478/udp
sudo ufw reload
sudo ufw statusเปิดพอร์ตเหล่านี้ที่ Network Firewall ของผู้ให้บริการ VPS ด้วย นี่เป็นการตั้งค่าแยกต่างหากในแผงควบคุมของ VPS ส่วนใหญ่ และเป็นสาเหตุที่ทำให้เครื่องที่ตั้งค่า ufw status ไว้ถูกต้องแล้วยังคงปฏิเสธการเชื่อมต่อ
STUN (Session Traversal Utilities for NAT) คือวิธีที่ Peer จะเรียนรู้หมายเลข IP และพอร์ตสาธารณะที่ NAT ของตนเองกำหนด เพื่อให้ Peer สองฝั่งสามารถพยายามสร้างอุโมงค์เชื่อมต่อโดยตรงได้ หากบล็อก UDP 3478 ไว้ Peer จะยังคงเชื่อมต่อกันได้ผ่าน Relay บน TCP 443 ทำให้ดูเหมือนไม่มีอะไรเสียหาย แต่คุณจะพบ Connection type: Relayed บน Peer ทุกเครื่องแทน และการรับส่งข้อมูลทั้งหมดจะวิ่งผ่าน VPS ของคุณแทนที่จะเป็นการเชื่อมต่อแบบ Peer-to-Peer
ในส่วนของซอฟต์แวร์ คุณต้องมี Docker พร้อมปลั๊กอิน Compose v2 รวมถึง jq และ curl สคริปต์จะตรวจสอบสิ่งเหล่านี้ทั้งหมดและจะหยุดทำงานหากขาดรายการใดรายการหนึ่งไป หาก Docker เป็นสิ่งที่ติดตั้งใหม่บนเครื่องนี้ ให้ดำเนินการ ติดตั้ง Docker Compose บน VPS ให้เรียบร้อยก่อน
พอร์ตที่ต้องเปิดหากไม่ใช้ Reverse Proxy ที่มาพร้อมกับระบบ
การใช้งานโดยไม่ใช้ Traefik หมายความว่าบริการแต่ละตัวจะถูกเปิดเผยโดยตรง และรายการพอร์ตที่ต้องเปิดจะเพิ่มขึ้นดังนี้:
- TCP 80 สำหรับ HTTP redirects
- TCP 443 สำหรับ HTTPS
- TCP 33073 สำหรับ management gRPC
- TCP 10000 สำหรับ signal gRPC
- TCP 33080 สำหรับ relay ผ่าน WebSocket หรือ QUIC
- UDP 3478 สำหรับ STUN
ให้เลือกวิธีนี้เฉพาะในกรณีที่เซิร์ฟเวอร์ของคุณมีการทำ TLS termination สำหรับบริการอื่นอยู่แล้วเท่านั้น มิฉะนั้นการใช้ Traefik ที่มาพร้อมกับระบบจะช่วยลดจำนวนกฎที่ต้องตั้งค่าและลดโอกาสเกิดข้อผิดพลาดได้มากกว่า
ติดตั้ง NetBird server ด้วยสคริปต์ quickstart
คำสั่งแบบบรรทัดเดียวที่ระบุไว้ในเอกสารจะทำการ pipe เวอร์ชันล่าสุดลงใน shell โดยตรง:
curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bashให้ใช้วิธีระบุเวอร์ชันที่แน่นอนแทน เพราะ latest มีการเปลี่ยนแปลงอยู่เสมอ การรันคำสั่งเดิมในเวลาที่ห่างกันสองสัปดาห์อาจทำให้ได้การติดตั้งที่ต่างกัน และไม่มีบันทึกในดิสก์ว่าไฟล์ config ถูกสร้างขึ้นโดยเวอร์ชันใด ให้ดาวน์โหลดเวอร์ชันที่ระบุ (tagged release) มาตรวจสอบก่อนแล้วค่อยรัน
mkdir -p ~/netbird
cd ~/netbird
curl -fsSL -o getting-started.sh \
https://github.com/netbirdio/netbird/releases/download/v0.76.2/getting-started.sh
less getting-started.sh
bash getting-started.shสคริปต์จะถามหาชื่อโดเมนก่อนเป็นอันดับแรก:
Enter the domain you want to use for NetBird (e.g. netbird.my-domain.com):จากนั้นจะถามถึงวิธีการจัดการ TLS:
Which reverse proxy will you use?
[0] Traefik (recommended - automatic TLS, included in Docker Compose)
[1] Existing Traefik (labels for external Traefik instance)
[2] Nginx (generates config template)
[3] Nginx Proxy Manager (generates config + instructions)
[4] External Caddy (generates Caddyfile snippet)
[5] Other/Manual (displays setup documentation)
Enter choice [0-5] (default: 0):ให้เลือก [0] สำหรับตัวเลือกที่ 2 ถึง 5 นั้น สคริปต์จะเขียนไฟล์ config snippet ไว้ให้และปล่อยให้คุณจัดการการเชื่อมต่อเอง ซึ่งเป็นวิธีที่ถูกต้องสำหรับเครื่องที่มี proxy รันอยู่แล้ว แต่ไม่เหมาะสำหรับเครื่องที่เพิ่งติดตั้งใหม่ ส่วนตัวเลือกที่ 0 จะถามหาอีเมลสำหรับ Let’s Encrypt เพื่อใช้ในการแจ้งเตือนเมื่อ certificate ใกล้หมดอายุ
สำหรับการติดตั้งครั้งแรก ให้ตอบปฏิเสธ (no) สำหรับบริการ NetBird Proxy เนื่องจากบริการนี้ต้องการ DNS record เพิ่มอีกสองรายการคือ proxy.netbird.example.com และ wildcard *.proxy.netbird.example.com ซึ่งไม่มีความจำเป็นสำหรับเครือข่าย mesh พื้นฐาน และให้ตอบปฏิเสธ (no) สำหรับ CrowdSec ด้วยเช่นกัน ทั้งสองอย่างนี้สามารถเพิ่มภายหลังได้
สคริปต์จะเขียนไฟล์ลงในไดเรกทอรีปัจจุบัน ได้แก่ docker-compose.yml, config.yaml (ด้วยสิทธิ์ 600), dashboard.env และ traefik-dynamic.yaml (หากคุณเลือกใช้ Traefik ที่มาพร้อมกัน) ให้ถือว่าไดเรกทอรีนี้เป็นสถานะของระบบที่คุณต้องเก็บรักษาไว้ เพราะ config.yaml เก็บกุญแจที่ใช้เข้ารหัสข้อมูลใน store หากทำไฟล์นี้หาย การติดตั้งใหม่ก็ไม่สามารถแก้ไขได้
docker compose ps
docker compose logs -f netbird-serverทุกบริการควรสามารถอ่าน running ได้ และ log ของเซิร์ฟเวอร์ควรจะนิ่ง ไม่ใช่การรีสตาร์ทวนซ้ำไปมา ให้ตรวจสอบ certificate แยกต่างหากด้วยคำสั่ง:
docker compose logs traefik | grep -i acmeACME (automatic certificate management environment) คือโปรโตคอลที่ Traefik ใช้เพื่อขอรับ certificate หากเกิดข้อผิดพลาด มักมีสาเหตุมาจากปัญหา DNS หรือการปิดพอร์ต 80 ไว้
สร้างบัญชีผู้ดูแลระบบบัญชีแรก
เปิด https://netbird.example.com ในการติดตั้งใหม่ ระบบจะแสดงหน้าตั้งค่าแทนที่จะเป็นแบบฟอร์มเข้าสู่ระบบ ให้กรอกที่อยู่อีเมล ชื่อ และรหัสผ่าน จากนั้นคลิก Create Account บัญชีนี้จะกลายเป็นผู้ดูแลระบบบัญชีแรก และระบบจะเปลี่ยนเส้นทางไปยังหน้าเข้าสู่ระบบ
บัญชีดังกล่าวจะถูกจัดเก็บไว้ในที่เก็บผู้ใช้ของ NetBird เอง ซึ่งขับเคลื่อนโดยผู้ให้บริการยืนยันตัวตนที่ฝังอยู่ในคอนเทนเนอร์ netbird-server โดยไม่ต้องพึ่งพาระบบภายนอก นี่คือการเปลี่ยนแปลงครั้งใหญ่ที่สุดเมื่อเทียบกับ NetBird แบบ self-hosted เมื่อปีก่อน ซึ่งการติดตั้งให้ใช้งานได้จำเป็นต้องตั้งค่า Zitadel หรือ Keycloak ก่อน และต้องคัดลอกค่า OIDC (OpenID Connect) จำนวน 4 ค่าลงใน setup.env ก่อนที่ระบบจะเริ่มทำงานได้
หากคุณพบคำเตือนเรื่องใบรับรองความปลอดภัยของเบราว์เซอร์แทนที่จะเป็นหน้าตั้งค่า แสดงว่าใบรับรองไม่ได้ถูกออกให้สำเร็จ ให้แก้ไขปัญหานี้ก่อนดำเนินการต่อ เนื่องจากแดชบอร์ดต้องสื่อสารกับ API ผ่านชื่อโฮสต์เดียวกัน และจะเกิดข้อผิดพลาดที่ตรวจสอบได้ยากหากใบรับรองไม่ถูกต้อง
เชื่อมต่อ peer เครื่องแรกของคุณ
ติดตั้งไคลเอนต์บนเครื่อง Linux ใดก็ได้ รวมถึงตัว VPS เองหากคุณต้องการให้มันอยู่ใน mesh:
curl -fsSL https://pkgs.netbird.io/install.sh | shบน Debian และ Ubuntu สคริปต์ดังกล่าวจะกำหนดค่า package repository ของ NetBird จากนั้นจึงติดตั้งไคลเอนต์ผ่าน apt ทำให้ตัวจัดการแพ็กเกจเป็นผู้ดูแลซอฟต์แวร์ในท้ายที่สุด หากคุณไม่สะดวกใจกับการส่งสคริปต์ผ่าน pipe เข้า shell ให้บันทึกไฟล์ไว้ก่อนด้วย curl -fsSL -o install.sh https://pkgs.netbird.io/install.sh แล้วอ่านเนื้อหาก่อนรันด้วย sh install.sh ไม่ว่าจะใช้วิธีใด ให้ตรวจสอบสิ่งที่ติดตั้งลงไป:
apt-cache policy netbirdnetbird คือไคลเอนต์บรรทัดคำสั่งและ daemon ส่วน netbird-ui คือแอปบนถาดระบบ (tray app) ซึ่งเซิร์ฟเวอร์แบบ headless ไม่จำเป็นต้องใช้งาน
จากนั้นกำหนดให้ไคลเอนต์เชื่อมต่อไปยังเซิร์ฟเวอร์ของคุณ:
sudo netbird up --management-url https://netbird.example.comหากละเว้น --management-url ไคลเอนต์จะลงทะเบียนกับบริการที่โฮสต์โดย NetBird เนื่องจากเป็นค่าเริ่มต้นที่คอมไพล์มาในตัว คำสั่งจะยังคงทำงานสำเร็จ เครื่องจะได้รับที่อยู่ IP และแดชบอร์ดที่คุณโฮสต์เองจะยังคงว่างเปล่า นี่เป็นจุดที่เกือบทุกคนพลาดในครั้งแรก
คำสั่งจะแสดง URL เพื่อให้คุณเปิดในเบราว์เซอร์เพื่อดำเนินการล็อกอินให้เสร็จสิ้น หลังจากนั้น:
netbird status
ip addr show wt0อ่านสี่บรรทัดจาก netbird status: Management: Connected, Signal: Connected, บรรทัด Relays: ที่รายงาน relay ทั้งหมดที่มีอยู่ และ NetBird IP: ในช่วง overlay range ส่วน wt0 คืออินเทอร์เฟซ WireGuard ที่ NetBird สร้างขึ้น ซึ่งควรจะมีที่อยู่ IP เดียวกันนี้
การเชื่อมต่อเครื่องที่สองแบบไม่ต้องเฝ้าหน้าจอด้วย setup key
การล็อกอินผ่านเบราว์เซอร์ไม่สามารถทำได้กับเครื่องที่ไม่มีเบราว์เซอร์และไม่มีผู้ใช้งานอยู่หน้าเครื่อง setup key คือโทเค็นสำหรับการยืนยันตัวตนล่วงหน้าซึ่งใช้ลงทะเบียนเครื่องโดยไม่ต้องผ่านขั้นตอนโต้ตอบ คุณสามารถสร้างคีย์นี้ได้ในแดชบอร์ดภายใต้หัวข้อ Setup Keys
คีย์มีอยู่ 2 ประเภท คีย์แบบใช้ครั้งเดียว (one-off key) จะยืนยันตัวตนเครื่องได้เพียงเครื่องเดียวแล้วจะถูกใช้จนหมด ส่วนคีย์แบบใช้ซ้ำได้ (reusable key) สามารถใช้ลงทะเบียนเครื่องได้หลายเครื่อง โดยสามารถกำหนดจำนวนสูงสุดได้ ทั้งสองประเภทต้องมีการกำหนดวันหมดอายุ และสามารถกำหนดให้ peer ใหม่เข้ากลุ่มโดยอัตโนมัติ เพื่อให้กฎการเข้าถึงของกลุ่มนั้นมีผลทันทีที่เครื่องปรากฏในระบบ
sudo netbird up --setup-key <SETUP-KEY> \
--management-url https://netbird.example.com \
--hostname build-runner-01--hostname ใช้สำหรับกำหนดชื่อที่จะแสดงในแดชบอร์ด หากไม่มีการกำหนดค่านี้ peer จะใช้ชื่อที่เครื่องเรียกตัวเอง ซึ่งการมีรายการจำนวนมากที่ชื่อ ubuntu จะไม่เป็นประโยชน์ต่อการจัดการ
สำหรับคอนเทนเนอร์และ build agent ที่มีอายุการใช้งานสั้น ให้ทำเครื่องหมายคีย์ว่าเป็น ephemeral ในขณะที่สร้าง peer ที่ลงทะเบียนด้วย ephemeral key จะถูกลบออกโดยอัตโนมัติเมื่อออฟไลน์นานเกิน 10 นาที ซึ่งช่วยป้องกันไม่ให้มีรายการที่ไม่ได้ใช้งานค้างอยู่ในรายการ peer
ข้อจำกัดประการหนึ่งที่ควรทราบก่อนวางแผนใช้งาน setup key คือ การหมดอายุหรือการลบคีย์จะหยุดการลงทะเบียนใหม่เท่านั้น แต่จะไม่ตัดการเชื่อมต่อเครื่องที่ลงทะเบียนไปแล้ว การเพิกถอนสิทธิ์การเข้าถึงของเครื่องต้องทำโดยการลบ peer นั้นออก
คุณยังจำเป็นต้องมี Identity Provider แยกต่างหากหรือไม่
สำหรับการติดตั้งขนาดเล็ก คำตอบคือไม่จำเป็น ระบบจัดเก็บผู้ใช้ในตัวสามารถจัดการบัญชีที่สร้างจากแดชบอร์ดได้ ซึ่งเพียงพอสำหรับผู้ใช้งานจำนวนไม่กี่คน
คุณจะต้องการ Identity Provider ภายนอกก็ต่อเมื่อคุณมีระบบดังกล่าวอยู่แล้วและไม่ต้องการจัดการรายชื่อผู้ใช้ซ้ำซ้อน NetBird รองรับทุก Provider ที่สื่อสารผ่านโปรโตคอล OIDC ให้คุณลงทะเบียน confidential OIDC client ใน Provider ของคุณ จากนั้นเพิ่มข้อมูลลงในแดชบอร์ดของ NetBird โดยใช้ค่า 4 รายการ ได้แก่ ชื่อ (name), client ID, client secret และ issuer โดย NetBird จะให้ redirect URL เพื่อนำไปกรอกกลับใน Provider ของคุณ ทั้งนี้มีการเตรียมการเชื่อมต่อสำเร็จรูปไว้สำหรับ Google, Microsoft Entra ID, Okta, Zitadel, Keycloak, Authentik และ Pocket ID ส่วนบริการอื่นๆ สามารถตั้งค่าผ่าน generic OIDC ได้ หากคุณใช้งาน Authentik เป็นระบบ single sign-on แบบ self-hosted อยู่แล้ว นี่คือแนวทางที่จะช่วยให้คุณคงรายชื่อผู้ใช้ไว้เพียงชุดเดียวแทนที่จะเป็นสองชุด
การล็อกอินแบบ local จะยังคงใช้งานได้หลังจากที่คุณเพิ่ม Provider เข้าไป และทุก Provider ที่กำหนดค่าไว้จะปรากฏบนหน้าล็อกอิน โปรดเก็บรักษาบัญชีผู้ดูแลระบบแบบ local ไว้หนึ่งบัญชีพร้อมรหัสผ่านที่รัดกุม เพื่อให้คุณยังมีช่องทางเข้าถึงระบบได้หากการตั้งค่า OIDC เกิดข้อผิดพลาด
NetBird หรือ Headscale: คุณควรใช้งาน control plane ตัวไหน?
ทั้งสองตัวช่วยลดการพึ่งพาบริการภายนอกเหมือนกัน นั่นคือการไม่ต้องเชื่อมต่อกับ control server ของผู้ให้บริการที่ไคลเอนต์ของคุณต้องติดต่อสื่อสารด้วยตามปกติ แต่ทั้งสองโครงการมีลักษณะการทำงานที่แตกต่างกัน
Headscale เป็นการนำ control server ของ Tailscale มาเขียนใหม่ โดยคุณยังคงใช้ไคลเอนต์อย่างเป็นทางการของ Tailscale ต่อไป ทั้งนี้ไม่มีหน้าเว็บคอนโซลอย่างเป็นทางการมาให้ คุณต้องจัดการผู้ใช้และ pre-authentication keys ผ่านคำสั่ง headscale โดยอ้างอิงกับไฟล์คอนฟิก ทั้งนี้มีหน้าเว็บอินเทอร์เฟซที่พัฒนาโดยชุมชนให้เลือกใช้ แต่ไม่ได้เป็นส่วนหนึ่งของโครงการหลัก วิธีนี้เหมาะสำหรับผู้ที่ต้องการเก็บสถานะไว้ในไฟล์และจัดการการเปลี่ยนแปลงผ่านระบบ version control
NetBird มาพร้อมกับผลิตภัณฑ์ที่ครบวงจร ได้แก่ ไคลเอนต์ของตนเอง, แดชบอร์ด, identity provider ในตัว และนโยบายการเข้าถึงที่แก้ไขได้ผ่านเบราว์เซอร์ วิธีนี้ทำให้มีส่วนประกอบที่ต้องดูแลบน VPS มากขึ้น แต่ช่วยลดภาระงานได้อย่างมากหากต้องส่งมอบงานให้เพื่อนร่วมงานที่ไม่ต้องการใช้งานผ่าน terminal
เลือกใช้ Headscale หากคุณใช้งานไคลเอนต์ของ Tailscale อยู่แล้ว หรือต้องการ control plane ที่มีขนาดเล็กที่สุดเท่าที่จะเป็นไปได้ เลือกใช้ NetBird หากมีหลายคนจำเป็นต้องจัดการ peer และคุณต้องการคอนโซลรวมถึงระบบ SSO โดยไม่ต้องประกอบระบบขึ้นมาเอง
VPS ขนาดเล็กที่สุดที่สามารถรันระบบนี้ได้คือเท่าใด
ข้อกำหนดขั้นต่ำที่ระบุไว้คือ CPU 1 คอร์ และหน่วยความจำ 2 GB บันทึกของ NetBird ระบุว่าปัจจุบันสามารถรันได้ที่ RAM ประมาณ 1 GB เนื่องจากมีการจัดการผู้ใช้แบบ local ซึ่งต่างจากโครงสร้างเดิมที่ต้องใช้ RAM 2 GB ถึง 4 GB ในสมัยที่ต้องติดตั้ง Zitadel ทั้งชุดร่วมด้วย แนะนำให้ซื้อขนาด 2 GB เพราะพื้นที่หน่วยความจำที่เหลือจะช่วยให้สามารถดึง image ใหม่ระหว่างการอัปเกรดได้ในขณะที่ image เก่ายังคงอยู่ในดิสก์
มี 3 สิ่งที่สามารถตัดออกได้หากใช้เครื่องขนาดเล็ก: ให้ปฏิเสธการติดตั้งบริการ NetBird Proxy ซึ่งมีไว้สำหรับเผยแพร่บริการภายในผ่านชื่อโฮสต์สาธารณะและไม่มีผลต่อการเชื่อมต่อระหว่าง peer, ให้ปฏิเสธการติดตั้ง CrowdSec ซึ่งสามารถเพิ่มภายหลังได้เมื่อเครื่องเปิดรับการเชื่อมต่อจากภายนอก แทนที่จะติดตั้งตั้งแต่วันแรก, และให้ใช้ SQLite store ตามค่าเริ่มต้นใน volume netbird_data โดยให้ย้ายไปใช้ PostgreSQL เฉพาะเมื่อคุณแยกการติดตั้งออกเป็นหลายเครื่องหรือเมื่อพบปัญหาการใช้งานพร้อมกันจำนวนมาก ซึ่งมีเอกสารระบุว่าเป็นขั้นตอนการย้ายข้อมูลที่สามารถทำได้ในภายหลัง
Relay เป็นส่วนประกอบเดียวที่คุณไม่สามารถตัดออกได้ หาก peer สองตัวมี NAT ที่กำหนดพอร์ตต่างกันสำหรับทุกปลายทาง ทั้งสองจะไม่สามารถสร้าง tunnel โดยตรงได้ ดังนั้น relay จึงเป็นเส้นทางเดียวที่ทำให้การเชื่อมต่อทำงานได้ การปิดใช้งาน relay ช่วยประหยัดหน่วยความจำได้เพียงเล็กน้อย แต่จะทำให้การเชื่อมต่อล้มเหลวในลักษณะที่ตรวจสอบสาเหตุได้ยาก
เมื่อเครื่องเดียวไม่เพียงพอต่อการใช้งาน Relay คือสิ่งแรกที่ควรย้ายออกไปติดตั้งแยกต่างหาก Relay แบบ standalone สามารถรันได้ด้วย NB_LISTEN_ADDRESS, NB_EXPOSED_ADDRESS, NB_AUTH_SECRET และ NB_ENABLE_STUN โดย shared secret จะต้องตรงกันทั้งบน relay และบนเซิร์ฟเวอร์หลัก มิฉะนั้นไคลเอ็นต์จะไม่สามารถยืนยันตัวตนกับ relay ได้
รูปแบบความล้มเหลวและสิ่งที่คุณจะพบ
แดชบอร์ดแสดงคำเตือนเกี่ยวกับใบรับรอง Traefik ไม่สามารถขอใบรับรองได้ ให้รัน docker compose logs traefik | grep -i acme สาเหตุมีสองประการ ประการแรกคือ dig +short netbird.example.com ยังไม่ชี้มาที่ VPS นี้ หรือประการที่สองคือพอร์ต TCP 80 ถูกปิดกั้นระหว่าง Let's Encrypt กับคอนเทนเนอร์ ซึ่งมักเกิดจากไฟร์วอลล์เครือข่ายของผู้ให้บริการมากกว่าที่จะเป็นที่ ufw ให้แก้ไขสาเหตุให้เรียบร้อยก่อนลองใหม่ เพราะการตรวจสอบที่ล้มเหลวมีข้อจำกัดด้านอัตรา (rate limit) ซึ่งจะทำให้คุณไม่สามารถลองใหม่ได้เป็นเวลาหนึ่งชั่วโมง
ไคลเอนต์แจ้งว่าเชื่อมต่อแล้วแต่แดชบอร์ดว่างเปล่า ไคลเอนต์ได้ลงทะเบียนกับบริการโฮสต์ของ NetBird เนื่องจาก --management-url หายไป ให้รัน netbird status --detail และอ่านบรรทัด Management: ซึ่งจะระบุชื่อเซิร์ฟเวอร์ที่ไคลเอนต์กำลังติดต่ออยู่จริง หากพบ Management: Connected to https://api.netbird.io:443 แสดงว่าไคลเอนต์เชื่อมต่อไปยังระบบคลาวด์ ให้รัน sudo netbird down แล้วรัน sudo netbird up --management-url https://netbird.example.com อีกครั้ง
เพียร์ทุกตัวแสดงสถานะ Connection type: Relayed ไม่มีการสร้างอุโมงค์เชื่อมต่อโดยตรง ทำให้ทราฟฟิกทั้งหมดต้องผ่าน VPS ของคุณและเพิ่มความหน่วง (latency) ให้ตรวจสอบพอร์ต UDP 3478 บนไฟร์วอลล์ของ VPS และไฟร์วอลล์ของผู้ให้บริการ เนื่องจาก STUN คือสิ่งที่ช่วยให้เพียร์ทราบที่อยู่สาธารณะและพอร์ตของตนเอง นอกจากนี้ netbird status --detail ยังแสดง Direct: false และประเภทของ ICE (interactive connectivity establishment) candidate สำหรับเพียร์แต่ละตัว ซึ่งจะแสดงให้เห็นว่ากระบวนการเชื่อมต่อดำเนินไปถึงขั้นตอนใด ในบางเครือข่าย การเชื่อมต่อแบบ relayed อาจเป็นผลลัพธ์เดียวที่ทำได้และไม่ได้หมายความว่ามีสิ่งใดผิดปกติ
เพียร์เข้าร่วมเครือข่ายแล้วแต่ไม่สามารถเข้าถึงสิ่งใดได้ การอยู่ใน mesh ไม่ได้หมายความว่าเพียร์สองตัวจะคุยกันได้เสมอไป นโยบายการเข้าถึง (access policies) เป็นตัวกำหนดเรื่องนี้ และกลุ่มที่ไม่มีนโยบายแนบอยู่จะไม่สามารถเข้าถึงสิ่งใดได้ ให้ตรวจสอบนโยบายในแดชบอร์ดก่อนที่คุณจะเริ่มดีบั๊กเส้นทาง (routes) และไฟร์วอลล์
netbird status รายงานปัญหาเกี่ยวกับ daemon บริการไม่ได้ทำงานอยู่ ให้ใช้ sudo netbird service status และ sudo netbird service start บันทึกของไคลเอนต์อยู่ที่ /var/log/netbird/client.log สำหรับสิ่งที่คุณไม่สามารถระบุสาเหตุได้ netbird debug bundle --anonymize --system-info จะรวบรวมบันทึก, สถานะ, เส้นทาง, การตั้งค่า DNS และสถานะไฟร์วอลล์ไว้ในไฟล์เก็บถาวรไฟล์เดียว
การสำรองข้อมูลและการอัปเกรด
มีสองสิ่งที่ครอบคลุมการติดตั้งทั้งหมด ได้แก่ ไดเรกทอรีที่เก็บ docker-compose.yml และ config.yaml รวมถึง Docker volume ที่เก็บฐานข้อมูลและคีย์เข้ารหัสลับ ให้สำรองข้อมูลสิ่งเหล่านี้ไปพร้อมกัน config.yaml เก็บกุญแจที่ใช้เข้ารหัสข้อมูลในที่จัดเก็บ ดังนั้นหากคัดลอกฐานข้อมูลโดยไม่มีไฟล์นี้ คุณจะไม่สามารถกู้คืนข้อมูลที่อ่านได้
docker volume ls
docker compose down
sudo tar czf netbird-config.tgz -C ~ netbird
docker run --rm -v netbird_netbird_data:/data -v "$PWD":/backup \
alpine tar czf /backup/netbird-data.tgz -C /data .
docker compose up -dCompose จะใส่ชื่อไดเรกทอรีโปรเจกต์นำหน้าชื่อ volume ดังนั้น volume ที่ระบุไว้ใน netbird_data มักจะปรากฏในชื่อ netbird_netbird_data ให้รัน docker volume ls ก่อนแล้วใช้ชื่อที่แสดงผลออกมา มิฉะนั้น docker run ด้านบนจะล้มเหลวโดยการสร้าง volume เปล่าขึ้นมาเงียบๆ และไม่ได้สำรองข้อมูลใดๆ ไว้ ให้เก็บไฟล์สำรองไว้นอก VPS หากคุณมีเครื่องมือสำรองข้อมูลอยู่แล้ว restic หรือ BorgBackup สามารถจัดการส่วนการสำรองข้อมูลนอกสถานที่ได้
การอัปเกรดเซิร์ฟเวอร์ทำได้โดยการ pull และ recreate:
docker compose pull
docker compose up -d
docker compose psก่อนที่คุณจะพึ่งพาวิธีดังกล่าว ให้รัน docker compose config | grep image: เสียก่อน แท็กใดก็ตามที่อ่านว่า latest ควรถูกกำหนดเวอร์ชันให้ชัดเจน ด้วยเหตุผลเดียวกับที่คุณกำหนดเวอร์ชันในสคริปต์ติดตั้ง นั่นคือคุณต้องการทราบว่ากำลังรันเวอร์ชันใดอยู่ และต้องการเวอร์ชันที่สามารถย้อนกลับไปได้เมื่อการอัปเกรดเกิดปัญหา ส่วนไคลเอนต์จะอัปเกรดผ่านตัวจัดการแพ็กเกจที่ใช้ติดตั้งโปรแกรมนั้นๆ
FAQ
ฉันจำเป็นต้องมี identity provider ของตัวเองเพื่อ self-host NetBird หรือไม่?
ไม่จำเป็น รุ่นปัจจุบันมีระบบจัดเก็บผู้ใช้ในตัว คุณสามารถสร้างบัญชีผู้ดูแลระบบบัญชีแรกผ่านเบราว์เซอร์ที่ https://netbird.example.com และเพิ่มผู้ใช้รายอื่นจากแดชบอร์ดได้ในภายหลัง การใช้ OIDC provider ภายนอกเป็นเพียงทางเลือกและสามารถเพิ่มในภายหลังได้โดยใช้ค่า 4 รายการ ได้แก่ name, client ID, client secret และ issuer คู่มือที่แนะนำให้คุณติดตั้ง Zitadel หรือ Keycloak ก่อนติดตั้ง NetBird เป็นการตั้งค่าที่ไม่จำเป็นอีกต่อไป และการทำตามคู่มือนั้นจะทำให้คุณต้องดูแลบริการเพิ่มขึ้นโดยไม่จำเป็น
ทำไม peer ทั้งหมดของฉันถึงแสดงสถานะเป็น Connection type: Relayed?
เนื่องจากไม่สามารถสร้างการเชื่อมต่อโดยตรงได้ ทราฟฟิกจึงต้องวิ่งผ่าน relay บน VPS ของคุณ สาเหตุทั่วไปคือพอร์ต UDP 3478 ถูกบล็อก ซึ่งเป็นพอร์ต STUN ที่ peer ใช้สำหรับค้นหา public address และพอร์ตของตนเอง ให้เปิดพอร์ตนี้บนไฟร์วอลล์ของ VPS และไฟร์วอลล์เครือข่ายของผู้ให้บริการ จากนั้นรันคำสั่ง netbird status --detail อีกครั้งและตรวจสอบบรรทัด Direct: หากเครือข่ายที่คุณใช้งานมีการทำ NAT โดยกำหนดพอร์ตแยกตามปลายทาง การเชื่อมต่อแบบ relayed จะเป็นผลลัพธ์เดียวที่เกิดขึ้นได้และไม่ได้มีการตั้งค่าผิดพลาดแต่อย่างใด
ไคลเอนต์เชื่อมต่อแล้วแต่แดชบอร์ดไม่แสดง peer เกิดอะไรขึ้น?
ไคลเอนต์ลงทะเบียนกับบริการ hosted ของ NetBird แทนที่จะเป็นเซิร์ฟเวอร์ของคุณ ซึ่งเป็นผลมาจากการไม่ได้ระบุค่า --management-url ในการตั้งค่า คำสั่ง netbird status --detail จะแสดงเซิร์ฟเวอร์ที่ไคลเอนต์กำลังติดต่ออยู่บนบรรทัด Management: ดังนั้นหากค่าที่แสดงเป็น https://api.netbird.io:443 ก็ถือว่ายืนยันได้ ให้รันคำสั่ง sudo netbird down ตามด้วย sudo netbird up --management-url https://netbird.example.com แล้ว peer จะปรากฏในแดชบอร์ดของคุณ
NetBird แบบ self-hosted แตกต่างจาก Headscale อย่างไร?
ทั้งสองอย่างทำหน้าที่แทน control server แบบ hosted ด้วยเซิร์ฟเวอร์ที่คุณดูแลเอง Headscale เป็นเพียง control plane เท่านั้น คุณต้องจัดการผ่านคำสั่ง headscale และไฟล์คอนฟิก ไม่มีเว็บคอนโซลอย่างเป็นทางการ และใช้ไคลเอนต์ของ Tailscale อย่างเป็นทางการ ส่วน NetBird มีไคลเอนต์ แดชบอร์ดผู้ดูแลระบบ และการรวม identity provider มาให้ในชุดเดียวกัน Headscale ใช้ทรัพยากรน้อยกว่าและเก็บสถานะไว้ในไฟล์ ส่วน NetBird ใช้งานง่ายกว่าสำหรับผู้ที่ไม่ต้องการใช้ terminal
เซิร์ฟเวอร์ VPS ขนาดเท่าใดที่จำเป็นสำหรับ NetBird แบบ self-hosted?
ข้อกำหนดขั้นต่ำที่ระบุไว้คือ CPU 1 คอร์ และหน่วยความจำ 2 GB ซึ่งเป็นขนาดที่แนะนำให้เลือกใช้ ปัจจุบันความต้องการใช้งานจริงลดลงเหลือประมาณ 1 GB ในรุ่นล่าสุดเนื่องจาก identity provider ถูกรวมไว้ในตัวแทนที่จะต้องติดตั้งแยกต่างหาก คุณสามารถเลือกไม่ติดตั้งบริการ proxy และ CrowdSec ในระหว่างการติดตั้ง และใช้ SQLite ที่เป็นค่าเริ่มต้นไปก่อนจนกว่าคุณจะมีความจำเป็นต้องใช้ PostgreSQL จริงๆ