Neptune DB クラスターIAM データベース認証を有効化する手順

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。
この記事では、「[Neptune.7] Neptune DB クラスターでは、IAM データベース認証が有効になっている必要があります」について、リスクと対策を解説します。

ポリシーの説明
Neptune の Security Hub コントロール – AWS Security Hub
このコントロールは、Neptune DB クラスターで IAM データベース認証が有効になっているかどうかをチェックします。Neptune DB クラスターで IAM データベース認証が有効になっていない場合、コントロールは失敗します。
リスク
Amazon Neptuneは、高速で信頼性の高いグラフデータベースサービスです。Neptune DBクラスターへの認証に従来のパスワードではなくIAMデータベース認証を使用していない場合、以下のようなセキュリティと運用上のリスクが発生します。
- 認証情報の管理負担と漏洩リスク: 従来のパスワード認証では、データベースユーザーのパスワードを個別に管理、ローテーション、安全に保管する必要があります。これにより、管理が複雑になり、ハードコードされたパスワードや不適切な管理による認証情報の漏洩リスクが高まります。パスワードが漏洩すると、不正アクセスによるデータ侵害に直結します。
- 権限管理の粒度の粗さ: IAMデータベース認証を使用しない場合、AWS IAMのきめ細やかなアクセス制御(最小特権の原則)をデータベースアクセスに直接適用できません。特定のIAMユーザーやロールからのアクセスを制限したり、詳細な条件に基づいてアクセスを許可したりすることが困難になります。これにより、過剰な権限が付与されたユーザーが存在するリスクが生じます。
- 監査証跡の不十分さ: 従来の認証方法では、データベースへのアクセス元がAWSのどのIAMエンティティであるかを直接特定するのが難しい場合があります。IAMデータベース認証を有効にすると、すべての接続試行がAWS CloudTrailに記録され、誰が、いつ、どこからデータベースにアクセスしたかという詳細な監査証跡が得られます。これにより、セキュリティ監査の精度が向上し、不正アクセスを迅速に特定できます。
- コンプライアンス違反: 多くの規制要件(例: GDPR, HIPAA, PCI DSS)では、認証情報の厳格な管理、アクセス制御の徹底、および包括的な監査証跡の保持が求められます。IAMデータベース認証を使用しない場合、これらのコンプライアンス要件を満たせず、法的リスクや罰金に直面する可能性があります。
- 通信の暗号化の欠如: IAMデータベース認証は、接続にTLS (Transport Layer Security) を強制します。これにより、クライアントとNeptune DBクラスター間のデータ転送が自動的に暗号化され、通信傍受による情報漏洩のリスクを低減できます。従来のパスワード認証では、TLS/SSLの有効化と管理を別途行う必要があります。
対策
Neptune DBクラスターでIAMデータベース認証を有効にすることは、これらのリスクを軽減し、セキュリティと運用効率を大幅に向上させるためのベストプラクティスです。
- IAMデータベース認証の有効化: Neptuneクラスターを作成または変更する際に、IAMデータベース認証を有効にします。
- IAMポリシーの作成と適用: データベースにアクセスするIAMユーザーまたはIAMロールに対して、
neptune-db:connect
アクションを許可する適切なIAMポリシーを作成します。このポリシーでは、アクセスを許可するデータベースユーザー名(または)と、対象のNeptuneクラスターリソースのARNを詳細に指定します。 - Neptune DBユーザーの作成: 接続時にはIAMロールまたはIAMユーザー名がデータベースユーザーとして機能します。例えば、
aws_iam_user
やaws_iam_role
で指定された名前でDBユーザーが動作します。 - アプリケーションからの接続方法の更新: アプリケーションやクライアントがデータベースに接続する際、従来のパスワードではなく、AWS SDKやIAM認証に対応したNeptuneドライバー(例えば、GremlinやOpenCypherクライアント)を使用して一時的な認証トークンを取得し、それを使用して接続するようにコードを更新します。
- CloudTrailとの統合: IAMデータベース認証によるすべての接続試行はAWS CloudTrailに記録されます。これらのログをCloudWatch Logsに連携し、異常なアクセスパターンを検知するためのアラートを設定することで、監視体制を強化します。
- 最小特権の原則の適用: IAMポリシーを厳密に定義し、データベースへのアクセス権限を必要最小限に抑えることで、セキュリティリスクをさらに低減します。
修復方法
AWSコンソールでの修復手順
AWSコンソールを使用して、Amazon Neptune DBクラスターでIAMデータベース認証を有効にします。
- Amazon Neptuneサービスへ移動: AWSコンソールにログインし、Amazon Neptuneサービスを開きます。
- クラスターの選択: 左側のナビゲーションペインで「データベース」を選択し、IAMデータベース認証を有効にしたいNeptune DBクラスターを選択します。
- クラスターの変更: クラスターの詳細ページの上部にある「変更」ボタンをクリックします。
- IAM DB認証の有効化: 「認証」セクションまでスクロールします。 「IAM 認証を有効にする」にチェックを入れます。
- 変更の適用: 変更画面の最下部にある「変更の適用」セクションで、変更をいつ適用するかを選択します。
- すぐに適用: クラスターのメンテナンスウィンドウを待たずに変更が適用されます。場合によっては、クラスターの短時間のダウンタイムが発生する可能性があります。
- 次のメンテナンスウィンドウで適用: 次に予定されているメンテナンスウィンドウ中に変更が適用されます。 選択後、「クラスターを変更」をクリックして設定を完了します。
- (重要)IAMポリシーの設定: IAMコンソールに移動し、データベースにアクセスするIAMユーザーやIAMロールに、
neptune-db:connect
アクションを許可するポリシーをアタッチします。

Terraformでの修復手順
TerraformでNeptune DBクラスターのIAMデータベース認証を有効にするには、aws_neptune_cluster
リソースの iam_database_authentication_enabled
パラメータを true
に設定します。
# Neptune DBクラスターの定義
resource "aws_neptune_cluster" "my_neptune_cluster" {
cluster_identifier = "my-neptune-cluster"
engine = "neptune"
engine_version = "1.2.0.0" # 使用するエンジンバージョンに合わせて変更
db_subnet_group_name = aws_neptune_subnet_group.main_neptune_subnet_group.name
vpc_security_group_ids = [aws_security_group.neptune_sg.id]
skip_final_snapshot = true # 本番環境では false に設定し、最終スナップショットを取得することを推奨
preferred_maintenance_window = "mon:03:00-mon:04:00" # メンテナンスウィンドウを指定 (オプション)
# IAMデータベース認証を有効化
iam_database_authentication_enabled = true
tags = {
Name = "MyNeptuneClusterWithIAMAuth"
Environment = "Development"
}
}
# Neptune DBインスタンスの定義 (クラスターに紐づくインスタンス)
resource "aws_neptune_cluster_instance" "cluster_instances" {
count = 1 # 必要なインスタンス数に調整 (最小1、通常は複数AZに配置)
identifier = "my-neptune-instance-${count.index}"
cluster_identifier = aws_neptune_cluster.my_neptune_cluster.id
instance_class = "db.r5.large" # インスタンスクラスを適切なものに調整
engine = "neptune"
publicly_accessible = false # 公開アクセスは無効にすることを推奨
}
# DBサブネットグループの定義
resource "aws_neptune_subnet_group" "main_neptune_subnet_group" {
name = "main-neptune-subnet-group"
subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_c.id] # あなたのプライベートサブネットIDに置き換え
tags = {
Name = "MainNeptuneSubnetGroup"
}
}
# セキュリティグループの定義 (Neptuneへのアクセスを許可)
resource "aws_security_group" "neptune_sg" {
name = "neptune-security-group"
description = "Allow inbound traffic to Neptune cluster"
vpc_id = aws_vpc.main.id
ingress {
from_port = 8182 # Neptuneのデフォルトポート
to_port = 8182
protocol = "tcp"
# ここにNeptuneにアクセスするEC2インスタンスやLambdaのセキュリティグループIDなどを設定
# 例: security_groups = [aws_security_group.app_sg.id]
# または、より限定されたCIDRブロックを設定
cidr_blocks = ["10.0.0.0/16"] # 適切なIP範囲に制限してください
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "NeptuneSecurityGroup"
}
}
# VPCおよびサブネットの定義例 (必要に応じて)
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main-vpc"
}
}
resource "aws_subnet" "private_a" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.10.0/24"
availability_zone = "ap-northeast-1a" # あなたのリージョンに合わせて変更
tags = {
Name = "private-subnet-a"
}
}
resource "aws_subnet" "private_c" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.11.0/24"
availability_zone = "ap-northeast-1c" # あなたのリージョンに合わせて変更
tags = {
Name = "private-subnet-c"
}
}
# (オプション) データベースにアクセスするIAMロールの定義例
resource "aws_iam_role" "neptune_access_role" {
name = "application-neptune-access-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com" # EC2インスタンスからアクセスする場合
}
},
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com" # Lambda関数からアクセスする場合
}
},
]
})
}
# (オプション) IAMロールにDB接続権限を付与するポリシー
resource "aws_iam_policy" "neptune_connect_policy" {
name = "application-neptune-connect-policy"
description = "Policy for application to connect to Neptune via IAM"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = "neptune-db:connect"
Resource = "arn:aws:neptune-db:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:cluster:${aws_neptune_cluster.my_neptune_cluster.cluster_identifier}"
},
]
})
}
# (オプション) IAMロールにポリシーをアタッチ
resource "aws_iam_role_policy_attachment" "neptune_access_attach" {
role = aws_iam_role.neptune_access_role.name
policy_arn = aws_iam_policy.neptune_connect_policy.arn
}
# (オプション) EC2インスタンスにロールをアタッチするためのインスタンスプロファイル
resource "aws_iam_instance_profile" "neptune_access_profile" {
name = "application-neptune-access-profile"
role = aws_iam_role.neptune_access_role.name
}
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
上記のTerraformコードでは、aws_neptune_cluster
リソースの iam_database_authentication_enabled = true
を設定することで、IAMデータベース認証を有効にしています。
また、aws_iam_policy
と aws_iam_role_policy_attachment
を使用して、指定したIAMロールが特定のNeptuneクラスターに接続できる権限を付与する方法も示しています。my-neptune-cluster
やサブネットIDなどのプレースホルダーは、実際の環境に合わせて修正してください。
最後に
この記事では、Neptune DBクラスターでIAMデータベース認証が有効になっていない状態について、リスクと対策を解説しました。IAMデータベース認証を導入することは、Neptuneへのアクセスをより安全に、より効率的に管理するための重要なステップです。パスワード管理の負担軽減、きめ細やかな権限制御、監査証跡の強化、そして自動的な通信暗号化といったメリットを享受できます。
この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。
運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。
最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。