Giải Pháp Tunnel VPN Đa Đường (N:m)
Hai ngày trước, sau khi thành công trong việc thiết lập kết nối đa đường MPTCP để truy cập GitHub mượt mà, tôi bắt đầu suy nghĩ về cách tích hợp giải pháp này vào hệ thống một cách liền mạch. Nếu không sử dụng VPN, việc điều hướng lưu lượng qua các tunnel sẽ gặp nhiều hạn chế. Mặc dù có thể thay đổi bản ghi DNS nội bộ để định tuyến các tên miền GitHub, nhưng cách này không mang lại trải nghiệm tối ưu.
Chúng tôi đã thử nghiệm PeerVPN để tạo tunnel VPN, hệ thống hoạt động ổn định nhưng lại không tận dụng được lợi thế của MPTCP. Vấn đề nằm ở chỗ PeerVPN sử dụng giao thức UDP để truyền thông, khiến toàn bộ lưu lượng chỉ đi theo một đường duy nhất. Việc chạy MPTCP trên một tunnel UDP đơn tuyến hoàn toàn phản tác dụng.
Điều này khiến chúng tôi cân nhắc đến các giải pháp VPN dựa trên TCP như OpenVPN. Tuy nhiên, trong lúc cấu hình OpenVPN, một ý tưởng đột phá nảy ra: Tại sao không cải tiến PeerVPN - một dự án mã nguồn mở - để hỗ trợ thiết lập nhiều đường truyền song song giữa nhiều địa chỉ IP?
Quá trình nghiên cứu mã nguồn cho thấy việc xây dựng một giải pháp VPN trên Linux thực chất rất đơn giản nhờ cơ chế thiết bị tun/tap đã được tích hợp sẵn. Hệ điều hành sẽ tự động chuyển toàn bộ lưu lượng tầng IP (hoặc Ethernet) đến thiết bị ảo này, nhiệm vụ của chúng ta chỉ là xử lý việc chuyển tiếp dữ liệu qua internet.
Tìm kiếm trên Google về các giải pháp VPN đa đường, tôi phát hiện nhiều dự án tương tự như Multipath-VPN - một giải pháp chỉ với vài trăm dòng mã Perl. Dù PeerVPN không quá phức tạp, nhưng phần lớn tính năng của nó không cần thiết cho nhu cầu của chúng tôi. Điều này khiến việc tự phát triển một giải pháp trở nên hợp lý hơn, ước tính cũng chỉ cần vài trăm dòng mã.
Khi xử lý lưu lượng ở tầng IP, UDP là lựa chọn tối ưu nhờ đặc tính cho phép mất gói và sắp xếp lại thứ tự. Điều này giúp tối đa hóa hiệu suất của tunnel. Nếu cả hai đầu tunnel đều có nhiều cổng ra mạng khác nhau, số lượng đường truyền song song có thể lên đến N*M (với N cổng ra ở đầu này và M cổng ra ở đầu kia). Việc quản lý kết nối trong trường hợp này sẽ phức tạp hơn nhiều, đặc biệt khi các cổng ra mạng không ổn định - điều rất phổ biến trong môi trường văn phòng khi ISP thường xuyên thay đổi địa chỉ IP.
Sau hai giờ nghiên cứu tài liệu phát triển thiết bị tun, tôi đã bắt tay vào viết code suốt cả đêm và cho ra đời mptun - giải pháp tunnel đa đường đầu tiên của riêng mình.
Thuật toán cân bằng tải động được thiết kế dựa trên nguyên tắc đơn giản: Ban đầu, tất cả các cổng ra IP đều được gán trọng số bằng nhau. Khi có lưu lượng cần gửi đi, hệ thống sẽ chọn ngẫu nhiên một cặp địa chỉ nguồn-đích dựa trên trọng số. Các gói IP đọc từ thiết bị tun sẽ được đóng gói UDP và chuyển tiếp. Mỗi lần gửi thành công từ một cổng ra sẽ làm tăng trọng số của cổng đó, tương tự như vậy với các gói nhận được từ một cổng vào.
Cơ chế này đảm bảo rằng: Cổng nào nhận/gửi nhiều sẽ có xác suất được chọn cao hơn. Ban đầu tôi dự định tích hợp thêm việc theo dõi tỷ lệ mất gói để điều chỉnh trọng số, nhưng kết quả thử nghiệm cho thấy cơ chế hiện tại đã đủ hiệu quả.
Trong thử nghiệm thực tế, văn phòng chúng tôi có 4 cổng ra mạng khác nhau, trong khi VPS đích chỉ có 1 cổng. Khi tải một file ZIP 40MB bằng wget:
- Phương pháp truyền thống (TCP đơn tuyến): Chỉ sử dụng 1 cổng ra
- MPTCP (4 kết nối TCP): Tăng tốc độ 2.6 lần
- mptun (tunnel UDP đa đường): Tăng tốc độ gần 4 lần, khai thác tối đa băng thông của cả 4 cổng ra
Tuy nhiên, với các file nhỏ hoặc khi đo độ trễ mạng, tỷ lệ mất gói có thể tăng nhẹ và độ phản hồi giảm. Điều này dễ hiểu vì các gói tin đi qua nhiều đường truyền khác nhau, trong khi các ứng dụng dựa trên yêu cầu-phản hồi thường bị ảnh hưởng bởi đường truyền chậm nhất.
Trong tương lai, tôi dự định mở rộng giải pháp cho trường hợp cả hai đầu đều có nhiều cổng ra. Ví dụ: Thuê VPS tại Nhật Bản và Mỹ, sau đó cấu hình DNAT trên VPS Nhật Bản để ánh xạ cổng UDP sang VPS Mỹ. Từ góc nhìn của văn phòng, thiết bị đích sẽ có hai địa chỉ IP thuộc hai mạng hoàn toàn khác nhau. Khi đó, các gói tin gửi đi sẽ được định tuyến đến các “điểm đến” khác biệt trên internet, giúp tối đa hóa khả năng vượt tường lửa.
Hiện tại đây vẫn chỉ là ý tưởng đang chờ được kiểm chứng thực tế.