MongoDB本番環境のセキュリティ:SCRAM、RBAC、TLS暗号化によるクラスタの堅牢化

Security tutorial - IT technology blog
Security tutorial - IT technology blog

アーキテクチャの比較:チームによるMongoDBセキュリティ実装の違い

エンジニアリングチームにおけるMongoDBのセキュリティ管理は、一般的に成熟度に応じて次の3段階に分類されます。

  • 境界防御のみの分離(VPCおよびファイアウォールルール):認証を無効にした状態でデータベースを運用し、プライベートサブネット、セキュリティグループ、VPNトンネルのみに依存して侵入を防ぐ手法です。
  • 共有管理者アカウントによる基本認証:認証は有効化されているものの、マイクロサービスが暗号化されていないTCP接続経由でrootやdbAdminAnyDatabaseなどの広範な管理者権限を使用して接続している状態です。
  • 多層防御(SCRAM-SHA-256、きめ細かなRBAC、TLS 1.3):すべてのサービスがソルト付きチャレンジレスポンス認証を用いた最小権限の個別アカウントで接続し、クライアント・ノード間およびレプリカ間のすべての通信が厳格に暗号化されている状態です。

MongoDBセキュリティ戦略の評価

採用するセキュリティ境界モデルは、開発速度、デバッグのオーバーヘッド、インシデント発生時の被害範囲の封じ込めに直接影響します。本番環境においてこれら3つの戦略がどのように機能するかを比較します。

1. 境界防御のみの分離

  • メリット:認証情報の管理オーバーヘッドが一切不要。接続プールの急増時におけるTLSハンドシェイクの初期レイテンシ(約1〜3ミリ秒)を削減可能。ローカルやステージング環境の構築が容易。
  • デメリット:極めて脆弱。単一のSSRF(サーバーサイド・リクエスト・フォージェリ)脆弱性や侵害されたワーカーノードが1つあるだけで、ポート27017経由ですべてのデータベースが露出します。データアクセスに関する監査証跡も残りません。

2. 共有管理者アカウントによる基本認証

  • メリット:迅速にセットアップ可能。形式的なコンプライアンス要件を満たし、特別な設定なしでレガシーな古いドライバーとも互換性を維持できます。
  • デメリット:セキュリティ侵害時の被害範囲が甚大。アナリティクス用ワーカーの認証情報が漏洩した場合、攻撃者に課金データやユーザー情報の書き込み権限まで奪われます。また、内部トラフィックが暗号化されていないため、共有サブネット上でのパケット盗聴に対しても脆弱です。

3. 多層防御(本番環境の標準)

  • メリット:侵害されたサービスの影響範囲を特定のコレクションのみに隔離。15,000回のPBKDF2ハッシュ処理により、転送中のパスワードを保護。SOC 2、HIPAA、PCI-DSS 4.0の必須要件にも準拠。
  • デメリット:証明書の自動更新や、CI/CDパイプラインにおけるデータベースユーザーの体系的なプロビジョニングが必要になります。

堅牢なデプロイメントを構成する主要コンポーネント

本番環境のデータベースには、基本となる3つのセキュリティレイヤーが不可欠です。

  1. SCRAM-SHA-256認証:旧来のMONGODB-CRやSCRAM-SHA-1プロトコルを置き換えるものです。HMAC-SHA-256と15,000回のPBKDF2反復処理を採用しており、万が一パスワードハッシュが漏洩した場合でもオフライン辞書攻撃を防ぎます。
  2. きめ細かなロールベースアクセス制御(RBAC):単一コレクションに対するreadWriteなど、アプリケーションに必要最小限の操作権限のみを付与し、管理操作は専用の踏み台ホスト(ジャンプホスト)に限定します。
  3. TLS 1.2/1.3の必須化:暗号化されていないTCP接続を即座に切断します。クライアント・サーバー間のすべてのクエリに加え、ノード境界を越えたレプリカセット内部の同期通信も保護します。

ステップ別の実装ガイド

新規にデプロイしたスタンドアロンノードやレプリカセットメンバーを、本番基準のセキュリティレベルへ引き上げる手順を説明します。

ステップ1:高エントロピーなパスワードの生成

設定ファイルを編集する前に、クラスタ管理者、バックアップエージェント、およびアプリケーションサービス用に、32文字以上(128ビット以上のエントロピー)の一意なパスワードを生成します。toolcraft.app/ja/tools/security/password-generator のブラウザベース生成ツールを利用すれば、ネットワーク経由でキーを送信することなく、Web Crypto APIによりローカル環境でエントロピーを生成できます。

ステップ2:クラスタ管理者のブートストラップ

データベースホスト上でローカルシェルを開き、mongoshを使用して未認証のインスタンスに接続します。

# 認証を有効化する前にローカルデーモンへ直接接続
mongosh --port 27017

adminデータベースに切り替え、SCRAM-SHA-256を使用して管理用のrootユーザーを作成します。

use admin;

db.createUser({
  user: "secAdmin",
  pwd: "ここに32文字以上の管理者パスワードを入力!",
  roles: [
    { role: "userAdminAnyDatabase", db: "admin" },
    { role: "readWriteAnyDatabase", db: "admin" },
    { role: "clusterAdmin", db: "admin" }
  ],
  mechanisms: ["SCRAM-SHA-256"]
});

ステップ3:最小権限のアプリケーションユーザーのプロビジョニング

マイクロサービス間で管理者認証情報を共有してはなりません。各サービスは専用のデータベースコンテキストに分離してください。

use orders_prod;

db.createUser({
  user: "svc_orders_app",
  pwd: "OrdersApp_SecureSecret_9876!",
  roles: [
    { role: "readWrite", db: "orders_prod" }
  ],
  mechanisms: ["SCRAM-SHA-256"]
});

読み取り処理が主体のレポート作成やキャッシュウォーミング用サービスには、読み取り権限のみを付与します。

use catalog_prod;

db.createUser({
  user: "svc_analytics_ro",
  pwd: "Analytics_ReadOnlySecret_5432!",
  roles: [
    { role: "read", db: "catalog_prod" }
  ],
  mechanisms: ["SCRAM-SHA-256"]
});

ステップ4:TLS証明書の準備

MongoDBでは、サーバー証明書と暗号化されていない秘密鍵を1つのPEMバンドルファイルに結合する必要があります。

# 秘密鍵とサーバー証明書を結合
cat /etc/ssl/certs/mongo-server.key /etc/ssl/certs/mongo-server.crt > /etc/ssl/certs/mongodb.pem

# ファイルのパーミッションをmongodシステムユーザーのみに制限
chmod 600 /etc/ssl/certs/mongodb.pem
chown mongodb:mongodb /etc/ssl/certs/mongodb.pem

ステップ5:mongod.confでのセキュリティポリシー適用

/etc/mongod.confを編集し、特定のプライベートIPインターフェースへのバインド、TLSの必須化、SCRAM認証の適用を設定します。

net:
  port: 27017
  bindIp: 127.0.0.1,10.0.1.15  # ループバックおよびプライベートVPCインターフェースのみにバインド
  tls:
    mode: requireTLS
    certificateKeyFile: /etc/ssl/certs/mongodb.pem
    CAFile: /etc/ssl/certs/ca.pem
    disabledProtocols: TLS1_0,TLS1_1

security:
  authorization: enabled
  authenticationMechanisms:
    - SCRAM-SHA-256

processManagement:
  timeZoneInfo: /usr/share/zoneinfo

デーモンを再起動して新しいポリシーを適用します。

sudo systemctl restart mongod
sudo systemctl status mongod

ステップ6:認証済み接続および暗号化接続のテスト

未認証接続や平文のTCP接続が拒否されることを確認します。CA証明書とアプリケーションアカウントを使用して接続テストを行います。

# TLSとSCRAM-SHA-256を使用してmongosh経由で接続
mongosh "mongodb://[email protected]:27017/orders_prod" \
  --tls \
  --tlsCAFile /etc/ssl/certs/ca.pem \
  --authenticationMechanism SCRAM-SHA-256 \
  --password "OrdersApp_SecureSecret_9876!"

アプリケーションドライバー(Node.js、Python PyMongo、Goなど)の場合は、次の標準URIフォーマットを使用します。

mongodb://svc_orders_app:[email protected]:27017/orders_prod?authSource=orders_prod&authMechanism=SCRAM-SHA-256&tls=true&tlsCAFile=/etc/ssl/certs/ca.pem

ステップ7:アクセス制御境界の検証

サービスアカウントが制限された管理用名前空間にアクセスできないことをテストします。

// svc_orders_appとしてログイン中
use admin;
db.system.users.find(); // 結果: MongoServerError: not authorized on admin to execute command (code 13)

認証失敗(コード18)やハンドシェイク切断がないか、/var/log/mongodb/mongod.logを定期的に確認してください。これにより、クレデンシャルスタッフィング攻撃やドライバーの設定不備を監査パイプラインで早期に検知できます。

Share: