Khủng hoảng lúc 2 giờ sáng: Tại sao một đường truyền WAN là không đủ
Đó là lúc 2 giờ sáng ngày thứ Ba khi điện thoại của tôi bắt đầu đổ chuông liên hồi. Đường truyền cáp quang chính tại chi nhánh chính của chúng tôi đã bị một đội thi công làm muộn cắt đứt. Mặc dù có kết nối LTE dự phòng, máy chủ vẫn hoàn toàn mất kết nối. Tại sao? Bởi vì bảng định tuyến vẫn ngoan cố tìm cách gửi các gói tin ra khỏi một interface đã chết. Tôi đã phải đăng nhập thủ công qua console, xóa route mặc định và thêm một route mới trong tình trạng nửa tỉnh nửa mê. Đó là đêm tôi quyết định sẽ không bao giờ dựa vào sự can thiệp thủ công nữa.
Hầu hết các doanh nghiệp vừa và nhỏ nghĩ rằng họ cần một bộ định tuyến Cisco hoặc Juniper đắt tiền để xử lý hai nhà cung cấp dịch vụ Internet (ISP). Thực tế là Ubuntu Server của bạn hoàn toàn có khả năng xử lý các kịch bản Dual WAN bằng cách sử dụng các công cụ đã được tích hợp sẵn trong kernel: IPRoute2 và Netplan. Tôi đã áp dụng cách tiếp cận này trong môi trường production và kết quả luôn ổn định, vừa tăng băng thông thông qua Load Balancing, vừa mang lại sự an tâm nhờ Failover tự động.
Khái niệm cốt lõi: Policy-Based Routing (PBR)
Định tuyến tiêu chuẩn hoạt động bằng cách nhìn vào IP đích. Nếu bạn muốn truy cập 8.8.8.8, kernel sẽ nhìn vào bảng định tuyến và gửi nó ra gateway mặc định. Trong thiết lập Dual WAN, điều này là không đủ. Chúng ta cần Policy-Based Routing (PBR) – Định tuyến dựa trên chính sách.
PBR cho phép chúng ta đưa ra quyết định định tuyến dựa trên địa chỉ nguồn hoặc các tiêu chí khác. Nếu một gói tin đi vào từ ISP1, phản hồi phải đi ngược lại qua ISP1. Nếu chúng ta chỉ có một bảng định tuyến, máy chủ có thể cố gắng gửi phản hồi của ISP1 thông qua ISP2, điều này sẽ bị ISP chặn ngay lập tức vì bị coi là gói tin giả mạo (spoofed packet). Để giải quyết vấn đề này, chúng ta tạo các bảng định tuyến riêng biệt cho mỗi ISP và một bảng chính để Load Balancing.
Thực hành: Cấu hình Dual WAN trên Ubuntu
Đối với thiết lập này, hãy giả định môi trường như sau:
- Interface eth0 (ISP1): IP 1.1.1.2, Gateway 1.1.1.1
- Interface eth1 (ISP2): IP 2.2.2.2, Gateway 2.2.2.1
- Interface eth2 (LAN): IP 192.168.1.1
Bước 1: Cấu hình Interface mạng với Netplan
Đầu tiên, chúng ta xác định các interface. Ubuntu sử dụng Netplan, vì vậy chúng ta chỉnh sửa file /etc/netplan/01-netcfg.yaml. Lưu ý rằng chúng ta không thiết lập gateway mặc định toàn cục ở đây. Thay vào đó, chúng ta xác định các route thủ công để tránh làm kernel bị nhầm lẫn.
network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses:
- 1.1.1.2/24
eth1:
addresses:
- 2.2.2.2/24
eth2:
addresses:
- 192.168.1.1/24
Áp dụng các thay đổi bằng lệnh sudo netplan apply. Tại thời điểm này, máy chủ của bạn không có gateway mặc định. nó có thể giao tiếp với các subnet nội bộ của ISP nhưng không thể truy cập internet.
Bước 2: Xác định các bảng định tuyến tùy chỉnh
Chúng ta cần thông báo cho hệ thống rằng có hai bảng định tuyến mới tồn tại. Chỉnh sửa file /etc/iproute2/rt_tables và thêm hai dòng vào cuối:
# Mở file cấu hình bảng định tuyến
# sudo nano /etc/iproute2/rt_tables
100 isp1
200 isp2
Bước 3: Tạo logic định tuyến
Bây giờ chúng ta sẽ đổ dữ liệu vào các bảng này. Chúng ta muốn mỗi bảng có gateway mặc định riêng và đảm bảo rằng lưu lượng bắt nguồn từ một interface cụ thể sẽ duy trì trên interface đó. Tôi thường đưa các lệnh này vào một script hoặc một dịch vụ systemd để đảm bảo chúng vẫn tồn tại sau khi khởi động lại.
# Thiết lập bảng định tuyến cho ISP1
ip route add 1.1.1.0/24 dev eth0 src 1.1.1.2 table isp1
ip route add default via 1.1.1.1 table isp1
# Thiết lập bảng định tuyến cho ISP2
ip route add 2.2.2.0/24 dev eth1 src 2.2.2.2 table isp2
ip route add default via 2.2.2.1 table isp2
# Các quy tắc định tuyến để đảm bảo lưu lượng phản hồi đi đúng cổng đã vào
ip rule add from 1.1.1.2 table isp1
ip rule add from 2.2.2.2 table isp2
Bước 4: Triển khai Load Balancing
Đây là nơi phép màu xảy ra. Chúng ta sử dụng tham số nexthop để phân phối lưu lượng qua cả hai gateway. Bạn có thể chỉ định trọng số (weight) nếu một ISP nhanh hơn ISP kia (ví dụ: weight 2 cho đường truyền 200Mbps và weight 1 cho đường truyền 100Mbps).
sudo ip route add default scope global \
nexthop via 1.1.1.1 dev eth0 weight 1 \
nexthop via 2.2.2.1 dev eth1 weight 1
Kernel Linux giờ đây sẽ thực hiện Load Balancing theo từng luồng (per-flow). Điều này có nghĩa là một kết nối đơn lẻ (như tải xuống một tệp) sẽ duy trì trên một WAN để tránh các vấn đề về sắp xếp lại gói tin, nhưng nhiều người dùng hoặc ứng dụng sẽ được trải rộng trên cả hai liên kết.
Tự động hóa Failover với Script kiểm tra sức khỏe
Load Balancing rất tuyệt vời, nhưng nếu ISP1 gặp sự cố, kernel vẫn có thể cố gắng gửi 50% lưu lượng vào “hố đen”. Chúng ta cần một cách để phát hiện lỗi và cập nhật bảng định tuyến. Mặc dù có các công cụ phức tạp như keepalived, một script bash đơn giản thường đáng tin cậy và dễ debug hơn cho tác vụ cụ thể này.
#!/bin/bash
# Script Failover cơ bản
ISP1_GW="1.1.1.1"
ISP2_GW="2.2.2.1"
CHECK_IP="8.8.8.8"
# Hàm kiểm tra kết nối
check_alive() {
ping -I $1 -c 3 -W 2 $CHECK_IP > /dev/null 2>&1
return $?
}
while true; do
check_alive eth0
ISP1_STAT=$?
check_alive eth1
ISP2_STAT=$?
if [ $ISP1_STAT -ne 0 ] && [ $ISP2_STAT -eq 0 ]; then
# ISP1 mất kết nối, ISP2 hoạt động - Chuyển toàn bộ sang ISP2
ip route replace default via $ISP2_GW dev eth1
elif [ $ISP1_STAT -eq 0 ] && [ $ISP2_STAT -ne 0 ]; then
# ISP2 mất kết nối, ISP1 hoạt động - Chuyển toàn bộ sang ISP1
ip route replace default via $ISP1_GW dev eth0
elif [ $ISP1_STAT -eq 0 ] && [ $ISP2_STAT -eq 0 ]; then
# Cả hai đều hoạt động - Khôi phục Load Balancing
ip route replace default scope global \
nexthop via $ISP1_GW dev eth0 weight 1 \
nexthop via $ISP2_GW dev eth1 weight 1
fi
sleep 5
done
Chạy script này như một dịch vụ chạy ngầm. Nó sẽ ping Google DNS thông qua các interface cụ thể. Nếu một bên thất bại, nó sẽ sửa đổi route mặc định trong bảng chính. Khi ISP phục hồi, nó sẽ tự động khôi phục trạng thái Load Balancing.
Kiểm tra và Giám sát
Để xác minh lưu lượng của bạn đang đi theo đường nào, đừng chỉ sử dụng ping. Hãy sử dụng traceroute với cờ chỉ định interface:
traceroute -i eth0 google.com
traceroute -i eth1 google.com
Để xem các route đang hoạt động hiện tại và các trọng số đang được sử dụng, hãy chạy:
ip route show
Kiểm tra các quy tắc chính sách để đảm bảo định tuyến dựa trên nguồn của bạn đang hoạt động:
ip rule show
Lời kết
Thiết lập Dual WAN trên Ubuntu không yêu cầu phần mềm độc quyền hay phần cứng đắt tiền. Bằng cách tận dụng nhiều bảng định tuyến của IPRoute2 và một script kiểm tra sức khỏe đơn giản, bạn có thể tạo ra một hệ thống vừa có tính linh hoạt vừa có hiệu suất cao.
Kinh nghiệm của tôi với thiết lập này cho thấy nó xử lý các sự cố nhỏ của ISP mượt mà hơn nhiều so với nhiều bộ định tuyến “multi-WAN” dành cho người tiêu dùng. Chỉ cần nhớ giữ cho các script của bạn đơn giản và việc giám sát luôn hoạt động. Nếu bạn lại thấy mình phải xử lý sự cố lúc 2 giờ sáng, bạn sẽ thấy biết ơn vì máy chủ đã tự động xử lý failover cho mình.

