SQSキューの暗号化を有効化してメッセージを保護する手順

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

ポリシーの説明
Amazon Simple Queue Service (SQS) は、分散システム間のメッセージングを可能にするフルマネージドメッセージキューイングサービスです。SQSキューでサーバーサイド暗号化(SSE)を有効にすることで、キューに保存されるすべてのメッセージが保管時に自動的に暗号化されます。AWS Key Management Service (KMS) またはSQSマネージド暗号化を使用して、メッセージの機密性を保護し、コンプライアンス要件を満たすことができます。暗号化されたメッセージは、受信時に透過的に復号化されるため、アプリケーションの変更は不要です。
修復方法
コンソールでの修復手順
AWSのコンソールを使用して、SQSキューの暗号化を有効化します。
ステップ1: 対象キューの選択
- SQSコンソールでキュー一覧を表示
- 暗号化を有効にしたいキューを選択
- 「編集」ボタンをクリック
ステップ2: 暗号化の有効化
- 「暗号化」セクションにスクロール
- 「サーバー側の暗号化」を有効化
- 暗号化キーを選択(AWS管理またはカスタマー管理)
- データキー再利用期間を設定

ステップ3: 変更の保存
- 「変更の保存」をクリック
- 既存のメッセージも自動的に暗号化される
- 暗号化状態の確認(キューの詳細ページ)
Terraformでの修復手順
TerraformでSQSキューの暗号化を有効にするコードと、主要な修正ポイントを説明します。
# KMSキーの作成(カスタマー管理キーを使用する場合)
resource "aws_kms_key" "sqs_key" {
description = "KMS key for SQS queue encryption"
deletion_window_in_days = 10
enable_key_rotation = true # 年次の自動キーローテーション
tags = {
Name = "sqs-encryption-key"
Environment = "Production"
Purpose = "SQS Message Encryption"
}
}
# KMSキーエイリアスの作成
resource "aws_kms_alias" "sqs_key_alias" {
name = "alias/sqs-encryption"
target_key_id = aws_kms_key.sqs_key.key_id
}
# KMSキーポリシー(SQSサービスアクセス許可)
resource "aws_kms_key_policy" "sqs_key_policy" {
key_id = aws_kms_key.sqs_key.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable IAM User Permissions"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Allow SQS to use the key"
Effect = "Allow"
Principal = {
Service = "sqs.amazonaws.com"
}
Action = [
"kms:Decrypt",
"kms:GenerateDataKey"
]
Resource = "*"
}
]
})
}
# 標準キューの作成(暗号化有効)
resource "aws_sqs_queue" "encrypted_standard_queue" {
name = "encrypted-standard-queue"
visibility_timeout_seconds = 30
message_retention_seconds = 345600 # 4日間
max_message_size = 262144 # 256 KB
delay_seconds = 0
receive_wait_time_seconds = 10 # ロングポーリング
# 暗号化設定 - 最重要設定
# 注意: sqs_managed_sse_enabled と kms_master_key_id は排他的
sqs_managed_sse_enabled = false # KMS暗号化を使用する場合はfalse
kms_master_key_id = aws_kms_key.sqs_key.id # カスタマー管理キー
kms_data_key_reuse_period_seconds = 300 # 5分間(パフォーマンスとセキュリティのバランス)
# デッドレターキュー設定
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.dlq.arn
maxReceiveCount = 3
})
# タグ
tags = {
Name = "Encrypted Standard Queue"
Environment = "Production"
Encryption = "KMS-Enabled"
Compliance = "PCI-DSS-HIPAA"
}
}
# FIFOキューの作成(暗号化有効)
resource "aws_sqs_queue" "encrypted_fifo_queue" {
name = "encrypted-fifo-queue.fifo"
fifo_queue = true
content_based_deduplication = true
deduplication_scope = "queue"
fifo_throughput_limit = "perQueue"
# 暗号化設定 - SQSマネージド暗号化(SSE-SQS)を使用
sqs_managed_sse_enabled = true # SSE-SQSを有効化(コスト無料)
# FIFOキュー特有の設定
visibility_timeout_seconds = 30
message_retention_seconds = 345600
tags = {
Name = "Encrypted FIFO Queue"
Environment = "Production"
Encryption = "AWS-Managed"
Type = "FIFO"
}
}
# デッドレターキュー(暗号化有効)
resource "aws_sqs_queue" "dlq" {
name = "dead-letter-queue"
message_retention_seconds = 1209600 # 14日間(最大)
# DLQも暗号化
kms_master_key_id = aws_kms_key.sqs_key.id
kms_data_key_reuse_period_seconds = 300
tags = {
Name = "Dead Letter Queue"
Purpose = "Failed Message Storage"
}
}
# キューポリシー(アクセス制御)
resource "aws_sqs_queue_policy" "queue_policy" {
queue_url = aws_sqs_queue.encrypted_standard_queue.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowSendMessage"
Effect = "Allow"
Principal = {
AWS = var.producer_role_arns # メッセージ送信者のロールARN
}
Action = [
"sqs:SendMessage",
"sqs:GetQueueAttributes"
]
Resource = aws_sqs_queue.encrypted_standard_queue.arn
},
{
Sid = "AllowReceiveMessage"
Effect = "Allow"
Principal = {
AWS = var.consumer_role_arns # メッセージ受信者のロールARN
}
Action = [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes"
]
Resource = aws_sqs_queue.encrypted_standard_queue.arn
}
]
})
}
# CloudWatchアラーム(監視)
resource "aws_cloudwatch_metric_alarm" "queue_depth" {
alarm_name = "sqs-queue-depth-high"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "2"
metric_name = "ApproximateNumberOfMessagesVisible"
namespace = "AWS/SQS"
period = "300"
statistic = "Average"
threshold = "1000"
alarm_description = "Alert when queue depth exceeds 1000 messages"
alarm_actions = [aws_sns_topic.alerts.arn]
dimensions = {
QueueName = aws_sqs_queue.encrypted_standard_queue.name
}
}
# データソース
data "aws_caller_identity" "current" {}
# 変数定義
variable "producer_role_arns" {
description = "List of IAM role ARNs allowed to send messages"
type = list(string)
}
variable "consumer_role_arns" {
description = "List of IAM role ARNs allowed to receive messages"
type = list(string)
}
# 出力値
output "queue_url" {
value = aws_sqs_queue.encrypted_standard_queue.url
description = "URL of the encrypted SQS queue"
}
output "queue_arn" {
value = aws_sqs_queue.encrypted_standard_queue.arn
description = "ARN of the encrypted SQS queue"
}
output "kms_key_id" {
value = aws_kms_key.sqs_key.id
description = "KMS key ID used for encryption"
sensitive = true
}
主要な修正ポイント
- sqs_managed_sse_enabled:
true
でSQSマネージド暗号化(SSE-SQS)を使用(コスト無料) - kms_master_key_id: KMSキーを使用する場合のキーのIDまたはARNを指定
- kms_data_key_reuse_period_seconds: データキー再利用期間(60-86400秒)
- enable_key_rotation: KMSキーの年次自動ローテーションを有効化
- redrive_policy: デッドレターキューも同様に暗号化を設定
最後に
この記事では、SQSキューの暗号化を有効化してメッセージを保護する手順について、包括的なリスク分析と具体的な修復方法を解説しました。
SQSキューの暗号化は、メッセージの機密性を保護し、PCI DSS、HIPAA、GDPRなどのコンプライアンス要件を満たすために不可欠です。SQSマネージド暗号化(SSE-SQS)またはKMS暗号化(SSE-KMS)を使用して、すべてのキューで暗号化を有効にすることを強く推奨します。既存のキューも簡単に暗号化を有効化できるため、速やかに対応してセキュリティリスクを軽減してください。
この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。 運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。 最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。