How to Disable AAAA DNS Lookups on Linux for IPv4-Only Networks


25 views

In production environments with legacy IPv4 infrastructure, AAAA record queries can cause significant latency when DNS servers fail to respond properly. Many embedded Linux devices (running Debian/Ubuntu/CentOS) experience connection timeouts due to:

  • Firewalls silently dropping AAAA queries
  • DNS servers returning malformed responses
  • 30-second timeout delays before falling back to IPv4

Common approaches like sysctl net.ipv6.conf.all.disable_ipv6=1 or resolv.conf tweaks don't actually prevent glibc from making AAAA queries. Here's what we've tested on modern distributions:

# These WON'T work for DNS-level prevention:
echo "blacklist ipv6" >> /etc/modprobe.d/blacklist.conf
sysctl -w net.ipv6.conf.all.disable_ipv6=1

Method 1: glibc's Happy Eyeballs Tuning

Edit /etc/gai.conf to prioritize IPv4:

# /etc/gai.conf
precedence ::ffff:0:0/96  100

Method 2: Local DNS Proxy

Run a local dnsmasq instance to filter AAAA queries:

apt install dnsmasq
echo "no-aaaa" >> /etc/dnsmasq.conf
echo "nameserver 127.0.0.1" > /etc/resolv.conf

Method 3: iptables DNS Filtering

Block outgoing AAAA queries at network level:

iptables -I OUTPUT -p udp --dport 53 -m string --hex-string "|001c|" --algo bm -j DROP
iptables -I OUTPUT -p tcp --dport 53 -m string --hex-string "|001c|" --algo bm -j DROP

For programs using glibc's resolver:

# Set environment variable
export RES_OPTIONS="no-tries no-rotate"

For Python applications:

import socket
def get_ipv4_by_name(host):
    return [i[4][0] for i in socket.getaddrinfo(host, None) if i[0] is socket.AF_INET]

Verify your solution works with tcpdump:

tcpdump -ni eth0 'port 53' | grep -e ' A? ' -e ' AAAA? '

Many embedded Linux devices operate in environments with legacy network infrastructure where IPv6 support is either broken or non-existent. The core issue manifests when:

int sock = socket(AF_INET6, SOCK_STREAM, 0);
struct addrinfo *result;
getaddrinfo("example.com", "http", NULL, &result);

Even on IPv4-only networks, glibc's resolver will still perform AAAA lookups, causing delays when remote DNS servers fail to respond properly.

Common approaches like sysctl net.ipv6.conf.all.disable_ipv6=1 don't prevent AAAA queries because:

  • DNS resolution occurs before IP stack checks
  • Modern glibc implements Happy Eyeballs algorithm
  • Applications may explicitly request IPv6 resolution

1. glibc Configuration (Preferred Method)

Edit /etc/gai.conf:

# Disable IPv6 DNS lookups
precedence ::ffff:0:0/96  100
label ::1/128       0
label ::/0          1
label 2002::/16     2
label ::/96         3

2. Resolver-Level Workaround

For systems using systemd-resolved:

# /etc/systemd/resolved.conf
[Resolve]
DNSOverTLS=opportunistic
DNSSEC=allow-downgrade
# Disable IPv6 resolution
DNSStubListenerExtra=127.0.0.1

3. Local DNS Proxy Solution

Deploy dnsmasq with custom filtering:

# /etc/dnsmasq.conf
no-resolv
server=8.8.8.8
server=8.8.4.4
filter-AAAA

Then point resolv.conf to 127.0.0.1

Verify with these diagnostic commands:

# Check DNS queries
tcpdump -i eth0 -n port 53
# Test resolution time
time host -t AAAA google.com
# Verify glibc behavior
strace -e trace=network curl https://example.com

For Java applications, add JVM arguments:

-Djava.net.preferIPv4Stack=true
-Dsun.net.inetaddr.ttl=60

For Python applications using requests:

import socket
socket.setdefaulttimeout(5)
socket.AF_INET6 = socket.AF_INET  # Force IPv4