更新时间:2025-11-26 GMT+08:00
分享

自动为多网卡Linux云服务器配置IPv4策略路由(Ubuntu)

操作场景

本文档指导用户使用自动化脚本为双网卡Linux云服务器配置策略路由,自动化脚本支持的操作系统为Ubuntu 22.04版本。

关于云服务器双网卡的背景知识及组网说明,请参见方案概述

Linux IPv4操作步骤

  1. 收集配置策略路由需要的云服务器IPv4网卡地址等信息。

    具体操作请参见收集云服务器网络信息

    本示例中,云服务器的网络信息如表1所示。

    表1 Linux IPv4信息说明

    类型

    主网卡

    扩展网卡

    源端

    • 网卡IPv4地址:10.0.0.115
    • 子网IPv4网段:10.0.0.0/24
    • 子网IPv4网关:10.0.0.1
    • 网卡IPv4地址:10.0.1.183
    • 子网IPv4网段:10.0.1.0/24
    • 子网IPv4网关:10.0.1.1

    目的端

    网卡IPv4地址:10.0.2.12

    不涉及

  2. 登录源端云服务器。

    ECS有多种登录方法,具体请参见登录弹性云服务器

  3. 执行以下命令,检查源端云服务器主网卡和目的端云服务器IPv4网络通信情况。

    配置多网卡策略路由前,请务必确保源端主网卡和目的端通信正常。

    ping -I 源端云服务器主网卡IPv4地址 目的端云服务器网卡IPv4地址

    命令示例:

    ping -I 10.0.0.115 10.0.2.12

    回显类似如下信息,表示可以正常通信。
    root@ecs-resource:~# ping -I 10.0.0.115 10.0.2.12
    PING 10.0.2.12 (10.0.2.12) from 10.0.0.115 : 56(84) bytes of data.
    64 bytes from 10.0.2.12: icmp_seq=1 ttl=64 time=0.262 ms
    64 bytes from 10.0.2.12: icmp_seq=2 ttl=64 time=0.193 ms
    64 bytes from 10.0.2.12: icmp_seq=3 ttl=64 time=0.086 ms
    ^C
    --- 10.0.2.12 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2045ms
    rtt min/avg/max/mdev = 0.086/0.180/0.262/0.072 ms
  4. 执行以下命令,查看云服务器网卡名称。

    ifconfig

    回显类似如下信息,通过网卡地址查找对应的网卡名称,本示例中:
    • 10.0.0.115为主网卡IPv4地址,对应的名称为eth0。
    • 10.0.1.183为扩展网卡IPv4地址,对应的名称为eth1。
    root@ecs-resource:~# ifconfig
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 10.0.0.115  netmask 255.255.255.0  broadcast 10.0.0.255
            inet6 fe80::f816:3eff:fe72:72e5  prefixlen 64  scopeid 0x20<link>
            ether fa:16:3e:72:72:e5  txqueuelen 1000  (Ethernet)
            RX packets 139035  bytes 201093027 (201.0 MB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 18669  bytes 1744334 (1.7 MB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 10.0.1.183  netmask 255.255.255.0  broadcast 10.0.1.255
            inet6 fe80::f816:3eff:fe72:7329  prefixlen 64  scopeid 0x20<link>
            ether fa:16:3e:72:73:29  txqueuelen 1000  (Ethernet)
            RX packets 2  bytes 738 (738.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 35  bytes 2466 (2.4 KB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  5. 执行以下步骤,创建自动化脚本配置IPv4路由。
    1. 执行以下命令,创建自动化配置脚本文件15-policy-route.sh

      vi /etc/NetworkManager/dispatcher.d/15-policy-route.sh

    2. i进入编辑模式。
    3. 在文件中添加自动化脚本配置文件。
      #!/bin/bash
      
      if [ "$2" != "up" ]; then
          exit 0
      fi
      
      interface=$1
      
      check_route_table() {
          local route_table_id=$1
          local ip_version=$2
          local max_attempts=100
          local attempts=0
      
          while [ $attempts -lt $max_attempts ]; do
              output=$(ip -$ip_version route show table $route_table_id &>/dev/null)
              if [ $? -ne 0 ] || [ -z "$output" ]; then
                  break
              else
                  route_table_id=$((route_table_id + 1))
                  attempts=$((attempts + 1))
              fi
          done
      
          echo $route_table_id
      }
      
      add_ipv4_route_table() {
          local DEFAULT_IPV4_ROUTE_TABLE_ID=1000
          v4_route_table_id=$(ip route show table all | grep -F "default via $gateway dev $interface table" | awk '{print $NF}')
          if [ -z $v4_route_table_id ]; then
              interface_number=$(echo $interface | grep -o '[0-9]*$')
              if [ -z "$interface_number" ]; then
                  v4_route_table_id="$DEFAULT_IPV4_ROUTE_TABLE_ID"
              else
                  v4_route_table_id=$((DEFAULT_IPV4_ROUTE_TABLE_ID + interface_number))
              fi
      
              v4_route_table_id=$(check_route_table $v4_route_table_id 4)
      
              echo "add policy route for dev: $interface table: $v4_route_table_id subnet: $subnet gateway: $gateway"
      
              ip route add default via $gateway dev $interface table $v4_route_table_id
              ip route add $subnet dev $interface table $v4_route_table_id
          fi
      }
      
      get_gateway_by_subnet() {
        subnet=$1
        IFS='/' read -r ip mask <<< "$subnet"
        IFS='.' read -r ip1 ip2 ip3 ip4 <<< "$ip"
        gateway="$ip1.$ip2.$ip3.$((ip4+1))"
        echo $gateway
      }
      
      generate_ipv4_policy_route() {
          subnet=$(nmcli device show $interface | grep -F 'IP4.ROUTE' | grep -F 'nh = 0.0.0.0' | cut -d'=' -f2 | cut -d',' -f1 | tr -d ' ' | head -n 1)
          gateway=$(get_gateway_by_subnet $subnet)
      
          add_ipv4_route_table
      
          nmcli device show $interface | grep -F 'IP4.ADDRESS' | while read -r line; do
              IP=$(echo $line | awk '{print $2}' | cut -d'/' -f1)
              if ip rule list | grep -F "$v4_route_table_id" | grep -q "$IP"; then
                  echo "ip rule already exists for $IP with table $v4_route_table_id"
                  continue
              fi
      
              echo "Adding rule for $IP on $interface with table $v4_route_table_id"
              ip rule add from $IP table $v4_route_table_id
          done
      }
      
      generate_ipv4_policy_route
    4. ESC退出,并输入:wq!保存配置。
    5. 执行以下命令,查看自动化配置脚本文件15-policy-route.sh的权限。

      ll /etc/NetworkManager/dispatcher.d/

      回显类似如下信息,15-policy-route.sh权限为-rw-r--r--,和其他系统文件(比如01-ifupdown*)的权限(-rwxr-xr-x)不一样。
      root@ecs-resource:~# ll /etc/NetworkManager/dispatcher.d/
      total 32
      drwxr-xr-x 5 root root 4096 Nov  7 12:21 ./
      drwxr-xr-x 7 root root 4096 Apr 22  2025 ../
      -rwxr-xr-x 1 root root 2293 Dec 11  2024 01-ifupdown*
      -rw-r--r-- 1 root root 2317 Nov  7 12:21 15-policy-route.sh
      -rwxrwxr-x 1 root root  719 May 10  2019 hook-network-manager*
      drwxr-xr-x 2 root root 4096 Dec 11  2024 no-wait.d/
      drwxr-xr-x 2 root root 4096 Dec 11  2024 pre-down.d/
      drwxr-xr-x 2 root root 4096 Dec 11  2024 pre-up.d/
    6. 执行以下命令,为自动化配置脚本文件15-policy-route.sh添加权限。

      sudo chown root:root /etc/NetworkManager/dispatcher.d/15-policy-route.sh

      sudo chmod 755 /etc/NetworkManager/dispatcher.d/15-policy-route.sh

    7. 执行以下命令,再次查看自动化配置脚本文件15-policy-route.sh的权限。

      ll /etc/NetworkManager/dispatcher.d/

      回显类似如下信息,15-policy-route.sh权限为-rwxr-xr-x。
      root@ecs-resource:~# ll /etc/NetworkManager/dispatcher.d/
      total 32
      drwxr-xr-x 5 root root 4096 Nov  7 12:21 ./
      drwxr-xr-x 7 root root 4096 Apr 22  2025 ../
      -rwxr-xr-x 1 root root 2293 Dec 11  2024 01-ifupdown*
      -rwxr-xr-x 1 root root 2317 Nov  7 12:21 15-policy-route.sh*
      -rwxrwxr-x 1 root root  719 May 10  2019 hook-network-manager*
      drwxr-xr-x 2 root root 4096 Dec 11  2024 no-wait.d/
      drwxr-xr-x 2 root root 4096 Dec 11  2024 pre-down.d/
      drwxr-xr-x 2 root root 4096 Dec 11  2024 pre-up.d/
    8. 执行以下命令,重启网络服务以触发脚本15-policy-route.sh运行。

      systemctl restart NetworkManager

      重启网络服务时,此处请确保不影响业务再重启。

  6. 依次执行以下命令,确认网卡IPv4策略路由是否添加成功。

    ip rule

    ip route show table 1000

    ip route show table 1001

    其中,table 1000为主网卡的路由表名称,table 1001为扩展网卡的路由表名称。

    回显类似如下信息,表示IPv4策略路由添加成功。
    root@ecs-resource:~# ip rule
    0:      from all lookup local
    32764:  from 10.0.1.183 lookup 1001
    32765:  from 10.0.0.115 lookup 1000
    32766:  from all lookup main
    32767:  from all lookup default
    root@ecs-resource:~# ip route show table 1000
    default via 10.0.0.1 dev eth0 
    10.0.0.0/24 dev eth0 scope link 
    root@ecs-resource:~# ip route show table 1001
    default via 10.0.1.1 dev eth1 
    10.0.1.0/24 dev eth1 scope link 
  7. 执行以下命令,验证源端云服务器和目的端云服务器是否可以通过IPv4地址正常通信。

    ping -I 源端云服务器主网卡IPv4地址 目的端云服务器网卡IPv4地址

    ping -I 源端云服务器扩展网卡IPv4地址 目的端云服务器网卡IPv4地址

    命令示例:

    ping -I 10.0.0.115 10.0.2.12

    ping -I 10.0.1.183 10.0.2.12

    回显类似如下信息,源端两个IPv4地址均可以和目的端正常通信,表示IPv4策略路由配置成功。
    root@ecs-resource:~# ping -I 10.0.0.115 10.0.2.12
    PING 10.0.2.12 (10.0.2.12) from 10.0.0.115 : 56(84) bytes of data.
    64 bytes from 10.0.2.12: icmp_seq=1 ttl=64 time=0.233 ms
    64 bytes from 10.0.2.12: icmp_seq=2 ttl=64 time=0.177 ms
    64 bytes from 10.0.2.12: icmp_seq=3 ttl=64 time=0.089 ms
    ^C
    --- 10.0.2.12 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2029ms
    rtt min/avg/max/mdev = 0.089/0.166/0.233/0.059 ms
    root@ecs-resource:~# ping -I 10.0.1.183 10.0.2.12
    PING 10.0.2.12 (10.0.2.12) from 10.0.1.183 : 56(84) bytes of data.
    64 bytes from 10.0.2.12: icmp_seq=1 ttl=64 time=0.300 ms
    64 bytes from 10.0.2.12: icmp_seq=2 ttl=64 time=0.194 ms
    64 bytes from 10.0.2.12: icmp_seq=3 ttl=64 time=0.100 ms
    ^C
    --- 10.0.2.12 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2025ms
    rtt min/avg/max/mdev = 0.100/0.198/0.300/0.081 ms

相关文档