Dns

為什麼 Chromium 記憶體 DNS 超過一分鐘?

  • June 25, 2019

我使用 Chromium 並且在我期望的時間內沒有記憶體 DNS 的問題。以 example.com 域為例。根據 DNS 設置,此域應再記憶體 26151 秒:

$ dig example.com

;; ANSWER SECTION:
example.com.        26151   IN  A   93.184.216.34

但是,當我在 Chromium 中打開 example.com 並打開 chrome://net-internals/#dns 時,IP 會在一分鐘內被遺忘!

在此處輸入圖像描述

為什麼 Chromium 不遵守域的 DNS 設置的 TTL?如何強制它記憶體 DNS 數據直到它們過期?

Chromium/Chrome 確實不會記憶體 DNS 請求超過一分鐘。

有趣的是,來自bugs-chromium -Issue 164026 - DNS TTL not honored from Apr 21 2011

系統中唯一的 DNS 記憶體是 chrome,它不支持 TTL。我們需要修復 chrome 和/或添加一個可以正確處理 TTL 的中間記憶體。

在 2012 年 12 月 4 日的票中回答:

HostCache 目前假定所有正面結果的 TTL=60 秒。對於非同步 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   }

引用自:https://unix.stackexchange.com/questions/363498