All Products
Search
Document Center

Alibaba Cloud Linux:Configure policy-based routes to direct traffic based on source IP addresses

Last Updated:Apr 01, 2026

On an Elastic Compute Service (ECS) instance running Alibaba Cloud Linux 3, the default routing algorithm selects routes based on the destination IP address of each packet. When traffic originates from a secondary network interface controller (NIC)—such as eth1—and is destined for the subnet of that NIC, the instance always routes it through the primary NIC (eth0) instead. As a result, applications bound to eth1's IP address may fail to send return traffic correctly.

Policy-based routes solve this by selecting routes based on the source IP address. After configuration, traffic from eth1 exits through eth1, and traffic from eth0 exits through eth0.

Supported OS

Alibaba Cloud Linux 3 only. NetworkManager must be running (enabled by default).

Choose between persistent and temporary routes

Route typeBehavior after restartUse when
PersistentRoutes remain activeProduction instances or any instance that restarts
TemporaryRoutes are clearedTesting or short-lived instances

Both types use a config_dual_traffic.sh script. The difference is in how the script applies routes: persistent routes use nmcli connection modify, while temporary routes use nmcli device modify.

Configure a persistent policy-based route

Persistent routes survive instance restarts.

Prerequisites

Before you begin, ensure that you have:

  • An ECS instance running Alibaba Cloud Linux 3

  • A secondary NIC (for example, eth1) attached to the instance

  • sudo privileges on the instance

Steps

  1. Create and open the config_dual_traffic.sh file.

    sudo vim config_dual_traffic.sh
  2. Press I to enter Insert mode, then paste the following script. The script retrieves the NIC's MAC address, IP address, netmask, and gateway from the Alibaba Cloud instance metadata service (http://100.100.100.200). You do not need to look up these values manually. The script then converts the netmask to CIDR notation and applies routing rules using nmcli connection modify.

    #!/bin/bash
    
    # Target NIC name
    NIC=$1
    
    # URL for metaserver
    BASE_URL="http://100.100.100.200/latest/meta-data/network/interfaces/macs"
    
    # MAC/IP address/netmask/gateway for NIC
    MAC=$(cat /sys/class/net/$NIC/address)
    IP_ADDRESS=$(curl $BASE_URL/$MAC/primary-ip-address)
    NETMASK=$(curl $BASE_URL/$MAC/netmask)
    GATEWAY=$(curl $BASE_URL/$MAC/gateway)
    
    # 255.255.255.0 to /24
    netmask_to_cidr() {
        local binary_mask=""
    
        IFS='.' read -ra ADDR <<<"$NETMASK"
        for octet in "${ADDR[@]}"; do
            binary_mask+=$(echo "obase=2; $octet" | bc)
        done
    
        local cidr=0
        for ((i=0; i<${#binary_mask}; i++)); do
            if [ "${binary_mask:$i:1}" == "1" ]; then
                ((cidr++))
            fi
        done
    
        echo "$cidr"
    }
    
    CIDR=$(netmask_to_cidr $NETMASK)
    NETWORK_ADDRESS=$(ipcalc -n $IP_ADDRESS $NETMASK | cut -d= -f2)
    IP_CIDR="${NETWORK_ADDRESS}/${CIDR}"
    
    # Connection name for NIC
    CONNECTION_NAME=$(nmcli -g NAME,DEVICE connection show | grep $NIC | awk -F: '{print $1}')
    
    echo "NIC name: $NIC"
    echo "mac addrss: $MAC"
    echo "ip address: $IP_ADDRESS"
    echo "netmask: $NETMASK"
    echo "IP_CIDR: $IP_CIDR"
    echo "default gateway: $GATEWAY"
    echo "connection: $CONNECTION_NAME"
    
    nmcli connection modify "$CONNECTION_NAME" +ipv4.routing-rules "priority 100 from $IP_ADDRESS table 200"
    nmcli connection modify "$CONNECTION_NAME" +ipv4.routes "0.0.0.0/0 $GATEWAY table=200"
    nmcli connection modify "$CONNECTION_NAME" +ipv4.routes "$IP_CIDR table=200"
    nmcli connection up "$CONNECTION_NAME"
    
    echo "The dual network card sending network configuration is completed."
  3. Press Esc, type :wq, and press Enter to save and close the file.

  4. Run the script for eth1. Replace eth1 with your actual secondary NIC name if different.

    sudo sh config_dual_traffic.sh eth1
  5. Verify the routing rules and route entries.

    ip rule
    ip route show table 200

    A successful configuration shows a routing rule for your NIC's IP address at priority 100, and the corresponding route entries in routing table 200. The following screenshot shows an example of the expected output.

    image

Configure a temporary policy-based route

Temporary routes are cleared when the instance restarts.

Prerequisites

Before you begin, ensure that you have:

  • An ECS instance running Alibaba Cloud Linux 3

  • A secondary NIC (for example, eth1) attached to the instance

  • sudo privileges on the instance

Steps

  1. Create and open the config_dual_traffic.sh file.

    sudo vim config_dual_traffic.sh
  2. Press I to enter Insert mode, then paste the following script. This script works the same as the persistent version, except it uses nmcli device modify instead of nmcli connection modify. The changes apply immediately but are not saved to the connection profile, so they are cleared after a restart.

    #!/bin/bash
    
    # Target NIC name
    NIC=$1
    
    # URL for metaserver
    BASE_URL="http://100.100.100.200/latest/meta-data/network/interfaces/macs"
    
    # MAC/IP address/netmask/gateway for NIC
    MAC=$(cat /sys/class/net/$NIC/address)
    IP_ADDRESS=$(curl $BASE_URL/$MAC/primary-ip-address)
    NETMASK=$(curl $BASE_URL/$MAC/netmask)
    GATEWAY=$(curl $BASE_URL/$MAC/gateway)
    
    # 255.255.255.0 to /24
    netmask_to_cidr() {
        local binary_mask=""
    
        IFS='.' read -ra ADDR <<<"$NETMASK"
        for octet in "${ADDR[@]}"; do
            binary_mask+=$(echo "obase=2; $octet" | bc)
        done
    
        local cidr=0
        for ((i=0; i<${#binary_mask}; i++)); do
            if [ "${binary_mask:$i:1}" == "1" ]; then
                ((cidr++))
            fi
        done
    
        echo "$cidr"
    }
    
    CIDR=$(netmask_to_cidr $NETMASK)
    NETWORK_ADDRESS=$(ipcalc -n $IP_ADDRESS $NETMASK | cut -d= -f2)
    IP_CIDR="${NETWORK_ADDRESS}/${CIDR}"
    
    # Device name for NIC
    DEVICE_NAME=$(nmcli -g NAME,DEVICE connection show | grep $NIC | awk -F: '{print $2}')
    
    echo "NIC name: $NIC"
    echo "mac addrss: $MAC"
    echo "ip address: $IP_ADDRESS"
    echo "netmask: $NETMASK"
    echo "IP_CIDR: $IP_CIDR"
    echo "default gateway: $GATEWAY"
    echo "device: $DEVICE_NAME"
    
    nmcli device modify "$DEVICE_NAME" +ipv4.routing-rules "priority 100 from $IP_ADDRESS table 200"
    nmcli device modify "$DEVICE_NAME" +ipv4.routes "0.0.0.0/0 $GATEWAY table=200"
    nmcli device modify "$DEVICE_NAME" +ipv4.routes "$IP_CIDR table=200"
    
    echo "The dual network card sending network configuration is completed."
  3. Press Esc, type :wq, and press Enter to save and close the file.

  4. Run the script for eth1. Replace eth1 with your actual secondary NIC name if different.

    sudo sh config_dual_traffic.sh eth1
  5. Verify the routing rules and route entries.

    ip rule
    ip route show table 200

    A successful configuration shows a routing rule for your NIC's IP address at priority 100, and the corresponding route entries in routing table 200. The following screenshot shows an example of the expected output.

    image