Sổ tay kỹ thuật

Policy routing và VRF trên Linux – ip rule, nhiều routing table

how-to#linux#iproute2#vrf#networking· cập nhật 2026-11-06

Dùng khi máy có nhiều uplink/ISP cần trả lời đúng cổng theo source IP, hoặc cần tách mạng management bằng VRF trên Linux.

Sửa trang này
Mục lục

Tóm tắt: Kernel duyệt ip rule theo pref tăng dần; rule nào khớp thì tra route trong table của rule đó, không thấy route thì đi tiếp rule sau. Mặc định có 3 rule: 0 local, 32766 main, 32767 default. Policy routing = thêm rule (from/to/fwmark/iif...) trỏ tới table riêng. VRF = interface ảo type vrf gắn với một table, các interface "enslave" vào VRF chỉ dùng table đó. Lệnh ip dưới đây mất sau reboot; bản bền xem phần netplan.

Luồng hoạt động

flowchart TD P["Packet / socket cần route"] --> R0["pref 0: lookup local"] R0 -->|"không phải IP local"| R1["pref 100: from 203.0.113.10 lookup isp2"] R1 -->|"khớp"| T["table isp2: default via 203.0.113.1"] R1 -->|"không khớp"| R2["pref 1000: l3mdev (VRF)"] R2 -->|"không thuộc VRF"| M["pref 32766: lookup main"] M -->|"không có route"| D["pref 32767: lookup default"]

Cấu hình

Đặt tên table

/etc/iproute2/rt_tables.d/isp.conf
100 isp1
200 isp2

Không bắt buộc (dùng số cũng được), nhưng ip rule / ip route show table isp2 dễ đọc hơn.

Ví dụ: eth0 198.51.100.10/24 (gw .1, ISP1, default trong main), eth1 203.0.113.10/24 (gw .1, ISP2). Không có policy routing thì gói trả lời cho traffic vào eth1 vẫn đi ra eth0 → bị ISP2 / rp_filter drop.

# Table riêng cho ISP2: connected + default
sudo ip route add 203.0.113.0/24 dev eth1 src 203.0.113.10 table isp2
sudo ip route add default via 203.0.113.1 dev eth1 table isp2
 
# Rule: gói có source 203.0.113.10 → tra table isp2
sudo ip rule add from 203.0.113.10 table isp2 pref 100
 
# Kiểm tra
ip rule show
ip route show table isp2
ip route get 192.0.2.50 from 203.0.113.10      # phải ra dev eth1

Chọn đường theo đích, fwmark, interface vào

Mục đích Lệnh
Đích cụ thể đi ISP2 ip rule add to 192.0.2.0/24 table isp2 pref 110
Theo mark (đặt bằng nftables/iptables) ip rule add fwmark 0x2 table isp2 pref 120
Traffic vào từ interface (router) ip rule add iif eth2 table isp2 pref 130
Theo user (process của uid) ip rule add uidrange 1001-1001 table isp2 pref 140
Theo port đích ip rule add ipproto tcp dport 443 table isp2 pref 150
Xoá rule ip rule del pref 100
Xoá cache route sau khi đổi ip route flush cache

VRF

# Tạo VRF mgmt dùng table 10, gán eth0 vào
sudo ip link add mgmt type vrf table 10
sudo ip link set mgmt up
sudo ip link set eth0 master mgmt          # IP của eth0 giữ nguyên, route connected chuyển sang table 10
sudo ip route add default via 198.51.100.1 table 10
 
# Xem
ip vrf show
ip -br link show master mgmt
ip route show vrf mgmt
ip rule show                               # kernel tự thêm rule "l3mdev" (pref 1000)
 
# Chạy lệnh trong VRF
sudo ip vrf exec mgmt ping -c3 198.51.100.1
sudo ip vrf exec mgmt ssh admin@198.51.100.20

Socket mở ở VRF mặc định không nhận kết nối đến từ interface trong VRF. Để sshd (chạy ở default VRF) nhận được SSH vào cổng mgmt:

/etc/sysctl.d/90-vrf.conf
net.ipv4.tcp_l3mdev_accept = 1
net.ipv4.udp_l3mdev_accept = 1

Cấu hình bền bằng netplan

/etc/netplan/01-netcfg.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    eth1:
      addresses: [203.0.113.10/24]
      routes:
        - to: default
          via: 203.0.113.1
          table: 200
        - to: 203.0.113.0/24
          scope: link
          table: 200
      routing-policy:
        - from: 203.0.113.10
          table: 200
          priority: 100

Netplan từ 0.105 (Ubuntu 22.04 có 0.106) hỗ trợ khoá vrfs: (table, interfaces, routes, routing-policy); xem man netplan. Áp dụng bằng netplan try như trong Netplan.

Lỗi thường gặp

Triệu chứng Nguyên nhân Cách xử lý
Ping vào IP ISP2 không có reply Reply đi ra default của main (ISP1) Thêm rule from <IP ISP2> table isp2
Có rule nhưng gói vào eth1 vẫn bị drop rp_filter=1 (strict) so với table main sysctl -w net.ipv4.conf.eth1.rp_filter=2 (loose)
ip route get đúng nhưng app vẫn ra sai cổng App không bind source IP, kernel chọn source theo main Bind source trong app, hoặc dùng rule fwmark/uidrange
RTNETLINK answers: File exists Rule/route đã tồn tại ip rule show, xoá bằng ip rule del pref N rồi thêm lại
Mất SSH sau ip link set eth0 master mgmt Session SSH đang đi qua eth0, route chuyển sang table VRF Làm từ console, hoặc bật tcp_l3mdev_accept trước
Lệnh trong VRF không phân giải DNS DNS server chỉ tới được qua VRF khác ip vrf exec mgmt cho cả client, hoặc dùng IP thay tên
Rule biến mất sau reboot Thêm bằng ip (runtime) Đưa vào netplan routing-policy / vrfs

Tham khảo