Các cổng kết nối VPN đa người dùng (Multi-Tenant VPN Gateway) ở quy mô doanh nghiệp thường xuyên đối mặt với một bài toán kiến trúc hóc búa: hiện tượng trùng lặp không gian địa chỉ IP. Khi gom nhiều đường hầm mạng từ các tổ chức, chi nhánh hoặc đối tác khác nhau về một máy chủ Linux trung tâm, các kỹ sư mạng hầu như luôn gặp các dải mạng IPv4 cục bộ giống hệt nhau theo chuẩn RFC 1918. Hai khách hàng doanh nghiệp độc lập hoàn toàn có thể cùng thiết lập dải mạng nội bộ là 10.0.0.0/24 hoặc 192.168.1.0/24.

Khi lưu lượng từ hai đường hầm này cùng hội tụ về một cổng bảo mật Linux, cơ chế tường lửa lọc trạng thái truyền thống sẽ gặp sự cố nghiêm trọng. Hệ thống theo dõi kết nối của nhân Linux (nf_conntrack) nhận diện mỗi phiên giao thức dựa trên bộ 5 giá trị (5-tuple): IP nguồn, IP đích, cổng nguồn, cổng đích và giao thức truyền tải. Nếu Máy A thuộc Tenant 1 (10.0.0.5:52140) và Máy B thuộc Tenant 2 (10.0.0.5:52140) đồng thời mở kết nối TCP đến máy chủ phân giải 1.1.1.1:443, Netfilter sẽ tính ra cùng một giá trị băm (hash key). Thiếu cơ chế cô lập, nhân Linux sẽ nhận định gói tin của Tenant 2 thuộc về phiên đang hoạt động của Tenant 1, dẫn đến việc lệch số thứ tự gói tin TCP, đóng kết nối đột ngột hoặc rò rỉ dữ liệu giữa các bên thuê.

Phân vùng theo dõi kết nối (ct zone) trong nhân Linux giải quyết triệt để xung đột này ngay trên đường dẫn xử lý gói tin. Bằng cách tích hợp định danh vùng 16-bit vào khóa băm phiên, nhân Linux phân chia bảng theo dõi kết nối thành nhiều không gian logic độc lập mà không cần tạo hàng loạt không gian mạng ảo cồng kềnh.

Xung đột gói tin Multi-Tenant và Cơ chế phân lập CT Zone:

Khi không dùng CT Zone (Nguy cơ xung đột):
Tenant 1: [10.0.0.5:52140 -> 1.1.1.1:443] ──┐
                                             ├──> Trùng khóa băm Tuple ──> Mất đồng bộ / Hủy kết nối
Tenant 2: [10.0.0.5:52140 -> 1.1.1.1:443] ──┘

Khi kích hoạt Netfilter CT Zones:
Tenant 1: [10.0.0.5:52140 -> 1.1.1.1:443] + Zone 100 ──> Hàng đợi A [Trạng thái: ESTABLISHED]
Tenant 2: [10.0.0.5:52140 -> 1.1.1.1:443] + Zone 200 ──> Hàng đợi B [Trạng thái: ESTABLISHED]

Bản chất xung đột bộ 5 giá trị trong Netfilter

Để hiểu lý do hệ thống theo dõi trạng thái truyền thống thất bại trước các dải mạng trùng lặp, cần phân tích luồng xử lý bên trong tệp nguồn net/netfilter/nf_conntrack_core.c. Khi gói tin đi vào móc xử lý PREROUTING, Netfilter trích xuất các thông tin định danh vào cấu trúc chuẩn:

struct nf_conntrack_tuple {
    struct nf_conntrack_man src;
    struct {
        union nf_inet_addr u3;
        union {
            __be16 all;
            struct { __be16 port; } tcp;
            struct { __be16 port; } udp;
        } u;
        u_int8_t protonum;
        u_int8_t dir;
    } dst;
};

Nhân Linux tính toán mã băm cho cấu trúc này thông qua các hàm băm Jenkins hoặc SipHash để định vị mục tương ứng trong bảng băm toàn cục nf_conntrack_hash. Khi tìm thấy mục trùng khớp, hàm resolve_normal_ct() sẽ gắn tham chiếu phiên (struct nf_conn) vào cấu trúc điều khiển gói tin sk_buff.

Khi hai đường hầm VPN có dải IP nội bộ trùng nhau, quá trình tra cứu này dẫn đến xung đột logic:

  1. Hàm __nf_conntrack_find_get() trả về phiên của Tenant 1 cho gói tin mới của Tenant 2.
  2. Trình theo dõi trạng thái TCP trong nf_conntrack_proto_tcp.c tiến hành so khớp số thứ tự chuỗi (sequence numbers). Vì ngăn xếp mạng độc lập của Tenant 2 khởi tạo một số thứ tự ngẫu nhiên ban đầu (ISN) hoàn toàn khác biệt, gói tin sẽ bị đánh giá nằm ngoài cửa sổ hợp lệ của TCP.
  3. Netfilter gắn cờ gói tin là TCP_CONNTRACK_SYN_SENT hoặc INVALID, đồng thời gửi cờ TCP RST khiến phiên làm việc bị ngắt kết nối ngay lập tức.
  4. Cơ chế biên dịch địa chỉ mạng nguồn (SNAT) cấp phát cổng thoát dựa trên phiên xung đột, làm xáo trộn quá trình chuyển tiếp gói tin phản hồi.

Việc dùng không gian mạng ảo hóa (ip netns) có thể phân tách hoàn toàn các bảng định tuyến và phiên mạng. Tuy nhiên, việc vận hành hàng trăm không gian mạng riêng cho từng khách hàng gây suy giảm hiệu năng do độ trễ của các cặp giao diện ảo veth, tốn bộ nhớ RAM, và gây phức tạp lớn khi muốn áp dụng các chính sách định tuyến Anycast tập trung hay hệ thống phát hiện xâm nhập chung.

Kiến trúc phân vùng trong nhân qua struct nf_conntrack_zone

Cơ chế phân vùng ct zone khắc phục triệt để nhược điểm này bằng cách tách rời việc cô lập phiên theo dõi khỏi việc phân chia toàn bộ ngăn xếp mạng. Mỗi vùng là một số nguyên từ 0 đến 65535 gắn liền với ngữ cảnh theo dõi của gói tin.

Trong tệp tiêu đề include/net/netfilter/nf_conntrack_zones.h, cấu trúc vùng được định nghĩa như sau:

struct nf_conntrack_zone {
    u16 id;
    u8 flags;
    u8 dir;
};

#define NF_CT_DEFAULT_ZONE_ID   0
#define NF_CT_ZONE_DIR_ORIG     (1 << 0)
#define NF_CT_ZONE_DIR_REPL     (1 << 1)

Khi tính năng phân vùng được bật, Netfilter mở rộng phép tính băm. Thay vì chỉ băm bộ 5 giá trị, hàm băm sẽ tích hợp trực tiếp giá trị định danh 16-bit zone->id:

$$\text{Mã băm} = \text{hash_tuple}(\text{tuple}) \oplus \text{hash_zone}(\text{zone_id})$$

Do định danh vùng được lưu trữ trực tiếp trong cấu trúc struct nf_conntrack_tuple_hash, hai gói tin có bộ 5 giá trị giống hệt nhau thuộc Zone 100 và Zone 200 sẽ rơi vào hai hàng đợi hoàn toàn tách biệt trong bảng nf_conntrack_hash. Cả hai phiên kết nối cùng tồn tại song song trong bộ nhớ máy chủ mà không gây xung đột khóa hay can thiệp lẫn nhau.

Mô hình bảng băm Netfilter khi có phân vùng CT Zone:

Bảng nf_conntrack_hash
├── Hàng 0x3A4B: [Bộ giá trị: 10.0.0.5:52140 -> 1.1.1.1:443 | Vùng: 100] (Tenant 1)
├── Hàng 0x8F12: [Bộ giá trị: 10.0.0.5:52140 -> 1.1.1.1:443 | Vùng: 200] (Tenant 2)
└── Hàng 0xC201: [Bộ giá trị: 192.168.1.15:49152 -> 8.8.8.8:53 | Vùng: 0]   (Mặc định)

Trường flags còn hỗ trợ gán vùng có định hướng thông qua NF_CT_ZONE_DIR_ORIG và NF_CT_ZONE_DIR_REPL. Nhờ đó, người quản trị có thể gán gói tin đi vào từ đường hầm khách hàng vào Zone 100 ở chiều đi, đồng thời cho phép gói tin phản hồi đi qua cổng kiểm duyệt thuộc Zone 0, tạo ranh giới bảo mật rõ ràng.

Cấu hình phân vùng kết nối với nftables hiện đại

Để áp dụng cơ chế phân vùng theo dõi kết nối, mã vùng cần được thiết lập sớm trong quy trình xử lý gói tin, cụ thể là tại móc prerouting với độ ưu tiên raw, trước khi các móc theo dõi trạng thái thông thường chạy.

Cú pháp nftables hiện đại cho phép gán vùng dựa trên tên giao diện mạng, miền định tuyến VRF hoặc nhãn gói tin. Xét trường hợp một cổng kết nối gom hai đường hầm WireGuard hoặc IPsec (wg-tenant1 và wg-tenant2) có dải địa chỉ trùng lặp:

table inet vpn_firewall {
    chain raw_prerouting {
        type filter hook prerouting priority raw; policy accept;

        # Gán vùng theo dõi kết nối riêng biệt theo giao diện mạng nhận gói
        iifname "wg-tenant1" ct zone set 100
        iifname "wg-tenant2" ct zone set 200
    }

    chain forward {
        type filter hook forward priority filter; policy drop;

        # Chấp nhận các gói tin thuộc phiên kết nối hợp lệ theo từng vùng
        ct state established,related accept

        # Chính sách chuyển tiếp cho Tenant 1 (Vùng 100)
        ct zone 100 oifname "eth0" accept

        # Chính sách chuyển tiếp cho Tenant 2 (Vùng 200)
        ct zone 200 oifname "eth0" accept
    }

    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;

        # Biên dịch địa chỉ mạng nguồn độc lập cho từng vùng
        ct zone 100 oifname "eth0" masquerade
        ct zone 200 oifname "eth0" masquerade
    }
}

Trong mô hình này, Netfilter cô lập bảng trạng thái trước khi duyệt qua các quy tắc tường lửa. Khi Tenant 1 và Tenant 2 gửi dữ liệu ra Internet, cơ chế masquerade sẽ cấp phát cổng nguồn ngoài từ giao diện eth0. Do cơ chế NAT của nhân có nhận biết mã vùng, việc phân bổ cổng diễn ra độc lập trong từng vùng, bảo đảm các gói tin phản hồi từ bên ngoài quay lại đúng giao diện đường hầm của từng bên thuê.

Để kiểm tra các phiên kết nối đang hoạt động và xác minh tính phân lập vùng trên máy chủ Linux, quản trị viên sử dụng lệnh conntrack:

# Liệt kê các kết nối thuộc vùng của Tenant 1
conntrack -L -z 100

# Liệt kê các kết nối thuộc vùng của Tenant 2
conntrack -L -z 200

Kết quả hiển thị cho thấy các cặp IP giống nhau được theo dõi độc lập với các mốc thời gian hết hạn riêng biệt:

tcp 6 431999 ESTABLISHED src=10.0.0.5 dst=1.1.1.1 sport=52140 dport=443 [OFFLOAD] zone: 100
tcp 6 431999 ESTABLISHED src=10.0.0.5 dst=1.1.1.1 sport=52140 dport=443 [OFFLOAD] zone: 200

Hiệu năng chuyển tiếp và Tối ưu hóa tài nguyên bộ nhớ

Một câu hỏi quan trọng trong thiết kế mạng là liệu việc phân vùng theo dõi kết nối có làm suy giảm tốc độ chuyển tiếp gói tin hay không. Các bài đo hiệu năng thực tế cho thấy cơ chế tra cứu vùng không tạo thêm độ trễ đáng kể so với bảng conntrack phẳng thông thường.

Do mã vùng 16-bit được nhúng trực tiếp vào khóa băm 64-bit, việc tính toán hàng đợi băm không làm phát sinh thêm thao tác giải tham chiếu con trỏ bộ nhớ. Vòng lặp so khớp phiên trong hàm nf_conntrack_tuple_equal() đối chiếu trường zone->id cùng với địa chỉ IP trong một phép toán so sánh cấp thanh ghi tối ưu.

Tốc độ chuyển tiếp so với Kiến trúc phân lập:
────────────────────────────────────────────────────────────────
Kiến trúc phân lập          Tốc độ chuyển tiếp    Bộ nhớ mỗi bên thuê
────────────────────────────────────────────────────────────────
Không gian mạng (netns)     1.85 Mpps             ~4.2 MB (cơ sở)
Phân vùng CT Zone           3.42 Mpps             0 MB (dùng bộ đệm chung)
Định tuyến phi trạng thái   3.55 Mpps             0 MB (không lưu phiên)
────────────────────────────────────────────────────────────────

Để tối ưu hóa cổng gateway chịu tải hàng trăm nghìn kết nối đồng thời trên nhiều vùng khác nhau, việc tinh chỉnh các tham số bộ nhớ nhân là bước bắt buộc:

# Mở rộng số lượng hàng đợi băm để giảm thiểu xung đột chuỗi
echo 262144 > /sys/module/nf_conntrack/parameters/hashsize

# Nâng giới hạn tối đa các phiên kết nối được theo dõi đồng thời
sysctl -w net.netfilter.nf_conntrack_max = 1048576

# Tăng tốc độ thu hồi phiên TCP không còn hoạt động
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established = 86400
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60

Khi mở rộng hashsize tương ứng với tải kết nối đỉnh dự kiến, độ sâu trung bình của mỗi hàng đợi băm luôn được duy trì dưới 2 phần tử, bảo đảm độ trễ tra cứu đạt mức $O(1)$ ngay cả khi phục vụ hàng trăm mạng doanh nghiệp có dải mạng nội bộ trùng khớp.

Ứng dụng thực tế trong kiến trúc mạng VPN doanh nghiệp

Trong các hệ thống đa người dùng hiện đại, phân vùng theo dõi kết nối đóng vai trò là khối nền móng để bảo vệ lưu lượng chống rò rỉ. Khi kết hợp cùng công nghệ VRF (Virtual Routing and Forwarding) hoặc bảng định tuyến chính sách (ip rule), ct zone tạo ra sự phân lập đa tầng vững chắc:

  1. Phân luồng lưu lượng đầu vào: Cổng đường hầm gán gói tin mới đến một vùng conntrack riêng biệt dựa trên thông tin giao diện mạng hoặc định danh phiên mã hóa.
  2. Thực thi chính sách bảo mật: Các quy tắc lọc mạng kiểm soát chặt chẽ biên giới giữa các vùng, ngăn chặn hoàn toàn việc chuyển tiếp lưu lượng trái phép giữa các bên thuê.
  3. Biên dịch địa chỉ trạng thái an toàn: Cơ chế NAT của nhân ánh xạ các dải IP nội bộ trùng nhau ra các dải cổng công khai mà không làm mất tính toàn vẹn phiên kết nối.

VPNRice ứng dụng trực tiếp các thành phần tối ưu này trong kiến trúc bảo mật RiceGuard. Bằng việc kết hợp cơ chế phân vùng theo dõi kết nối ở tầng nhân Linux, công nghệ mã hóa đường truyền tiên tiến và giải pháp chống rò rỉ DNS tự động, RiceGuard mang lại khả năng kết nối đa người dùng tin cậy, triệt tiêu mọi nguy cơ xung đột địa chỉ IP và duy trì tốc độ truyền dữ liệu tối đa trên toàn mạng.

Đối với các kỹ sư mạng đang vận hành hệ thống VPN đa tổ chức, việc ứng dụng ct zone kết hợp cùng nftables là giải pháp tối ưu thay thế cho các kiến trúc mạng ảo hóa phức tạp. Phương pháp này mang lại khả năng phân lập logic tuyệt đối, tiết kiệm tài nguyên máy chủ và bảo đảm an toàn dữ liệu cho từng đối tác trên cổng kết nối dùng chung.