MongoDB 基本的なセキュリティ設定

スポンサーリンク

MongoDBの基本的なセキュリティ設定についてまとめます。接続を許可するインターフェースを指定したりポート番号を変えたりユーザ認証をしたりする方法をまとめます。

前提

公式ドキュメント

参考になる公式ドキュメントを以下に示します。

動作確認済環境

  • Rocky Linux 8.6
  • MongoDB Server 6.0.2

構成図

以下の構成で動作確認をします。

                   172.16.1.0/24
        +-----------------+-----------------+
        |                 |                 |
 ens192 | .10      ens192 | .20      ens192 | .30
 +------+------+   +------+------+   +------+------+ 
 |  linux010   |   |  linux020   |   |  linux030   | 
 | (Rocky8.6)  |   | (Rocky8.6)  |   | (Rocky8.6)  | 
 | (Primary)   |   | (Secondary) |   | (Secondary) | 
 +------+------+   +------+------+   +------+------+
 ens224 | .10      ens224 | .20      ens224 | .30
        |                 |                 |
        +-----------------+-----------------+
                   172.16.2.0/24

事前設定

検証シナリオの都合上、「非レプリケーション構成」「レプリケーション構成」の順に動作確認をします。

初期設定時点ではレプリケーションを設定しない状態とします。

ネットワーク接続許可関連の設定

MongoDBはListen状態にするインターフェースを指定したりListenするポート番号を変更したりする事ができます。/etc/mongod.confのnetに関する記述を以下のように変更し、mongodを再起動して設定を反映させます。

net以外の部分は説明を省略します

net:
  port: 27100
  bindIp: 172.16.1.10
net:
  port: 27100
  bindIp: 172.16.1.20
net:
  port: 27100
  bindIp: 172.16.1.30

本シナリオを構成は172.16.1.0/24と172.16.2.0/24の2つのサブネットを持つ構成です。前者の172.16.1.0/24のみmongodがListen状態になるように設定しました。それでは172.16.1.0/24のみ接続可能である事を確認しましょう。

linux020からlinux010に対して、172.16.1.0/24セグメント経由で疎通可能な事を確認します。

[root@linux020 ~]# ping 172.16.1.10 -c 1
PING 172.16.1.10 (172.16.1.10) 56(84) bytes of data.
64 bytes from 172.16.1.10: icmp_seq=1 ttl=64 time=0.509 ms

--- 172.16.1.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.509/0.509/0.509/0.000 ms
[root@linux020 ~]# mongosh --quiet mongodb://172.16.1.10:27100/test
test> 

linux020からlinux010に対して、172.16.2.0/24セグメント経由の接続を試みます。接続が拒否される事を確認します。

[root@linux020 ~]# ping 172.16.2.10 -c 1
PING 172.16.2.10 (172.16.2.10) 56(84) bytes of data.
64 bytes from 172.16.2.10: icmp_seq=1 ttl=64 time=0.456 ms

--- 172.16.2.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.456/0.456/0.456/0.000 ms
[root@linux020 ~]# mongosh --quiet mongodb://172.16.2.10:27100/test
MongoNetworkError: connect ECONNREFUSED 172.16.2.10:27100
[root@linux020 ~]# 

RBAC(Role-Based Access Control)

スタンドアローン構成の場合

ユーザ作成と認証有効化

MongoDBはロール(役割)ベースの権限管理の機能を備えています。さっそく動作確認をしてみましょう。

sample01データベースに対するデータベース管理者を作成します。MongoDBにビルトインで組み込まれているロールを使うならば”dbOwner”と指定します。

use sample01
db.createUser({
  user: "dba01",
  pwd: "P@ssw0rd",
  roles: [{role: "dbOwner", db: "sample01"}]
})

sample02データベースに対しても同様のデータベース管理者を作成します。

use sample02
db.createUser({
  user: "dba02",
  pwd: "P@ssw0rd",
  roles: [{role: "dbOwner", db: "sample02"}]
})

MongoDBに対するrootの管理者を作成します。

use admin
db.createUser({
  user: "admin",
  pwd: "P@ssw0rd",
  roles: [{role: "root", db: "admin"}]
})

想定通りのユーザが作成されたか否かはgetUsers()で確認できます。

admin> use sample01
switched to db sample01
sample01> db.getUsers()
{
  users: [
    {
      _id: 'sample01.dba01',
      userId: new UUID("18dc2907-027e-44db-b3b7-c5b4acb1b594"),
      user: 'dba01',
      db: 'sample01',
      roles: [ { role: 'dbOwner', db: 'sample01' } ],
      mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
    }
  ],
  ok: 1
}
sample01> 

スタンドアローン構成で認証を有効にするにはsecurity.authorizationをenabledに変更します。/etc/mongod.confのsecurityに関する記述を以下のように変更し、mongodを再起動して設定を反映させます。

security以外の部分は説明を省略します

security:
  authorization: enabled

動作確認

それでは認証なしで接続してみましょう。すると、コマンド実行時にエラーが返される事が分かります。

[root@linux010 ~]# mongosh --quiet mongodb://172.16.1.10:27100/test
test> show dbs
MongoServerError: command listDatabases requires authentication
test> 

sample01データベースにdba01ユーザで接続します。この場合は適切な権限が与えられているので、Collection作成などの操作が可能です。

[root@linux010 ~]# mongosh --quiet mongodb://172.16.1.10:27100/sample01 -u dba01 -p P@ssw0rd
sample01> db.createCollection('employee')
{ ok: 1 }
sample01> db.employee.insertOne({name:"scott",password:"tiger"})
{
  acknowledged: true,
  insertedId: ObjectId("63539e3cf4a1e4ac16211a6d")
}
sample01>

sample02データベースにdba01ユーザでの接続を試みます。この場合は、権限がないので接続そのものを拒否されます。

[root@linux010 ~]# mongosh --quiet mongodb://172.16.1.10:27100/sample02 -u dba01 -p P@ssw0rd
MongoServerError: Authentication failed.
[root@linux010 ~]# 

レプリケーション構成の場合

KeyFileの作成

それではレプリケーション構成の認証を動作確認しましょう。まずはレプリケーション構成に変更するために、/etc/mongod.confに以下を加筆します。

replication:
  replSetName: "rs0"
  oplogSizeMB: 1024

設定反映のための再起動を試みます。すると、レプリケーション構成の場合はsecurity.keyFileというパラメタが必須である旨のエラーメッセージが出力されます。

[root@linux010 ~]# systemctl restart mongod.service 
Job for mongod.service failed because the control process exited with error code.
See "systemctl status mongod.service" and "journalctl -xe" for details.
[root@linux010 ~]# journalctl -xe
10月 22 16:42:42 linux010.gokatei.go systemd[1]: Starting MongoDB Database Server...
-- Subject: Unit mongod.service has begun start-up
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- Unit mongod.service has begun starting up.
10月 22 16:42:42 linux010.gokatei.go mongod[3088]: BadValue: security.keyFile is required when authorization is enabled with replica sets
10月 22 16:42:42 linux010.gokatei.go mongod[3088]: try '/usr/bin/mongod --help' for more information
10月 22 16:42:42 linux010.gokatei.go systemd[1]: mongod.service: Control process exited, code=exited status=2
10月 22 16:42:42 linux010.gokatei.go systemd[1]: mongod.service: Failed with result 'exit-code'.
-- Subject: Unit failed
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- The unit mongod.service has entered the 'failed' state with result 'exit-code'.
10月 22 16:42:42 linux010.gokatei.go systemd[1]: Failed to start MongoDB Database Server.
-- Subject: Unit mongod.service has failed
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- Unit mongod.service has failed.
-- 
-- The result is failed.

security.keyFileは6文字から1024文字でbase64された文字列のファイルを指定します。このファイルを用いる事によって、レプリケーションを組む(正確にはシャーディング構成のmongosやconfigサーバも含まれる)MongoDB同士の認証をします。

それではkeyFileを作成しましょう。以下は756文字のキーファイルを作成する操作例です。

openssl rand -base64 756 > /etc/mongoKey.txt
chown mongod:mongod /etc/mongoKey.txt
chmod 400 /etc/mongoKey.txt

作成したキーファイルをすべてのMongoDBサーバへ転送します。

パーミッション含めて正確にコピーください。scpはユーザ含めて転送されませんので、scpコマンドを使用する場合は再度の権限設定が必要です。

rsync -av /etc/mongoKey.txt 172.16.1.20:/etc/
rsync -av /etc/mongoKey.txt 172.16.1.30:/etc/

KeyFileの設定

/etc/mongod.confを以下のように設定し、replicationとkeyFileを設定します。

security.keyFileを設定した場合は、security.authorizationを明示指定しなくても暗黙的に有効になります。

#replication:
replication:
  replSetName: "rs0"
  oplogSizeMB: 1024

#security:
security:
  authorization: enabled
  keyFile: /etc/mongoKey.txt

mongodを再起動し、設定を反映させます。

systemctl restart mongod.service

レプリケーションの開始

レプリケーションを開始するにはroot権限が必要です。root権限を持っているのはadminユーザですのでadminユーザでmongodへログインします。その後、rs.initiate()メソッドによりレプリケーションを開始できます。

[root@linux010 ~]# mongosh --quiet mongodb://172.16.1.10:27100/admin -u admin -p P@ssw0rd
admin> rs.initiate(
...   {
...     _id : "rs0",
...     members: [
...       { _id : 0, host : "172.16.1.10:27100" , priority : 2 },
...       { _id : 1, host : "172.16.1.20:27100" , priority : 1 },
...       { _id : 2, host : "172.16.1.30:27100" , priority : 0 }
...     ]
...   }
... )
{ ok: 1 }
rs0 [direct: other] admin> 

rs0 [direct: primary] admin> 
タイトルとURLをコピーしました