linux系统中/etc/hosts是否优先解析取决于/etc/nsswitch.conf中hosts行是否配置为files在前,如hosts: files dns;files对应/etc/hosts,dns对应/etc/resolv.conf,修改后需用getent hosts验证生效。

Linux 系统默认就支持用 /etc/hosts 优先解析,但是否真能优先,取决于 nsswitch.conf 的配置,而不是 hosts 文件本身有没有改。
关键不是“怎么让系统用 hosts”,而是“确保它按你期望的顺序查 hosts 再查 DNS”。
确保 /etc/nsswitch.conf 启用并前置 files
打开 /etc/nsswitch.conf:
sudo nano /etc/nsswitch.conf
找到这一行:
hosts: files dns
✅ 正确含义:先查 /etc/hosts(files 源),命中即返回;没找到再走 DNS。
❌ 错误写法举例:hosts: dns(跳过 hosts)、hosts: dns files(DNS 优先)、hosts:(空行或缺失)。
⚠️ 注意:
files对应的就是/etc/hosts;dns对应/etc/resolv.conf中的 nameserver;resolve通常指systemd-resolved服务。
检查 /etc/hosts 格式是否合规
哪怕只错一个空格,整行也会被忽略:
- IP 和域名之间必须用英文空格或 Tab 分隔,不能用
=、中文空格、全角符号 - 每行只写一个 IP,后面跟主域名 + 可选别名(空格分隔)
- 注释必须独占一行,以
#开头 - 示例正确写法:
127.0.0.1 example.local dev-api.test 192.168.1.100 db.internal staging-db 0.0.0.0 tracker.ads.com
❌ 错误写法(会被跳过):
127.0.0.1=example.local # 用了等号 127.0.0.1 example.local # 全角空格(看不见) #127.0.0.1 example.local # 整行被当注释,实际没写
验证是否真走 hosts(别信 ping)
ping 可能受缓存或应用层逻辑干扰。用这个命令最准:
getent hosts example.local
它严格按 nsswitch.conf 的 hosts: 行执行,并显示来源(比如 files 表示来自 /etc/hosts)。
如果返回 IP 且来源是 files,说明配置生效;
如果返回空或来自 dns,说明要么 hosts 没匹配,要么 nsswitch.conf 没配 files,或者被 systemd-resolved 干扰。
排查常见干扰项
-
systemd-resolved 正在运行?
它可能把hosts: files dns实际变成hosts: files resolve dns,而resolve本身又依赖/etc/resolv.conf。可检查:systemctl is-active systemd-resolved ls -l /etc/resolv.conf # 若指向 127.0.0.53,说明被 stub resolver 接管
此时仍会查 hosts(只要
files在resolve前),但需确认nsswitch.conf没写成hosts: resolve [!UNAVAIL=return] files这类反序。 -
nscd 缓存未清理?
如果启用了nscd(Name Service Caching Daemon),改完 hosts 或 nsswitch.conf 后要刷新:sudo systemctl restart nscd # 或仅清 hosts 缓存 sudo nscd -i hosts
程序自己绕过系统解析?
Chrome、Electron 应用、某些 Java 或 Node.js 程序可能内置 DNS 缓存或直连 DNS。这类情况getent仍准,但curl或浏览器不一定反映 hosts 结果。
补充:屏蔽网站或开发映射的小技巧
- 屏蔽用
0.0.0.0 domain.com,比127.0.0.1更可靠(避免本地服务响应) - IPv6 场景下,记得加
::1 domain.com,否则启用 IPv6 的程序可能不走 IPv4 的127.0.0.1 - 云服务器重启后 hosts 被重写?大概率是
cloud-init自动更新,临时禁用:sudo sed -i 's/^update_etc_hosts.*$/#&/' /etc/cloud/cloud.cfg
不复杂但容易忽略。











