すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud DNS:iOS 14 ネイティブ暗号化 DNS ソリューション

最終更新日:Nov 09, 2025

このドキュメントでは、iOS 14 のネイティブ暗号化 DNS ソリューションを統合および開発する方法について説明します。

概要

DNS 名前解決は、ネットワーク リソースにアクセスするための最初のホップです。 iOS 14 以降、システムは 2 つの標準暗号化 DNS プロトコル(DNS over TLS(DoT)と DNS over HTTPS(DoH))をネイティブでサポートしています。 これらのプロトコルは、次の 2 つの問題に対処できます。

第一に、従来のローカル DNS クエリとレスポンスは暗号化されていない UDP に基づいており、一般的な DNS ハイジャックにつながる可能性があります。

第二に、ローカル DNS サーバー自体が信頼できない場合や、ローカル DNS サービスが利用できない場合があります。

これらの問題に対処するために、HTTPDNSHTTPDNS ソフトウェア開発キット (SDK) を使用するソリューションを提供します。しかし、SDK の使用には、302 リダイレクトシナリオでの直接 IP 接続の処理や iOS でのサーバー名表示 (SNI) の問題など、技術的な課題があります。iOS 14 の暗号化 DNS 機能は、SDK 統合ソリューションに関連する問題を効果的に解決します。以下の例では、HTTPDNS をデフォルトの暗号化 DNS リゾルバーとして設定する方法を示します。

警告
  1. iOS 14 ネイティブ暗号化 DNS ソリューションは、iOS 14 以降を実行している物理デバイスでのみサポートされています。

  2. アプリが期待どおりに動作することを保証するために、DoH または DoT サービスの例外によって発生するドメイン名解決の失敗を防ぐために、ローカル DNS へのフォールバック メカニズムを実装する必要があります。

  3. SDK 統合ソリューションと比較して、ネイティブ ソリューションは自動サービス フェールオーバーをサポートしておらず、サービスレベル契約(SLA)も提供していません。 ビジネスにネイティブ ソリューションを使用する場合は、サービス例外の監視とドメイン名解決のためのデバイスのローカル DNS への自動フェールオーバーのコードを実装する必要があります。

HTTPDNS を iOS 14 ネイティブ暗号化 DNS ソリューションと統合する方法

iOS 14 は、暗号化 DNS を設定するための 2 つの方法を提供しています。

  • 単一アプリのすべての接続に対して暗号化 DNS を有効にする。

デバイス全体ではなく、アプリのみに暗号化 DNS を使用するには、NetworkExtension の nw_privacy_context_t を調整して、アプリの暗号化 DNS を有効にすることができます。 アプリ内で開始されたすべての DNS 名前解決はこの構成を使用します。 参考までに、単一アプリのすべての接続に対して DoH を有効にするデモ を提供しています。

DoH プロトコルを使用してアプリ レベルで暗号化 DNS を使用するためのサンプル コード:

#import <NetworkExtension/NetworkExtension.h>
if (@available(iOS 14.0, *)){
        nw_privacy_context_t defaultPrivacyContext = NW_DEFAULT_PRIVACY_CONTEXT;
        nw_endpoint_t dohResolverEndpoint = nw_endpoint_create_url("https://*****-************.alidns.com/dns-query");//DoH 暗号化アドレス
        nw_endpoint_t v4ResolverEndpoint1 = nw_endpoint_create_host("223.5.5.5", "443");
        nw_endpoint_t v4ResolverEndpoint2 = nw_endpoint_create_host("223.6.6.6", "443");
        nw_endpoint_t v6ResolverEndpoint1 = nw_endpoint_create_host("2400:3200::1", "443");
        nw_endpoint_t v6ResolverEndpoint2 = nw_endpoint_create_host("2400:3200:baba::1", "443");
        nw_resolver_config_t fallbackResolvers = nw_resolver_config_create_https(dohResolverEndpoint);
        nw_resolver_config_add_server_address(fallbackResolvers, v4ResolverEndpoint1);
        nw_resolver_config_add_server_address(fallbackResolvers, v4ResolverEndpoint2);
        nw_resolver_config_add_server_address(fallbackResolvers, v6ResolverEndpoint1);
        nw_resolver_config_add_server_address(fallbackResolvers, v6ResolverEndpoint2);
        nw_privacy_context_require_encrypted_name_resolution(defaultPrivacyContext, true, fallbackResolvers);
    }

DoT プロトコルを使用してアプリ レベルで暗号化 DNS を使用するためのサンプル コード:

#import <NetworkExtension/NetworkExtension.h>
if (@available(iOS 14.0, *)){
        nw_privacy_context_t defaultPrivacyContext = NW_DEFAULT_PRIVACY_CONTEXT;
        nw_endpoint_t dotResolverEndpoint = nw_endpoint_create_host("******-************.alidns.com", "853");//DoT 暗号化アドレス
        nw_endpoint_t v4ResolverEndpoint1 = nw_endpoint_create_host("223.5.5.5", "853");
        nw_endpoint_t v4ResolverEndpoint2 = nw_endpoint_create_host("223.6.6.6", "853");
        nw_endpoint_t v6ResolverEndpoint1 = nw_endpoint_create_host("2400:3200::1", "853");
        nw_endpoint_t v6ResolverEndpoint2 = nw_endpoint_create_host("2400:3200:baba::1", "853");
        nw_resolver_config_t fallbackResolvers = nw_resolver_config_create_tls(dotResolverEndpoint);
        nw_resolver_config_add_server_address(fallbackResolvers, v4ResolverEndpoint1);
        nw_resolver_config_add_server_address(fallbackResolvers, v4ResolverEndpoint2);
        nw_resolver_config_add_server_address(fallbackResolvers, v6ResolverEndpoint1);
        nw_resolver_config_add_server_address(fallbackResolvers, v6ResolverEndpoint2);
        nw_privacy_context_require_encrypted_name_resolution(defaultPrivacyContext, true, fallbackResolvers);
    }

次のコードは、ローカル DNS へのフォールバック メカニズムを実装する方法を示しています。 URLSessionDelegate を介して NSURLSessionTaskTransactionMetrics を取得し、リクエストが失敗した後に DoH または DoT を無効にすることができます。

#pragma mark URLSession Delegate
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics {
    if ([metrics.transactionMetrics count] <= 0) return;
    [metrics.transactionMetrics enumerateObjectsUsingBlock:^(NSURLSessionTaskTransactionMetrics *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
        if (obj.resourceFetchType == NSURLSessionTaskMetricsResourceFetchTypeNetworkLoad) {
            if (@available(iOS 14.0, *)) {
                NSURLSessionTaskMetricsDomainResolutionProtocol dnsProtocol = obj.domainResolutionProtocol;
                NSLog(@"%@",[NSString stringWithFormat:@"DNS タイプは %ld です", (long)dnsProtocol]);
                NSLog(@"%@",[NSString stringWithFormat:@"0:不明、1:UDP、2:TCP、3:TLS、4:HTTPS"]);
                if (dnsProtocol == NSURLSessionTaskMetricsDomainResolutionProtocolUnknown) {
                    NSLog(@"%@",[NSString stringWithFormat:@"DNS ソースが不明なため、DoH を無効にします"]);
                    nw_privacy_context_require_encrypted_name_resolution(NW_DEFAULT_PRIVACY_CONTEXT, false, nil);
                }
            }
        }
    }];
}
  • デバイス上のすべてのアプリケーションに対して暗号化 DNS を有効にする。

システム全体で暗号化 DNS を使用する場合、NEDNSSettingsManager API を使用してシステム全体の暗号化 DNS 設定を構成する NetworkExtension アプリを作成できます。

DoH プロトコルを使用して NetworkExtension を介してシステム全体の DNS サーバーを設定するサンプル コード:

import NetworkExtension

NEDNSSettingsManager.shared().loadFromPreferences { loadError in
            if let loadError = loadError {
                // ...エラー処理...
                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://*****-************.alidns.com/dns-query")//DoH 暗号化アドレス
            NEDNSSettingsManager.shared().dnsSettings = dohSettings
            NEDNSSettingsManager.shared().saveToPreferences { saveError in
                if let saveError = saveError {
                  // ...エラー処理...
                  return
                }
            }
        }

NetworkExtension と DoT プロトコルを使用して、システム全体の DNS サーバを設定するコード例:

import NetworkExtension

NEDNSSettingsManager.shared().loadFromPreferences { loadError in
            if let loadError = loadError {
                // ...エラー処理...
                return
            }
            let dotSettings = NEDNSOverTLSSettings(servers: ["223.5.5.5","223.6.6.6","2400:3200:baba::1","2400:3200::1"])
            dotSettings.serverName = "******-************.alidns.com"//DoT 暗号化アドレス
            NEDNSSettingsManager.shared().dnsSettings = dotSettings
            NEDNSSettingsManager.shared().saveToPreferences { saveError in
                if let saveError = saveError {
                  // ...エラー処理...
                  return
                }
            }
        }

DNS 構成には、HTTPDNS サーバーアドレス、DoT または DoH プロトコル、および一連のネットワークルールが含まれます。ネットワークルールは、DNS 設定がさまざまなネットワークと互換性があることを保証します。

ネットワーク ルール構成のコード例:

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
      ]

上記のコードは 3 つのネットワークルールを設定します。最初のルールでは、DNS 構成は SSID が "MyWorkWiFi" の Wi-Fi ネットワークで有効になりますが、非公開のエンタープライズドメイン名 enterprise.example.net に対しては有効になりません。2 番目のルールでは、構成はセルラーネットワークで無効になります。3 番目のルールである NEOnDemandRuleConnect は、DNS 構成がデフォルトで有効になることを指定します。DNS 構成はシステムでサポートされているため、NetworkExtension アプリを作成する際に拡張プログラムを実装する必要はありません。Network Extensions で「DNS 設定」オプションを選択するだけです。

setNetworkExtension

NetworkExtension アプリを実行すると、DNS 構成がシステムにインストールされます。この構成を有効化するには、「設定」→「一般」→「VPNとネットワーク」→「DNS」の順に移動し、手動で有効にする必要があります。

share