All Products
Search
Document Center

Alibaba Cloud DNS:Native encrypted DNS in iOS 14

Last Updated:Apr 09, 2024

This topic describes how to use Alibaba Cloud Public DNS in iOS 14 that natively supports encrypted Domain Name System (DNS).

Overview

DNS resolution is the first step for network resource access. iOS 14 natively supports two encrypted DNS protocols: DNS over TLS (DoT) and DNS over HTTPS (DoH). Encrypted DNS resolves the following issues:

DNS hijacking. Traditional local DNS queries and responses are transmitted over non-encrypted UDP, which is prone to DNS hijacking.

Untrusted local DNS servers or unavailable local DNS service.

Alibaba Cloud Public DNS provides SDKs to resolve the preceding issues that occur during DNS resolution. However, the use of Alibaba Cloud Public DNS SDKs encounters technical difficulties, such as how to handle the 302 redirect for direct IP address access, how to handle direct IP address access for WebView, and how to solve the Server Name Indication (SNI) issue in iOS. The encrypted DNS feature in iOS 14 resolves these difficulties. For more information about how to set Alibaba Cloud Public DNS as the default resolver for encrypted DNS queries, see the source code of DoHTestDemo.

Use Alibaba Cloud Public DNS in iOS 14 that natively supports encrypted DNS

You can configure encrypted DNS settings in iOS 14 by using one of the following methods:

1. Select a DNS server as the default global DNS resolver for all apps. If you use a server of Alibaba Cloud Public DNS, you can use the NEDNSSettingsManager API to write a NetworkExtension app to configure global encrypted DNS.

The following sample code shows how to use NetworkExtension to set a global DNS server by using the DoH protocol:

import NetworkExtension

NEDNSSettingsManager.shared().loadFromPreferences { loadError in
            if let loadError = loadError {
                // ...handle error...
                return
            }
            let dohSettings = NEDNSOverHTTPSSettings(servers: ["223.5.5.5","223.6.6.6","2400:3200:baba::1","2400:3200::1"])
            dohSettings.serverURL=URL (string: "https://Account ID that is assigned to you when you register your app in the Alibaba Cloud DNS console.alidns.com/dns-query")
            NEDNSSettingsManager.shared().dnsSettings = dohSettings
            NEDNSSettingsManager.shared().saveToPreferences { saveError in
                if let saveError = saveError {
                  // ...handle error...
                  return
                }
            }
        }

The following sample code shows how to use NetworkExtension to set a global DNS server by using the DoT protocol:

import NetworkExtension

NEDNSSettingsManager.shared().loadFromPreferences { loadError in
            if let loadError = loadError {
                // ...handle error...
                return
            }
            let dotSettings = NEDNSOverTLSSettings(servers: ["223.5.5.5","223.6.6.6","2400:3200:baba::1","2400:3200::1"])
            dotSettings.serverName = "Account ID that is assigned to you when you register your app on the Public DNS page of the Alibaba Cloud DNS console.alidns.com"
            NEDNSSettingsManager.shared().dnsSettings = dotSettings
            NEDNSSettingsManager.shared().saveToPreferences { saveError in
                if let saveError = saveError {
                  // ...handle error...
                  return
                }
            }
        }

The DNS settings include the server address of Alibaba Cloud Public DNS, DoT or DoH protocol, and a set of network rules. The network rules ensure that the DNS settings are compatible with different networks.

The following sample code shows how to configure network rules:

let workWiFi = NEOnDemandRuleEvaluateConnection()
     workWiFi.interfaceTypeMatch = .wiFi
     workWiFi.ssidMatch = ["MyWorkWiFi"]
     workWiFi.connectionRules = [NEEvaluateConnectionRule(matchDomains: ["enterprise.example"], andAction: .neverConnect)]
            
     let disableOnCell = NEOnDemandRuleDisconnect()
     disableOnCell.interfaceTypeMatch = .cellular
            
      let enableByDefault = NEOnDemandRuleConnect()
      NEDNSSettingsManager.shared().onDemandRules = [
                workWiFi,
                disableOnCell,
                enableByDefault
      ]

The preceding code configures three network rules. The first rule indicates that the DNS settings take effect on the Wi-Fi network whose SSID is MyWorkWiFi but do not take effect for the private enterprise domain name enterprise.example.net. The second rule indicates that the DNS settings do not take effect on a cellular network. The third rule indicates that the DNS settings take effect by default. You do not need to implement Extension when you write the NetworkExtension app. You need only to select DNS Settings in Network Extensions to allow iOS 14 to support DNS settings.

setNetworkExtension

Run the NetworkExtension app to add the DNS settings to iOS 14. You must go to Settings > General > VPN & Network > DNS and manually select the DNS settings.

share

2. Enable encrypted DNS for all or specific connections of a single app.

For example, you can enable encrypted DNS only for your app, but not all apps in the system. You can set the PrivacyContext of Network.framework to enable encrypted DNS for all or specific connections of your app.

The following sample code shows how to enable encrypted DNS for a single connection of an app by using the DoH protocol:

import Network

let privacyContext = NWParameters.PrivacyContext(description: "EncryptedDNS")
        if let url=URL (string: "https://Account ID that is assigned to you when you register your app in the Alibaba Cloud DNS console.alidns.com/dns-query") {
            let address1 = NWEndpoint.hostPort(host: "223.5.5.5", port: 443)
            let address2 = NWEndpoint.hostPort(host: "223.6.6.6", port: 443)
            let address3 = NWEndpoint.hostPort(host: "2400:3200::1", port: 443)
            let address4 = NWEndpoint.hostPort(host: "2400:3200:baba::1", port: 443)
            privacyContext.requireEncryptedNameResolution(true, fallbackResolver: .https(url, serverAddresses: [address1,address2,address3,address4]))
        }

The following sample code shows how to enable encrypted DNS for a single connection of an app by using the DoT protocol:

import Network

 let privacyContext = NWParameters.PrivacyContext(description: "EncryptedDNS")
        let alidnsHost=NWEndpoint.hostPort (host: "Account ID that is assigned to you when you register your app in the Alibaba Cloud DNS console.alidns.com", port: 853)
        let address1 = NWEndpoint.hostPort(host: "223.5.5.5", port: 853)
        let address2 = NWEndpoint.hostPort(host: "223.6.6.6", port: 853)
        let address3 = NWEndpoint.hostPort(host: "2400:3200::1", port: 853)
        let address4 = NWEndpoint.hostPort(host: "2400:3200:baba::1", port: 853)
        privacyContext.requireEncryptedNameResolution(true, fallbackResolver: .tls(alidnsHost, serverAddresses: [address1,address2,address3,address4]))

If you want to enable encrypted DNS for all connections of an app, you can use the default PrivacyContext. All DNS queries sent from the app are resolved by using PrivacyContext.

The following sample code shows how to enable encrypted DNS for all connections of an app by using the DoH protocol:

import Network

if let aliUrl=URL (string: "https://Account ID that is assigned to you when you register your app in the Alibaba Cloud DNS console.alidns.com/dns-query"){
            let address1 = NWEndpoint.hostPort(host: "223.5.5.5", port: 443)
            let address2 = NWEndpoint.hostPort(host: "223.6.6.6", port: 443)
            let address3 = NWEndpoint.hostPort(host: "2400:3200::1", port: 443)
            let address4 = NWEndpoint.hostPort(host: "2400:3200:baba::1", port: 443)
            NWParameters.PrivacyContext.default.requireEncryptedNameResolution(true, fallbackResolver: .https(aliUrl, serverAddresses: [address1,address2,address3,address4]))
            }

The following sample code shows how to enable encrypted DNS for all connections of an app by using the DoT protocol:

import Network

let alidnsHost=NWEndpoint.hostPort (host: "Account ID that is assigned to you when you register your app in the Alibaba Cloud DNS console.alidns.com", port: 853)
        let address1 = NWEndpoint.hostPort(host: "223.5.5.5", port: 853)
        let address2 = NWEndpoint.hostPort(host: "223.6.6.6", port: 853)
        let address3 = NWEndpoint.hostPort(host: "2400:3200::1", port: 853)
        let address4 = NWEndpoint.hostPort(host: "2400:3200:baba::1", port: 853)
        NWParameters.PrivacyContext.default.requireEncryptedNameResolution(true, fallbackResolver: .tls(alidnsHost, serverAddresses: [address1,address2,address3,address4]))