【问题标题】:How can I prevent/restrict an unauthorized node from joining an an Akka cluster?如何防止/限制未经授权的节点加入 Akka 集群?
【发布时间】:2020-07-28 12:53:02
【问题描述】:

在 Akka Cluster 示例、文档和教程中,似乎任何节点都可以通过了解集群和集群的种子节点来加入集群。如何防止未经授权的节点加入?

【问题讨论】:

  • 我相信推荐的答案是:不要让您的集群成为公共网络。在云提供商中设置您的安全组/网络或在 VPN 网络上配置访问。
  • 还有不推荐的答案吗?我之所以问,是因为我想创建一个公共但获得许可的集群,其中加入的权限可能会动态变化。
  • 那大概建个权限服务来保护Akka集群的地址吧?这里的逻辑应该和任何鉴权服务几乎一样。
  • 您可以订阅ClusterDomainEvents 并采取行动从集群中踢出未经授权的节点。这比预防更有效。除此之外,本地防火墙规则通常是可调整的。你也可以破解 Aeron 做你想做的事。

标签: scala akka cluster-computing distributed-computing akka-cluster


【解决方案1】:

我试图实现这个功能,但我也没有在 Akka 集群中找到这个功能。我设法通过在参与者上创建一个授权标志,将集群包装在Option[Cluster] 中,并在preStart() mwethod 中决定订阅或不订阅集群上的参与者。这已经阻止了参与者接收消息。但是,它仍然可以向集群成员发送消息。然后我把标志放在case UserMessage(content) if (authorized) => ??? 上。我没有将演员从集群中踢出,但我相信这只是在他起床后踢他。

object Alice extends ChatApp("Alice", 2551, true)
object Bob extends ChatApp("Bob", 2552, true)
object Fabio extends ChatApp("Fabio", 2554, false)

演员

class ChatActor(nickname: String, port: Int, authorized: Boolean) extends Actor with ActorLogging {
  // 1: initialize the cluster object
  val cluster: Option[Cluster] = if (authorized) Some(Cluster(context.system)) else None

  // 2: subscribe to cluster event in preStart
  override def preStart(): Unit = {
    if (authorized) {
      cluster match {
        case Some(c) => c.subscribe(
          self,
          initialStateMode = InitialStateAsEvents,
          classOf[MemberEvent]
        )
        case None => log.info(s"user [$nickname] is not authorized to enter in the cluster =(. Please leave the cluster.")
      }
    }
  }

  // 3: unsubscribe self in postStop
  override def postStop(): Unit = {
    cluster match {
      case Some(c) => c.unsubscribe(self)
      case None => log.info(s"user [$nickname] is not authorized to enter in the cluster =(.")
    }
  }

  override def receive: Receive = online(Map())

  /** chatRoom is the data structure to the users in the chat */
  def online(chatRoom: Map[String, String]): Receive = {
    case UserMessage(content) if (authorized) =>
      chatRoom.keys.foreach { address =>
        val chatActorSelection: ActorSelection = context.actorSelection(s"${address}/user/chatActor")
        chatActorSelection ! ChatMessage(nickname, content)
      }
  }
}

【讨论】:

    猜你喜欢
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    相关资源
    最近更新 更多