1 คะแนน โดย GN⁺ 2024-03-14 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

การปรับปรุง WireGuard ของ Fly.io

  • Fly.io แปลงคอนเทนเนอร์เป็น VM แล้วรันบนฮาร์ดแวร์ทั่วโลกโดยใช้พลังของ Firecracker
  • ใช้งาน WireGuard อย่างมาก และตอนนี้มันกลายเป็นส่วนหนึ่งของ API สำหรับลูกค้าแล้ว
  • ทุกครั้งที่รัน CLI flyctl ระบบจะสร้างสแตก TCP/IP และสื่อสารกับ Fly Machines โดยตรงด้วยที่อยู่ IPv6 เฉพาะ
  • แนวทางนี้มีทั้งข้อดีและข้อเสีย และมีการปรับปรุงบางอย่าง

สถานการณ์ก่อนหน้านี้

  • เซิร์ฟเวอร์ "gateway" ที่อยู่ทั่วโลกทำหน้าที่รับการเชื่อมต่อ WireGuard และเชื่อมต่อไปยังเครือข่ายส่วนตัวที่เหมาะสม
  • ทุกครั้งที่รัน flyctl จะสร้างหรือเชื่อมต่อกับโปรเซสเอเจนต์เบื้องหลัง
  • เอเจนต์สร้างการตั้งค่า WireGuard peer ใหม่จาก GraphQL API
  • API ส่งการตั้งค่า peer ไปยัง gateway ที่เหมาะสมผ่านระบบส่งข้อความ NATS
  • บริการ wggwd บน gateway รับการตั้งค่า เก็บไว้ในฐานข้อมูล SQLite และเพิ่มเข้าไปในเคอร์เนล
  • API ตอบกลับคำขอ GraphQL พร้อมส่งการตั้งค่า และ flyctl จะเชื่อมต่อกับ WireGuard peer
  • NATS แม้จะรวดเร็ว แต่ไม่รับประกันการส่งถึง และไม่จัดการล้าง peer เก่าที่ค้างอยู่บน gateway

วิธีที่ดีกว่า

  • การเก็บ WireGuard peer ไม่จำเป็นต้องใช้ฐานข้อมูลที่ซับซ้อน
  • เปลี่ยนให้ gateway ดึงการตั้งค่าจาก API ทุกครั้งที่ต้องการ
  • เพิ่ม peer เข้าเคอร์เนลเฉพาะตอนที่ไคลเอนต์ต้องการเชื่อมต่อ และลบออกได้เมื่อไม่จำเป็น

ทำให้ WireGuard peer แบบ JIT เป็นไปได้

  • อินเทอร์เฟซการตั้งค่า WireGuard ของเคอร์เนล Linux ใช้ Netlink
  • สามารถระบุและดักจับแพ็กเก็ตคำขอเชื่อมต่อ WireGuard ได้ด้วย BPF filter และ packet socket
  • WireGuard ไม่มีแนวคิดเรื่อง "client" และ "server" แต่เป็นโปรโตคอลแบบ point-to-point
  • เมื่อ flyctl ส่งแพ็กเก็ต UDP ไปยัง gateway นั่นคือ handshake initiation
  • สามารถใช้ BPF filter เพื่อจับการเชื่อมต่อขาเข้าได้
  • เนื่องจากอิงกับเฟรมเวิร์กโปรโตคอล Noise จึงต้องถอดรหัสเพื่อระบุคำขอ
  • สามารถสร้าง event feed เพื่อรับ public key ของผู้ใช้ทุกคนที่พยายามเชื่อมต่อกับ gateway
  • ทุกครั้งที่พบ peer ใหม่ จะดึงข้อมูลของ peer นั้นผ่านคำขอ HTTP API ภายในแล้วติดตั้ง

เปิดแอปได้ในระดับนาที

  • บน Fly.io สามารถดีพลอยแอปได้อย่างรวดเร็วและรับ JIT WireGuard peer ของตัวเองได้

มาดูกราฟกัน

  • หลังจากรันระบบนี้มาหลายสัปดาห์ จำนวน WireGuard peer เก่าที่ค้างอยู่บน gateway ลดลงอย่างชัดเจน
  • gateway คงสถานะน้อยลง และการตั้งค่า peer ทำได้เร็วขึ้น
  • มีการแชร์ผลลัพธ์ที่ประสบความสำเร็จในวันเปลี่ยนผ่านผ่านกราฟ Grafana

ความเห็นของ GN⁺

  • การปรับปรุง WireGuard ของ Fly.io เป็นตัวอย่างที่ดีของการยกระดับประสิทธิภาพและความเสถียรของเครือข่ายอย่างมาก
  • แนวทางนี้อาจช่วยเสริมการจัดการทราฟฟิกเครือข่ายและความปลอดภัยได้ โดยเฉพาะในบริการบนคลาวด์
  • โปรเจ็กต์อื่นที่มีความสามารถคล้ายกัน ได้แก่ Tailscale และ ZeroTier ซึ่งต่างก็เป็นทางเลือก VPN สำหรับผู้ใช้ส่วนบุคคลและองค์กร
  • เมื่อนำ WireGuard มาใช้ ควรพิจารณาเรื่องการตั้งค่าเครือข่าย นโยบายความปลอดภัย และความเข้ากันได้
  • ข้อดีของการเลือกเทคโนโลยีนี้คือประสิทธิภาพที่รวดเร็วและการตั้งค่าที่เรียบง่าย แต่ก็อาจมีความท้าทายในด้านการผสานเข้ากับโครงสร้างพื้นฐานเดิมหรือการดูแลจัดการ

1 ความคิดเห็น

 
GN⁺ 2024-03-14
ความคิดเห็นจาก Hacker News
  • มีการบอกว่า WireGuard ของลินุกซ์เคอร์เนลไม่มีฟีเจอร์ติดตั้ง peer ตามคำขอ ทำให้เกิดปัญหาในการออกแบบระบบ

    • WireGuard ของลินุกซ์เคอร์เนลขาดความสามารถในการติดตั้ง peer ตามคำขอ จึงทำให้ออกแบบระบบได้ยาก
    • แม้จะเพิ่ม peer ระหว่างรันไทม์ได้ แต่ดูเหมือนว่าต้องการยืนยันตัวตนของ peer ก่อนเพิ่มเข้า interface เพื่อป้องกันรายการที่ไม่จำเป็น
    • ใช้ตัวกรอง eBPF เพื่อจัดการการเชื่อมต่อแบบ routed ด้วยคีย์เข้ารหัสกับฝั่งที่ยืนยันตัวตนแล้วโดยตรง และเมื่อการตรวจสอบเสร็จสิ้นจึงเพิ่ม peer เข้า interface แล้วลบออกเมื่อหมดเวลา
  • ผมเห็นด้วยว่าคำขอ HTTP โดยตรงเชื่อถือได้มากกว่าการ routing ผ่าน message queue แต่ก็แปลกใจที่ข้อความที่หายไปเพราะ NATS ส่งผลต่อบริการมากขนาดนั้น

    • เห็นด้วยกับความเห็นที่ว่าคำขอ HTTP โดยตรงเชื่อถือได้มากกว่า message queue แต่สงสัยที่ข้อความสูญหายใน NATS ส่งผลต่อบริการอย่างมีนัยสำคัญ
    • ปกติคาดว่าเมื่อข้อความสูญหาย NATS จะพยายามส่งซ้ำ จึงตั้งคำถามว่าทำไมถึงเกิดปัญหาด้านความเชื่อถือได้ที่สังเกตได้ชัด
  • อยากโปรโมตโปรเจ็กต์เชิงทดลองล่าสุดของผม หากคุณสนใจสร้างแอป Go ที่ทำงานเป็น WireGuard peer ใน user space ลองดูได้

    • แนะนำโปรเจ็กต์ของตนสำหรับผู้ที่สนใจสร้างแอป Go ที่ทำงานเป็น WireGuard peer ใน user space
    • ตั้งอยู่บนพื้นฐานของงานที่ยอดเยี่ยมของ wireguard-go แต่ต้องการทำให้ง่ายขึ้นเพื่อให้เหมาะกับการใช้งานแบบไลบรารีมากกว่าเดิม
    • สนใจการสร้าง service mesh และคิดว่าการรองรับหลายภาษาอาจยาก แต่ก็น่าจะทำ socket API ได้
    • กล่าวถึงว่ายังไม่เห็น hardware acceleration สำหรับการเข้ารหัสของ WireGuard จึงอาจแข่งขันกับ mTLS ได้ยาก
    • ทำงานฟรีแลนซ์ในด้านเครือข่ายความเร็วสูง/ความปลอดภัย และเชิญผู้สนใจติดต่อมาได้ (อีเมลอยู่ในโปรไฟล์)
  • น่าสนใจที่การ tunnel WireGuard บน WebSockets เป็นค่าตั้งต้น แม้ไม่ดีต่อประสิทธิภาพ แต่ก็น่าจะเหมาะกับงาน DevOps ที่ใช้ flyctl

    • สังเกตว่าการ tunnel WireGuard ผ่าน WebSockets เป็นค่าตั้งต้น
    • แม้จะไม่เหมาะที่สุดในด้านประสิทธิภาพ แต่คาดว่าสำหรับงาน DevOps ที่ใช้ flyctl ก็คงไม่มีปัญหา
    • สงสัยเกี่ยวกับอนาคตของ QUIC/HTTP3 และตั้งคำถามว่าผู้ดูแลเครือข่ายจะจัดการ UDP บนพอร์ต 443 อย่างถูกต้องแทนที่จะบล็อกหรือไม่
  • เราสามารถติดตั้ง peer ในฐานะผู้ส่งได้ และ flyctl เป็นผู้ตอบกลับ ลินุกซ์เคอร์เนลเริ่มการเชื่อมต่อ WireGuard ไปยัง flyctl วิธีนี้ใช้ได้ผล และโปรโตคอลก็ไม่ได้สนใจมากนักว่าใครเป็นเซิร์ฟเวอร์หรือไคลเอนต์ การเชื่อมต่อใหม่จะถูกติดตั้งให้เร็วที่สุด

    • อธิบายวิธีที่ติดตั้ง peer ในฐานะผู้ส่ง โดยมี flyctl เป็นผู้ตอบกลับ และให้ลินุกซ์เคอร์เนลเริ่มการเชื่อมต่อ WireGuard
    • กล่าวว่าตัวโปรโตคอลไม่ได้ยึดติดกับบทบาทเซิร์ฟเวอร์และไคลเอนต์มากนัก และการเชื่อมต่อใหม่สามารถเกิดขึ้นได้อย่างรวดเร็วมาก
  • สตาร์ตอัปของเราใช้ Fly มาเกือบ 1 ปีแล้ว ฟีเจอร์หลักที่เปลี่ยนโค้ดให้เป็นโค้ดที่ deploy แล้วได้ภายในไม่ถึง 1 นาทีมันยอดเยี่ยมมาก และยังสปินอัป/ดาวน์โหนดใหม่ได้ภายในไม่กี่วินาที

    • แชร์ประสบการณ์ที่สตาร์ตอัปของตนใช้ Fly มาเกือบ 1 ปี
    • มองบวกกับความสามารถในการ deploy โค้ดได้อย่างรวดเร็ว แต่รู้สึกว่าบริษัทยังไม่ค่อยสุกงอม
    • กล่าวถึงประสบการณ์ที่ API server ของ Fly เข้าใช้งานไม่ได้เป็นเวลา 48 ชั่วโมง และปัญหาการตัดการเชื่อมต่อของผลิตภัณฑ์ "db" ที่ไม่สม่ำเสมอ
    • ชี้ว่า API ของ Fly ล่มบ่อยจนมีปัญหาในการ deploy การแก้ไขบริการใหม่
    • บอกว่าคิดถึงประสบการณ์การ deploy แบบนั้น แต่พอใจมากกว่ากับการใช้ Cloud Run ของ GCP
  • “ทุกครั้งที่รัน flyctl, CLI ตัวมหึมาแสนน่ารักของเราจะสร้าง TCP/IP stack ขึ้นมากลางอากาศ แล้วสื่อสารกับ Fly Machines โดยตรงด้วย IPv6 address เฉพาะของตัวเอง”

    • แสดงความสงสัยต่อคำอธิบายที่ว่าเมื่อรัน flyctl จะสร้าง TCP/IP stack ขึ้นมาทันทีและสื่อสารกับ Fly Machines โดยตรงผ่าน IPv6 address เฉพาะ
  • อะไรเป็นตัวป้องกันไม่ให้แพ็กเก็ต handshake เริ่มต้นถูกส่งซ้ำเข้า network stack? ถ้าเป็นแบบนั้นก็น่าจะไม่มี packet loss อีกทั้งการตรวจสอบ udp[8] = 1 ในตัวกรอง eBPF มีจุดประสงค์อะไร?

    • ตั้งคำถามถึงกลไกที่ป้องกันไม่ให้แพ็กเก็ต handshake เริ่มต้นถูกส่งซ้ำเข้า network stack และถามเหตุผลที่ตรวจสอบค่าของแพ็กเก็ต UDP เฉพาะในตัวกรอง eBPF
  • ถ้าจะ deploy แอปพลิเคชันแบบ dockerized ทั่วไปไปที่ Fly.io ต้องทำอย่างไร? เอาเงินผมไปเลย

    • แสดงความสนใจและความตั้งใจที่จะ deploy แอปพลิเคชันแบบ dockerized ไปยัง Fly.io
  • สำหรับทุกคนที่เหลือ ผมขอโปรโมต Netmaker แบบไม่อายเลย

    • แชร์ประสบการณ์ที่พึงพอใจกับ Netmaker พร้อมกล่าวถึงความจำเป็นในการเข้าถึง AWS VPC เป็นการส่วนตัว และหวังว่า Netmaker จะถูกนำไปใช้แพร่หลายมากขึ้น