Encrypt DNS in iOS 14 applications
In iOS 14, Apple introduced support for passing the DNS queries over HTTPS (DoH) or TLS (DoT). So why bother encrypting DNS queries when HTTPS is widely in use?
In iOS 14, Apple introduced support for passing the DNS queries over HTTPS (DoH) or TLS (DoT). So why bother encrypting DNS queries when HTTPS is widely in use? Because if someone (ISPs, on-path routers, law enforcement agency, etc.) is eavesdropping on your application's unencrypted DNS queries, they will be able to map which API / services your application uses and potentially "map" your service.
You can read more about DoH and DoT here
Unencrypted DNS
To better understand how easy it is for someone to eavesdrop on unencrypted DNS queries, let's run the following sample code:
import UIKit
import Network
import PlaygroundSupport
let url = URL(string: "https://stackoverflow.com/questions/24058336/how-do-i-run-asynchronous-callbacks-in-playground")!
let config = URLSessionConfiguration.default
config.requestCachePolicy = .reloadIgnoringLocalCacheData
config.urlCache = nil
let session = URLSession.init(configuration: config)
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print(error ?? "Unknown error")
return
}
let contents = String(data: data, encoding: .utf8)
print(contents!)
PlaygroundPage.current.finishExecution()
}.resume()
PlaygroundPage.current.needsIndefiniteExecution = true
To eavesdrop on the DNS queries, we will use Wireshark, a well-known network protocol analyzer.
As you can see in the figure below, Wireshark mapped the service and its IP addresses used in the sample code easily.
Moreover, since the DNS messages are unprotected, other attacks are possible:
- Queries could be directed to a resolver that performs DNS hijacking.
- Firewalls can easily intercept, block or modify any unencrypted DNS traffic based on the port number alone.
Encrypted DNS using DoH/DoT
Encrypted DNS (DoH or DoT) mitigates the privacy issue illustrated above. To decide which one is better to use, you can read multiple articles on the web that compare DoH to DoT, but it all boils down to these points:
- DNS over TLS may seem faster as it's one level lower, but based on benchmarks, that's not the case.
- It's harder for mediators to monitor and censor DNS queries if it's DNS over HTTPS. It looks like regular HTTPS traffic, while DNS over TLS requires separate port usage, namely: 853.
- Even with encrypted DNS, TLS connections contain unencrypted domain names (SNI). TLS 1.3 mitigates it.
Based on the above, DoH is a definite winner. 🤖
On iOS 14, to make use of DoH, we need to configure the NWParameters.PrivacyContext
with a DNS (which supports DoH) resolver's central host HTTPS and its backup hosts IPs.
import UIKit
import Network
import PlaygroundSupport
enum DoHConfigurarion: Hashable {
case cloudflare
var httpsURL: URL {
switch self {
case .cloudflare:
return URL(string: "https://cloudflare-dns.com/dns-query")!
}
}
var serverAddresses: [NWEndpoint] {
switch self {
case .cloudflare:
return [
NWEndpoint.hostPort(host: "1.1.1.1", port: 443),
NWEndpoint.hostPort(host: "1.0.0.1", port: 443),
NWEndpoint.hostPort(host: "2606:4700:4700::1111", port: 443),
NWEndpoint.hostPort(host: "2606:4700:4700::1001", port: 443)
]
}
}
}
let url = URL(string: "https://stackoverflow.com/questions/24058336/how-do-i-run-asynchronous-callbacks-in-playground")!
let secureDNS = DoHConfigurarion.cloudflare
NWParameters.PrivacyContext.default.requireEncryptedNameResolution(
true,
fallbackResolver: .https(
secureDNS.httpsURL,
serverAddresses: secureDNS.serverAddresses
)
)
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print(error ?? "Unknown error")
return
}
let contents = String(data: data, encoding: .utf8)
print(contents!)
PlaygroundPage.current.finishExecution()
}.resume()
PlaygroundPage.current.needsIndefiniteExecution = true
Running the sample code using DoH configuration resulted in Wireshark failing to pick up any of the DNS queries made.
🎉 🎊🎉 🎊🎉 🎊🎉 🎊🎉 🎊🎉 🎊
For applying encrypted DNS using the Network framework, you can take a look at Apple's WWDC 2020 session: Enable encrypted DNS.
Many DNS resolvers, such as Google, Cloudflare, Alibaba, etc., support encrypted DNS. Therefore, we have created an enum that implements NWParameters.PrivacyContext
configuration for each provider, for your convenience.
In summary, iOS14 added support for encrypted DNS and, in particular, DoH, which enhances privacy significantly. We strongly recommend using it in your applications, and if you still have concerns, Apple teamed up with Cloudflare and Fastly to further improve DoH by introducing Oblivious DoH.
Thanks for reading!