Рассмотрим важный момент, касающийся аутентификации пользователей в шардированном кластере MongoDB, поскольку в документации этот момент описан не в явном виде.
В такой среде необходимо понимать два понятия об аутентификации пользователя, особенно когда вы являетесь администратором базы данных:
- cluster authentication , то есть аутентификация, выполняемая при подключении через роутер mongos.
- local authentication , то есть аутентификация, выполняемая при локальном подключении к конкретному шарду через демон mongod.
Чтобы проиллюстрировать это, будем использовать простую конфигурацию кластера следующим образом:
Cluster authentication
Когда вы устанавливаете соединение с защищенным кластером MongoDB через роутер mongos , информация об аутентификации фактически проверяется в коллекции system.users в базе данных admin сервера конфигурации (config:27018).
Ваши шарды (в примере rs01 и rs02) ничего не знают о пользователе / пароле, который вы используете для подключения.
Точно так же: каждый раз, когда вы создаете нового пользователя, подключенного через mongos , его информация (имя пользователя, пароль, роли, база данных) сохраняется только в коллекции system.users в базе данных admin сервера конфигурации (config:27018).
Вы можете проверить это. Создайте нового пользователя через mongos и попробуйте подключиться к шарду (например, rs01) с теми же учетными данными: вы получите ошибку — Ошибка аутентификации.
Однако, поскольку пользователи, созданные с помощью mongos, хранятся на сервере конфигурации, вы можете использовать те же учетные данные для локального подключения на сервере конфигурации и через mongos! Каждый пользователь, созданный при локальном подключении к серверу конфигурации, может быть использован для подключения через mongos.
Local authentication
Когда вы устанавливаете соединение с репликой шардированного кластера MongoDB через процесс mongod (rs01 или rs02 в данном примере), информация об аутентификации на этот раз проверяется в коллекции system.users в базе данных admin в конкретной реплике куда вы пытаетесь подключится (rs01 или rs02).
Точно так же, как cluster authentication: каждый раз, когда вы создаете нового пользователя для локального подключенного к шарду , его информация (имя пользователя, пароль, роли, база данных) сохраняется только в коллекции system.users в базе данных admin реплики, к которой вы подключены (rs01, …).
Вы не можете использовать пользователя, которого вы создали таким образом, для подключения через роутер mongos !!!
Кроме того, пользователь может быть создан только для определенного сегмента (шард, реплика) или иметь разные пароли / привилегии для каждого сегмента (шарда, реплики) вашего кластера. Пользователь с тем же именем может также существовать в конфиг кластере (config:27018).
Вывод получается следующий: чтобы иметь возможность авторизоваться через роутер mongos в шардированный кластер, необходимо создать пользователя как в конфиг кластере (config:27018) так и в каждой реплике каждого шарда!
Рассмотрим на практике как настраивается авторизация в уже существующем кластере.
Будет добавлен пользователь user в базу admin, который будет иметь доступ ко всем базам и коллекциям шардированного кластера, аналогично можно создать пользователя, который будет иметь доступ только в определенную базу данных.
Пример конфига шардов.
/etc/mongod.conf
1 2 3 4 5 6 |
... security: authorization: enabled transitionToAuth: true keyFile: /opt/mongo/keyfile ... |
mongod cli
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
use admin; db.createUser( { user: "user", pwd: "superpassword!", roles : [ { role : "dbAdmin", db : "admin" }, { role : "readWrite", db : "admin" }, { role : "clusterAdmin", db : "admin" }, { role: "clusterManager", db: "admin" }, { role: "userAdminAnyDatabase", db: "admin" } ] } ) |
Конфиг роутера:
/etc/mongos.conf
1 2 3 4 |
... security: keyFile: /opt/mongo/keyfile ... |
Конфигурация реплики config серверов:
/etc/mongod.conf
1 2 3 4 5 |
... security: transitionToAuth: true keyFile: /opt/mongo/keyfile ... |
Добавление пользователя через mongos cli (или непосредственно в config кластере):
mongod cli
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
use admin; db.createUser( { user: "user", pwd: "superpassword!", roles : [ { role : "dbAdmin", db : "admin" }, { role : "readWrite", db : "admin" }, { role : "clusterAdmin", db : "admin" }, { role: "clusterManager", db: "admin" }, { role: "userAdminAnyDatabase", db: "admin" } ] } ) |
Если прав не хватает добавить везде роли
1 2 3 4 |
db.grantRolesToUser( 'user', [ { role : 'userAdminAnyDatabase', db : 'admin' }, { role : 'dbAdminAnyDatabase', db : 'admin' }, { role : 'readWriteAnyDatabase', db : 'admin' } ] ) |
оригинал статьи тут