Help us understand the problem. What is going on with this article?

MongoDB ユーザー認証設定は必ずしましょう

More than 1 year has passed since last update.

概要

下記のURLの記事は2019年5月8日の記事でMongoDBがパスワードなしでアクセス出来て2.75億件のデータが取得可能な状態だったと伝えています。

https://www.bleepingcomputer.com/news/security/over-275-million-records-exposed-by-unsecured-mongodb-database/

また、過去(2015年)の記事でも40,000台の保護されていないMongoDBが見つかったと伝えています。

https://thehackernews.com/2015/02/mongodb-database-hacking.html

よって、MongoDBをインストールしたらユーザー認証の設定は必ずしましょう。さらに、ユーザ認証の設定をせずにIPのバインド設定がlocalhost以外の設定にしてしまったらもう最悪です。

「MongoDBを始めた頃に知っていたら、と思う14のこと」の記事でも最初にユーザー認証のことが書かれています。

以降ではユーザー認証の設定とユーザーの登録を行いますが、ユーザー管理については説明していません。

ユーザー認証の設定パラメータ

コマンドラインオプションの場合は--authを追加します

mongod --dbpath <directory>  --auth

設定ファイルの場合authorizationenabledにします

security:
   authorization: enabled

最初のスーパーユーザーの登録

まず、ユーザー認証を有効にしてmongodを立ち上げます。

スーパーユーザーとはLinuxのrootのようなもです。 MongoDBは決まったユーザーIDはありませんので、スーパーユーザーは何によってきまるかというとそれはロールです。ここではロールとしてビルトインされているrootを使います。

https://docs.mongodb.com/manual/reference/built-in-roles/index.html#superuser-roles

以下ではユーザー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のアクセス権の設定には注意してください。

.mongorc.js
db.getSiblingDB("admin").auth("mongo","18fuw63x")

ユーザー登録してもまだ安心できない

--auth付きで起動する場合は必ずバッチファイルを用意してmongodを起動するか、設定ファイルを使用しましょう。

理由として、mongodを再起動するときに--authパラメータ無しで再起動するとユーザー認証なしでも使えてしまうからです。これは設定ファイルでauthorization: enabledを付けなくても同様ですが、一度設定して設定を消すことは無いと思います。しかし、--authを付け忘れることはありがちです。
次に--authを付けなかったときの場合分けは次の通りです。

  1. 正しいユーザー・パスワードを指定したときはOK
  2. 間違ったユーザー・パスワードを指定したときはエラー
  3. ユーザー認証しなかったときはOK

1.,2.は経験するので--auth付きだと思ってしまいます。しかし、3.はやらないので--auth無しとは気が付きにくいです。特に.mongorc.jsauth()コマンドを記述した場合はなおさら気が付きません。

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()
>
h6591
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした