Android原生请求Cloudflare站点出现UnknownHostException问题咨询
问题根因分析
你遇到的DNS解析失败并非Cloudflare拦截普通DNS请求,核心原因如下:
- 目前主流浏览器默认开启了DNS over HTTPS(DoH) 能力,查询域名时不会走系统配置的UDP 53端口DNS服务器,所以会出现系统nslookup、安卓原生DNS查询无返回,但浏览器可正常解析的情况。后续浏览器触发拦截是因为Cloudflare的Bot管理规则识别到请求特征异常,触发了访问限制。
- 你尝试直接使用顶级域名IP请求无效的原因是Cloudflare同一个IP会托管大量站点,请求缺少Host头和正确的SNI(服务器名称指示)信息时,Cloudflare无法正确路由请求,会直接返回错误。
解决方案
按照以下步骤修改即可正常发起请求:
- 替换DNS查询逻辑为DoH查询
不要依赖安卓系统原生的普通DNS查询,自行实现DoH查询逻辑,使用公共DoH服务查询目标域名的A记录,拿到真实的IP地址。 - 自定义HTTP客户端的DNS解析逻辑
推荐改用OkHttp作为HTTP客户端,实现自定义Dns接口,在接口中直接返回你通过DoH查询到的IP,避免HTTP客户端调用系统DNS接口查询,示例代码如下:
OkHttpClient client = new OkHttpClient.Builder() .dns(host -> { // 此处替换为你自己的DoH查询逻辑,返回对应host的IP列表 if (host.equals("bot.whatismyipaddress.com")) { return Arrays.asList(InetAddress.getByName("你查询到的IP")); } return Dns.SYSTEM.lookup(host); }) .build();
- 模拟真实浏览器请求头
不要使用HTTP客户端默认的User-Agent,将请求头完全模拟为手机浏览器的配置,包括User-Agent、Accept、Accept-Language、Accept-Encoding、Referer等字段,示例配置:
Request request = new Request.Builder() .url("https://bot.whatismyipaddress.com/") .header("User-Agent", "Mozilla/5.0 (Linux; Android 10; P30 Pro Build/HUAWEIVOG-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Mobile Safari/537.36") .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8") .header("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2") .header("Accept-Encoding", "gzip, deflate, br") .header("Referer", "https://whatismyipaddress.com/") .build();
- 处理Cloudflare人机验证
如果触发了Cloudflare的5秒盾验证页面,可通过两种方式处理:- 用WebView加载一次目标站点,自动执行验证逻辑,拿到
cf_clearanceCookie后,后续所有请求都带上该Cookie即可正常访问 - 对接可自动解析Cloudflare验证的处理逻辑
- 用WebView加载一次目标站点,自动执行验证逻辑,拿到
- 控制请求频率
避免短时间内向同一站点发起大量请求,防止Cloudflare的DDoS防护规则直接拉黑你的出口IP。
内容的提问来源于stack exchange,提问作者zeg
相关产品推荐
相关产品推荐

