Dokumen ini menjelaskan cara menggunakan DoH di klien iOS.
Latar Belakang
Cara umum mengintegrasikan HTTPDNS pada iOS adalah dengan mengimpor kit pengembangan perangkat lunak (SDK) HTTPDNS, lalu menangani isu-isu seperti verifikasi sertifikat HTTPS dan ekstensi Indikasi Nama Server (SNI). Pendekatan ini memungkinkan Anda memanfaatkan fitur resolusi HTTPDNS dalam aplikasi sesuai kebutuhan. Untuk informasi lebih lanjut, lihat Gunakan HTTPDNS dalam skenario iOS native.
Apple memperkenalkan DNS aman di iOS 14+, menambahkan solusi baru yang layak untuk mengintegrasikan HTTPDNS melalui DoH. Dua video WWDC berikut dapat dijadikan referensi:
Tingkatkan keamanan DNS untuk aplikasi dan server: Memperkenalkan pengetahuan dasar tentang DNS aman.
Aktifkan DNS terenkripsi: Memperkenalkan cara menggunakan DNS aman, termasuk metode implementasi tingkat sistem dan tingkat aplikasi.
Penggunaan DNS aman didukung secara asli oleh iOS, berlaku langsung pada tingkat pemrosesan jaringan global aplikasi atau perangkat tanpa memerlukan modifikasi pada detail permintaan jaringan di tingkat kode, membuat solusi ini lebih elegan secara keseluruhan. Namun, solusi ini juga memiliki keterbatasan signifikan. Jika HTTPDNS diintegrasikan melalui DNS aman:
Hanya dapat berlaku pada tingkat aplikasi atau tingkat perangkat, dan semua resolusi nama domain dalam ruang lingkup yang sesuai akan melewati HTTPDNS, termasuk permintaan jaringan dari SDK pihak ketiga dalam aplikasi, tanpa kemampuan untuk mengontrol pada tingkat granular halus.
Jika Anda memilih untuk membuatnya berlaku pada tingkat perangkat, pengguna akhir perlu memberikan izin khusus. Umumnya, hanya aplikasi utilitas jaringan yang dapat mengajukan izin ini.
Prasyarat
Aktifkan DoH dan peroleh titik akhir ingest DoH. Untuk informasi lebih lanjut, lihat Konfigurasikan layanan DoH.
Jika DoH tidak diaktifkan, permintaan resolusi akan gagal, dan server HTTPDNS akan mengembalikan kode kesalahan 400.
Jika Anda mengatur Cakupan Resolusi Domain ke Domain dalam daftar domain, server HTTPDNS akan mengembalikan kode status 200 tetapi tanpa hasil resolusi untuk domain yang tidak ada dalam daftar.
Jika "Ruang Lingkup Resolusi Domain" diatur ke "Semua domain", untuk domain dalam daftar hitam, server HTTPDNS akan mengembalikan kode status 200 tetapi tanpa hasil resolusi.
Menggunakan konfigurasi DoH tingkat aplikasi
iOS 14+ network.framework menyediakan privacyContext untuk mengonfigurasi DoH secara independen untuk aplikasi, yang dapat mengontrol proses resolusi DNS selama siklus hidup aplikasi.
Kode Contoh
Buat DataTaskManager untuk mengelola NSURLSession.
@interface DataTaskManager : NSObject <NSURLSessionTaskDelegate>#import "DataTaskManager.h"
@import Network;
@import Foundation;
- (instancetype)init {
self = [super init];
if (self) {
_networkQueue = dispatch_queue_create("com.taskmanager.queue", DISPATCH_QUEUE_SERIAL);
[self setupDoHConfiguration];
}
return self;
}
- (void)setupDoHConfiguration {
dispatch_async(self.networkQueue, ^{
NSLog(@"Menyiapkan konfigurasi DoH...");
// Buat URL titik akhir untuk HTTPDNS DoH
const char *dohServerURL = "https://1xxxx3.aliyunhttpdns.com/dns-query";
nw_endpoint_t urlEndpoint = nw_endpoint_create_url(dohServerURL);
NSLog(@"Menggunakan server DoH: %s", dohServerURL);
nw_resolver_config_t resolverConfig = nw_resolver_config_create_https(urlEndpoint);
nw_privacy_context_require_encrypted_name_resolution(NW_DEFAULT_PRIVACY_CONTEXT, true, resolverConfig);
NSLog(@"Konfigurasi DoH diterapkan ke konteks privasi");
});
}Lengkapi inisialisasi di ViewController.viewDidLoad.
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
......
self.dataTaskManager = [[DataTaskManager alloc] init];
......
}URLSession dan pustaka jaringan pihak ketiga berbasis URLSession akan menggunakan instance PrivacyContext default saat melakukan permintaan jaringan. Saat konfigurasi DoH selesai, semua permintaan URLSession dalam aplikasi saat ini akan menggunakan DoH untuk resolusi DNS.
Instrumen Kinerja Resolusi
Anda dapat menggunakan NSURLSessionTaskMetrics untuk menginstrumen proses DNS, sehingga memungkinkan Anda memverifikasi apakah resolusi DoH berfungsi dan memantau waktu resolusi DNS.
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics {
NSLog(@"\n=== Mengumpulkan metrik untuk permintaan ke: %@ ===\n", task.originalRequest.URL);
task.taskDescription = [NSString stringWithFormat:@"%.2f,%@",
metrics.taskInterval.duration,
task.originalRequest.URL.absoluteString];
if ([metrics.transactionMetrics count] > 0) {
[metrics.transactionMetrics enumerateObjectsUsingBlock:^(NSURLSessionTaskTransactionMetrics *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
NSString *fetchTypeStr = @"Tidak Dikenal";
switch (obj.resourceFetchType) {
case NSURLSessionTaskMetricsResourceFetchTypeNetworkLoad:
fetchTypeStr = @"Muatan Jaringan";
break;
case NSURLSessionTaskMetricsResourceFetchTypeServerPush:
fetchTypeStr = @"Dorongan Server";
break;
case NSURLSessionTaskMetricsResourceFetchTypeLocalCache:
fetchTypeStr = @"Cache Lokal";
break;
}
NSLog(@"Jenis Pengambilan: %@", fetchTypeStr);
if (obj.resourceFetchType == NSURLSessionTaskMetricsResourceFetchTypeNetworkLoad) {
NSURLSessionTaskMetricsDomainResolutionProtocol dnsProtocol = obj.domainResolutionProtocol;
NSString *dnsProtocolStr = @"Tidak Dikenal (0)";
BOOL isDoH = NO;
switch (dnsProtocol) {
case NSURLSessionTaskMetricsDomainResolutionProtocolUDP:
dnsProtocolStr = @"UDP (1)";
break;
case NSURLSessionTaskMetricsDomainResolutionProtocolTCP:
dnsProtocolStr = @"TCP (2)";
break;
case NSURLSessionTaskMetricsDomainResolutionProtocolTLS:
dnsProtocolStr = @"TLS (3)";
break;
case NSURLSessionTaskMetricsDomainResolutionProtocolHTTPS:
dnsProtocolStr = @"HTTPS/DoH (4)";
isDoH = YES;
break;
}
NSLog(@"Protokol DNS: %@", dnsProtocolStr);
#if TARGET_OS_SIMULATOR
NSLog(@"Berjalan di simulator - Deteksi protokol DNS tidak didukung");
#else
if (!isDoH) {
NSLog(@"DoH tidak terdeteksi");
}
#endif
// Dapatkan data kinerja resolusi DNS
if (obj.domainLookupStartDate && obj.domainLookupEndDate) {
int dnsLookupTime = ceil([obj.domainLookupEndDate timeIntervalSinceDate:obj.domainLookupStartDate] * 1000);
NSLog(@"Detail Pencarian DNS:");
NSLog(@" Mulai: %@", obj.domainLookupStartDate);
NSLog(@" Akhir: %@", obj.domainLookupEndDate);
NSLog(@" Durasi: %d ms", dnsLookupTime);
} else {
NSLog(@"Tidak ada pencarian DNS yang dilakukan (mungkin di-cache)");
}
// Dapatkan data kinerja permintaan jaringan
if (obj.connectStartDate && obj.connectEndDate) {
NSTimeInterval connectionTime = [obj.connectEndDate timeIntervalSinceDate:obj.connectStartDate];
NSLog(@"Waktu Koneksi: %.3f detik", connectionTime);
}
}
}];
} else {
NSLog(@"Tidak ada metrik transaksi yang tersedia");
}
}Mekanisme Cadangan
Setelah menyelesaikan cadangan, ini akan memengaruhi semua permintaan berbasis URLSession berikutnya dalam aplikasi.
Konfigurasi DoH berfungsi pada perangkat iOS 14 nyata dan versi yang lebih baru serta pada emulator. Namun, saat menjalankan aplikasi di emulator, nilai
NSURLSessionTaskMetricsDomainResolutionProtocolyang dibaca olehNSURLSessionTaskMetricsselalu bernilai 0 (Unknown). Perhatikan perbedaan ini saat menguji fitur terkait di emulator.
Konfigurasikan pengaturan timeout untuk mendapatkan informasi pengecualian tepat waktu saat resolusi DNS gagal:
// Atur timeout koneksi
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.waitsForConnectivity = NO;
config.timeoutIntervalForRequest = 5;
config.timeoutIntervalForResource = 10;Dalam rantai instrumen yang disebutkan di atas, Anda dapat merumuskan strategi cadangan yang sesuai. Berikut adalah contoh fallback global ke LocalDNS saat pengecualian DNS terdeteksi:
......
if (obj.resourceFetchType == NSURLSessionTaskMetricsResourceFetchTypeNetworkLoad) {
NSURLSessionTaskMetricsDomainResolutionProtocol dnsProtocol = obj.domainResolutionProtocol;
NSString *dnsProtocolStr = @"Tidak Dikenal (0)";
BOOL isDoH = NO;
switch (dnsProtocol) {
case NSURLSessionTaskMetricsDomainResolutionProtocolUDP:
dnsProtocolStr = @"UDP (1)";
break;
case NSURLSessionTaskMetricsDomainResolutionProtocolTCP:
dnsProtocolStr = @"TCP (2)";
break;
case NSURLSessionTaskMetricsDomainResolutionProtocolTLS:
dnsProtocolStr = @"TLS (3)";
break;
case NSURLSessionTaskMetricsDomainResolutionProtocolHTTPS:
dnsProtocolStr = @"HTTPS/DoH (4)";
isDoH = YES;
break;
}
NSLog(@"Protokol DNS: %@", dnsProtocolStr);
#if TARGET_OS_SIMULATOR
NSLog(@"Berjalan di simulator - Deteksi protokol DNS tidak didukung");
#else
if (!isDoH) {
NSLog(@"DoH tidak terdeteksi, beralih ke DNS lokal");
dispatch_async(dispatch_get_main_queue(), ^{
// Nonaktifkan DoH dan gunakan LocalDNS
nw_privacy_context_require_encrypted_name_resolution(NW_DEFAULT_PRIVACY_CONTEXT, false, nil);
});
}
#endif
}
......Jika "Ruang Lingkup Resolusi Domain" diatur ke "Domain dalam daftar domain":
Untuk domain yang tidak ada dalam daftar domain, dnsProtocolStr dalam contoh mencetak "Unknown (0)".
Untuk domain yang ada dalam daftar domain, dnsProtocolStr dalam contoh mencetak "HTTPS/DoH (4)".
Jika "Ruang Lingkup Resolusi Domain" diatur ke "Semua domain":
Untuk domain dalam daftar hitam, dnsProtocolStr dalam contoh akan mencetak "Tidak Dikenal (0)".
Untuk domain yang tidak dalam daftar hitam, dnsProtocolStr dalam contoh akan mencetak "HTTPS/DoH (4)".
Menggunakan konfigurasi DoH tingkat sistem
Anda dapat mengonfigurasi DoH untuk perangkat iOS dengan mengonfigurasi profil sistem. Perhatikan bahwa DoH tingkat sistem akan memengaruhi semua aplikasi di perangkat.
Ikuti langkah-langkah berikut untuk mengonfigurasi alamat DoH:
Ganti alamat DoH dalam konten contoh dan simpan sebagai file
.mobileconfig, misalnyamy_company_doh.mobileconfig.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>DNSSettings</key>
<dict>
<key>DNSProtocol</key>
<string>HTTPS</string>
<key>ServerURL</key>
<!---- Ganti alamat di sini dengan alamat akses DoH --->
<string>https://1xxxx3.aliyunhttpdns.com/dns-query</string>
</dict>
<key>PayloadDescription</key>
<string>Mengonfigurasi iOS untuk menggunakan EMAS HTTPDNS DoH</string>
<key>PayloadDisplayName</key>
<string>EMAS HTTPDNS DoH</string>
<key>PayloadIdentifier</key>
<string>com.apple.dnsSettings.managed.9B498EC0C-EF6C-44F0-BFB7-0000658B99AC</string>
<key>PayloadType</key>
<string>com.apple.dnsSettings.managed</string>
<key>PayloadUUID</key>
<string>465AB183-5E34-4794-9BEB-B5327CF61F27</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>ProhibitDisablement</key>
<false/>
</dict>
</array>
<key>PayloadDescription</key>
<string>Menambahkan konfigurasi EMAS HTTPDNS DoH ke iOS</string>
<key>PayloadDisplayName</key>
<string>Konfigurasi EMAS HTTPDNS DoH</string>
<key>PayloadIdentifier</key>
<string>com.emas.apple-dns</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>130E6D6F-69A2-4515-9D77-99342CB9AE76</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
Publikasikan
my_company_doh.mobileconfigke server penyimpanan file atau kirimkan ke perangkat iOS melalui email.Di perangkat iOS, unduh
my_company_doh.mobileconfigmenggunakan browser atau klien email.Instal profil ini di Pengaturan > Umum > VPN & Manajemen Perangkat.