Khi bảng định tuyến mặc định trở thành rào cản
Bạn đã bao giờ rơi vào cảnh dở khóc dở cười khi hai khách hàng khác nhau yêu cầu kết nối VPN, nhưng cả hai đều dùng dải IP 192.168.1.0/24 chưa? Thông thường, Linux kernel chỉ duy trì một bảng định tuyến chính (Main Routing Table). Mọi interface từ eth0 đến các tunnel đều nhìn vào đây để đẩy gói tin đi. Khi có sự trùng lặp IP, server sẽ hoàn toàn mất phương hướng vì không biết phải trả gói tin về cho ai.
Trước đây, mình thường dùng Policy Based Routing (PBR) kết hợp với ip rule. Tuy nhiên, khi hệ thống lên đến 50 hay 100 khách hàng, việc quản lý hàng trăm dòng rule trở thành một cơn ác mộng thực sự. Debug lỗi định tuyến lúc này cực kỳ tốn thời gian.
VRF (Virtual Routing and Forwarding) xuất hiện để giải quyết triệt để vấn đề này. Nó tạo ra các thực thể định tuyến ảo độc lập. Hãy tưởng tượng VRF giống như cách chúng ta chia VLAN ở Layer 2, nhưng áp dụng cho bảng định tuyến ở Layer 3.
So sánh thực tế: PBR và VRF
Để chọn đúng công cụ, chúng ta cần nhìn rõ sự khác biệt giữa hai cách tiếp cận phổ biến nhất hiện nay:
1. Policy Based Routing (PBR)
- Cơ chế: Gói tin đi vào sẽ được soi xét (source IP, port…) để gán vào bảng định tuyến tương ứng.
- Điểm yếu: Cấu hình
ip ruledễ chồng chéo và không cô lập hoàn toàn ở mức interface. Càng nhiều rule, hiệu năng xử lý gói tin càng bị ảnh hưởng.
2. VRF (Virtual Routing and Forwarding)
- Cơ chế: Bạn gán cứng interface vào một “VRF device”. Mỗi VRF sở hữu một bảng định tuyến riêng biệt, tách biệt hoàn toàn với phần còn lại của hệ thống.
- Điểm mạnh: Cô lập tuyệt đối. Một tiến trình có thể chạy biệt lập bên trong VRF mà không hề biết đến sự tồn tại của các mạng khác.
Các bước triển khai VRF trên môi trường thực tế
Bạn cần một kernel Linux bản 4.3 trở lên để bắt đầu. Các distro phổ biến như Ubuntu 22.04 hay RHEL 9 hiện nay đều hỗ trợ rất tốt. Trong ví dụ này, mình sẽ tạo 2 VRF cho tenant-A và tenant-B.
Bước 1: Kích hoạt module VRF
Đầu tiên, hãy kiểm tra xem kernel đã nạp module cần thiết chưa:
sudo modprobe vrf
# Xác nhận lại
lsmod | grep vrf
Bước 2: Khởi tạo các VRF Device
Mỗi VRF trong Linux đóng vai trò như một interface ảo “cha”. Bạn phải gán cho mỗi VRF một Table ID duy nhất để định danh bảng định tuyến của nó.
# Tạo VRF cho Tenant A (Table 10)
sudo ip link add vrf-a type vrf table 10
sudo ip link set vrf-a up
# Tạo VRF cho Tenant B (Table 20)
sudo ip link add vrf-b type vrf table 20
sudo ip link set vrf-b up
Bước 3: Gán Interface và xử lý trùng IP
Đây là phần quan trọng nhất. Giả sử eth1 nối với Tenant A và eth2 nối với Tenant B. Khi cần tính toán chia nhỏ subnet cho nhiều tenant, mình thường dùng IP Subnet Calculator để tránh nhầm lẫn các thông số network và broadcast.
# Cấu hình cho Tenant A
sudo ip link set dev eth1 master vrf-a
sudo ip addr add 192.168.1.1/24 dev eth1
sudo ip link set eth1 up
# Cấu hình cho Tenant B (Dùng trùng dải IP vẫn chạy tốt)
sudo ip link set dev eth2 master vrf-b
sudo ip addr add 192.168.1.1/24 dev eth2
sudo ip link set eth2 up
Bước 4: Kiểm tra tính độc lập
Lúc này, lệnh ip route thông thường sẽ không hiển thị các dải IP của tenant. Để xem bảng định tuyến riêng, bạn cần chỉ định rõ tên VRF:
# Kiểm tra định tuyến của Tenant A
ip route show vrf vrf-a
# Hoặc xem trực tiếp qua Table ID
ip route show table 10
Cách chạy ứng dụng bên trong VRF
Nhiều bạn sau khi cấu hình xong thường than phiền là không ping được. Nguyên nhân là do các lệnh mặc định luôn chạy ở bảng định tuyến chính (Main Table).
Thực hiện lệnh Ping
Để kiểm tra kết nối của Tenant A, bạn phải ép lệnh ping đi qua VRF tương ứng:
# Ping đến IP 192.168.1.100 của Tenant A
ping -I vrf-a 192.168.1.100
Vận hành dịch vụ (Nginx, SSH, Python)
Cơ chế ip vrf exec cực kỳ mạnh mẽ. Nó cho phép khởi chạy một process nằm trọn trong ngữ cảnh của VRF đó.
# Chạy web server chỉ phục vụ Tenant B
sudo ip vrf exec vrf-b python3 -m http.server 8080
Kết quả là chỉ những client kết nối từ eth2 mới vào được port 8080. Client từ Tenant A hoàn toàn bị chặn đứng dù có cùng dải IP.
Những lưu ý “xương máu” khi dùng VRF
Qua quá trình triển khai thực tế, mình rút ra 3 điểm cần đặc biệt lưu tâm:
- Vấn đề Localhost: Các dịch vụ trong VRF đôi khi không thể kết nối tới
127.0.0.1. Hãy bậtnet.ipv4.tcp_l3mdev_accept = 1để các service có thể lắng nghe trên mọi VRF mà không cần bind thủ công từng cái. - DNS Resolution: Nếu DNS server nằm ở bảng định tuyến chính, các tiến trình trong VRF sẽ không phân giải được tên miền. Bạn nên đặt DNS server riêng trong từng VRF hoặc thiết lập Inter-VRF routing.
- Bẫy Iptables: Gói tin đi qua VRF device sẽ chạy qua chuỗi PREROUTING và POSTROUTING hai lần. Hãy kiểm tra kỹ các rule firewall để tránh việc gói tin bị drop vô lý.
Lời kết
VRF là công cụ thay thế hoàn hảo cho việc lạm dụng máy ảo hay container chỉ để tách bảng định tuyến. Cách tiếp cận này giúp hạ tầng của bạn minh bạch, bảo mật và dễ mở rộng hơn nhiều. Nếu bạn đang xây dựng Gateway hoặc VPN cho nhiều khách hàng, hãy áp dụng VRF ngay để đơn giản hóa việc quản lý mạng.

