安卓无法解析内部网络中的主机名 - 但我不能使用IP地址

3

我的Android应用程序用于客户内部网络,并且配置的一部分涉及他们输入其Web服务的URL。

从一开始,Android似乎无法看到内部网络中的主机名,因此到目前为止,我一直建议人们使用其服务器的IP地址。最近出现的一个问题是,一个客户将SSL应用于其服务器,这意味着URL仅可以通过https访问,并且自签名证书当然与主机名而不是IP地址匹配。无论您指定http还是https,通过IP地址的URL请求都不再起作用。

搜索了几天,建议要么对设备进行root并修改hosts文件,要么提供一个内部DNS-over-TLS服务器,但这两个选项都对我不可用。

解决内部主机名肯定不会这么难吧?

我不确定这是否是代码问题,因为在Chrome中也可以重现该问题,但以下是我的代码:

protected JSONObject doInBackground(String... params) {
            try {
                URL url = new URL("http://officeserver/PTSWeb/PTSCommsServer.asmx");
                HttpURLConnection huc = (HttpURLConnection) url.openConnection();
                HttpURLConnection.setFollowRedirects(false);
                huc.setConnectTimeout(5 * 1000);
                huc.setRequestMethod("GET");
                huc.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)");
                huc.connect(); //FAILS HERE WITH UNABLE TO RESOLVE HOST
                BufferedReader in = new BufferedReader(new InputStreamReader(huc.getInputStream()));
                String result = "";
                StringBuilder total = new StringBuilder();
                for (String line; (line = in.readLine()) != null; ) {
                    total.append(line).append('\n');
                }
                in.close();
                result = total.toString();
                return new JSONObject(result);
            } catch (Exception e) {
                try {
                    JSONObject MyErrorJSON = new JSONObject();
                    MyErrorJSON.accumulate("WasError", "True");
                    MyErrorJSON.accumulate("ResponseText", e.toString());
                    return MyErrorJSON;
                } catch (Exception x) {
                    return null;
                }
            }
        }

您应该能够使用客户网络上DNS服务的详细信息配置Android设备;例如:https://www.androidpolice.com/2020/03/26/make-android-use-dns-server-choice/ - Stephen C
很遗憾,他们没有DNS-over-TLS兼容的服务器。至少他们是这么告诉我的。 - Psiloc
以下是其他的替代方案:https://android.stackexchange.com/questions/78320。1)编辑`/etc/hosts`文件。2)在设备本身上安装本地DNS服务器... - Stephen C
如何在设备上安装证书? - tadev
“Android从一开始似乎无法看到内部网络中的主机名”--这个主机名是在哪里定义的?这是一个真实DNS服务器上的真实DNS条目,还是一些特定于Windows的东西?“客户已将SSL应用于其服务器,这意味着URL仅通过https访问,并且自签名证书当然与主机名匹配而不是IP地址”--那么您将遇到其他问题,因为如果证书是自签名的,Android将拒绝该证书。 - CommonsWare
显示剩余3条评论
2个回答

1
在过去的12个月中,此文章已经收到了很多关注,因此我想在这里发布我的“答案”,以防不只是我遇到了这个问题。我已经困扰于这个问题已经6年以上,近2年来成为了一个严重的头痛。我得出结论,Android确实无法在没有root设备的情况下解析任何简单内部网络上的主机名。但是,它可以通过IP地址或完全限定域名找到服务器。因此,您(或在我这种情况下,我的客户)需要重新配置SSL证书以处理发送到IP地址或FQDN以及主机名的请求。这是通过将两者作为SAN(Subject Alternative Name)添加到证书中完成的。
例如:
SAN 1: DNS Name=pts
SAN 2: DNS Name=pts.local
SAN 3: DNS Name=pts.domain.co.uk
SAN 4: IP Address=93.184.216.34
SAN 5: IP Address=2606:2800:220:1:248:1893:25c8:1946

注意“DNS Name”和“IP地址”标题之间的区别。在某些边缘情况下,将IP地址添加为DNS名称可能也有帮助吗?

使用DNS类型的主题备用名称与IP地址无效。https://superuser.com/a/1499403 - zapl
这绝对是严格的真理,但如果必须这样做,我也不会犹豫。 - Psiloc

0

您实际上可以通过 IP 地址连接到简单的 HTTP,将其放入清单中以允许明文流量:

<application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接