Linux環境におけるMongoDBサーバーセキュリティ設定ガイド:RBAC、TLS、Encryption at Restの構築

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

1. クイックスタート(5分でポートを保護)

UbuntuやCentOSにインストールした直後のMongoDBは、デフォルトで認証が無効になっており、誰でもアクセスできる状態です。誤ってポート27017をインターネットに公開してしまうと、Shodanなどの自動スキャンツールにより数分でデータベースが検出されてしまいます。以下は、このリスクを即座に遮断するための最速手順です。

ステップ 1: root管理者アカウントの作成

サーバーのターミナルを開き、MongoDBシェルにアクセスします:

mongosh

adminデータベースに切り替え、最高権限を持つ管理者アカウントを作成します:

use admin
db.createUser({
  user: "siteRootAdmin",
  pwd: "MatKhauCucKyPhucTap123!@#",
  roles: [ { role: "root", db: "admin" } ]
})
exit

ステップ 2: 設定ファイルで認証を有効化

root権限で/etc/mongod.confファイルを開きます:

sudo nano /etc/mongod.conf

securityセクションを探し、authorization(認可)機能を有効にします:

security:
  authorization: enabled

さらにnetセクションを確認し、MongoDBが外部へ意図せずバインドされていないことを確認します:

net:
  port: 27017
  bindIp: 127.0.0.1

ステップ 3: サービスの再起動と接続確認

sudo systemctl restart mongod

# 作成したユーザーでログインをテスト
mongosh -u siteRootAdmin -p --authenticationDatabase admin

これで、有効なユーザー名とパスワードを持たない接続はすべて即座に拒否されます。

2. 本番環境向け3層防御の実践

インフラの現場では、開発者が4〜5個のマイクロサービスの.envファイルにrootユーザーをそのまま記述してしまうケースをよく見かけます。これでは1つのサービスに脆弱性があるだけで、攻撃者にデータベースクラスター全体を掌握されてしまいます。安全に運用するためには、RBAC、TLS、Encryption at Restの3層の防御壁を構築する必要があります。

第1層: ロールベースアクセス制御(RBAC)

最も重要な原則は「最小権限の原則」です。バックエンドサービスに必要な操作のみ、指定したデータベースに対して許可します。

例えば、ecommerce_dbに対するreadWrite権限のみを持つAPIバックエンド用アカウントを作成する場合:

use ecommerce_db
db.createUser({
  user: "app_backend",
  pwd: "AppSecurePassword_2026_!$",
  roles: [
    { role: "readWrite", db: "ecommerce_db" }
  ]
})

データベースのパスワードや内部接続用のシークレットには、最低24〜32文字のランダムな文字列を生成してください。ToolCraftのPassword Generatorを利用すると手軽に作成できます。このツールはブラウザ側(クライアントサイド)で100%処理され、サーバーにデータを送信しないため、シークレットキーの生成時にも安全です。

第2層: TLS/SSLによる通信経路の暗号化

MongoDBサーバーとバックエンドアプリが別々のVPS上に配置されている場合、TLSを有効にしていないとネットワーク上のパケットを盗聴される危険があります。証明書と秘密鍵を1つのPEMファイル(例: /etc/ssl/mongodb.pem)にまとめておきましょう。

/etc/mongod.confファイルでTLSを設定します:

net:
  port: 27017
  bindIp: 127.0.0.1,10.0.1.15
  tls:
    mode: requireTLS
    certificateKeyFile: /etc/ssl/mongodb.pem
    CAFile: /etc/ssl/ca.crt

mongodを再起動し、CA証明書を指定して接続テストを行います:

mongosh --tls --tlsCAFile /etc/ssl/ca.crt -u app_backend -p --authenticationDatabase ecommerce_db

3. 応用: データ保存時の暗号化(Encryption at Rest)

保存データの暗号化を行うことで、ディスクスナップショットが誤って流出したり、物理ドライブが盗難に遭ったりした場合でもデータを保護できます。

アプローチ 1: ネイティブWiredTiger暗号化(MongoDB Enterprise)

Enterprise版では、キーファイルを指定することでWiredTigerストレージエンジンを直接暗号化できます:

# ランダムな32バイトのキーファイルを生成し、厳格に権限を設定
openssl rand -base64 32 | sudo tee /etc/mongodb-keyfile
sudo chown mongodb:mongodb /etc/mongodb-keyfile
sudo chmod 400 /etc/mongodb-keyfile

/etc/mongod.confでキーファイルのパスを指定します:

security:
  authorization: enabled
  enableEncryption: true
  encryptionKeyFile: /etc/mongodb-keyfile

アプローチ 2: ブロックデバイス層での暗号化(MongoDB Community)

Community版にはenableEncryptionフラグが用意されていません。最も実用的な方法は、データディレクトリ/var/lib/mongodbをカーネルレベルの暗号化パーティション(LUKS)上に配置するか、fscryptを利用することです。これにより、データ本体、インデックス、ジャーナルログ(journal)がすべて透過的に暗号化されます。I/Oパフォーマンスの低下は通常2〜4%程度に抑えられ、本番環境でも十分に実用可能です。

4. 現場で役立つ運用のTips

  • 再起動前にYAMLの構文をチェックする: mongod.confはスペースのインデントが1つズレていたりタブが混入していたりするだけで、サービス再起動時にエラーで停止します。YAML ↔ JSON Converterなどのツールを使って事前にファイル構造を検証し、フォーマットエラーを未然に防ぎましょう。
  • UFWファイアウォールでポートを制限する: ポート27017へのアクセスは、バックエンドの内部IPからのみ許可します:
    sudo ufw default deny incoming
    sudo ufw allow from 10.0.1.20 to any port 27017 proto tcp
    sudo ufw reload
  • データベースプロファイラーの扱いに注意する: 本番環境でprofile: 2(すべてのクエリを記録)を有効化しないでください。ログイン失敗時や機密データの更新時に、/var/log/mongodb/mongod.logへ平文のパスワードが出力されてしまう恐れがあります。
  • キーファイルのパーミッションは常に400に制限する: TLS証明書や暗号化キーファイルはすべてmongodb:mongodbユーザーが所有し、読み取り専用(chmod 400)にする必要があります。キーファイルの権限設定が緩い場合、MongoDBは起動を自動的に中断します。
Share: