Linux域名解析经glibc调用getaddrinfo等接口,受/etc/nsswitch.conf中hosts行配置(如files dns)和/etc/resolv.conf中nameserver、search、options等参数共同控制,且可能被systemd-resolved等服务接管。

Linux系统解析域名时,并非直接查询DNS服务器,而是经过一套由glibc、nsswitch和配置文件共同决定的解析流程。理解这个流程,才能准确诊断DNS问题并合理配置/etc/resolv.conf。
DNS解析的实际执行路径
Linux下域名解析默认走的是glibc提供的getaddrinfo()或gethostbyname()接口,其行为受两个关键因素控制:
-
/etc/nsswitch.conf中
hosts:行的配置,例如hosts: files dns表示先查/etc/hosts,再走DNS;若写成hosts: dns [NOTFOUND=return] files则顺序和失败策略完全不同 - 启用DNS解析后,才真正读取
/etc/resolv.conf来获取nameserver地址、搜索域、超时等参数 - 注意:systemd-resolved、dnsmasq、NetworkManager等服务可能接管
/etc/resolv.conf,使其变为符号链接(如指向/run/systemd/resolve/stub-resolv.conf),此时直接修改该文件无效
/etc/resolv.conf核心字段详解
该文件每行一个指令,常见有效项包括:
-
nameserver:指定DNS服务器IP,最多支持3个;系统按顺序尝试,第一个无响应才用第二个;不支持端口号(除非启用glibc 2.34+并配合
options ndots:等扩展) - search:定义搜索域,用于补全不带点的短域名(如ping web → 尝试web.example.com);多个域用空格分隔,最多6个,总长不超过256字节
- domain:仅设置单个默认域(与search互斥,同时存在时search优先)
-
options:常用子项有:
timeout:1(每次UDP查询等待秒数)、attempts:2(每个server重试次数)、ndots:2(域名中至少含2个点才直接当FQDN查,否则先加search域)
配置注意事项与典型场景
手动维护/etc/resolv.conf需避开常见陷阱:
- 避免硬编码写死——尤其在DHCP或云环境中,应通过NetworkManager的
[main] dns=none或systemd-networkd的DNS=配置交由网络服务管理 - 若需固定使用特定DNS(如1.1.1.1),建议停用systemd-resolved后,将
/etc/resolv.conf改为普通文件并写入:
nameserver 1.1.1.1
nameserver 8.8.8.8
options timeout:1 attempts:2 - 容器内DNS常继承宿主机,但Docker会覆盖
/etc/resolv.conf;可通过--dns参数或/etc/docker/daemon.json统一设置 - 验证是否生效:用
getent hosts example.com绕过缓存直调解析逻辑,比nslookup更能反映真实流程
调试与验证方法
定位DNS问题时,分层检查更高效:
- 确认
/etc/nsswitch.conf中hosts行未禁用dns,且顺序符合预期 - 运行
strace -e trace=connect,getaddrinfo -s trace=connect getent hosts google.com 2>&1 | grep -i "connect\|resolv"观察实际连接的DNS地址 - 用
systemd-resolve --status(若启用systemd-resolved)或resolvectl status查看当前生效的解析配置 - 临时测试某DNS:用
dig @8.8.8.8 google.com +short或nslookup google.com 1.1.1.1跳过本地配置验证上游连通性










