
假设你已将网站迁移到新服务器,并想在切换公共 DNS 记录之前确认一切正常。或者你想为本地网络中的一台机器起一个简短易记的名称。在这两种情况下,你都可以通过在 hosts 文件中添加一行,完全不接触 DNS 就告诉计算机某个域名指向哪里。
hosts 文件将域名(主机名)映射到 IP 地址。它是包括 Linux、Windows 和 macOS 在内的所有主流操作系统都使用的一个纯文本文件。
hosts 文件优先于 DNS。当你输入想要访问的网站域名时,操作系统首先检查其 hosts 文件中是否有对应的域名。如果没有匹配条目,它才会查询配置的 DNS 服务器来解析名称。这仅影响进行更改的那台计算机,而不影响该域名在全球范围内的解析方式。
在本文中,我们将提供在 Linux、macOS 和 Windows 上修改 hosts 文件的说明。
快速参考
| 任务 | 值 |
|---|---|
| hosts 文件路径(Linux / macOS) | /etc/hosts |
| hosts 文件路径(Windows) | C:\Windows\System32\drivers\etc\hosts |
| 在 Linux / macOS 上打开 | sudo nano /etc/hosts |
| 刷新 DNS 缓存(Linux,systemd-resolved) | sudo resolvectl flush-caches |
| 刷新 DNS 缓存(macOS) | sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder |
| 条目格式 | IP_ADDRESS hostname [aliases] |
| 屏蔽网站 | 0.0.0.0 ads.example.com |
| 注释一行 | # This is a comment |
hosts 文件格式
hosts 文件中的条目采用以下格式:
IPAddress DomainName [DomainAliases]
IP 地址和域名之间必须至少有一个空格或制表符分隔。一行可以在域名之后包含一个或多个以空格分隔的别名。以 # 开头的行是注释,会被忽略。
一个示例 hosts 文件如下所示:
# Static table lookup for hostnames. # See hosts(5) for details. 127.0.0.1 localhost 127.0.1.1 linuxize.desktop linuxize # Custom entries 192.168.1.10 server.example.com server ::1 localhost ip6-localhost ip6-loopback
第一行是每个系统都自带的那一行:它将 localhost 映射到 IPv4 回环地址,以便程序能通过名称访问本机。在 Debian 和 Ubuntu 桌面安装中出现的 127.0.1.1 一行,映射的是机器自身的主机名。当你更改主机名时,也要更新这一行。
关于格式的几个要点:
• IPv4 与 IPv6:该文件同时支持两者。对 IPv6 回环地址使用 ::1。 • 多个别名:一个 IP 地址可以在同一行拥有多个主机名:192.168.1.10 server server.local dev。 • 屏蔽:将域名映射到 0.0.0.0 以屏蔽它:0.0.0.0 ads.example.com。这是屏蔽列表中的通常约定。在 Linux 上,到 0.0.0.0 的连接仍会到达本机,因此如果你计算机上的 Web 服务器监听所有接口,它会应答被屏蔽的请求。
hosts 文件的更改对新连接立即生效,但当 DNS 条目被浏览器或其他应用程序缓存时除外。
要撤销任何更改,请打开文件并删除你添加的行。
hosts 文件与 DNS 查找顺序
hosts 文件之所以在 DNS 之前被检查,是因为系统是这样配置的,而不是因为文件本身有任何特殊之处。在 Linux 上,查找顺序由 /etc/nsswitch.conf 中的 hosts: 行设置。要查看它,请运行:
grep ^hosts /etc/nsswitch.conf
在 Ubuntu 26.04 上,输出如下所示:
hosts: files mdns4_minimal [NOTFOUND=return] dns
源会从左向右依次尝试。files 是 /etc/hosts 文件,mdns4_minimal 通过组播 DNS 处理 .local 名称,dns 将查询发送到配置的 DNS 服务器。由于 files 排在第一位,在 /etc/hosts 中成功查找到就会在查询 DNS 之前停止搜索。
IPv4 和 IPv6 的行为取决于解析器以及应用程序请求地址的方式。使用 glibc 且 files 后接直接 DNS 查询时,如果 hosts 文件只包含 IPv4 条目,仅 IPv6 的查找可能会继续到 DNS。当 systemd-resolved 处理查找并启用了 hosts 文件支持时,它会针对 /etc/hosts 中的名称在本地应答,而不会为其地址向上游 DNS 查询。不要假定 IPv4 条目会在每个系统上都覆盖 IPv6 解析;如果你需要同时覆盖两者,请在单独的行上添加预期的 IPv6 地址。
常见用例
在 DNS 传播前测试网站 将网站迁移到新服务器时,你可以在本地 hosts 文件中将域名指向新服务器的 IP,以便在更新公共 DNS 记录之前验证其是否正常工作。只有你的机器使用新 IP;其他所有人仍看到旧服务器。
本地开发 将友好的本地域名映射到 127.0.0.1,使你的开发环境可通过易读地址访问:
127.0.0.1 myapp.test 127.0.0.1 api.myapp.test
.test 顶级域被保留用于此类用途,永远不会被公开注册。避免使用 .local,它被保留用于组播 DNS,并可能导致查找缓慢,尤其是在 macOS 上。
屏蔽网站 将不需要的域名映射到 0.0.0.0,将它们从真实服务器重定向开:
0.0.0.0 ads.example.com 0.0.0.0 tracker.example.com
覆盖特定主机的 DNS 强制让主机名解析到特定 IP,而不管 DNS 返回什么,这对于内部服务器、测试负载均衡器或绕过 DNS 传播延迟很有用。
在 Linux 中修改 hosts 文件
在 Linux 上,该文件的完整路径是 /etc/hosts。
以下说明适用于所有 Linux 发行版,包括 Ubuntu、Debian、Fedora、RHEL 和 Linux Mint。
sudo nano /etc/hosts
如果你只需添加单个条目,根本不需要打开编辑器。将这一行通过管道传给带有 -a 选项的 tee 命令,它会将内容追加到文件末尾:
echo
"192.168.1.10 server.example.com"
|
sudo tee -a /etc/hosts
务必使用 -a。没有它,tee 会覆盖整个文件并删除现有条目,包括 localhost。
在 Windows 中修改 hosts 文件
在 Windows 上,该文件的完整路径是 C:\Windows\System32\drivers\etc\hosts。以下说明适用于 Windows 10 和 Windows 11。
C:\Windows\System32\drivers\etc\hosts
Windows 会自动获取更改,因此通常不需要单独的 DNS 刷新步骤。如果旧 IP 地址仍然存在,请以管理员身份打开命令提示符并运行 ipconfig /flushdns。如果你的浏览器缓存了旧 IP,请关闭并重新打开它。
在 macOS 中修改 hosts 文件
在 macOS 上,该文件的完整路径是 /etc/hosts。以下说明适用于所有近期 macOS 版本。
sudo nano /etc/hosts
验证 hosts 文件更改
编辑 hosts 文件后,请验证主机名是否解析到你输入的 IP 地址。在 Linux 上,用以下命令检查示例中的 IPv4 条目:
getent ahostsv4 server.example.com
对于示例条目,输出如下所示:
192.168.1.10 STREAM server.example.com 192.168.1.10 DGRAM 192.168.1.10 RAW
每一行都针对不同的套接字类型显示相同的 IP 地址。getent ahostsv4 命令使用系统配置的名称解析源并请求 IPv4 地址,因此你可以检查结果是否与你的条目匹配。普通的 getent hosts 会先尝试 IPv6,并且在 IPv4 条目不抑制 IPv6 查找的系统上可能返回 DNS 答案。
在 Linux 或 macOS 上,你也可以用以下命令测试:
ping -c
1
server.example.com
输出第一行显示主机名解析到的 IP 地址。要将你的本地覆盖与公共 DNS 比较,请对显式的外部解析器使用 dig。将 example.com 替换为你正在测试的公开域名:
dig @1.1.1.1 example.com A
@1.1.1.1 参数将查询发送到 Cloudflare 的公共解析器,A 请求 IPv4 记录。你也可以用 nslookup 指定 DNS 服务器。如果没有显式服务器,这些工具会使用配置的解析器,它可能是本地 systemd-resolved 存根并返回你的 hosts 文件覆盖。
如果主机名仍解析到旧地址,请刷新 DNS 缓存并重启你正在测试的浏览器或应用程序。某些应用程序独立于操作系统缓存 DNS。
故障排查
更改未生效 最常见的原因是浏览器或操作系统中缓存了 DNS 响应。使用上面相关章节中的命令刷新 DNS 缓存,然后关闭并重新打开浏览器。某些应用程序维护自己的 DNS 缓存,可能需要重启。
保存文件时出现 "Permission denied" hosts 文件需要管理员权限才能编辑。在 Linux 和 macOS 上,请始终用 sudo 打开它。在 Windows 上,在打开文件之前请确保记事本以管理员身份运行。
域名在浏览器中仍解析到旧 IP 浏览器独立于操作系统缓存 DNS。编辑 hosts 文件并刷新操作系统缓存后,请打开一个新的浏览器窗口或清除浏览器的 DNS 缓存。在 Chrome 中,前往 chrome://net-internals/#dns 并点击 Clear host cache。
Vim 中的 "E212: Can't open file for writing" 你在没有 sudo 的情况下在 Vim 中打开了 /etc/hosts,因此 Vim 无法保存它。要在不丢失编辑内容的情况下保存,请输入 :w !sudo tee %,输入你的密码,然后用 :q! 退出。下次请用 sudo vim /etc/hosts 打开文件。有关更多保存选项,请参阅如何在 Vim 中保存文件。
常见问题
编辑 hosts 文件会影响网络上的其他用户吗?不会。hosts 文件只影响进行编辑的那台计算机。网络上的其他设备继续正常使用 DNS。
用于屏蔽时,127.0.0.1 和 0.0.0.0 有什么区别?两者都有效,而 0.0.0.0 是屏蔽列表中更常见的选择,因为它不是一个真实的目的地址。两者都不能保证失败:在 Linux 上,到任一地址的连接都会到达本机,因此监听所有接口的本地 Web 服务器都会应答。如果没有任何进程在监听,两种情况都会立即拒绝连接。
如何撤销 hosts 文件的更改?用 sudo nano /etc/hosts(Linux/macOS)或以管理员身份运行的记事本(Windows)打开文件,删除你添加的行,保存文件,并刷新 DNS 缓存。
编辑 hosts 文件后需要重启计算机吗?不需要。更改对新连接立即生效。你只需要在旧结果被缓存时刷新 DNS 缓存,并在浏览器独立缓存了 DNS 响应时重启浏览器。
我可以在同一行添加多个域名吗?可以。你可以在主主机名之后在同一行添加多个别名(以空格分隔):192.168.1.10 server server.local dev.example.com。所有别名都解析到同一个 IP 地址。
结论
在测试迁移后移除临时的 hosts 文件条目,以便你的计算机遵循未来的 DNS 更改。如果某个应用程序仍在使用旧地址,请在再次检查前清除其缓存的结果。