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:
- Multiple routing tables
- Policy routing rules
- 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