Table of Contents
*Предыдущая версия данного руководства была написана Мелиссой Андерсон.*
Введение
MongoDB, или просто *Mongo*, — это документоориентированная база данных с открытым исходным кодом, используемая во многих современных веб-приложениях. Она относится к базам данных NoSQL, поскольку не опирается на традиционную табличную структуру реляционных баз данных. Вместо этого она хранит документы типа JSON с динамическими схемами.
MongoDB не поддерживает активированную по умолчанию аутентификацию, что означает, что любой пользователь с доступом к серверу, на котором установлена база данных, может добавлять и удалять данные без ограничений. Из этого руководства вы узнаете, как создать пользователя с правами администратора и активировать аутентификацию, чтобы защититься от этой уязвимости. Затем мы выполним тесты, чтобы подтвердить, что только данный пользователь с правами администратора имеет доступ к базе данных.
Предварительные требования
Для этого обучающего модуля вам потребуется следующее:
- Сервер на базе Ubuntu 20.04. На сервере должен быть пользователь без привилегий root с правами администратора и брандмауэр, настроенный с помощью UFW. Вы можете выполнить настройку, следуя указаниям руководства по начальной настройке сервера для Ubuntu 20.04.
- MongoDB, установленная на сервере. Данное руководство было протестировано с помощью MongoDB версии <^>4.4<^>, но оно также должно быть актуально для более старых версий MongoDB. Чтобы установить Mongo на ваш сервер, воспользуйтесь руководством по установке MongoDB на Ubuntu 20.04.
Шаг 1 — Добавление пользователя с правами администратора
С момента выхода версии <^>3.0<^> демон MongoDB настроен только на прием соединений с локального сокета Unix и автоматически не открывается для широкого Интернета. Однако аутентификация по умолчанию все еще отключена. Это означает, что любой пользователь, который имеет доступ к серверу, на котором установлена MongoDB, также имеет полный доступ к базам данных.
В качестве первого шага для защиты от этой уязвимости вы создадите пользователя с правами администратора. Позже вы активируете аутентификацию и воспользуетесь этим пользователем с правами администратора, чтобы получить доступ к базе данных.
Чтобы добавить пользователя с правами администратора, вам нужно сначала подключиться к оболочке Mongo. Поскольку аутентификация отключена, вы можете сделать это с помощью команды mongo без каких-либо опций:
mongo
Над запросом командной строки Mongo будет выведен текст. Поскольку вы еще не активировали аутентификацию, он будет включать предупреждение о том, что контроль доступа не активирован для базы данных, а доступ для чтения/записи данных и конфигурации базы данных никак не ограничен:
[secondary_label Output]
MongoDB shell version v<^>4.4.0<^>
. . .
2020-06-09T13:26:51.391+0000 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2020-06-09T13:26:51.391+0000 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
. . .
>
Эти предупреждения исчезнут после активации аутентификации, но сейчас они означают, что любой человек, который может получить доступ к вашему серверу Ubuntu, также может получить контроль над вашей базой данных.
Чтобы продемонстрировать это, запустите команду Mongo show dbs:
show dbs
Эта команда возвращает список всех баз данных на сервере. Однако после активации аутентификации список отображается на основе *роли* пользователя Mongo или уровня доступа к конкретной базе данных, который имеет пользователь. Поскольку аутентификация отключена, команда будет возвращать каждую базу данных, присутствующую в системе, без ограничений:
[secondary_label Output]
admin 0.000GB
config 0.000GB
local 0.000GB
В этом примере вывода отображаются только базы данных по умолчанию. Однако если у вас в системе есть базы данных, содержащие конфиденциальные данные, любой пользователь может найти их с помощью этой команды.
В рамках устранения этой уязвимости данный шаг описывает добавление пользователя с правами администратора. Для этого необходимо сначала подключиться к базе данных admin. Именно здесь хранится информация о пользователях, например, имена пользователей, пароли и роли:
use admin
[secondary_label Output]
switched to db admin
MongoDB устанавливается с рядом методов оболочки на базе JavaScript, которые вы можете использовать для управления вашей базой данных. Например, метод db.createUser используется для создания новых пользователей в базе данных, для которой запускается метод.
Воспользуйтесь методом db.createUser:
db.createUser(
Этот метод требует указать имя и пароль пользователя, а также любые роли, которые будет иметь пользователь. Напомним, что MongoDB хранит свои данные в виде документов JSON. Поэтому при создании нового пользователя все, что вы делаете, — это создаете документ для хранения соответствующих данных пользователя в форме отдельных полей.
Как и в случае объектов в JSON, документы в MongoDB начинаются и заканчиваются фигурными скобками ({ и }). Чтобы начать добавление пользователя, введите открывающую фигурную скобку:
Примечание. Mongo не зарегистрирует метод db.createUser как законченный, пока вы не добавите закрывающую скобку. Когда вы сделаете этого, указание поменяется со знака больше (>) на многоточие (...).
{
Затем добавьте поле user: с желаемым именем пользователя в качестве значения в двойных кавычках и поставьте запятую. В следующем примере указано имя пользователя AdminSammy, но вы можете ввести любое имя пользователя, которое вам нравится:
user: "<^>AdminSammy<^>",
Далее введите поле pwd с методом passwordPrompt() в качестве значения. Когда вы выполните метод db.createUser, метод passwordPrompt() будет отображать запрос на ввод пароля. Это более безопасное решение по сравнению с вводом вашего пароля в виде открытого текста, как вы делали это при вводе имени пользователя.
Примечание. Метод passwordPrompt() совместим только с MongoDB версии <^>4.2<^> и выше. Если вы используете более старую версию Mongo, вам нужно будет вводить пароль в виде открытого текста, так же как вы вводили ваше имя пользователя:
pwd: "<^>password<^>",
Обязательно добавьте запятую после этого поля:
pwd: passwordPrompt(),
Затем укажите роли, которые вы хотите добавить для вашего пользователя с правами администратора. Поскольку вы создаете пользователя с правами администратора, необходимо как минимум предоставить ему роль userAdminAnyDatabase для базы данных admin. Это позволит пользователю с правами администратора создавать и изменять новых пользователей и роли. Поскольку у пользователя с правами администратора есть эта роль в базе данных admin, это также предоставит ему доступ с правами суперпользователя ко всему кластеру.
Кроме того, в следующем примере пользователю с правами администратора будет предоставлена роль readWriteAnyDatabase. Она предоставляет пользователю с правами администратора возможность читать и изменять данные в любой базе данных в кластере, за исключением конфигурационных и локальных баз данных, предназначенных главным образом для внутреннего использования:
roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
После этого добавьте закрывающую фигурную скобку для обозначения конца документа:
}
Поставьте закрывающую круглую скобку, чтобы завершить и выполнить метод db.createUser:
)
В целом ваш метод db.createUser должен выглядеть следующим образом:
> db.createUser(
... {
... user: "<^>AdminSammy<^>",
... pwd: passwordPrompt(),
... roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
... }
... )
Если синтаксис каждой строки не имеет ошибок, метод будет выполняться корректно и вам будет предложено ввести пароль:
[secondary_label Output]
Enter password:
Введите надежный пароль по своему выбору. Далее вы получите подтверждение того, что пользователь был добавлен:
[secondary_label Output]
Successfully added user: {
"user" : "<^>AdminSammy<^>",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
},
"readWriteAnyDatabase"
]
}
После этого вы можете выйти из клиента MongoDB:
exit
На этом этапе вашему пользователю будет разрешено вводить учетные данные. Однако делать это будет необязательно, пока вы не активируете аутентификацию и не перезапустите демон MongoDB.
Шаг 2 — Активация аутентификации
Чтобы активировать аутентификацию, необходимо изменить файл конфигурации MongoDB mongod.conf. После активации и перезапуска службы Mongo пользователи все равно смогут подключаться к базе данных без аутентификации. Однако они не смогут читать или изменять какие-либо данные до тех пор, пока не представят корректное имя пользователя и пароль.
Откройте файл конфигурации в предпочитаемом текстовом редакторе. Мы будем использовать nano:
sudo nano /etc/mongod.conf
Прокрутите страницу вниз и найдите закомментированный раздел security:
[label /etc/mongod.conf]
. . .
#security:
#operationProfiling:
. . .
Раскомментируйте эту строку, удалив знак решетки (#):
[label /etc/mongod.conf]
. . .
security:
#operationProfiling:
. . .
Затем добавьте параметр authorization и установите для него значение "enabled". Когда вы закончите, строки должны выглядеть следующим образом:
[label /etc/mongod.conf]
. . .
security:
<^>authorization: "enabled"<^>
. . .
Обратите внимание, что у строки security: нет пробелов в начале, а строка authorization: выделена двумя пробелами в начале.
После добавления этих строк сохраните и закройте файл. Если вы использовали nano для редактирования файла, нажмите CTRL + X, Y, а затем ENTER.
Затем перезапустите демон, чтобы изменения вступили в силу:
sudo systemctl restart mongod
После этого проверьте состояние службы, чтобы убедиться, что перезапуск был выполнен корректно:
sudo systemctl status mongod
Если команда restart была выполнена успешно, вы получите вывод, указывающий, что служба mongod активна и была недавно запущена:
[secondary_label Output]
● mongod.service - MongoDB Database Server
Loaded: loaded (/lib/systemd/system/mongod.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2020-06-09 22:06:20 UTC; 7s ago
Docs: https://docs.mongodb.org/manual
Main PID: 15370 (mongod)
Memory: 170.1M
CGroup: /system.slice/mongod.service
└─15370 /usr/bin/mongod --config /etc/mongod.conf
Jun 09 22:06:20 <^>your_host<^> systemd[1]: Started MongoDB Database Server.
Убедившись, что демон сохранил изменения и успешно запустился, вы можете проверить, что настройки аутентификации, которые вы добавили, работают согласно ожиданиям.
Шаг 3 — Тестирование настроек аутентификации
Чтобы начать тестирование параметров аутентификации, которые вы добавили на предыдущем шаге, на корректность работы, сначала выполните подключение без указания каких-либо учетных данных, чтобы убедиться, что ваши действия попадут под ограничения:
mongo
Теперь, когда вы активировали аутентификацию, ни одно из отображавшихся ранее предупреждений не появится:
[secondary_label Output]
MongoDB shell version v<^>4.4.0<^>
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("5d50ed96-f7e1-493a-b4da-076067b2d898") }
MongoDB server version: <^>4.4.0<^>
>
Убедитесь в наличии ограничения доступа, запустив команду show dbs еще раз:
show dbs
Как было упомянуто в шаге 1, на вашем сервере есть как минимум несколько баз данных по умолчанию. Однако в этом случае команда не будет выводить данные, поскольку вы не выполнили аутентификацию в качестве пользователя с соответствующими правами.
Поскольку эта команда не возвращает никакой информации, можно с уверенностью сказать, что настройка аутентификации работает согласно ожиданиям. Также вы не сможете создавать пользователей или выполнять другие задачи, требующие наличия определенных прав, без предварительной аутентификации.
Теперь мы можем двигаться дальше и выйти из оболочки MongoDB:
Примечание. Вместо запуска команды exit, которую вы использовали ранее в шаге 1, в качестве альтернативы вы можете закрыть оболочку, просто нажав CTRL + C.
exit
Далее необходимо убедиться, что ваш пользователь с правами администратора может корректно выполнять аутентификацию, выполнив следующую команду mongo для подключения с помощью этого пользователя. Эта команда имеет флаг -u, который предшествует имени пользователя, от имени которого вы хотите выполнить подключение. Обязательно замените AdminSammy на имя вашего пользователя с правами администратора. Команда также имеет флаг -p, который будет запрашивать пароль пользователя, и указывает admin в качестве базы данных аутентификации, где было создано соответствующее имя пользователя:
mongo -u <^>AdminSammy<^> -p --authenticationDatabase admin
Введите пароль пользователя при запросе, после чего вы сможете войти в оболочку. Находясь в оболочке попробуйте снова воспользоваться командой show dbs:
show dbs
Так как вы успешно выполнили аутентификацию, на этот раз команда успешно вернет список всех баз данных на сервере:
[secondary_label Output]
admin 0.000GB
config 0.000GB
local 0.000GB
Это служит подтверждением, что аутентификация была успешно активирована.
Заключение
С помощью этого руководства вы настроили пользователя MongoDB с правами администратора, который может быть использован для создания и изменения новых пользователей и ролей, а также для управления вашим экземпляром MongoDB. Также вы настроили для вашего экземпляра MongoDB требование, согласно которому пользователи должны проходить аутентификацию с помощью действующего имени пользователя и пароля, прежде чем они смогут взаимодействовать с любыми данными.
Дополнительную информацию об управлении пользователями MongoDB см. в официальной документации по этой теме. Также вам, возможно, будет интересно узнать больше о том, как работает аутентификация в MongoDB.
Если вы планируете взаимодействовать с вашим экземпляром MongoDB удаленно, воспользуйтесь нашим руководством по настройке удаленного доступа для MongoDB в Ubuntu 20.04.