为什么 Chromium 没有缓存 DNS 超过一分钟?

use*_*421 27 cache dns chrome

我使用 Chromium 并且遇到了 DNS 没有在我期望的时间内被缓存的问题。以 example.com 域为例。根据 DNS 设置,此域应再缓存 26151 秒:

$ dig example.com

;; ANSWER SECTION:
example.com.        26151   IN  A   93.184.216.34
Run Code Online (Sandbox Code Playgroud)

但是,当我在 Chromium 中打开 example.com 并打开 chrome://net-internals/#dns 时,IP 会在一分钟内忘记!

在此处输入图片说明

为什么 Chromium 不遵守域的 DNS 设置的 TTL?如何强制它缓存 DNS 数据直到它们过期?

Rui*_*iro 33

Chromium/Chrome 确实不会缓存超过一分钟的 DNS 请求。

有趣的是,来自bugs-chromium - 问题 164026 - DNS TTL 从 2011 年 4 月 21 日起未兑现

系统中唯一的 DNS 缓存是 chrome,它不支持 TTL。我们需要修复 chrome 和/或添加一个可以正确处理 TTL 的中间缓存。

2012 年 12 月 4 日票中的答案:

HostCache 当前假定所有正面结果的 TTL=60s。对于异步 DNS 解析器,我们计划使用 TTL=max(60s, server_reported_ttl),即至少 60s。其基本原理是提高缓存性能。(当一个 CDN NS 提供 TTL=10-20s,并且获取所有子资源需要 30s+ 时,我们经常需要在一个页面加载期间重新查询相同的主机名。)

门票于 2013 年 10 月 10 日关闭:

CrOS 上的 Chrome 使用异步 DNS 解析器,它遵循 TTL = max(60s, > server_reported_ttl)

我将其作为 WontFix 关闭(已过时/按预期工作)。

多年来,这一直是一个已知问题。他们的内部 DNS 解析器会忽略 DNS 记录的 TTL,并且只缓存 DNS 请求 1 分钟。

多年来,用户一直在要求更改默认行为的功能,而 Google 从未创建过。

过去,您可以在 中禁用内部 DNS 解析器chrome://flags,现在功能上不再公开。

总结一下,它是一个功能,例如,它是通过设计实现的。

(我最初写的它永远不会被更改,这显然不是真的。一个真正有决心的人可以重新编译 Chromium 或破解 Chrome 二进制文件。)。

因此,作为附录:有大量文件证明 Google 工程师不打算尊重 Chrome/ium 中收到的 DNS 答案中的默认 TTL。

来自DNS 查询的负缓存 (DNS NCACHE)

与缓存正面响应一样,解析器限制它缓存负面响应的时间是明智的......

虽然暗示解析器可能/应该对缓存 DNS 答案施加最大限制,但 Google Chrome 上的 1 分钟限制可能太低了。

PS 我实际上在检索 Chrome 统计信息以回答这个问题时发现了多年来一直困扰我的问题的答案:Chrome:具有随机 DNS 名称的 DNS 请求:恶意软件?

PPS 从下面的代码中,很明显否定答案没有被缓存(TTL=0)。

来自https://chromium.googlesource.com/chromium/src/net/dns/host_resolver_impl.cc

  99 // Default TTL for successful resolutions with ProcTask.
 100 const unsigned kCacheEntryTTLSeconds = 60;
 101 
 102 // Default TTL for unsuccessful resolutions with ProcTask.
 103 const unsigned kNegativeCacheEntryTTLSeconds = 0;
 104 
 105 // Minimum TTL for successful resolutions with DnsTask.
 106 const unsigned kMinimumTTLSeconds = kCacheEntryTTLSeconds;

1518   // Called by ProcTask when it completes.
1519   void OnProcTaskComplete(base::TimeTicks start_time,
1520                           int net_error,
1521                           const AddressList& addr_list) {
1522     DCHECK(is_proc_running());
1523 
1524     if (dns_task_error_ != OK) {
1525       base::TimeDelta duration = base::TimeTicks::Now() - start_time;
1526       if (net_error == OK) {
1527         UMA_HISTOGRAM_LONG_TIMES_100("AsyncDNS.FallbackSuccess", duration);
1528         if ((dns_task_error_ == ERR_NAME_NOT_RESOLVED) &&
1529             ResemblesNetBIOSName(key_.hostname)) {
1530           UmaAsyncDnsResolveStatus(RESOLVE_STATUS_SUSPECT_NETBIOS);
1531         } else {
1532           UmaAsyncDnsResolveStatus(RESOLVE_STATUS_PROC_SUCCESS);
1533         }
1534         base::UmaHistogramSparse("Net.DNS.DnsTask.Errors",
1535                                  std::abs(dns_task_error_));
1536         resolver_->OnDnsTaskResolve(dns_task_error_);
1537       } else {
1538         UMA_HISTOGRAM_LONG_TIMES_100("AsyncDNS.FallbackFail", duration);
1539         UmaAsyncDnsResolveStatus(RESOLVE_STATUS_FAIL);
1540       }
1541     }
1542 
1543     if (ContainsIcannNameCollisionIp(addr_list))
1544       net_error = ERR_ICANN_NAME_COLLISION;
1545 
1546     base::TimeDelta ttl =
                                              # always  0 seconds
1547         base::TimeDelta::FromSeconds(kNegativeCacheEntryTTLSeconds);
1548     if (net_error == OK)
                                              # always 60 seconds 
1549       ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds);  
1550 
1551     // Source unknown because the system resolver could have gotten it from a
1552     // hosts file, its own cache, a DNS lookup or somewhere else.
1553     // Don't store the |ttl| in cache since it's not obtained from the server.
1554     CompleteRequests(
1555         MakeCacheEntry(net_error, addr_list, HostCache::Entry::SOURCE_UNKNOWN),
1556         ttl);
1557   }
Run Code Online (Sandbox Code Playgroud)

  • 令人遗憾的是,chrome 根本没有进行 dns 缓存。每当我对 NS 进行快速更改并刷新 dns 缓存时,我总是必须牢记 chrome 自己也这样做。 (5认同)
  • 对我来说有趣的是,chrome 正在缓存基于某些域的 TTL 的 DNS 查找,例如这个域`dougblack.io`,所以可能完整的规则有点复杂。但是 100 个域中有 99 个的行为与您描述的一样。 (4认同)
  • Chrome 会发出看似随机的 DNS 请求,以确定它是否位于劫持所有 DNS 请求的网络上(例如某些付费无线接入点)。另外,我认为您在配置中查看的“超时”值是 DNS 服务器响应的 1 秒超时,而不是 1 分钟的 TTL。 (2认同)
  • @OleK - 我有点同意,但同时我可以看到哪里很短......比如说,60 秒左右:),缓存是一个好主意(以节省一点网络流量)并且仍然允许诸如循环之类的事情dns等工作 (2认同)