如何在不编辑 iOS 中的 /etc/hosts 的情况下使用直接 ip 访问 HTTPS?

Posted

技术标签:

【中文标题】如何在不编辑 iOS 中的 /etc/hosts 的情况下使用直接 ip 访问 HTTPS?【英文标题】:How can I access HTTPS using direct ip without editing /etc/hosts in iOS? 【发布时间】:2015-08-24 10:09:35 【问题描述】:

默认情况下,example.com 解析为 123.123.123.123

但如果我想将其解析为100.100.100.100

对于 http,我可以简单地将 url 更改为 http://100.100.100.100,并带有标题“Host:example.com”。

但它不适用于 HTTPS。(错误:SSL 证书问题:无效证书链)。

我的问题是不是为什么,我不想跳过证书验证。

如何在 Objective-C 中获得与 curl 一样的效果

--resolve 选项:

--resolve <host:port:address>
          Provide a custom address for a specific host and port pair. Using this, you can make the  curl  requests(s)
          use  a specified address and prevent the otherwise normally resolved address to be used. Consider it a sort
          of /etc/hosts alternative provided on the command line. The port number should be the number used  for  the
          specific  protocol  the  host  will  be  used for. It means you need several entries if you want to provide
          address for the same host but different ports.

也就是说,如何在 Objective-C 的 HTTPS 请求中进行自定义 DNS 查询?

【问题讨论】:

你正在尝试做的事情对我来说似乎是错误的。如果您知道要使用的 IP 地址并且它们是真实的,那么使用这些 IP 运行的设备也有名称。让我们假设 192.168.0.1 是 one.example.com,而 192.168.0.2 是 two.example.com。然后,与其尝试规避名称解析 IP 映射,不如将域 example.com 的代码中的映射添加到您要在测试中使用的真实设备名称。或者在某个地方有一个知道使用哪个变量的变量:one.example.com 或 two.example.com。从这个问题来看,您必须有计划将代码切换到 .0.2 吗? @RoryMcKinnel 一种可能的用例是绕过 ISP 提供商造成的 DNS 污染。 不确定什么是 DNS 污染?您的意思是住宅 ISP IP 地址一直在更改,因此您无法查找它们吗?如果是这样,那就是静态 ISP IP 的用途,或者动态 DNS 用于具有动态 IP 的人想要一个固定的 DNS 查找名称。无论哪种方式,如果您需要覆盖,那么对我来说,您需要自己的映射,因为您暗示您知道要使用的映射而不是 DNS 系统?所以你想要一个函数createURLFromDNSNameUsingMyDNSOverrides 之类的。 @RoryMcKinnel 例如,server.com 的正确 ip 是 123.123.123.123。但是某些最终用户可能会得到错误的 dns 结果,在这种情况下,由于 ip 错误,他们无法连接到 server.com。是的。我知道映射。 DNS有时是错误的。 en.wikipedia.org/wiki/DNS_spoofingen.greatfire.org/faq/what-does-dns-poisoning-mean 【参考方案1】:

当您使用https时,您在请求中使用的地址与服务器返回的证书给您的地址必须一致。

如果您向 https://100.100.100.100 发送请求,则服务器必须返回 100.100.100.100 的证书。即使您成功连接到 https://www.xyz.com,并且 www.xyz.com 解析为 100.100.100.100,连接到 https://100.100.100.100 也无法正常工作,不能工作,而且绝对不能工作,因为服务器将返回 www.xyz.com 而不是 100.100.100.100 的证书。

【讨论】:

谢谢,但我的问题不是为什么。 它应该告诉你,无论你尝试什么,它都行不通。你在问“如何”,答案是“不可能”。 我认为这是可能的。 Curl 的 '--resolve' 选项就是一个证明。在 Python 等其他语言中,名称解析阶段可以轻松替换为自己的代码(例如 ***.com/questions/2236498/…) 我的 2 美分:如果您使用严格的选项来防止访问证书 URL 不匹配重定向 URL 的站点(如默认的 chrome 行为),您将不会被重定向 - 这是因为效果是预期的。简而言之,你不能拥有它!如果您使用宽松的选项(许多 Web 客户端允许),您可以继续,但您仍然会收到警告,在这种情况下,用户应该进行干预并接受风险【参考方案2】:

我看到以下选项:

使用您自己的 DNS 服务器和相应的主机/IP 条目配置 如果你想坚持使用 Objective C,苹果有一个指导方针Overriding SSL Chain Validation Correctly 使用支持您提到的功能的 libcurl:http://curl.haxx.se/libcurl/c/resolve.html

示例

#include <stdio.h>
#include <curl/curl.h>
 
int main(void)

  CURL *curl;
  CURLcode res = CURLE_OK;
  struct curl_slist *host = NULL;
 
  /* Each single name resolve string should be written using the format
     HOST:PORT:ADDRESS where HOST is the name libcurl will try to resolve,
     PORT is the port number of the service where libcurl wants to connect to
     the HOST and ADDRESS is the numerical IP address
   */ 
  host = curl_slist_append(NULL, "example.com:80:127.0.0.1");
 
  curl = curl_easy_init();
  if(curl) 
    curl_easy_setopt(curl, CURLOPT_RESOLVE, host);
    curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
    res = curl_easy_perform(curl);
 
    /* always cleanup */ 
    curl_easy_cleanup(curl);
  
 
  curl_slist_free_all(host);
 
  return (int)res;

更新: 由于作者不想跳过证书验证,现在这不是一个选项:

您可以尝试在您的情况下忽略 AFNetworking 中的 ssl 证书

I want to allow invalid SSL certificates with AFNetworking

【讨论】:

以上是关于如何在不编辑 iOS 中的 /etc/hosts 的情况下使用直接 ip 访问 HTTPS?的主要内容,如果未能解决你的问题,请参考以下文章

红帽linux下使用 vim /etc/hosts命令却无法编辑是怎么回事?

ubuntu下如何实现windows的host文件功能,即域名与IP的自动转换

API 等价于 etc/hosts?

如何在“docker build”期间更新 Docker 映像中的 /etc/hosts 文件

在Linux/Windows系统上编辑/etc/hosts文件

使用 shell 脚本修改 /etc/hosts 文件