如何使用SNI

时间:2017-07-03 11:10:26

标签: ios swift nsurlsession sni nsurlprotocol

首先是服务器端: 有一个内部可达的apache服务器,有几个虚拟主机。 对于http(sans'!)请求,我使用IP作为URL,并在Host-Headerfield中添加主机名。

这很有效。

但是当我建立SSL连接时,我遇到的问题似乎与SNI有关。

我发现了这个Overriding TLS Chain Validation Correctly并在我的代码中实现了它。

所以我更新了信任

func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)

但我仍然从服务器获得400。

更新 URLSession确实支持SNI,但我的问题是我需要添加其他内容或更改hostname中的SSLHandshake

首先是服务器的简短描述: 服务器是一个Apache服务器,只能通过IP访问,但它有多个vhost,可以通过主机名在本地使用,但当我从外部设备(如iPhone)连接到它时,我必须在{添加vhost的主机名{1}}。

所以我的工作是:我使用基于IP的URL创建URLRequest,然后添加带有主机名的Host-Headerfield Headerfield

HOST

这适用于非安全的http-Requests,但是一旦使用https,服务器就会返回" 400 Bad request"并且http-ssl-error.log包含以下错误:

if let url = URL("https://192.168.178.54:8890") {
    var request = URLRequest(url: url)
    request.addValue("foobar:8890", forHTTPHeaderField: "Host")
    …
}

这是因为默认情况下,SSLHandshake使用URL中提供的值,在我的例子中,这是IP。

我现在试图弄清楚如何在SSLHandshake中提供不同的主机名,或者提供类似自己的DNS解析器的东西,我仍然可以使用基于主机名的URL,但iOS可以直接获得路由。 / p>

1 个答案:

答案 0 :(得分:0)

首先,我们是如何解决它的:服务器专家最终正确地完成了他们的工作,并且没有搞乱设备设置。

返回,我也将我的问题发布在Apple Dev Forums

我也从我的TSI收到了此消息:

  

将您的事件转移给了我,因为我通常都领导   DTS中的NSURLSession和TLS问题(我当时不在办公室时   您的事件最初是来的。

     

回到您的技术问题,看来我已经回复了您   通过为此创建的DevForums线程。

     

https://forums.developer.apple.com/thread/82179

     

该回复相当简短,但确实涵盖了要点:

     
      
  • 无法在NSURLSession级别配置SNI名称

  •   
  • 我建议的替代方法是使用.local DNS名称

  •   
     

如上所述,我的DevForums响应非常简短,因此如果您有   关于后者的任何后续问题,我很乐意回答   在这里。

     

您可以/可以/在网络的较低级别覆盖SNI名称   堆栈,即CFSocketStream(通过NSSStream和   CFStream API)和安全传输。理论上你可以实现   您的NSURLProtocol子类中您自己的HTTP协议层,使用   这些API用于TLS-over-TCP方面,但我/ strong /   建议不要这样做,因为这需要大量工作。

     

分享并享受   -奎因《爱斯基摩人!》 Apple开发人员关系,开发人员技术支持,核心操作系统/硬件

相关问题