首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WebSocket通过Amazon或直接(远程IP问题)

WebSocket通过Amazon或直接(远程IP问题)
EN

Stack Overflow用户
提问于 2012-12-26 10:00:39
回答 2查看 1.7K关注 0票数 1

我们使用WebSockets与EC2实例进行通信。我们的脚本使用nodejs和Express提供,然后初始化WebSocket。现在使用的是ELB,这使得识别客户端IP变得更加困难。使用x转发-对于报头,我们可以在HTTP上下文中获得IP,但是当涉及到服务器中的WebSocket上下文时,它似乎不是由亚马逊转发的。

我们确定了两种选择:

  1. 直接与实例通信WebSocket (使用其公共DNS)。
  2. 维护某种类型的sessionid,其中在HTTP上下文中存储IP并将其与sessionid关联。客户端将使用HTTP获取它的会话it,并在WebSockets上使用它。服务器将识别客户端并从缓存中解析其IP。

这两个选项都不是很好:1不是容错的,2是复杂的。还有更多的解决办法吗?亚马逊能以某种方式转发IP吗?什么是最佳做法?

谢谢

EN

回答 2

Stack Overflow用户

发布于 2012-12-30 16:55:34

我曾与websocket合作过,也曾与ELB合作过,但我从未与他们一起工作过,所以我没有意识到弹性负载均衡器上的HTTP转发器不理解websocket请求.

所以我想您一定是在使用TCP转发器,这解释了为什么要使用不同的端口,当然TCP转发器是不知道协议的,所以它根本不会添加任何报头。

一个似乎相当通用和简单的选项是,您的应用程序的http端通过将信息推送而不是存储在缓存中进行检索,从而向websocket端提供建议。它是可伸缩和轻量级的,假设在您的环境中没有任何障碍使其难以或不可能实现。

在生成加载websocket的网页时,以字符串"ipv4:“和客户端的IP (例如”192.168.1.1“)为例,连接和加密它们,并使结果具有url友好性:

代码语言:javascript
复制
/* pseudo-code */
base64_encode(aes_encrypt('ipv4:192.168.1.1','super_secret_key'))

使用带有128位aes和IP地址的示例密钥,我得到:

代码语言:javascript
复制
/* actual value returned by pseudo-code above */
1v5n2ybJBozw9Vz5HY5EDvXzEkcz2A4h1TTE2nKJMPk=

然后,在为包含websocket的页面呈现html时,动态构建url:

代码语言:javascript
复制
ws = new WebSocket('ws://example.com/sock?client=1v5n2ybJBozw9Vz5HY5EDvXzEkcz2A4h1TTE2nKJMPk=');

假设您的代码可以访问websocket中的查询字符串,则可以使用超级秘密键对查询参数“aes_decrypt”中的字符串进行aes_decrypt,然后验证它是否以"ipv4:“开头.如果没有,那它就不是合法的价值。

当然,"ipv4:“(在字符串的开头)和"client”(用于查询参数)是任意的选择,没有任何实际意义。我选择128位AES也是武断的。

当然,这个设置的问题是,它需要重放:给定的客户端IP地址总是生成相同的值。如果您只将客户端IP地址用于“信息目的”(例如日志记录或调试),那么这可能就足够了。如果您要将它用于更重要的事情,您可能希望扩展此实现--例如,添加一个时间戳:

代码语言:javascript
复制
'ipv4:192.168.1.1;valid:1356885663;' 

在接收端,解码字符串并检查时间戳。如果它不是+/-无论你认为安全的时间间隔是多少,那就不要相信它。

这些建议都取决于您动态生成websocket url的能力,浏览器连接它的能力,以及您能够访问websocket请求中URL的querystring部分.但如果这些碎片能够到位,也许这会有所帮助。

其他想法(来自评论):

上面我建议的时间戳是离时代只有几秒钟,它提供了一个递增计数器,它不需要平台中的状态--它只需要所有服务器时钟都是正确的--所以它不会增加不必要的复杂性。如果解密的值包含的时间戳小于(例如)5秒,与服务器的当前时间(+/-)不同,那么您就知道您正在处理的是一个经过身份验证的客户端。允许的时间间隔只需要在加载原始页面后客户端尝试其websocket连接的最大合理时间,再加上所有服务器时钟的最大偏差。

当然,通过NAT,多个不同的用户可能在同一个源IP地址后面。事实上,虽然不太可能,但用户实际上可以从一个不同的源IP中建立websocket连接,而不是他们发起第一个http连接的那个,并且仍然是相当合法的.听起来,身份验证用户的身份对您来说可能比实际的源IP更重要。

如果在加密的字符串中也包含了经过身份验证的用户ID,那么您的值对于原始IP、用户帐户和时间来说是唯一的,精确度为1秒。我想这就是你所指的额外盐。将用户帐户添加到字符串应该可以获得您想要的信息。

代码语言:javascript
复制
'ipv4:192.168.1.1;valid:1356885663;memberid:32767;' 

TLS应防止未经授权方发现此加密字符串,但避免可重放性也很重要,因为生成的URL可在用户浏览器的html页面的“视图源”中以明文形式提供。您不希望今天被授权但明天未经授权的用户能够使用一个应该被识别为不再有效的签名字符串来欺骗他们的方式。键入时间戳并要求它掉进一个非常小的有效窗口可以防止这种情况发生。

票数 1
EN

Stack Overflow用户

发布于 2013-01-01 22:43:35

这取决于应用程序的严重程度。

基于客户端IP地址的任何一种决策都是有风险的。基于它的安全,更重要的是。虽然到目前为止所提供的建议在给定的约束范围内都能很好地工作,但是对于一个健壮的企业应用程序来说,这还不够。

客户端IP地址可以被NAT掩盖,正如前面已经指出的。因此,从他们的工作地点访问Web的人通常看起来拥有相同的IP地址。人们在家里的路由器充当NAT,所以每个在家访问Web的家庭成员似乎都有相同的IP地址。或者是同一个人从电脑和平板电脑访问应用程序.

无论是否在NAT后面,在同一台计算机上使用来自两个浏览器的应用程序都会出现地址相同的情况。同样,同一浏览器中的多个选项卡似乎具有相同的地址。

其他连接点,如代理或负载平衡器,也可能隐藏原始客户端IP地址,这样代理/负载平衡器后面的东西就会认为它们是客户端。(更复杂或更低级别的中介可以阻止这种情况,这使他们变得更加复杂或昂贵。)

鉴于以上所述,严重的应用程序不应依赖客户端IP地址进行任何类型的重要决策,特别是围绕安全性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14038928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档