概要
下記のURLの記事は2019年5月8日の記事でMongoDBがパスワードなしでアクセス出来て2.75億件のデータが取得可能な状態だったと伝えています。
また、過去(2015年)の記事でも40,000台の保護されていないMongoDBが見つかったと伝えています。
よって、MongoDBをインストールしたらユーザー認証の設定は必ずしましょう。さらに、ユーザ認証の設定をせずにIPのバインド設定がlocalhost以外の設定にしてしまったらもう最悪です。
「MongoDBを始めた頃に知っていたら、と思う14のこと」の記事でも最初にユーザー認証のことが書かれています。
以降ではユーザー認証の設定とユーザーの登録を行いますが、ユーザー管理については説明していません。
ユーザー認証の設定パラメータ
コマンドラインオプションの場合は--auth
を追加します
mongod --dbpath <directory> --auth
設定ファイルの場合authorization
を enabled
にします
security:
authorization: enabled
最初のスーパーユーザーの登録
まず、ユーザー認証を有効にしてmongod
を立ち上げます。
スーパーユーザーとはLinuxのrootのようなもです。 MongoDBは決まったユーザーIDはありませんので、スーパーユーザーは何によってきまるかというとそれはロールです。ここではロールとしてビルトインされているroot
を使います。
以下ではユーザーIDをmongo
、パスワードを18fuw63x
としています。
$ mongo
> use admin
switched to db admin
> db.createUser({user:"mongo", pwd:"18fuw63x", roles:["root"]})
Successfully added user: { "user" : "mongo", "roles" : [ "root" ] }
> exit
ユーザーID/パスワードを指定してMongoDBに接続する
-u
を付けます。
$ mongo -u mongo
MongoDB shell version v4.0.9-31-g52532c50a4
Enter password:
mongodbコネクションストリングでは
$ mongo mongodb://mongo@localhost/
MongoDB shell version v4.0.9-31-g52532c50a4
Enter password:
パスワードも一緒に指定するときは以下のようにしますが、使わないようにしてください。理由はlinuxのpsコマンドなどでパスワードが他人に見られてしまいます。
$ mongo -u mongo -p 18fuw63x
$ mongo mongodb://mongo:18fuw63x@localhost/
その他の方法として、MongoDBに接続してから認証を実行する。
$ mongo
> use admin
switched to db admin
> db.auth("mongo","18fuw63x")
1
また、下記のようにデータベースを指定するとエラーになります。
$ mongo test -u mongo
$ mongo mongodb://mongo@localhost/test
理由は指定したDB名(test
)が認証用のDBとして使われるためです。ユーザーを登録したのはadmin
です。そこで、下記のように認証用のDBを指定します。
$ mongo test -u mongo --authenticationDatabase admin
$ mongo mongodb://mongo@localhost/test?authSource=admin
コンソールからユーザーID・パスワードの入力を省略したいとき
ユーザーホームに.mongorc.js
というファイルを作り、下記のスクリプトを記述します。.mongorc.js
はmongoを起動する際に読み込まれるJavaScriptファイルです。パスワードが書かれているので.mongorc.js
のアクセス権の設定には注意してください。
db.getSiblingDB("admin").auth("mongo","18fuw63x")
ユーザー登録してもまだ安心できない
--auth
付きで起動する場合は必ずバッチファイルを用意してmongod
を起動するか、設定ファイルを使用しましょう。
理由として、mongod
を再起動するときに--auth
パラメータ無しで再起動するとユーザー認証なしでも使えてしまうからです。これは設定ファイルでauthorization: enabled
を付けなくても同様ですが、一度設定して設定を消すことは無いと思います。しかし、--auth
を付け忘れることはありがちです。
次に--auth
を付けなかったときの場合分けは次の通りです。
- 正しいユーザー・パスワードを指定したときはOK
- 間違ったユーザー・パスワードを指定したときはエラー
- ユーザー認証しなかったときはOK
1.,2.は経験するので--auth
付きだと思ってしまいます。しかし、3.はやらないので--auth
無しとは気が付きにくいです。特に.mongorc.js
にauth()
コマンドを記述した場合はなおさら気が付きません。
psコマンドや設定ファイルを確認する以外に、どうやったら起動中のMongoDBのユーザー認証有無が分かるか調べたら、次のコマンドが有効でした。設定ファイルの場合も同様でparsed.security.authorization
を見れば分かります。ユーザー認証を指定しない場合はparsed.security.authorization
が無いようです。
> db.adminCommand( { getCmdLineOpts: 1 } )
{
"argv" : [
"mongod",
"--dbpath",
"db",
"--auth"
],
"parsed" : {
"security" : {
"authorization" : "enabled"
},
"storage" : {
"dbPath" : "db"
}
},
"ok" : 1
}
>
これ以外に無いかいろいろ試した結果、存在しないsystem.???
をfind()
すると分かります。どのバージョンでもなのかは分かりません。
ユーザー認証が有効の場合
> db.system.xx.find()
Error: error: {
"ok" : 0,
"errmsg" : "not authorized on test to execute command { find: \"system.xx\", filter: {}, lsid: { id: UUID(\"80d87cee-460f-4f97-b965-552a8417d604\") }, $db: \"test\" }",
"code" : 13,
"codeName" : "Unauthorized"
}
>
ユーザー認証が無効の場合
> db.system.xx.find()
>