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は起動を自動的に中断します。
