Vấn đề: Nút thắt cổ chai tại Hub trong các mô hình Site-to-Site VPN truyền thống
Việc kết nối các chi nhánh về trụ sở chính hầu như luôn bắt đầu bằng các tunnel IPsec site-to-site tĩnh. Bạn thiết lập một tunnel từ Spoke A đến Hub, và một tunnel khác từ Spoke B đến Hub. Khi các chi nhánh chỉ cần truy cập máy chủ tính lương hoặc cơ sở dữ liệu trung tâm, mô hình này hoạt động rất tốt. Nhưng rắc rối sẽ nảy sinh ngay khi các chi nhánh cần giao tiếp trực tiếp với nhau—chẳng hạn như SIP trunking giữa các chi nhánh, đồng bộ cơ sở dữ liệu theo thời gian thực hoặc các tác vụ sao lưu rsync.
Giả sử Spoke A tại Frankfurt thực hiện một cuộc gọi VoIP đến Spoke B tại Tokyo. Từng gói tin thoại trước tiên đều phải đi qua mạng internet công cộng để đến Hub trung tâm ở Virginia. Tại đó, Hub giải mã payload, tra cứu bảng định tuyến, mã hóa lại rồi chuyển tiếp ngược qua Thái Bình Dương đến Spoke B. Hiện tượng vòng ngược (hair-pinning) này khiến độ trễ tăng vọt từ mức khứ hồi trực tiếp dự kiến 210 ms lên đến 430 ms, đồng thời ngốn sạch băng thông upstream trên gateway của Hub.
Bạn có thể tránh hiện tượng hair-pinning bằng cách xây dựng mô hình full mesh với các tunnel IPsec tĩnh giữa mọi địa điểm. Nhưng độ phức tạp mở rộng quy mô là vô cùng khủng khiếp: O(N²). Chỉ riêng việc liên kết 50 văn phòng chi nhánh đã đòi hỏi tới 1.225 cấu hình IPsec riêng biệt. Một thay đổi nhỏ về địa chỉ IP hay subnet cũng sẽ biến việc vận hành thành cơn ác mộng.
Khái niệm cốt lõi: Phân tích kiến trúc DMVPN trên Linux
Cisco phát triển Dynamic Multipoint VPN (DMVPN) nhằm tách biệt các endpoint của tunnel khỏi địa chỉ IP public cố định. Trên Linux, bạn không cần đến phần cứng chuyên dụng độc quyền hay giấy phép SD-WAN doanh nghiệp đắt đỏ. Bạn hoàn toàn có thể đạt được kiến trúc dynamic mesh tương tự nhờ ba khối thành phần sau:
- Multipoint GRE (mGRE): GRE tiêu chuẩn tạo ra các liên kết point-to-point, đòi hỏi một interface ảo riêng biệt cho từng peer. Ngược lại, mGRE sử dụng một tunnel interface duy nhất (như
gre1) để điều phối và tiếp nhận lưu lượng một cách linh hoạt từ hàng trăm endpoint public tùy ý. - Next Hop Resolution Protocol (NHRP): Được xử lý bởi
opennhrp, giao thức này hoạt động tương tự như ARP cho mạng overlay của bạn. Các Spoke kết nối và đăng ký địa chỉ IP public của mình với Next Hop Server (NHS, thường là Hub). Khi Spoke A muốn gửi gói tin đến mạng LAN của Spoke B, nó sẽ hỏi Hub địa chỉ IP public thực tế của Spoke B, sau đó thiết lập tức thì một liên kết overlay trực tiếp. - IPsec Transport Mode: Chúng ta sử dụng strongSwan để mã hóa toàn bộ lưu lượng GRE. Vì header của mGRE đã đảm nhiệm việc định tuyến và đánh địa chỉ overlay, IPsec sẽ chạy ở Transport Mode gọn nhẹ thay vì Tunnel Mode. Điều này giúp giảm thiểu overhead của header xuống chỉ còn khoảng 36 bytes mỗi gói tin thay vì hơn 56 bytes.
Thực hành: Xây dựng môi trường Lab
Dù bạn đang liên kết các cụm máy chủ bare-metal phân tán giữa Hetzner và AWS hay kết nối các edge gateway từ xa sử dụng IP động, giải pháp này mang lại một mạng lưới mesh bền bỉ, không phụ thuộc nhà cung cấp mà không cần phần cứng đắt đỏ.
1. Sơ đồ mạng và quy hoạch địa chỉ IP
Chúng ta sẽ cấu hình ba máy chủ Linux chạy Debian 12 hoặc Ubuntu 24.04 LTS:
- Hub (NHS): IP public
198.51.100.1, IP VPN Overlay10.255.255.1/24 - Spoke 1: IP public
203.0.113.10, IP VPN Overlay10.255.255.10/24, LAN192.168.10.0/24 - Spoke 2: IP public
203.0.113.20, IP VPN Overlay10.255.255.20/24, LAN192.168.20.0/24
2. Cài đặt các gói phần mềm cần thiết
Trước tiên, hãy cài đặt strongSwan, các tiện ích định tuyến và OpenNHRP trên cả ba máy chủ. Sau đó kích hoạt tính năng chuyển tiếp gói tin (packet forwarding) IPv4:
sudo apt-get update
sudo apt-get install -y strongswan strongswan-pki opennhrp iproute2
# Kích hoạt chuyển tiếp gói tin trong kernel
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.d/99-dmvpn.conf
# Tắt reverse path filtering để tránh drop gói tin trên các interface động
sudo sysctl -w net.ipv4.conf.all.rp_filter=0
sudo sysctl -w net.ipv4.conf.default.rp_filter=0
3. Cấu hình strongSwan để bảo vệ lưu lượng GRE
Vì mGRE chủ động trỏ tới địa chỉ IP của spoke theo lưu lượng phát sinh, strongSwan cần các chính sách transport linh hoạt (wildcard) thay vì định nghĩa peer cố định. Trên Hub và cả hai Spoke, mở file /etc/ipsec.conf:
# /etc/ipsec.conf trên Hub và các Spoke
config setup
charondebug="ike 1, knl 1, cfg 1"
conn %default
keyexchange=ikev2
ike=aes256-sha256-modp2048!
esp=aes256-sha256!
type=transport
dpdaction=restart
dpddelay=30s
auto=route
conn dmvpn-gre
left=%defaultroute
leftprotoport=gre
right=%any
rightprotoport=gre
authby=secret
Thiết lập Pre-Shared Key (PSK) chung trong /etc/ipsec.secrets trên tất cả các node:
# /etc/ipsec.secrets
: PSK "RobustSharedKeyForDMVPN_2026"
Áp dụng cấu hình: sudo ipsec restart
4. Cấu hình Hub (Next Hop Server)
Tạo interface multipoint GRE trên Hub với key ID 1234:
sudo ip tunnel add gre1 mode mgre key 1234 ttl 64
sudo ip addr add 10.255.255.1/24 dev gre1
sudo ip link set dev gre1 up
Tiếp theo, cấu hình /etc/opennhrp/opennhrp.conf trên Hub để phản hồi các yêu cầu phân giải địa chỉ mà không cần file mapping tĩnh:
# /etc/opennhrp/opennhrp.conf trên Hub
interface gre1
holding-time 7200
multicast dynamic
shortcut
redirect
Khởi động NHRP daemon: sudo opennhrp -d
5. Cấu hình Spoke 1 và Spoke 2
Khởi tạo interface mGRE trên Spoke 1:
sudo ip tunnel add gre1 mode mgre key 1234 ttl 64
sudo ip addr add 10.255.255.10/24 dev gre1
sudo ip link set dev gre1 up
Bây giờ, cấu hình OpenNHRP daemon của Spoke 1 để đăng ký địa chỉ WAN với Hub:
# /etc/opennhrp/opennhrp.conf trên Spoke 1
interface gre1
map 10.255.255.1/24 198.51.100.1 register
holding-time 3600
shortcut
redirect
Thực hiện cấu hình tương tự trên Spoke 2, cập nhật địa chỉ interface thành 10.255.255.20/24. Sau đó khởi chạy daemon trên cả hai spoke: sudo opennhrp -d.
6. Kiểm tra kết nối Dynamic Spoke-to-Spoke
Kiểm tra xem cả hai spoke đã đăng ký địa chỉ NBMA public với Hub hay chưa:
hub$ sudo opennhrpctl show
Type: local, IP: 10.255.255.1/32
Type: dynamic, IP: 10.255.255.10/32, NBMA: 203.0.113.10, flags: registered
Type: dynamic, IP: 10.255.255.20/32, NBMA: 203.0.113.20, flags: registered
Tạo lưu lượng truyền thẳng từ Spoke 1 tới địa chỉ IP tunnel của Spoke 2:
spoke1$ traceroute 10.255.255.20
Dưới đây là cơ chế hoạt động chi tiết bên dưới: Gói tin #1 đi qua Hub (10.255.255.1). OpenNHRP phát hiện lưu lượng trung chuyển giữa hai spoke và gửi thông điệp NHRP Redirect tới Spoke 1. Spoke 1 lập tức gửi NHRP Resolution Request và nhận diện được địa chỉ NBMA của Spoke 2 (203.0.113.20). Chỉ trong vòng 40 ms, strongSwan thiết lập thành công IKEv2 SA trực tiếp giữa 203.0.113.10 và 203.0.113.20. Gói tin #2 cùng toàn bộ lưu lượng sau đó sẽ truyền thẳng chỉ với 1 hop, bỏ qua Hub hoàn toàn.
Lời kết
DMVPN giải quyết triệt để sự đánh đổi nan giải giữa chi phí vận hành và độ trễ mạng. Thay vì phải duy trì hàng trăm tunnel point-to-point, mỗi node chỉ cần quản lý một interface mGRE duy nhất. strongSwan đảm nhiệm việc mã hóa thông qua IPsec transport mode, trong khi OpenNHRP tự động thiết lập các đường tắt (shortcut) chỉ khi lưu lượng thực tế yêu cầu.
Để đưa mô hình này vào môi trường production, hãy triển khai BGP hoặc OSPF thông qua FRRouting (FRR) trên lớp mạng overlay gre1. Bằng cách đó, các subnet nội bộ phía sau từng chi nhánh sẽ tự động quảng bá và hội tụ mạng bất cứ khi nào các spoke thiết lập đường truyền trực tiếp với nhau.

