Amazon MQ RabbitMQブローカーでのクラスターデプロイメントモードの適用について

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。

今回は、Amazon MQ for RabbitMQブローカーがシングルインスタンスデプロイメントモードになっている状態について、そのリスクと対策を解説します。

ポリシーの説明

Amazon MQ の Security Hub コントロール – AWS Security Hub

[MQ.6] RabbitMQ ブローカーはクラスターデプロイメントモードを使用する必要があります。

このコントロールは、Amazon MQ RabbitMQ ブローカーのデプロイモードがクラスターデプロイに設定されているかどうかを確認します。単一インスタンスブローカー (デフォルトで有効) がデプロイモードに設定されている場合、コントロールは失敗します。

リスク

Amazon MQは、クラウド内でメッセージブローカーを簡単にセットアップして運用できるフルマネージドサービスです。Apache ActiveMQとRabbitMQの2種類のオープンソースメッセージブローカーをサポートしています。RabbitMQブローカーをAmazon MQでデプロイする際、シングルインスタンス(シングルノード)デプロイメントモードを選択することが可能です。しかし、このモードで運用している場合、以下のような重大な可用性と耐久性のリスクが発生します。

  • 単一障害点 (Single Point of Failure): シングルインスタンスデプロイメントでは、RabbitMQブローカーが単一のノード上で稼働します。このノードに障害が発生した場合(例: ハードウェア障害、ソフトウェアクラッシュ、ネットワーク問題、アベイラビリティーゾーンの停止など)、メッセージングサービス全体が利用できなくなり、アプリケーションのダウンタイムが発生します。
  • データ損失のリスク: シングルノードでは、メッセージデータは基本的にそのノードのストレージにのみ保存されます。ノード障害が発生した場合、まだ消費されていないメッセージや、永続化されていないメッセージが完全に失われる可能性があります。これにより、トランザクションの整合性やデータの正確性が損なわれ、ビジネスプロセスに深刻な影響を与える可能性があります。
  • メンテナンス時のダウンタイム: 計画的なメンテナンス作業(例: パッチ適用、バージョンアップグレード、インスタンスタイプの変更など)を行う際も、シングルノードではサービスを停止せざるを得ません。これにより、サービス提供が中断され、ビジネスに影響を与える可能性があります。
  • スケーラビリティの限界: シングルノードでは、メッセージ処理能力や接続数のスケールアウトができません。トラフィックが増加した場合、パフォーマンスボトルネックとなり、メッセージの遅延や処理能力の低下を招きます。

対策

Amazon MQ RabbitMQブローカーをクラスターデプロイメントモードで運用することは、上記のすべてのリスクを軽減し、高可用性、高い耐久性、およびスケーラビリティを確保するための重要なベストプラクティスです。

  • 高可用性の確保: クラスターデプロイメントは、3つのRabbitMQブローカーノードを論理的にグループ化したものです。これらのノードは、異なるアベイラビリティーゾーン(AZ)に分散してデプロイされるため、単一のノード障害やAZ障害が発生しても、他のノードがサービスを継続し、メッセージングサービスの可用性を大幅に向上させます。
  • データの耐久性と冗長性: クラスター内の各ノードは専用のAmazon Elastic Block Store (Amazon EBS) ボリュームを持ち、データはクラスター内の全ノードに自動的に複製されます。これにより、ノード障害やAZ障害が発生しても、メッセージデータが失われるリスクが最小限に抑えられ、高いデータの耐久性が保証されます。
  • ゼロダウンタイムメンテナンス: クラスターデプロイメントでは、Amazon MQがローリングアップデートを実行できるため、計画的なメンテナンス作業(バージョンアップグレード、パッチ適用など)をゼロダウンタイムで実行できます。
  • スケーラビリティの向上: 複数のノードで構成されるため、メッセージ処理の負荷を分散し、より多くのクライアント接続とメッセージスループットを処理できます。

修復方法

Amazon MQ RabbitMQブローカーをクラスターデプロイメントモードにする方法は、AWSコンソールまたはTerraformで行えます。既存のシングルインスタンスブローカーを直接クラスターモードに変更することはできないため、新しいクラスターブローカーを作成し、アプリケーションの接続先を移行する必要があります。

AWSコンソールでの修復手順

AWSコンソールを使用して、Amazon MQ for RabbitMQブローカーをクラスターデプロイメントモードで新規作成します。

  1. Amazon MQサービスへ移動: AWSコンソールにログインし、Amazon MQ サービスを開きます。
  2. ブローカーの作成: 左側のナビゲーションペインで「ブローカー」を選択し、「ブローカーを作成」をクリックします。
  3. ブローカータイプの選択:
    • RabbitMQ」を選択します。
    • 次へ」をクリックします。
  4. デプロイメントモードの選択:
    • デプロイモード」で、「クラスターデプロイ」を選択します。
      • これにより、3つのアベイラビリティーゾーンに分散されたノードが自動的にプロビジョニングされます。
  1. インスタンスタイプとRabbitMQバージョンの選択:
    • ブローカーインスタンスタイプ」と「RabbitMQバージョン」を選択します。本番環境の要件に基づいて適切なタイプを選択してください。
  2. ブローカーの詳細設定:
    • ブローカー名」を入力します。
    • ユーザー名」と「パスワード」を入力します。パスワードは強力なものを使用し、安全に管理してください。
  3. ネットワークとセキュリティの設定:
    • VPC」、「サブネット」、「セキュリティグループ」を選択します。
      • ブローカーはプライベートサブネットに配置し、セキュリティグループで必要なポート(RabbitMQの場合、デフォルトは5671 for AMQPS、15671 for RabbitMQ Management Plugin)のみを許可するように設定することを強く推奨します。
    • パブリックアクセスの許可」は、「No」を選択し、ブローカーへのインターネットからの直接アクセスを防ぎます。
  4. その他の設定 (オプション):
    • ストレージ暗号化、ログ、メンテナンスウィンドウ、タグなどを設定します。
  5. ブローカーの作成: 設定内容を確認し、「ブローカーを作成」をクリックします。
    • ブローカーの作成には数分かかる場合があります。
  6. アプリケーションの接続情報の移行: 新しいクラスターブローカーが「Running」状態になったら、アプリケーションの接続先を新しいブローカーのエンドポイントURLに更新します。
  7. 古いシングルインスタンスブローカーの削除(オプション): 新しいクラスターブローカーが正常に機能し、すべてのメッセージが処理されたことを確認した後、古いシングルインスタンスブローカーを削除できます。

Terraformでの修復手順

TerraformでAmazon MQ for RabbitMQブローカーをクラスターデプロイメントモードで作成するには、aws_mq_broker リソースの deployment_mode パラメータを "CLUSTER_MULTI_AZ" に設定します。

# (前提) VPC, サブネット, セキュリティグループは別途定義
resource "aws_vpc" "mq_vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "mq-vpc"
  }
}

resource "aws_subnet" "mq_subnet_a" {
  vpc_id            = aws_vpc.mq_vpc.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "${data.aws_region.current.name}a"
  tags = {
    Name = "mq-subnet-a"
  }
}

resource "aws_subnet" "mq_subnet_b" {
  vpc_id            = aws_vpc.mq_vpc.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "${data.aws_region.current.name}b"
  tags = {
    Name = "mq-subnet-b"
  }
}

resource "aws_subnet" "mq_subnet_c" {
  vpc_id            = aws_vpc.mq_vpc.id
  cidr_block        = "10.0.3.0/24"
  availability_zone = "${data.aws_region.current.name}c"
  tags = {
    Name = "mq-subnet-c"
  }
}

resource "aws_security_group" "mq_sg" {
  name        = "rabbitmq-mq-sg"
  description = "Security group for Amazon MQ RabbitMQ broker"
  vpc_id      = aws_vpc.mq_vpc.id

  # Inbound rules for RabbitMQ:
  # AMQPS (client connections)
  ingress {
    from_port   = 5671
    to_port     = 5671
    protocol    = "tcp"
    # アクセス元を制限 (例: アプリケーションサーバのセキュリティグループID)
    cidr_blocks = [aws_vpc.mq_vpc.cidr_block] # VPC内部からのアクセスを許可
  }
  # RabbitMQ Management Plugin (Web UI)
  ingress {
    from_port   = 15671
    to_port     = 15671
    protocol    = "tcp"
    # アクセス元を制限 (例: 運用者のIPアドレスや踏み台サーバのセキュリティグループID)
    cidr_blocks = ["10.0.0.0/16"] # 例: 運用用VPCのCIDR
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"] # 必要に応じて制限
  }
  tags = {
    Name = "RabbitMQMQ_SG"
  }
}

# Amazon MQ for RabbitMQ ブローカー (クラスターデプロイメント)
resource "aws_mq_broker" "my_rabbitmq_broker_cluster" {
  broker_name        = "my-secure-rabbitmq-cluster"
  engine_type        = "RabbitMQ"
  engine_version     = "3.10.20" # 最新のサポートバージョンを指定
  host_instance_type = "mq.m5.large" # 適切なインスタンスタイプを選択

  # **重要: クラスターデプロイメントモードを設定**
  deployment_mode    = "CLUSTER_MULTI_AZ"

  # 少なくとも3つのサブネット(異なるAZ)を指定
  # CLUSTER_MULTI_AZの場合、自動的に3つのサブネットを使用します
  # subnet_ids はdeployment_modeがSINGLE_INSTANCE_STANDBYの場合に必要
  # Clusterモードの場合、特定のサブネットを明示的に指定する必要はありません。
  # Amazon MQがVPC内の利用可能なサブネットから自動的に選択します。
  # ただし、特定のサブネットに制限したい場合は以下のように指定できます。
  # subnet_ids = [aws_subnet.mq_subnet_a.id, aws_subnet.mq_subnet_b.id, aws_subnet.mq_subnet_c.id]

  security_groups = [aws_security_group.mq_sg.id]
  publicly_accessible = false # **重要: パブリックアクセスを無効にする**

  # 管理ユーザー
  user {
    username = "rabbitmqadmin" # デフォルトではないユーザー名
    password = "MyStrongRabbitMQPassw0rd!" # 強力なパスワード。Secrets Managerとの連携を推奨
  }

  # ログの設定 (オプション)
  logs {
    audit   = true
    general = true
    # CloudWatch Logsへの出力設定
  }

  # ストレージ暗号化 (オプション、推奨)
  storage_type = "EBS" # RabbitMQはEBSのみ
  # kms_key_id を指定することで、CMKでの暗号化が可能 (デフォルトはAWS管理キー)
  # kms_key_id = "arn:aws:kms:ap-northeast-1:123456789012:key/your-kms-key-id" 

  tags = {
    Name        = "MySecureRabbitMQBrokerCluster"
    Environment = "Production"
  }
}

# 現在のAWSアカウント情報とリージョンを取得
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}

上記のTerraformコードでは、aws_mq_broker リソースの deployment_mode パラメータを "CLUSTER_MULTI_AZ" に設定することで、RabbitMQブローカーをクラスターデプロイメントモードで作成しています。

  • deployment_mode = "CLUSTER_MULTI_AZ": これにより、RabbitMQブローカーが3つのアベイラビリティーゾーンにまたがるクラスターとしてデプロイされます。
  • publicly_accessible = false: セキュリティのために、パブリックアクセスを無効にすることを強く推奨します。
  • user: ブローカーの管理ユーザーのユーザー名とパスワードを設定します。デフォルトではないユーザー名を使用し、強力なパスワードを設定してください。
  • security_groups: ブローカーに適用するセキュリティグループを指定します。RabbitMQのAMQPSポート(5671)と管理プラグインポート(15671)へのアクセスを、必要なソースIPアドレスやセキュリティグループに制限します。

my-secure-rabbitmq-cluster などのプレースホルダーは、実際の環境に合わせて修正してください。また、engine_version は常にAWSがサポートする最新のバージョンを使用するようにしてください。

最後に

この記事では、Amazon MQ for RabbitMQブローカーをクラスターデプロイメントモードで運用することの重要性について解説しました。この設定は、単一障害点のリスクを排除し、メッセージデータの耐久性を高め、計画的メンテナンス時のダウンタイムを回避し、システムの可用性と信頼性を大幅に向上させる上で不可欠です。 貴社のAmazon MQ RabbitMQブローカーは、クラスターデプロイメントモードで運用されていますか?この機会にぜひ設定を確認・強化してみてください。 こちらの内容の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。運用が非常にラクに出来る製品になっていますのでぜひ興味がある方はお問い合わせお待ちしております。

最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る