DNS拦截和处理

常见 DNS 拦截方式

拦截方式影响
ISP 劫持 网络运营商强制解析特定域名,返回错误地址(如广告页面)
DNS 污染 某些 DNS 服务器返回错误 IP,导致无法访问目标网站
企业防火墙 组织内的网络策略屏蔽某些 DNS 请求
GFW(防火长城) 阻止访问特定域名,返回错误 IP 或超时

表现

  • APP 网络请求失败(如 API 请求超时、域名解析失败)
  • 页面无法加载(WebView 或 Safari 加载特定网站失败)
  • DNS 查询时间长(影响 APP 启动速度)

iOS DNS 优化方案

方案 1:使用自定义 DNS 服务器

可以切换至 Google DNS、Cloudflare DNS 或 DoH(DNS over HTTPS) 进行更安全的解析:

let config = URLSessionConfiguration.default
config.connectionProxyDictionary = [
    kCFNetworkProxiesHTTPEnable: true,
    kCFNetworkProxiesHTTPProxy: "8.8.8.8",  // Google DNS
    kCFNetworkProxiesHTTPPort: 53
]
let session = URLSession(configuration: config)

推荐 DNS 服务器

  • Google DNS8.8.8.8 / 8.8.4.4
  • Cloudflare DNS1.1.1.1 / 1.0.0.1
  • Quad9 DNS9.9.9.9

 

方案 2:使用 DoH(DNS over HTTPS)

iOS 14+ 支持 DoH(加密 DNS 请求),可以有效防止 DNS 劫持

复制代码
let dohURL = URL(string: "https://dns.google/dns-query")!
var request = URLRequest(url: dohURL)
request.setValue("application/dns-json", forHTTPHeaderField: "Accept")

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    if let data = data {
        print("DoH Response: \(String(data: data, encoding: .utf8) ?? "")")
    }
}
task.resume()
复制代码

优点

  • 防止 DNS 劫持(使用 HTTPS 加密请求)
  • 提高解析速度(基于 HTTP/3 的 DNS 查询更快)

 

方案 3:使用 getaddrinfo 预解析 DNS

iOS 默认在 每次请求时解析 DNS,可以使用 getaddrinfo 预解析 域名的 IP 地址,提高网络请求速度:

复制代码
import Foundation

func resolveHost(_ host: String) -> [String] {
    var results: [String] = []
    var hints = addrinfo(
        ai_flags: AI_DEFAULT,
        ai_family: AF_INET,
        ai_socktype: SOCK_STREAM,
        ai_protocol: IPPROTO_TCP
    )

    var info: UnsafeMutablePointer<addrinfo>?
    if getaddrinfo(host, nil, &hints, &info) == 0 {
        var ptr = info
        while ptr != nil {
            if let sa = ptr?.pointee.ai_addr {
                var ipBuffer = [CChar](repeating: 0, count: Int(INET6_ADDRSTRLEN))
                inet_ntop(AF_INET, sa, &ipBuffer, socklen_t(INET6_ADDRSTRLEN))
                results.append(String(cString: ipBuffer))
            }
            ptr = ptr?.pointee.ai_next
        }
        freeaddrinfo(info)
    }
    return results
}

let ipList = resolveHost("example.com")
print("Resolved IPs: \(ipList)")
复制代码

优势

  • 减少 DNS 查询时间
  • 提升 APP 启动速度
  • 避免被劫持时切换备用 IP

 

方案 4:使用 CFNetwork API 强制 IP 直连

如果你的 APP 遭遇 DNS 劫持,可以 直接连接 IP,而非域名

let url = URL(string: "http://93.184.216.34")!  // example.com 的 IP
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
    if let data = data {
        print("Response: \(String(data: data, encoding: .utf8) ?? "")")
    }
}.resume()

优势

  • 绕过 DNS 劫持
  • 适用于 CDN 加速失败的情况
posted @   程石亮  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示