Điểm nghẽn chuyển tiếp gói tin trong gateway VPN mã hóa

Trên các cổng định tuyến VPN tập trung (concentrator), thiết bị NAT cấp nhà mạng hay các node chuyển tiếp đa luồng, quản trị viên hệ thống thường đối mặt với trần hiệu năng phần cứng nghiêm trọng. Ngay cả khi máy chủ được trang bị vi xử lý hàng chục nhân cùng card mạng PCIe thế hệ mới, số lượng gói tin xử lý mỗi giây (Packets Per Second - PPS) thường bị giới hạn bởi năng lực xử lý ngắt phần mềm trên từng CPU core trước khi chạm ngưỡng băng thông vật lý.

Trong kiến trúc mạng Linux truyền thống, mọi gói tin chuyển tiếp (forwarding) đều phải đi qua chuỗi hook phức tạp của hệ thống tường lửa Netfilter:

[ Cáp mạng vật lý ] 
        |
        v
[ Vòng đệm RX Driver / NAPI Poll ]
        |
        v
[ PREROUTING (conntrack, mangle, raw, dnat) ]
        |
        v
[ Quyết định định tuyến (fib_lookup) ]
        |
        v
[ FORWARD (filter, giới hạn tốc độ) ]
        |
        v
[ POSTROUTING (snat, masquerade, mangle) ]
        |
        v
[ Phân giải láng giềng (ARP/NDP) / Egress Qdisc ]
        |
        v
[ Vòng đệm TX Driver ] ---> [ Cáp mạng vật lý ]

Mỗi mắt xích xử lý đều tiêu tốn tài nguyên cho các bộ đếm nguyên tử (atomic counters), khóa xoay trên bảng băm theo dõi kết nối (nf_conntrack_lock), cấp phát cấu trúc bộ đệm gói tin (sk_buff), và liên tục truy vấn bảng định tuyến (FIB). Khi gateway xử lý hàng ngàn luồng hầm bảo mật đồng thời (như WireGuard, RiceGuard hay IPsec), chi phí này nhân lên theo cấp số nhân:

  1. Tra cứu lặp lại cho luồng đã xác lập: Các gói tin thuộc về phiên TCP hoặc UDP đã duy trì lâu dài vẫn phải trải qua kiểm tra toàn bộ tập luật tường lửa và máy trạng thái conntrack.
  2. Tranh chấp bộ nhớ đệm đa nhân: Bảng băm theo dõi kết nối được chia sẻ giữa các CPU core. Lưu lượng PPS cao làm phát sinh hiện tượng xung đột dòng nhớ đệm (cache line bouncing) trên bộ nhớ đệm L3.
  3. Độ trễ đóng gói kép: Việc chuyển tiếp lưu lượng sau khi giải mã hoặc điều hướng gói tin UDP đóng gói ngoài đòi hỏi gói tin phải đi qua chuỗi hook Netfilter thêm một lần nữa.

Để tháo gỡ điểm nghẽn này mà không làm suy giảm tính an toàn của cơ chế kiểm tra gói tin theo trạng thái (Stateful Packet Inspection), cộng đồng nhân Linux đã phát triển hệ tầng Netfilter Flowtable (được tích hợp chính thức từ phiên bản Linux 4.16 bởi Pablo Neira Ayuso).

Kiến trúc Ingress Fastpath của Netfilter Flowtable

Netfilter Flowtable là cơ chế ghi nhớ đường đi tắt (shortcut cache) ngay trong nhân Linux dành cho các luồng dữ liệu hai chiều đã xác lập. Thay vì buộc từng gói tin phải chạy qua toàn bộ chuỗi mắt xích Netfilter, Flowtable ghi nhận các luồng sau khi hoàn tất giai đoạn bắt tay khởi tạo (ct state established) và thiết lập một lối đi tắt trực tiếp tại điểm đón gói (ingress hook) của card mạng.

                       [ Gói tin đến từ card mạng ]
                                    |
                                    v
                     +-----------------------------+
                     |    Flowtable Ingress Hook   |
                     +-----------------------------+
                                   / \
                   Khớp luồng?    /   \   Chưa có luồng?
                                 /     \
                               CÓ       KHÔNG
                               /         \
                              v           v
       +-------------------------+     +-------------------------------+
       | Đường tắt Fastpath:     |     | Chuỗi Netfilter truyền thống: |
       | - Cập nhật trạng thái   |     | - PREROUTING                  |
       | - Thay thế NAT / Mangle |     | - Đánh giá conntrack          |
       | - Giảm TTL / sửa MAC    |     | - Tra cứu fib_lookup          |
       | - Gửi thẳng đến TX Dev  |     | - FORWARD & POSTROUTING       |
       +-------------------------+     +-------------------------------+
                    |                                  |
                    |                         Kết nối đã xác lập?
                    |                                  |
                    |                                  v
                    |                      [ Thêm vào Flowtable ]
                    \                                  /
                     \                                /
                      v                              v
                    +----------------------------------+
                    |    dev_queue_xmit (Egress NIC)   |
                    +----------------------------------+

Cơ chế vận hành nội tại trong nhân Linux

Phần lõi của Flowtable được triển khai tại tệp net/netfilter/nf_flow_table_core.c. Khi gói tin đi vào giao diện mạng đã cấu hình Flowtable:

  1. Đón gói tại tầng Ingress: Hàm nf_flow_offload_ip_hook() tiếp nhận gói tin ngay tại giai đoạn NF_INET_INGRESS, trước cả ip_rcv() và chuỗi PREROUTING.
  2. Tra cứu bộ 5 giá trị (5-tuple): Một bảng băm được bảo vệ bởi cơ chế Read-Copy-Update (RCU) không khóa thực hiện đối chiếu bộ 5 thông tin: IP nguồn, IP đích, cổng nguồn, cổng đích và giao thức tầng 4.
  3. Thực thi chuyển tiếp tốc độ cao:
    • Giảm TTL: Giảm giá trị Time-To-Live và tính toán lại checksum của header IP.
    • Biến đổi NAT trực tiếp: Nếu luồng có áp dụng SNAT hoặc DNAT, Flowtable chỉnh sửa địa chỉ và cổng ngay trên tiêu đề gói tin.
    • Ghi đè địa chỉ lớp 2: Địa chỉ MAC đích (đã được lưu sẵn từ bước phân giải trước) được ghi thẳng vào Ethernet header mà không cần truy vấn bảng ARP.
    • Đưa thẳng sang giao diện đích: Gói tin bỏ qua mã định tuyến tầng mạng (ip_forward) và được đẩy thẳng tới hàng đợi truyền tải của card mạng phát qua dev_queue_xmit().

Khi luồng xuất hiện cờ kết thúc TCP FIN/RST hoặc hết hạn nhàn rỗi (idle timeout), mục ghi sẽ bị xóa khỏi Flowtable. Các gói tin kế tiếp sẽ tự động chuyển về đường xử lý chuẩn của Netfilter, bảo toàn tính toàn vẹn của kết nối.

So sánh Fastpath phần mềm và Tăng tốc phần cứng SmartNIC

Hệ thống Flowtable hỗ trợ hai cấp độ tăng tốc tùy thuộc vào phần cứng máy chủ:

Tiêu chí Chuyển tiếp Linux chuẩn Fastpath phần mềm Flowtable Tăng tốc phần cứng SmartNIC
Vị trí xử lý Đa hook (Pre/Fwd/Post) NF_INET_INGRESS (Nhân Linux) ASIC / TCAM trên card mạng
Xử lý conntrack Mọi gói tin Chỉ gói bắt tay đầu phiên Chỉ gói bắt tay đầu phiên
Mức chiếm dụng CPU Cao (Tất cả nhân CPU bận rộn) Thấp (Bỏ qua ngăn xếp IP) 0% CPU cho các luồng hoạt động
Độ trễ chuyển tiếp 15 – 35 µs 4 – 8 µs < 1.5 µs
Khả năng mở rộng PPS 1.5 – 3.2 Mpps / nhân 6.5 – 12.0 Mpps / nhân Tốc độ dây (100Gbps+ mỗi cổng)
Yêu cầu phần cứng Mọi card mạng chuẩn Mọi card mạng chuẩn Card hỗ trợ TC offload (Mellanox, Intel E810)

Tăng tốc phần cứng (Hardware Offload)

Khi vận hành trên các máy chủ trang bị card mạng thông minh (SmartNIC) hỗ trợ TC flower offload hoặc Netfilter flow offload (như NVIDIA Mellanox ConnectX-5, ConnectX-6 Dx, hoặc Intel E810), nhân Linux có thể nạp toàn bộ bảng Flowtable vào bộ nhớ TCAM của card mạng.

Bằng cách kích hoạt chỉ thị flags { offload; } trong cấu hình nftables, kernel sẽ chuyển đổi các quy tắc luồng và biến đổi NAT thành lệnh phần cứng qua giao tiếp switchdev. Khi đó, các gói tin dữ liệu trong luồng sẽ được định tuyến, sửa đổi địa chỉ và phát ra cáp quang hoàn toàn trong silicon của card mạng mà không làm tiêu tốn một chu kỳ CPU máy chủ nào.

Ứng dụng Flowtable trong hạ tầng VPN hiện đại

Trong kiến trúc gateway VPN mật độ cao, lưu lượng mạng phân chia thành hai ranh giới xử lý:

  1. Lưu lượng UDP đóng gói bên ngoài: Gói tin đến từ Internet công cộng chuyển vào tiến trình giải mã VPN (wg0, riceguard0, tun0).
  2. Lưu lượng định tuyến bên trong sau giải mã: Các gói tin dữ liệu sau khi giải mã được phân phối tới mạng nội bộ, máy chủ dịch vụ hoặc đường truyền ra Internet qua NAT.

Áp dụng Flowtable cho hạ tầng định tuyến mang lại nhiều giá trị thiết thực:

1. Giảm thiểu tắc nghẽn CPU cho RiceGuard

Trong các gateway triển khai RiceGuard phục vụ hàng chục ngàn kết nối đồng thời, việc giảm tải đến 60% chỉ lệnh CPU cho việc theo dõi kết nối giúp tài nguyên vi xử lý tập trung tối đa cho các tác vụ mật mã ChaCha20-Poly1305. Nhờ đó, thông lượng tổng thể của hệ thống tăng vọt và loại bỏ tình trạng rớt gói khi lưu lượng biến động đột ngột.

2. Triệt tiêu hiện tượng rung pha (Jitter) cho cuộc gọi và game

Các luồng âm thanh thoại VoIP (SIP/RTP) và truyền tải dữ liệu game tương tác sử dụng các bộ cổng UDP cố định. Với Flowtable, 99.8% gói tin của các luồng này được chuyển tiếp qua đường tắt. Thời gian di chuyển của gói tin qua nhân máy chủ giảm từ 25 microgiây xuống dưới 5 microgiây, ngăn chặn hiện tượng xáo trộn thứ tự gói tin giữa các CPU core.

3. Phối hợp nhịp nhàng với kiểm soát chất lượng dịch vụ (QoS)

Khi gói tin rời khỏi đường tắt qua dev_queue_xmit(), nó vẫn đi vào hàng đợi qdisc của card mạng đích. Quản trị viên có thể kết hợp Flowtable với FQ-CoDel hoặc CAKE để loại bỏ hoàn toàn bufferbloat mà vẫn giữ được tốc độ chuyển tiếp tối đa của phần cứng.

Hướng dẫn thiết lập nftables Flowtable thực tế

Dưới đây là kịch bản cấu hình nftables hoàn chỉnh để triển khai Flowtable chuyển tiếp lưu lượng giữa giao diện mạng ngoài (eth0) và giao diện nội bộ hoặc cổng hầm VPN (eth1 / wg0):

#!/usr/sbin/nft -f

# Xóa bỏ các tập luật cũ
flush ruleset

table inet vpn_router {
    # 1. Định nghĩa Flowtable gắn với các cổng mạng
    flowtable ft_fastpath {
        hook ingress priority filter
        devices = { eth0, eth1 }
        # Nếu card mạng hỗ trợ tăng tốc phần cứng SmartNIC, mở ghi chú dòng sau:
        # flags { offload; }
    }

    # 2. Chuỗi lọc gói chuyển tiếp (Forward chain)
    chain forward {
        type filter hook forward priority filter; policy drop;

        # Đẩy các kết nối TCP và UDP đã xác lập vào đường tắt fastpath
        meta l4proto { tcp, udp } flow add @ft_fastpath

        # Chấp nhận các gói tin established và related trên đường chuẩn
        ct state established,related accept

        # Loại bỏ các gói tin lỗi trạng thái
        ct state invalid drop

        # Cho phép luồng kết nối mới từ mạng nội bộ ra Internet
        iifname "eth1" oifname "eth0" accept
    }

    # 3. Biến đổi địa chỉ nguồn (SNAT / Masquerade)
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;

        # Thực hiện Masquerade trên cổng WAN ngoài
        oifname "eth0" masquerade
    }
}

Kiểm tra và giám sát hoạt động của Flowtable

Sau khi áp dụng cấu hình, người vận hành có thể theo dõi trực tiếp các luồng đang chạy trên đường tắt:

# Liệt kê các luồng đang hoạt động trong Flowtable và số lượng gói/byte
nft list flowtable inet vpn_router ft_fastpath

# Theo dõi số liệu gỡ lỗi phần cứng qua sysfs (nếu bật hardware offload)
cat /sys/kernel/debug/netfilter/nf_flowtable/*

# Đối chiếu số liệu thống kê giữa đường chuẩn và đường tắt
cat /proc/net/stat/nf_conntrack

Trong kết quả hiển thị của nft list flowtable, các luồng đang được xử lý sẽ hiển thị chi tiết số byte, số gói tin và thời gian nhàn rỗi còn lại. Khi bật tính năng tăng tốc phần cứng, các luồng có ký hiệu [OFFLOAD] biểu thị phần cứng card mạng đang trực tiếp đảm nhiệm việc chuyển tiếp.

Lưu ý kỹ thuật khi triển khai thực tế

  1. Phân mảnh gói tin (Fragmentation): Flowtable không thực hiện ghép nối các mảnh gói tin IP phân mảnh. Những mảnh gói tin không chứa tiêu đề tầng 4 đầy đủ sẽ tự động trượt khỏi Flowtable và đi vào chuỗi conntrack thông thường. Hãy đảm bảo tính năng TCP MSS clamping hoặc Path MTU Discovery được kích hoạt chuẩn xác trên các cổng kết nối hầm.
  2. Trao đổi khóa định kỳ (Re-keying): Các giao thức như WireGuard tự động tạo lại khóa mật mã sau mỗi vài phút. Các gói tin bắt tay này sử dụng cấu trúc điều khiển riêng và sẽ chuyển qua đường thông thường mà không làm ảnh hưởng đến các luồng dữ liệu đang chạy trên fastpath.
  3. Tương thích giao diện ảo: Flowtable có thể liên kết trực tiếp với các giao diện mạng ảo (VLAN sub-interfaces như eth0.100 hay Bonding bond0), mang lại độ linh hoạt cao trong môi trường máy chủ ảo hóa và trung tâm dữ liệu.

Việc chuyển đổi cơ chế theo dõi luồng từ xử lý trên từng gói tin sang xử lý một lần khi khởi tạo kết nối giúp các gateway VPN chạy Linux đạt hiệu năng tối ưu, duy trì độ trễ thấp và bảo đảm tính ổn định lâu dài.