1

我正在编写一个 Android 应用程序并想定义房间。房间将容纳某些游戏的所有用户。这就像扑克有 4 个玩家,每个房间可以容纳 4 个用户。我还想使用 rabbitmq 来实现可扩展性和可定制性。问题是 Android 应用程序使用相同的用户名:密码将所有用户连接到 RabbitMQ 服务器(特定虚拟主机)。

我想我担心一个用户可能能够读/写来自不同队列的消息,这是应该的。有多种解决方案不满意:

  1. 在每个 Android 应用程序中使用不同的用户:这确实无法做到,因为 Android Market 不允许每个下载它的用户使用不同的应用程序。即便如此,这也是一个愚蠢的想法。

  2. 设置适当的访问控制:http ://www.rabbitmq.com/access-control.html 。我想这不会阻止恶意攻击者从/向它无权访问的队列读取/写入消息的问题。

  3. 设置适当的路由键:我猜如果每个用户创建另一个队列,它可以从中读取消息并将消息发布到专门定义的队列,这可以工作。但我想问题是一样的,因为用户将使用相同的用户名:密码连接到 RabbitMQ:因此该用户可以读取所有队列并写入它们(基于访问规则)。

我的问题是:如何允许攻击者读取/写入仅代表他当前加入的房间的队列,并阻止访问其他队列?

4

2 回答 2

2

我自己正在开发一个扑克应用程序 =)

我依赖于基于 Akka/Actors(查看 Erlang)之类的基于流式 Web 套接字的流量,并希望它能够正常工作(仍然有点担心安全 Web 套接字)。

也就是说,我也在考虑使用 RabbitMQ 来接收玩家动作。我认为您不想将用户名或密码暴露给兔子队列。事实上,您甚至可能不希望从外部世界访问队列服务器。

相反,设置一些您的用户可以建立连接的服务器。这将是您的“前端”,Android 客户端将与之交谈。每个用户将通过安全的 TCP 连接连接到服务器,然后登录到您的系统。这是用户将拥有自己的用户名和密码的地方。如果身份验证成功,则保持套接字处于活动状态(这是我对 TCP 的了解较弱的地方),然后将用户信息与此套接字相关联。

当玩家做出动作(例如弃牌或加注)时,通过安全 TCP 连接将他们的动作发送到您的“前端”(此连接仍应建立)。“前端”然后检查哪个用户连接到此套接字,然后将消息发布到理想情况下包含用户 ID、所采取的操作和表 ID 的队列。换句话说,唯一允许访问队列的 IP 是您的前端服务器,而前端服务器只使用兔子队列的单个用户名/密码。

由您来处理队列消息的交换并将消息路由到正确的表(或确保该表只处理它负责的消息 - 这就是我现在喜欢 Akka 的原因:) 一旦消息到达到表中,验证消息中的用户 id 是实际轮到的用户 id,然后根据表的状态验证发送的操作是可接受的。例如,如果我收到一个 CHECK 请求,而用户只能 CALL/FOLD/RAISE,那么我只会回复无效操作或直接丢弃整个消息。

不要让公众排队,并始终确保您没有安全漏洞,尤其是当您开始处理真实货币时。

希望这可以帮助...

编辑:我只想说清楚。任何时候客户端进行操作,他们只需要发送操作和表 ID 或您需要的任何信息。不要让他们发送他们的用户 ID 或任何用户特定信息。您的“前端”服务器应该根据请求进入的套接字自动关联用户 ID。如果他们在请求中提交了任何用户信息,最好将其记录下来,然后丢弃数据。我会记录它只是因为我不喜欢试图作弊的人,如果他们向您发送意外数据,这可能就是他们正在做的事情。

于 2012-10-16T22:31:03.277 回答
2

也许我不太了解应用程序,但根据我的经验,RabbitMQ 通常用于后端,例如,在创建具有数据库和应用程序服务器以及其他松散耦合实体的分布式系统时。消息队列是异步应用程序设计的重要工具,理论上每个消息队列都可以由 RabbitMQ 生成一个单独的进程,这使得它具有显着的可扩展性。

您在问题中提到的似乎更像是用户的访问控制机制。我会在系统的前端看到这一点。例如,在将传入消息传递到消息队列之前对传入消息进行过滤。您甚至可能需要考虑通过每个用户的速率控制来防止 DoS。

干杯!

于 2012-08-14T15:09:44.070 回答