MongoDBのユーザ管理

#はじめに
MongoDBのユーザ管理について記します。
詳細は[公式マニュアル](https://docs.mongodb.com/manual/security/)をご覧下さい。

#概要
MongoDBはデフォルトの場合、認証・認可機能が有効になっておらず、無制限で使えます。ここでは、MongoDBの認証・認可機能の概要と使い方を記します。

MongoDBの認証方式にはSCRAM-SHA-1とMONGODB-CR(Challenge and Response)、X.509公開鍵認証が用意されており、デフォルトはSCRAM-SHA-1です(バージョン3.0以降)。Enterprise版ではさらに、Kerberos認証、LDAPプロキシ認証に対応しているそうです。

#作業の流れ
まず、MongoDBのユーザ管理者を登録します。
次に認証・認可を有効にします。
最後に一般ユーザを登録します。

#環境
| 使用環境 | バージョン |
| --- | --- |
| CentOS | 7.4.1708 |
| MongoDB | v3.4.9 |

#ユーザ管理者の登録
まずはユーザの管理者を登録します。これはcreate usersやgrant rolesなどで一般ユーザの登録や権限の割り当てを行うユーザで、userAdminロールやuserAdminAnyDatabaseロールを割り当てられたユーザになります。

MongoDBのユーザ情報はadminデータベースで管理します。adminデータベースに接続して、ユーザ管理者を登録します。

```
# MongoDBに接続する。
mongo

# adminデータベースに接続する。
use admin

# ユーザ管理者を登録する。
db.createUser({
  user:"管理者のID(adminなど)",
  pwd:"パスワード",
  roles:[{ role:"userAdminAnyDatabase", db:"admin" }]
})
```

#MongoDBの認証・認可を有効にする
認証・認可機能を有効にするため、MongoDBのインスタンスを再起動します。mongodの実行時に--authオプションを付けます。

```
mongod --auth --dbpath /var/lib/mongo
```

なお、systemctlで起動する場合、/etc/mongod.confに以下を追記します。

```
# security:のコメントアウトを外し忘れないように！
security:
  authorization: enabled
```

これで認証・認可が有効になりました。

# ユーザ管理者でログインする
ユーザ管理者でMongoDBに接続します。mongoコマンドで接続した後にdb.authを使ってユーザ管理者としてログインする方法と、mongoコマンドの実行時にユーザ管理者としてログインする方法があります。

* db.authで認証する方法

```
$ mongo
> use admin
> db.auth("管理者のID", "パスワード")
```

* mongoコマンドで認証する方法

```
$ mongo -u "ユーザ管理者" -p "パスワード" --authenticationDatabase="admin"
```

#ユーザ登録
ユーザを登録する際には登録先のデータベースを指定する必要があります。このデータベースをauthentication databaseと呼びます。
ユーザがmongoコマンドでログインする際には、--authenticationDatabaseオプションでこのデータベースを指定する必要があります。

なお、ユーザに権限を割り当てることで、authentication database以外のDBにも接続可能となります。

ユーザの登録は以下のコマンドとなります。

```
> use [データベース名(authentication databaseとなる)]
> db.createUser(
  {
    user: "ユーザ名",
    pwd:"パスワード",
    roles:[
       {role:"readWrite",  db:"使用するデータベース名"},
       {role:"readWrite",  db:"使用するデータベース名"},
       ・・・
    ]
  }
)
```

rolesには、このユーザが使用するデータベースとそのデータベースに対するロールを複数指定できます。

#接続してみる
作成したユーザでデータベースに接続するには以下を実行します。

```
$ mongod -u "ユーザ名" -p "パスワード" --authenticationDatabase="登録時に指定したauthentcation databaseの名前"
```

#ロール一覧
用意されているロールは以下の通り。詳細は[Built-In Roles](https://docs.mongodb.com/manual/reference/built-in-roles/)を参照のこと。

| 種別 | ロール名 | 概要 |
|---|---|---|
| Database User Roles | read | システム系のDBやコレクション以外のデータを読む権限 |
| | readWrite | システム系のDBやコレクション以外のデータを読み書きする権限 |
| Database Administration Roles | dbAdmin | データベースの管理権限 |
| | dbOwner | システム全体の管理権限。readWrite、dbAdmin、userAdminロールと関連付いている。|
| | userAdmin | ユーザやロールの管理者 |
| Cluster Administration Roles | clusterAdmin | クラスタの管理権限。clusterManager、clusterMonitor、hostManagerロールと紐付く。|
| | clusterManager | クラスタの運用管理権限 |
| | clusterMonitor | クラスタのモニタリングツールに対する参照権限 |
| | hostManager | サーバの運用管理権限 |
| Backup and Restore Roles | backup | データのバックアップ権限 |
| | restore | バックアップデータからのリストア権限 |
| ALL-Database Roles | readAnyDatabase | 全てのDBの読み取り権限 |
| | readWriteAnyDatabase | 全てのDBの読み書き権限 |
| | userAdminAnyDatabase | 全てのDBのユーザ管理権限 |
| | dbAdminAnyDatabase | 全てのDBのデータベース管理権限。dbAdminと同等。 |
| Superuser Roles | root | システム全体の管理権限。readWriteAnyDatabase、dbAdminAnyDatabase、userAdminAnyDatabase、clusterAdmin roles、restore、backupが紐付く。|
| Internal Role | __system | 内部処理用の権限。割り当ててはいけない。|