When working with Linux network namespaces, many developers assume DNS settings would automatically get isolated through /etc/netns/
- but this isn't the default behavior on most modern distributions. The traditional approach of creating /etc/netns/mynamespace/resolv.conf
only works if you're using legacy network namespace management tools.
Here are three proven methods to achieve DNS isolation:
Method 1: Manual Mount Binding
# Create namespace
sudo ip netns add myns
# Create custom resolv.conf
mkdir -p /etc/netns/myns
echo "nameserver 8.8.8.8" > /etc/netns/myns/resolv.conf
# Mount it when entering namespace
sudo ip netns exec myns mount --bind /etc/netns/myns/resolv.conf /etc/resolv.conf
Method 2: Using systemd-resolved
# First enable systemd-resolved
sudo systemctl enable --now systemd-resolved
# Then for your namespace:
sudo ip netns exec myns systemd-resolve --interface=veth0 --set-dns=1.1.1.1 --set-domain=example.com
Method 3: Container-style DNS Management
# Use a minimal DNS server like dnsmasq
sudo ip netns exec myns dnsmasq \
--no-hosts \
--no-resolv \
--server=9.9.9.9 \
--listen-address=127.0.0.1 \
--bind-interfaces \
--pid-file=/var/run/myns-dnsmasq.pid
# Then point resolv.conf to localhost
echo "nameserver 127.0.0.1" | sudo ip netns exec myns tee /etc/resolv.conf
For long-running namespaces, consider these approaches:
- Create systemd service units that handle the DNS configuration
- Use network namespace managers like
ip-netns
with custom hooks - Implement a small daemon that watches for namespace changes
Essential troubleshooting commands:
# Check active DNS config
sudo ip netns exec myns cat /etc/resolv.conf
# Test DNS resolution
sudo ip netns exec myns nslookup example.com
# Verify routes
sudo ip netns exec myns ip route
When using network namespaces with container runtimes:
# CNI plugin configuration snippet
{
"dns": {
"nameservers": ["10.96.0.10"],
"search": ["namespace.svc.cluster.local"]
}
}
Remember that some container runtimes may override these settings during pod initialization.
When working with Linux network namespaces, many developers assume DNS configuration follows the same isolation pattern as network interfaces. However, the reality is more nuanced. Traditional /etc/resolv.conf
remains global across namespaces unless properly configured.
By default, all network namespaces share the same DNS resolution settings from these locations:
/etc/resolv.conf
/run/systemd/resolve/stub-resolv.conf
/run/resolv.conf
This explains why you're observing system-wide DNS changes when modifying these files.
Modern Linux systems support per-namespace DNS configuration through the /etc/netns/
directory structure. Here's how to implement it:
# Create the netns directory structure
sudo mkdir -p /etc/netns/ns1
# Create namespace-specific resolv.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/netns/ns1/resolv.conf
# Create and enter the namespace
sudo ip netns add ns1
sudo ip netns exec ns1 bash
For systems without automatic namespace resolution, manually mount a custom resolv.conf:
# Create temporary mount point
sudo mkdir -p /etc/netns/ns1
# Create custom DNS config
echo "nameserver 1.1.1.1" > /tmp/ns1-resolv.conf
# Mount it inside the namespace
sudo mount --bind /tmp/ns1-resolv.conf /etc/resolv.conf
# Verify functionality
sudo ip netns exec ns1 cat /etc/resolv.conf
For systems using systemd-resolved (common in modern distributions):
# Create DNS override for the namespace
sudo resolvectl dns ns1 9.9.9.9
sudo resolvectl domain ns1 ~internal.example.com
# Verify the configuration
sudo ip netns exec ns1 resolvectl status
For more complex setups resembling container environments:
# Create mount namespace along with network namespace
sudo unshare --net --mount -- /bin/bash
# Set up private /etc
mount -t tmpfs tmpfs /etc
# Populate custom DNS config
echo "nameserver 208.67.222.222" > /etc/resolv.conf
chmod 644 /etc/resolv.conf
- Check
ls -l /etc/resolv.conf
to identify symlinks - Verify namespace awareness with
ip netns list
- Test DNS resolution with
nslookup example.com
inside the namespace - Inspect mount points with
findmnt
in both namespaces