DNS 概念:
DNS 域名解析系统,解析成相应的服务器IP, DNS劫持是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名
由于DNS请求报文是明文状态,可能在请求过程被监测,然后伪装DNS服务器发送带有假ip地址的响应报文,从而使主机访问假的服务器。
LocalDNS
LocalDNS 是常见ios本地的DNS解析方式,不依赖http请求 , 在网络发起请求时,通过NSURLProtocol 拦截请求域名 进行本地解析 获得 Ip 地址 , 实际开发中可使用HttpDNS解析域名获得IP地址,也可以自己设置ip池。
NSURLProtocol
上面提到 NSURLProtocol 是网络拦截的关键,可通过子类化来定义新的或已存在的URL加载行为 如:
. 拦截加载请求,返回特定数据
.对发出请求的header进行格式化
.过滤请求和返回中的敏感信息
因为项目需要拦截wkwebview 加载,通过ip直连的方式防止DNS劫持,首先hook wkwebview 注册 NSURLProtocol子类
+ (void)wk_registerScheme:(NSString *)scheme { Class cls = NSClassFromString(@"WKBrowsingContextController"); SEL sel = NSSelectorFromString(@"registerSchemeForCustomProtocol:"); if ([cls respondsToSelector:sel]) { // 放弃编辑器警告 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [cls performSelector:sel withObject:scheme]; #pragma clang diagnostic pop } } + (void)wk_unregisterScheme:(NSString *)scheme { Class cls = NSClassFromString(@"WKBrowsingContextController"); SEL sel = NSSelectorFromString(@"unregisterSchemeForCustomProtocol:"); if ([cls respondsToSelector:sel]) { // 放弃编辑器警告 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [cls performSelector:sel withObject:scheme]; #pragma clang diagnostic pop } }
具体NSURLProtocol子类实现请看Dmeo
参考: NSURLProtocol