【问题标题】:How to inspect websocket traffic with charlesproxy for iOS simulator/devices如何使用 charlesproxy 为 iOS 模拟器/设备检查 websocket 流量
【发布时间】:2016-01-10 11:04:12
【问题描述】:

我想检查通过 web 套接字 的网络流量,我无法控制网络代码,因为这是一个二进制库,我没有源代码,所以 我不能在代码的网络部分做任何日志/断点

我尝试使用声称能够嗅探 websockets 的最新版本的 CharlesProxy 但是当我尝试使用 websockets 的 url 和 api 时,我的 iPhone 调用的端点列表中甚至没有提及.

我已验证 CharlesProxy 配置正确,因为即使在 SSL 下我也能够检查非 websocket 流量。

所以我的问题是:有没有人找到解决方案来使用 CharlesProxy 检查通过 websockets 的流量?

注意:我在使用 iOS9 时禁用了 ATS

谢谢!

【问题讨论】:

  • 问题解决了吗?我有 Charles 3.11.2,但仍然看不到 websocket 流量。
  • 我在 charles 中看不到来自 ios 的 websocket,但是从 javascript 启动时我可以看到它们
  • 你找到这个问题的答案了吗?
  • @AndrewPaulSimmons 是的,它适用于设备和模拟器。在 Charles 中,转到代理设置 > 启用 Socks 代理。通过 SOCKS 启用 HTTP 代理可能也会有所帮助。
  • 我们正在使用红蜘蛛,但没有获取 WS 数据

标签: ios sockets websocket charles-proxy cfnetwork


【解决方案1】:

找到一个变通的解决方案: 尝试后得出结论,iOS模拟器虽然遵循HTTP的系统代理设置,但没有遵循WebSocket。也不遵循 Socks5 代理设置。 但是,我们可以在 Charles 中使用Reverse Proxies 来强制模拟器使用它。 在 Charles 中,点击 Proxy -> Reverse Proxies,设置一个本地地址作为您的 WebSocket 服务器的透明代理,然后在您的 new WebSocket(<address>) 中使用该地址(在 React Native 的情况下),然后您可以看到您的 WebSocket 连接出现在 Charles 中

【讨论】:

  • 你能分享一个所有领域的例子吗?本地地址字段默认禁用
【解决方案2】:

更新: 显然 socket.io-client-swift v15.1.0 现在正确支持 SOCKS 代理。我还没有尝试过,但这意味着不再需要对红蜘蛛进行这些手动编辑。


接受的答案似乎不适用于 iOS 设备上的 Socket.IO。

最新版本的 Socket.IO-Client-Swift(撰写本文时为 15.0.0)使用 Starscream 用于 iOS/OS X 上的 WebSockets。

好消息是红蜘蛛支持 SOCKS 代理:

  1. Socket.IO 不公开 Starscream websocket 或提供任何 API 来启用 SOCKS 代理行为。

  2. 红蜘蛛内置的 SOCKS 代理使用操作系统 SOCKS 代理设置,设置起来很麻烦(至少对于 iOS)。

如果我有时间,我可能会提出一个 PR 来更彻底地解决这个问题,但鉴于它需要红蜘蛛和 Socket.IO-Client-Swift 的工作,这并不完全简单。

为了临时调试目的(这是 Charles 的用例!)解决这个问题的最简单方法是编辑 WebSocket.swift 文件作为 Starscream 的一部分,并替换以下代码:

if enableSOCKSProxy {
    let proxyDict = CFNetworkCopySystemProxySettings()
    let socksConfig = CFDictionaryCreateMutableCopy(nil, 0, proxyDict!.takeRetainedValue())
    let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
    CFWriteStreamSetProperty(outputStream, propertyKey, socksConfig)
    CFReadStreamSetProperty(inputStream, propertyKey, socksConfig)
}

使用此代码:

let socksConfig = CFDictionaryCreateMutableCopy(nil, 0, CFNetworkCopySystemProxySettings()!.takeRetainedValue()) as! [String: Any]
let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
let ip = socksConfig["HTTPSProxy"]
let proxySocksConfig = ["SOCKSProxy": ip, "SOCKSPort": 8889, "SOCKSEnable": true] as CFDictionary // Where 8889 is the SOCKS proxy port in Charles
CFWriteStreamSetProperty(outputStream, propertyKey, proxySocksConfig)
CFReadStreamSetProperty(inputStream, propertyKey, proxySocksConfig)

这将确保 SOCKS 代理默认启用,并将通过 Charles 路由所有 websockets 流量。

然后您需要确保在 iOS 中配置了 HTTP 代理设置(因为 HTTP 和 SOCKS 将使用相同的 IP),在 Charles 中启用了 SOCKS 代理,并且端口与上面代码中的端口匹配(默认为 8889)。

【讨论】:

  • 更新 WebSocket.swift 后它仍然不适合我。你能扩展最后一节吗?我在 Charles 中启用了 SOCKS 代理并且端口匹配,但我想知道我是否遗漏了什么。
  • 没关系。我让它工作了。我错过了 enableSOCKSProxy 必须是真的。
  • 如果你替换整个部分包括 if enableSOCKSProxy { ... },那么你不需要设置enableSOCKSProxy = true,它将默认为所有连接启用... .
【解决方案3】:

感谢乔纳森·埃利斯(Jonathan Ellis)非常有帮助的回答! 我正在使用 Pusher,效果很好!

但是,我发现socksConfig 并不总是包含有效数据,并且当我从那里提取 IP 时它无法正常工作或会使应用程序崩溃。由于我们从那里得到的唯一东西是本地主机 IP,我刚刚在 WebSocket.swift 中替换了以下内容@

if enableSOCKSProxy {
    let proxyDict = CFNetworkCopySystemProxySettings()
    let socksConfig = CFDictionaryCreateMutableCopy(nil, 0, proxyDict!.takeRetainedValue())
    let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
    CFWriteStreamSetProperty(outputStream, propertyKey, socksConfig)
    CFReadStreamSetProperty(inputStream, propertyKey, socksConfig)
}

用这个:

let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
let proxySocksConfig = ["SOCKSProxy": "127.0.0.1", "SOCKSPort": 8889, "SOCKSEnable": true] as CFDictionary // Where 8889 is the SOCKS proxy port in Charles
CFWriteStreamSetProperty(outputStream, propertyKey, proxySocksConfig)
CFReadStreamSetProperty(inputStream, propertyKey, proxySocksConfig)

然后按照您的描述在 Charles 中启用 socks 代理。

再次感谢!

【讨论】:

    【解决方案4】:

    我终于找到了答案。

    Charles 3.11.2 与 WebSocket 完美配合。

    我使用socketIO,所以我已经看到在协商阶段发送的http请求,但是我错过了websockets流量。

    一开始socketIO尝试使用polling,然后切换到使用websockets

    当您转到状态为 "Sending request body" 这实际上是 wss:// 请求的请求时,websocket 流量是可见的。

    您甚至为此类流量设置了一个专用标签。其余消息将显示在此处。

    PS1。确保您已正确连接到套接字,然后它会出现在 Charles 中。
    PS2。我建议使用 socketIO,它对于像 websockets 这样的全双工流量来说是一个很好的增强。

    【讨论】:

    • 太棒了!我几乎要设置 Wireshark 作为替代方案。
    • 问题是关于 iOS 模拟器的 Web 套接字。通过 JS 发送时,使用 Charles 看到 Web 套接字没有问题。
    猜你喜欢
    • 2013-05-24
    • 2012-07-10
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多