是否可以获取传入 websocket 连接的 IP 地址?

Posted

技术标签:

【中文标题】是否可以获取传入 websocket 连接的 IP 地址?【英文标题】:Is it possible to get the IP address of an incoming websocket connection? 【发布时间】:2018-10-23 13:31:09 【问题描述】:

我的 websocket 服务器是这样运行的:

ws_hdl = WebSocketHandler.new do |ws|

    # here we should determine the IP address of an incoming connection

end

srv = Server.new ws_hdl
srv.listen("0.0.0.0", 8080)

是否可以获取远程主机的IP地址? 它是日志记录和安全原因所必需的。

提前感谢任何好的建议!

【问题讨论】:

【参考方案1】:

我不知道你用的是什么,但Kemal 我会这样做:

require "kemal"

ws "/" do |socket, env|
  p env.request
end

Kemal.run

标题如下所示:

HTTP::Headers"Host" => "example.com:80", "User-Agent" => “curl/7.49.1”、“接受”=>“/”、“连接”=>“升级”、“升级” => "websocket", "Origin" => "http://example.com:80", "Sec-WebSocket-Key" => "SGVsbG8sIHdvcmxkIQ==", "Sec-WebSocket-Version" => "13"

然后需要在客户端前面设置像 nginx 这样的代理来添加 IP 到 headers:https://***.com/a/27458651/1597964

【讨论】:

我只使用标准的 Crystal API 来保持 websocket 连接。不要认为将 Kemal 用于可以使用标准 API 解决的任务是一个好主意。感谢您使用 Nginx 添加附加标头的想法!【参考方案2】:

抱歉,我无法正确测试,但我想我有一个解决方案。

该块具有网络套接字ws,但也可以具有HTTP::Context 作为第二个参数。这将包含一个HTTP::Request,其中包含标题。包括像REMOTE_ADDR 这样的东西。

ws_hdl = WebSocketHandler.new do |ws, context|

  context.request.headers # all headers
  context.request.headers["REMOTE_ADDR"]? # Should be the IP address

end

srv = Server.new ws_hdl
srv.listen("0.0.0.0", 8080)

【讨论】:

不!有关远程主机的信息不通过 HTTP 标头传输! Web 服务器可以自行确定远程客户端地址并将其提供给服务器的 API。但不幸的是,Crystal 的内置 Web 服务器不提供此信息。因此,目前记录远程客户端 IP 的唯一方法是通过 nginx 服务器代理连接并在请求中添加额外的标头。估计是Crystal的web server api的一个很大的毛病!

以上是关于是否可以获取传入 websocket 连接的 IP 地址?的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular 和 rxjs 中重新连接 websocket?

如何告诉 websocket 服务器接受传入的连接?

限制 ASP.NET 4.5 中 WebSocket 的性能因素?

如何使用WebSocket

如何使用 uWS 访问 HTTP 请求的 IP 地址?

mac上怎么连接到socket