🙌

ひとりMongoDB University 12/17 - Built-In Roles (2)

2020/12/17に公開

この記録は、アドベントカレンダー形式の、MongoDB Universityの学習コースの記録、17日目になります!
ただいまコース: M103[1]を進めています。目標は12/25までにChapter1の完走!

Chapter 1: Built-In Roles: Part 2(動画)

前日のおさらい

  • ロールはカスタマイズできる
  • 今回はビルトインロールを使う
  • ロールは、対象とする権限セット、対象にするリソースの組み合わせ
  • リソースはデータベース単位、コレクション単位、またはクラスタ

userAdminロールを持ったユーザを作成する

  • userAdminロールは、ユーザ操作(ユーザ作成、削除、パスワード変更、ロール設定)を担うビルトインロール
  • データベースやデータの操作に対する権限はありません!
# DockerのMongoDBのコンテナから試す

mongo admin

MongoDB shell version v4.4.2
connecting to: mongodb://127.0.0.1:27017/admin?compressors=disabled&gssapiServiceName=mongodb

> show databases
admin   0.000GB
config  0.000GB
local   0.000GB

# ユーザ管理用のAdminをパスワード付きで作成します
> db.createUser(
   { user: "security_officer",
     pwd: "h3ll0th3r3",
     roles: [ { db: "admin", role: "userAdmin" } ]
   }
 )
Successfully added user: {
        "user" : "security_officer",
        "roles" : [
                {
                        "db" : "admin",
                        "role" : "userAdmin"
                }
        ]
}

# 表示してみる
> show users
{
        "_id" : "admin.security_officer",
        "userId" : UUID("5ba5cc9e-fbbe-4c9e-ae50-bdf0824355c8"),
        "user" : "security_officer",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "userAdmin",
                        "db" : "admin"
                }
        ],
        "mechanisms" : [
                "SCRAM-SHA-1",
                "SCRAM-SHA-256"
        ]
}

dbAdminロールを持ったユーザを作成する

  • dbAdminロールは、データ操作(データベース、インデックス、コレクション、バリデーションやクラスタの作成更新)を担うビルトインロール
  • ユーザ作成やユーザへのロール付与はできません
  • プロファイル、統計データの取得も可能です

リソースの指定

  • dbAdminロールや、データ操作に関する権限は、対象を指定できる
  • データベースごとに絞ったロール付与ができる

# ここでは"admin"データベースに対するdbAdminロールのユーザを追加
db.createUser(
  { user: "dba",
    pwd: "c1lynd3rs",
    roles: [ { db: "admin", role: "dbAdmin" } ]
  }
)

Successfully added user: {
        "user" : "dba",
        "roles" : [
                {
                        "db" : "admin",
                        "role" : "dbAdmin"
                }
        ]
}

# おなじなまえとパスワードでも、リソース(データベース)が違えばユーザも違う
# Namespace的に違うので
> use m103
switched to db m103
> show databases
admin   0.000GB
config  0.000GB
local   0.000GB

db.createUser(
  { user: "dba",
    pwd: "c1lynd3rs",
    roles: [ { db: "m103", role: "dbAdmin" } ]
  }
)

Successfully added user: {
        "user" : "dba",
        "roles" : [
                {
                        "db" : "m103",
                        "role" : "dbAdmin"
                }
        ]
}

# dbOwnerのロールも設定
db.grantRolesToUser( "dba",  [ { db: "playground", role: "dbOwner"  } ] )

dbOwnerロール

The database owner can perform any administrative action on the database. This role combines the privileges granted by the readWrite, dbAdmin and userAdmin roles.

このロールは、データベースのオーナー権限を設定する。
基本的には、dbAdminとuserAdminロール、そして、読み書きの権限と併せて付与される。

設定したロールは、db.runCommand() を通して確認できる。

> db.runCommand( { rolesInfo: { role: "dbOwner", db: "playground" }, showPrivileges: true} )
{
        "roles" : [
                {
                        "role" : "dbOwner",
                        "db" : "playground",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ],
                        "privileges" : [
                                {
                                        "resource" : {
                                                "db" : "playground",
                                                "collection" : ""
                                        },
                                        "actions" : [
                                                "bypassDocumentValidation",
                                                "changeCustomData",
                                                "changePassword",
                                                "changeStream",
                                                "collMod",
                                                "collStats",
                                                "compact",
                                                "convertToCapped",
                                                "createCollection",
                                                "createIndex",
                                                "createRole",
                                                "createUser",
                                                "dbHash",
                                                "dbStats",
                                                "dropCollection",
                                                "dropDatabase",
                                                "dropIndex",
                                                "dropRole",
                                                "dropUser",
                                                "emptycapped",
                                                "enableProfiler",
                                                "find",
                                                "grantRole",
                                                "insert",
                                                "killCursors",
                                                "listCollections",
                                                "listIndexes",
                                                "planCacheIndexFilter",
                                                "planCacheRead",
                                                "planCacheWrite",
                                                "reIndex",
                                                "remove",
                                                "renameCollectionSameDB",
                                                "revokeRole",
                                                "setAuthenticationRestriction",
                                                "storageDetails",
                                                "update",
                                                "validate",
                                                "viewRole",
                                                "viewUser"
                                        ]
                                },
                                {
                                        "resource" : {
                                                "db" : "playground",
                                                "collection" : "system.js"
                                        },
                                        "actions" : [
                                                "changeStream",
                                                "collStats",
                                                "convertToCapped",
                                                "createCollection",
                                                "createIndex",
                                                "dbHash",
                                                "dbStats",
                                                "dropCollection",
                                                "dropIndex",
                                                "emptycapped",
                                                "find",
                                                "insert",
                                                "killCursors",
                                                "listCollections",
                                                "listIndexes",
                                                "planCacheRead",
                                                "remove",
                                                "renameCollectionSameDB",
                                                "update"
                                        ]
                                },
                                {
                                        "resource" : {
                                                "db" : "playground",
                                                "collection" : "system.profile"
                                        },
                                        "actions" : [
                                                "changeStream",
                                                "collStats",
                                                "convertToCapped",
                                                "createCollection",
                                                "dbHash",
                                                "dbStats",
                                                "dropCollection",
                                                "find",
                                                "killCursors",
                                                "listCollections",
                                                "listIndexes",
                                                "planCacheRead"
                                        ]
                                }
                        ],
                        "inheritedPrivileges" : [
                                {
                                        "resource" : {
                                                "db" : "playground",
                                                "collection" : ""
                                        },
                                        "actions" : [
                                                "bypassDocumentValidation",
                                                "changeStream",
                                                "collMod",
                                                "collStats",
                                                "compact",
                                                "convertToCapped",
                                                "createCollection",
                                                "createIndex",
                                                "dbHash",
                                                "dbStats",
                                                "dropCollection",
                                                "dropDatabase",
                                                "dropIndex",
                                                "emptycapped",
                                                "enableProfiler",
                                                "find",
                                                "insert",
                                                "killCursors",
                                                "listCollections",
                                                "listIndexes",
                                                "planCacheIndexFilter",
                                                "planCacheRead",
                                                "planCacheWrite",
                                                "reIndex",
                                                "remove",
                                                "renameCollectionSameDB",
                                                "storageDetails",
                                                "update",
                                                "validate"
                                        ]
                                },
                                {
                                        "resource" : {
                                                "db" : "playground",
                                                "collection" : "system.js"
                                        },
                                        "actions" : [
                                                "changeStream",
                                                "collStats",
                                                "convertToCapped",
                                                "createCollection",
                                                "createIndex",
                                                "dbHash",
                                                "dbStats",
                                                "dropCollection",
                                                "dropIndex",
                                                "emptycapped",
                                                "find",
                                                "insert",
                                                "killCursors",
                                                "listCollections",
                                                "listIndexes",
                                                "planCacheRead",
                                                "remove",
                                                "renameCollectionSameDB",
                                                "update"
                                        ]
                                },
                                {
                                        "resource" : {
                                                "db" : "playground",
                                                "collection" : "system.profile"
                                        },
                                        "actions" : [
                                                "changeStream",
                                                "collStats",
                                                "convertToCapped",
                                                "createCollection",
                                                "dbHash",
                                                "dbStats",
                                                "dropCollection",
                                                "find",
                                                "killCursors",
                                                "listCollections",
                                                "listIndexes",
                                                "planCacheRead"
                                        ]
                                },
                                {
                                        "resource" : {
                                                "db" : "playground",
                                                "collection" : ""
                                        },
                                        "actions" : [
                                                "changeCustomData",
                                                "changePassword",
                                                "createRole",
                                                "createUser",
                                                "dropRole",
                                                "dropUser",
                                                "grantRole",
                                                "revokeRole",
                                                "setAuthenticationRestriction",
                                                "viewRole",
                                                "viewUser"
                                        ]
                                }
                        ]
                }
        ],
        "ok" : 1
}

関連資料

The userAdmin role explicitly provides the following actions:

  changeCustomData
  changePassword
  createRole
  createUser
  dropRole
  dropUser
  grantRole
  revokeRole
  setAuthenticationRestriction
  viewRole
  viewUser

全てユーザ管理に関わる権限

このロールに対しての注意

userAdminロールを持っているユーザは、基本はユーザ管理に関する権限のみを行使するけれど、自分自身に対してデータベース操作のロールも割り当てることができる。(grantRole)
結果的に何でもできる、superuserになってしまうので、取り扱いには注意すること。
クラスタも対象にデータベースの操作ができてしまう。

Built-In Roles: Part 2 (クイズ)

Problem

Which of the following actions are granted to the userAdmin built-in role?

こたえ

  • viewUser
  • createRole, dropRole

(他にもたくさんあるけど、選択肢の中では以上)

Lab: Creating First Application User (演習問題)

Web内のIDE上で操作、テストを走らせるよ!

課題

  • Connect to a mongod instance that is already running in the background on port 27000.

    • まず設定調整が必要(デフォルトでないので)
  • The m103-admin user has also already been created for you with password m103-pass.

    • m103-adminというユーザが作成されているので、そのユーザを使って接続
  • Use the db.createUser() command to create a user for a CRUD application.

    • CRUDアプリケーション専用のユーザを作る
    • Role: readWrite on applicationData database
    • Authentication source: admin
    • Username: m103-application-user
    • Password: m103-application-pass
  • テストを実行してみる

解答

  • mongodb.confはport:27000 になっているので大丈夫そう
storage:
  dbPath: /var/mongodb/db
net:
  bindIp: localhost
  port: 27000
security:
  authorization: enabled
systemLog:
  destination: file
  path: /var/mongodb/logs/mongod.log
  logAppend: true
processManagement:
  fork: true
# --forkオプションと同じでバックグラウンドで動く
mongod -f mongodb.conf

# すでに作成済みのユーザで接続
mongo -u m103-admin -p m103-pass --port 27000
MongoDB shell version v4.0.5
connecting to: mongodb://127.0.0.1:27000/?gssapiServiceName=mongodb

....

To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---

>

接続できたので、専用ユーザを作る&ロールを割り当てる(複数)


db.createUser(
  { user: "m103-application-user",
    pwd: "m103-application-pass",
     roles: [ { db: "admin", role: "readWrite" } ]
   }
 )


db.createUser(
  { user: "m103-application-user",
    pwd: "m103-application-pass",
    roles: [ { db: "applicationData", role: "readWrite" } ]
  }
)

Successfully added user: {
        "user" : "m103-application-user",
        "roles" : [
                {
                        "db" : "applicationData",
                        "role" : "readWrite"
                }
        ]
}

# これではダメだった!ネームスペースを変更しないとだめ!!
# 一旦削除
> db.dropUser("m103-application-user", {w: "majority", wtimeout: 5000})

再チャレンジ!!

# adminで
use admin

> db.createUser(
  { user: "m103-application-user",
    pwd: "m103-application-pass",
    roles: [ { db: "applicationData", role: "readWrite" } ]
  }
)

# ネームスペース切り替え

> use applicationData
switched to db applicationData

# 再チャレンジ
> db.createUser(
  { user: "m103-application-user",
    pwd: "m103-application-pass",
    roles: [ { db: "applicationData", role: "readWrite" } ]
  }
)
Successfully added user: {
        "user" : "m103-application-user",
        "roles" : [
                {
                        "db" : "applicationData",
                        "role" : "readWrite"
                }
        ]
}

なんとか通りました!

今日の進捗

あと少しになりました。明日にはChapter1が完走できるかも!!

きょうのzenn

ひきつづき同じ方法で進めていますが、操作しようとしたらupdateのメッセージが!
ありがとうございます!

脚注
  1. M103: Basic Cluster Administration のコースになります。コースを開始すると、完了までの期限は2ヶ月以内です。 ↩︎

Discussion