1 điểm bởi GN⁺ 2024-03-14 | 1 bình luận | Chia sẻ qua WhatsApp

Các cải tiến WireGuard của Fly.io

  • Fly.io chuyển container thành VM và chạy chúng trên phần cứng toàn cầu bằng sức mạnh của Firecracker.
  • Fly.io sử dụng WireGuard rất nhiều, và giờ đây nó đã trở thành một phần trong API khách hàng.
  • Mỗi khi chạy CLI flyctl, hệ thống tạo một ngăn xếp TCP/IP và giao tiếp trực tiếp với Fly Machines bằng một địa chỉ IPv6 duy nhất.
  • Cách tiếp cận này có những ưu và nhược điểm riêng, và đã có một số cải tiến.

Tình hình trước đây

  • Các máy chủ "gateway" trên khắp thế giới tiếp nhận kết nối WireGuard và đảm nhiệm việc nối chúng vào mạng riêng phù hợp.
  • Mỗi lần chạy flyctl, hệ thống sẽ tạo hoặc kết nối tới một tiến trình agent chạy nền.
  • Agent tạo một cấu hình peer WireGuard mới từ GraphQL API.
  • API gửi cấu hình peer tới gateway thích hợp thông qua hệ thống nhắn tin NATS.
  • Trên gateway, dịch vụ wggwd nhận cấu hình, lưu vào cơ sở dữ liệu SQLite và thêm vào kernel.
  • API phản hồi yêu cầu GraphQL để chuyển cấu hình, và flyctl kết nối tới peer WireGuard.
  • NATS nhanh nhưng không đảm bảo việc phân phối, và cũng không dọn dẹp các peer cũ còn sót lại trên gateway.

Một cách tốt hơn

  • Việc lưu trữ các peer WireGuard không cần tới một cơ sở dữ liệu phức tạp.
  • Hệ thống được thay đổi để gateway tự lấy cấu hình từ API mỗi khi cần.
  • Chỉ thêm peer vào kernel khi client muốn kết nối, và có thể gỡ ra khi không còn cần nữa.

Có thể triển khai peer WireGuard JIT

  • Giao diện cấu hình WireGuard trong kernel Linux sử dụng Netlink.
  • Có thể nhận diện và chặn các gói yêu cầu kết nối WireGuard bằng bộ lọc BPF và packet socket.
  • WireGuard không có khái niệm "client" và "server", mà là một giao thức point-to-point.
  • Khi flyctl gửi một gói UDP tới gateway, đó là handshake initiation.
  • Có thể dùng bộ lọc BPF để bắt các kết nối đi vào.
  • Vì dựa trên framework giao thức Noise, cần giải mã để nhận diện yêu cầu.
  • Có thể tạo một luồng sự kiện để lấy khóa công khai của mọi người dùng đang cố kết nối tới gateway.
  • Mỗi khi thấy một peer mới, hệ thống sẽ lấy thông tin peer đó qua một yêu cầu HTTP API nội bộ và cài đặt nó.

Khởi chạy ứng dụng theo phút

  • Trên Fly.io, có thể triển khai ứng dụng nhanh chóng và nhận peer JIT WireGuard riêng của mình.

Xem biểu đồ

  • Sau vài tuần vận hành hệ thống này, số lượng peer WireGuard cũ còn sót lại trên gateway đã giảm đáng kể.
  • Gateway duy trì ít trạng thái hơn và việc cấu hình peer diễn ra nhanh hơn.
  • Chia sẻ kết quả thành công trong ngày chuyển đổi thông qua biểu đồ Grafana.

Ý kiến của GN⁺

  • Cải tiến WireGuard của Fly.io là một ví dụ tốt về việc cải thiện đáng kể hiệu năng và độ ổn định mạng.
  • Cách tiếp cận này có thể đặc biệt hữu ích trong việc tăng cường quản lý lưu lượng mạng và bảo mật cho các dịch vụ dựa trên đám mây.
  • Những dự án khác cung cấp tính năng tương tự có thể kể đến Tailscale hoặc ZeroTier, cũng mang lại các lựa chọn thay thế VPN cho người dùng cá nhân và doanh nghiệp.
  • Khi áp dụng WireGuard, cần cân nhắc cấu hình mạng, chính sách bảo mật và khả năng tương thích.
  • Lợi ích của việc chọn công nghệ này là hiệu năng nhanh và cấu hình đơn giản, nhưng cũng có thể gặp thách thức trong tích hợp với hạ tầng hiện có hoặc ở khía cạnh quản trị.

1 bình luận

 
GN⁺ 2024-03-14
Ý kiến trên Hacker News
  • WireGuard trong nhân Linux được cho là gây ra vấn đề trong thiết kế triển khai vì không có chức năng cài đặt peer theo yêu cầu.

    • WireGuard trong nhân Linux thiếu khả năng cài đặt peer theo yêu cầu, khiến việc thiết kế trở nên khó khăn.
    • Có thể thêm peer trong lúc chạy, nhưng dường như mục tiêu là xác thực peer trước khi thêm vào interface để tránh các mục không cần thiết.
    • Sử dụng bộ lọc eBPF để trực tiếp quản lý kết nối dựa trên định tuyến khóa mã hóa với đối tác đã được xác thực; sau khi xác minh xong thì thêm peer vào interface và gỡ ra sau khi timeout.
  • Tôi đồng ý rằng HTTP request đáng tin cậy hơn so với việc định tuyến qua hàng đợi thông điệp, nhưng tôi ngạc nhiên khi việc mất message trong NATS lại ảnh hưởng lớn đến dịch vụ như vậy.

    • Đồng ý với quan điểm rằng HTTP request trực tiếp đáng tin cậy hơn message queue, nhưng thấy lạ khi việc mất message trong NATS lại gây ảnh hưởng đáng kể đến dịch vụ.
    • Thông thường người ta kỳ vọng NATS sẽ thử gửi lại khi mất message, nên bày tỏ thắc mắc về lý do xuất hiện vấn đề độ tin cậy rõ rệt như vậy.
  • Tôi muốn giới thiệu một dự án thử nghiệm gần đây. Nếu bạn quan tâm đến việc xây dựng ứng dụng Go hoạt động như một WireGuard peer ở user space thì hãy xem thử.

    • Giới thiệu dự án của mình dành cho những ai quan tâm đến việc xây dựng ứng dụng Go hoạt động như một WireGuard peer ở user space.
    • Dựa trên thành quả rất tốt của wireguard-go, nhưng muốn đơn giản hóa để phù hợp hơn cho việc sử dụng như một thư viện.
    • Quan tâm đến việc xây dựng service mesh, và dù hỗ trợ nhiều ngôn ngữ có thể khó, họ nghĩ rằng có thể triển khai socket API.
    • Nhắc rằng hiện vẫn chưa thấy tăng tốc phần cứng cho mã hóa của WireGuard, nên có thể khó cạnh tranh với mTLS.
    • Cho biết mình đang làm freelancer trong lĩnh vực mạng tốc độ cao/bảo mật và ai quan tâm thì có thể liên hệ qua email trong hồ sơ.
  • Thật thú vị khi việc tunnel WireGuard qua WebSockets lại là cấu hình mặc định. Điều này không tốt cho hiệu năng, nhưng có lẽ phù hợp với các tác vụ DevOps nơi dùng flyctl.

    • Chú ý đến việc tunnel WireGuard qua WebSockets là cấu hình mặc định.
    • Dù không tối ưu cho hiệu năng, nhưng dự đoán sẽ không thành vấn đề với các tác vụ DevOps dùng flyctl.
    • Tò mò về tương lai của QUIC/HTTP3, đồng thời đặt câu hỏi liệu các nhà vận hành mạng có xử lý đúng UDP trên cổng 443 thay vì chặn nó hay không.
  • Chúng tôi có thể cài đặt peer với vai trò bên khởi phát, còn flyctl là bên phản hồi. Nhân Linux khởi tạo kết nối WireGuard tới flyctl. Cách này hoạt động, và giao thức thực ra không quá quan tâm ai là server hay client. Kết nối mới được thiết lập nhanh nhất có thể.

    • Giải thích cách cài đặt peer với vai trò bên khởi phát trong khi flyctl là bên phản hồi, và nhân Linux sẽ khởi tạo kết nối WireGuard.
    • Cho biết giao thức không quá bị ràng buộc bởi vai trò server và client, và kết nối mới có thể được thiết lập rất nhanh.
  • Startup của tôi đã dùng Fly gần một năm. Tính năng cốt lõi giúp chuyển từ code sang code đã triển khai trong vòng chưa đầy một phút thật tuyệt vời. Có thể spin up/down node mới chỉ trong vài giây.

    • Chia sẻ kinh nghiệm startup đã dùng Fly gần một năm.
    • Đánh giá tích cực về khả năng triển khai code rất nhanh, nhưng cảm thấy công ty vẫn còn hơi non.
    • Nhắc đến trải nghiệm API server của Fly không thể truy cập trong 48 giờ và vấn đề ngắt kết nối không nhất quán của sản phẩm "db".
    • Chỉ ra rằng việc truy cập API của Fly thường xuyên bị gián đoạn, gây khó khăn cho việc triển khai chỉnh sửa dịch vụ mới.
    • Nói rằng vẫn nhớ trải nghiệm deploy đó, nhưng cảm thấy hài lòng hơn khi dùng Cloud Run của GCP.
  • “Mỗi khi chạy flyctl, CLI đồ sộ nhưng đáng yêu của chúng tôi sẽ tạo ra một TCP/IP stack ngay trong không khí và giao tiếp trực tiếp với Fly Machines bằng một địa chỉ IPv6 riêng.”

    • Bày tỏ sự tò mò về lời giải thích rằng khi chạy flyctl, nó sẽ tạo ra một TCP/IP stack tức thời và giao tiếp trực tiếp với Fly Machines qua một địa chỉ IPv6 riêng.
  • Điều gì ngăn gói handshake ban đầu bị chuyển tiếp lại vào network stack? Nếu làm vậy thì có vẻ sẽ không có mất gói. Ngoài ra, mục đích của việc kiểm tra udp[8] = 1 trong bộ lọc eBPF là gì?

    • Đặt câu hỏi về cơ chế ngăn gói handshake ban đầu bị chuyển tiếp lại vào network stack và lý do kiểm tra một giá trị UDP cụ thể trong bộ lọc eBPF.
  • Làm thế nào để triển khai một ứng dụng đã được docker hóa bất kỳ lên Fly.io? Hãy lấy tiền của tôi.

    • Thể hiện sự quan tâm và sẵn sàng chi trả để biết cách triển khai một ứng dụng đã được docker hóa lên Fly.io.
  • Với tất cả những người khác, tôi xin shamelessly quảng bá Netmaker.

    • Chia sẻ trải nghiệm hài lòng khi dùng Netmaker, nhắc đến nhu cầu cá nhân về quyền truy cập vào AWS VPC, và hy vọng Netmaker sẽ được chấp nhận rộng rãi hơn.