DNS

運作流程

推薦閱讀 How DNS works 網站, 裡面用漫畫的方式來呈現, 以可愛的圖像來說明 DNS 的運作。

實做

mDNS (Multicast DNS)

mDNS 是在 RFC 6762 中定義的協議, 藉由 multicast UDP 來在 local network 裡尋找對應的服務, 此作法不需要 DNS server, 也不需要額外的設定。 (經由 mDNS 可以達成 Service Discovery 的效果)

由於是使用 UDP, 所以在網路中沒有對應的服務時並不會 block, 若有人收到並回應的話才進行後續處理。 mDNS 預設只處理 .local TLD 的網域。

相關實做:

相關使用:

  • AirPlay

  • AirPrint

  • Google Cast

  • Cloud Print

相關連結:

常見 DNS 設定

  • Cloudflare: 1.1.1.1

  • Google: 8.8.8.8

讓 NetworkManager 使用 systemd-resolved

開啟 systemd-resolved

sudo systemctl enable systemd-resolved
sudo systemctl start systemd-resolved
systemd-resolve --status
systemd-resolve --statistics
systemd-resolve en.wikipedia.org

設定 NetworkManager 的 DNS 使用 systemd-resolved

/etc/NetworkManager/conf.d/dns.conf

[main]
dns=systemd-resolved
sudo systemctl restart NetworkManager

/etc/resolv.conf

1983 年,4.3BSD 釋出時包含了第一個通用的 Unix IP stack, 也成為現代 Unix-like 系統網路實做的基礎, 其中 resolv.conf 是其中一部分。

/etc/resolv.conf 的處理是 libc 的一部分, 實做可以參考 musl:

Trust-DNS

Trust-DNS 是用 Rust 實做的 DNS client/server。

Resolver

主要的型別為 Resolver , DNS 主機設定為 ResolverConfig , DNS query 調整為 ResolverOpts (例如 TTL、要不要使用 /ect/hosts )。

ResolverConfig 提供了一些預設的 DNS 設定, 例如 Google、Cloudflare、Quad9, 也可以選擇 DNS over TLS 或是 DNS over HTTPS。

範例:

////////////////////////////////////////
// 1. 全部用預設
////////////////////////////////////////

// Construct a new Resolver with default configuration options
let resolver = Resolver::new(ResolverConfig::default(), ResolverOpts::default()).unwrap();
// Lookup the IP addresses associated with a name.
// The final dot forces this to be an FQDN, otherwise the search rules as specified
// in `ResolverOpts` will take effect. FQDN's are generally cheaper queries.
// Return type is `ResolveResult<LookupIp>`
let response = resolver.lookup_ip("www.example.com.").unwrap();
// There can be many addresses associated with the name,
//  this can return IPv4 and/or IPv6 addresses
let address = response.iter().next().expect("no addresses returned!");
if address.is_ipv4() {
    assert_eq!(address, IpAddr::V4(Ipv4Addr::new(93, 184, 216, 34)));
} else {
    assert_eq!(address, IpAddr::V6(Ipv6Addr::new(0x2606, 0x2800, 0x220, 0x1, 0x248, 0x1893, 0x25c8, 0x1946)));
}

////////////////////////////////////////
// 2. 使用 /etc/resolv.conf 的設定
////////////////////////////////////////

// Use the host OS'es `/etc/resolv.conf`
let resolver = Resolver::from_system_conf().unwrap();
let response = resolver.lookup_ip("www.example.com.").unwrap();

////////////////////////////////////////
// 3. 使用 Cloudflare
////////////////////////////////////////

let resolver = Resolver::new(ResolverConfig::cloudflare(), ResolverOpts::default()).unwrap();
let response = resolver.lookup_ip("www.example.com.").unwrap();

////////////////////////////////////////
// 3. 使用 Cloudflare 的 DNS over HTTPS
////////////////////////////////////////

let resolver = Resolver::new(ResolverConfig::cloudflare_https(), ResolverOpts::default()).unwrap();
let response = resolver.lookup_ip("www.example.com.").unwrap();