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


2 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