针对 Cloudflare Web 服务器的 Android 本机 https GET 上的 UnknownHostException(非 Cloudflare Web 服务器工作)

UnknownHostException on Android native https GET against a Cloudflare Webserver (Non-Cloudflare webservers work)

尝试在 https://bot.whatismyipaddress.com/ 上进行 HTTP GET 时出现此错误 我的代码:

public void dostuff(){
                    ...
                    targeturl = "https://bot.whatismyipaddress.com/";
                    response = _makeSimpleHttpRequest(targeturl, "GET", ""); 
                    ...
}
 public static String _makeSimpleHttpRequest(String targetUrl, String methodGetPostX, String postBody) throws MalformedURLException, IOException, NotImplementedException{
String responseline = "";
        String temp = "";
        HttpURLConnection httpConn = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        OutputStream outputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        BufferedWriter bufferedWriter = null;

        try {
            java.net.URL url = null;
            url = new java.net.URL(targetUrl); // system default DNS resolver
            httpConn = (HttpURLConnection)url.openConnection(); // HERE THE ERROR OCCURED
            ...
}

错误:

W/System.err: java.net.UnknownHostException: Unable to resolve host "bot.whatismyipaddress.com": No address associated with hostname
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:156)
        at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
        at java.net.InetAddress.getAllByName(InetAddress.java:1152)
        at com.android.okhttp.Dns.lookup(Dns.java:41)
        at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:178)
        at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:144)
        at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:86)
        at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:176)
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:248)
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:211)
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:30)
        at mypackage.utils.CommonUtils._makeSimpleHttpRequest(CommonUtils.java:251)
        at mypackage.utils.CommonUtils._makeSimpleHttpRequest(CommonUtils.java:293)
        at mypackage.utils.CommonUtils.lambda$isNetworkAvailable[=12=](CommonUtils.java:77)
        at mypackage.utils.-$$Lambda$CommonUtils$I9O8EFeqOM7bNsVQ5uILro0gOxg.call(Unknown Source:4)
        at com.google.android.gms.tasks.zzy.run(com.google.android.gms:play-services-tasks@@17.2.0:2)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:929)
    Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
        at libcore.io.Linux.android_getaddrinfo(Native Method)
        at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
        at libcore.io.BlockGuardOs.android_getaddrinfo(BlockGuardOs.java:200)
        at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:135)
        ... 24 more

我将 DNS 解析器更改为自行实现的 DNS 解析器。在 android 设备上 bot.whatismyipaddress.com 无法解析。但是 whatismyipaddress.com 被正确解析为 ipv4 地址。使用 windows 命令行我得到相同的结果:

nslookup whatismyipaddress.com
Server:  fritz.box
Address:  192.168.178.1

Nicht autorisierende Antwort:
Name:    whatismyipaddress.com
Addresses:  2606:4700::6810:9b24
          2606:4700::6810:9a24
          104.16.154.36
          104.16.155.36
>>
>>        
nslookup bot.whatismyipaddress.com
Server:  fritz.box
Address:  192.168.178.1

Name:    bot.whatismyipaddress.com
(----- no Addresses! ----)
>>
>>

以前它在浏览器中工作(在 phone 和 PC 上)。然而,经过几次尝试,浏览器也被阻止了。浏览器通过 android 本机和 nslookups 已经失败。

我将 URL 更改为另一个 cloudflare 服务器 checkip.dyndns.org,结果相同。 android 本机 HTTP-GET 调用在 DNS 查找期间立即失败。一段时间后浏览器出现故障。

我更改为非 cloudflare 服务器 ipinfo.io/ip 正确通过。

我猜 cloudflare 网络服务器不喜欢本机 android DNS 解析器(或 nslookup)...也许某种 DDOS 保护?有谁知道如何从 android 向 cloudflare 网络服务器发送一个简单的 HTTP-GET 而不会被阻塞?我已经尝试交替使用 SSL Unsafe 和 topdomain 的 ip。但是我认为问题已经出现在执行任何 http 调用之前的 DNS-Resolver 步骤中...谢谢您的提示!

设备Huawei P30 pro VOG-L29 Android 10.1.0 Build 10.1.0.161(c431e23r2p5),WIFI和移动数据都存在问题

我认为您可能过度推断这是 Cloudflare 的问题或被阻止。快速搜索您的第一项服务会收到一条通知,表明他们已将其关闭(可能是由于高使用率)-

As of November 10, 2021 we are no longer providing this API due to massive abuse.

https://whatismyipaddress.com/api

您的其他服务可能遇到类似的可靠性问题。服务器安全不会真正导致 DNS 查找失败。幸运的是,您可以尝试很多很多替代方案。例如-

https://www.ipify.org/

或者 Cloudflare 甚至有一个可以使用的(未记录的)端点 -

https://www.cloudflare.com/cdn-cgi/trace

但归根结底,如果您想要可靠/有保证的东西,您可能需要为此付费。否则,请准备好经常转向新服务。幸运的是,返回的数据应该很容易集成(IP 地址)。