How to Configure Per-Interface DNS Settings on RHEL/CentOS 6 (eth0 vs eth1)


2 views

When working with multi-homed RHEL/CentOS 6 systems, you might encounter situations where different network interfaces need to use different DNS servers. The traditional approach of adding DNS settings in /etc/sysconfig/network-scripts/ifcfg-ethX files often gets ignored in favor of the global /etc/resolv.conf settings.

The NetworkManager and legacy network scripts handle DNS configuration differently than you might expect:

# Typical ifcfg-eth0 entry that doesn't work as expected
DNS1=10.0.0.2

This gets overwritten by whatever is in resolv.conf, leading to DNS resolution failures when the primary interface goes down.

The most reliable approach involves combining:

  1. Multiple routing tables
  2. Policy routing rules
  3. Interface-specific resolv.conf files

First, create custom routing tables for each interface:

# Add to /etc/iproute2/rt_tables
100 eth0_table
101 eth1_table

Then configure the routing rules:

# For eth0 (10.0.0.1/24)
ip route add 10.0.0.0/24 dev eth0 src 10.0.0.1 table eth0_table
ip route add default via 10.0.0.1 dev eth0 table eth0_table
ip rule add from 10.0.0.1 lookup eth0_table

# For eth1 (192.168.0.1/24)
ip route add 192.168.0.0/24 dev eth1 src 192.168.0.1 table eth1_table
ip route add default via 192.168.0.1 dev eth1 table eth1_table
ip rule add from 192.168.0.1 lookup eth1_table

Create interface-specific resolv.conf files:

# /etc/resolv.conf.eth0
nameserver 10.0.0.2

# /etc/resolv.conf.eth1
nameserver 192.168.0.2

Then add these scripts to maintain the symlink:

#!/bin/bash
# /etc/NetworkManager/dispatcher.d/99dns-symlink

INTERFACE=$1
STATUS=$2

if [ "$STATUS" = "up" ]; then
    case "$INTERFACE" in
        eth0) ln -sf /etc/resolv.conf.eth0 /etc/resolv.conf ;;
        eth1) ln -sf /etc/resolv.conf.eth1 /etc/resolv.conf ;;
    esac
fi

For more flexibility, consider running dnsmasq as a local resolver:

# /etc/dnsmasq.conf
listen-address=127.0.0.1
server=/10.0.0.0/24/10.0.0.2
server=/192.168.0.0/24/192.168.0.2

Then point /etc/resolv.conf to 127.0.0.1 and let dnsmasq handle the routing decisions.

Add the routing rules to /etc/rc.local or create proper init scripts:

# Example for eth0
ip route flush table eth0_table
ip route add 10.0.0.0/24 dev eth0 src 10.0.0.1 table eth0_table
ip route add default via 10.0.0.1 dev eth0 table eth0_table

When working with multi-homed RHEL/CentOS 6 systems, you might encounter situations where different network interfaces require distinct DNS configurations. The standard approach of using /etc/resolv.conf falls short because:

  • It provides system-wide DNS configuration
  • Doesn't adapt when interfaces go down
  • Lacks interface-specific routing logic

The DNS settings in /etc/sysconfig/network-scripts/ifcfg-ethX files only take effect during interface initialization. The NetworkManager service (or legacy network service) writes these values to resolv.conf at startup but doesn't dynamically manage them during runtime.

# Typical ifcfg-eth0 example that doesn't work as expected
DEVICE=eth0
BOOTPROTO=static
IPADDR=10.0.0.1
NETMASK=255.255.255.0
DNS1=10.0.0.2

The most robust approach combines policy routing with a local caching DNS resolver:

# Install required packages
yum install dnsmasq iproute

# Configure dnsmasq
cat > /etc/dnsmasq.d/multidns.conf << EOF
listen-address=127.0.0.1
server=/0.10.in-addr.arpa/10.0.0.2
server=/168.192.in-addr.arpa/192.168.0.2
server=10.0.0.2@eth0
server=192.168.0.2@eth1
EOF

# Configure policy routing
cat > /etc/iproute2/rt_tables.d/multidns.conf << EOF
100 eth0_dns
101 eth1_dns
EOF

ip route add default via 10.0.0.1 table eth0_dns
ip route add default via 192.168.0.1 table eth1_dns
ip rule add from 10.0.0.1 lookup eth0_dns
ip rule add from 192.168.0.1 lookup eth1_dns

For systems using NetworkManager (even on RHEL6):

# Create connection-specific configs
nmcli con mod eth0 ipv4.dns "10.0.0.2"
nmcli con mod eth0 ipv4.dns-priority 10
nmcli con mod eth1 ipv4.dns "192.168.0.2"
nmcli con mod eth1 ipv4.dns-priority 20

# Make settings persistent
nmcli con up eth0
nmcli con up eth1

For environments where both DNS servers should be available with failover:

# /etc/resolv.conf configuration
options timeout:1 attempts:1
nameserver 10.0.0.2
nameserver 192.168.0.2

# Combined with interface monitoring
cat > /usr/local/bin/dns-watchdog.sh << 'EOF'
#!/bin/bash
while true; do
    if ! ping -c 1 -I eth0 10.0.0.2 >/dev/null; then
        sed -i '/10.0.0.2/d' /etc/resolv.conf
    else
        grep -q "10.0.0.2" /etc/resolv.conf || echo "nameserver 10.0.0.2" >> /etc/resolv.conf
    fi
    sleep 30
done
EOF