*Предыдущая версия данного руководства была написана Мелиссой Андерсон.*

Введение

MongoDB, или просто *Mongo*, — это документоориентированная база данных с открытым исходным кодом, используемая во многих современных веб-приложениях. Она относится к базам данных NoSQL, поскольку не опирается на традиционную табличную структуру реляционных баз данных. Вместо этого она хранит документы типа JSON с динамическими схемами.

MongoDB не поддерживает активированную по умолчанию аутентификацию, что означает, что любой пользователь с доступом к серверу, на котором установлена база данных, может добавлять и удалять данные без ограничений. Из этого руководства вы узнаете, как создать пользователя с правами администратора и активировать аутентификацию, чтобы защититься от этой уязвимости. Затем мы выполним тесты, чтобы подтвердить, что только данный пользователь с правами администратора имеет доступ к базе данных.

Предварительные требования

mongodb illustration for: Предварительные требования

Для этого обучающего модуля вам потребуется следующее:

  • Сервер на базе 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&lt;^&gt;4.4.0&lt;^&gt;



 . . .



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.



 . . .



&gt;

				
			

Эти предупреждения исчезнут после активации аутентификации, но сейчас они означают, что любой человек, который может получить доступ к вашему серверу 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: "&lt;^&gt;AdminSammy&lt;^&gt;",

				
			

Далее введите поле pwd с методом passwordPrompt() в качестве значения. Когда вы выполните метод db.createUser, метод passwordPrompt() будет отображать запрос на ввод пароля. Это более безопасное решение по сравнению с вводом вашего пароля в виде открытого текста, как вы делали это при вводе имени пользователя.

Примечание. Метод passwordPrompt() совместим только с MongoDB версии <^>4.2<^> и выше. Если вы используете более старую версию Mongo, вам нужно будет вводить пароль в виде открытого текста, так же как вы вводили ваше имя пользователя:

				
					
pwd: "&lt;^&gt;password&lt;^&gt;",

				
			

Обязательно добавьте запятую после этого поля:

				
					
pwd: passwordPrompt(),

				
			

Затем укажите роли, которые вы хотите добавить для вашего пользователя с правами администратора. Поскольку вы создаете пользователя с правами администратора, необходимо как минимум предоставить ему роль userAdminAnyDatabase для базы данных admin. Это позволит пользователю с правами администратора создавать и изменять новых пользователей и роли. Поскольку у пользователя с правами администратора есть эта роль в базе данных admin, это также предоставит ему доступ с правами суперпользователя ко всему кластеру.

Кроме того, в следующем примере пользователю с правами администратора будет предоставлена роль readWriteAnyDatabase. Она предоставляет пользователю с правами администратора возможность читать и изменять данные в любой базе данных в кластере, за исключением конфигурационных и локальных баз данных, предназначенных главным образом для внутреннего использования:

				
					
roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]

				
			

После этого добавьте закрывающую фигурную скобку для обозначения конца документа:

				
					
}

				
			

Поставьте закрывающую круглую скобку, чтобы завершить и выполнить метод db.createUser:

				
					
)

				
			

В целом ваш метод db.createUser должен выглядеть следующим образом:

				
					
&gt; db.createUser(

... {

... user: "&lt;^&gt;AdminSammy&lt;^&gt;",

... pwd: passwordPrompt(),

... roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]

... }

... )

				
			

Если синтаксис каждой строки не имеет ошибок, метод будет выполняться корректно и вам будет предложено ввести пароль:

				
					
[secondary_label Output]

Enter password:

				
			

Введите надежный пароль по своему выбору. Далее вы получите подтверждение того, что пользователь был добавлен:

				
					
[secondary_label Output]

Successfully added user: {

	"user" : "&lt;^&gt;AdminSammy&lt;^&gt;",

	"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:

 &lt;^&gt;authorization: "enabled"&lt;^&gt;

. . .

				
			

Обратите внимание, что у строки 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 &lt;^&gt;your_host&lt;^&gt; systemd[1]: Started MongoDB Database Server.

				
			

Убедившись, что демон сохранил изменения и успешно запустился, вы можете проверить, что настройки аутентификации, которые вы добавили, работают согласно ожиданиям.

Шаг 3 — Тестирование настроек аутентификации

Чтобы начать тестирование параметров аутентификации, которые вы добавили на предыдущем шаге, на корректность работы, сначала выполните подключение без указания каких-либо учетных данных, чтобы убедиться, что ваши действия попадут под ограничения:

				
					
mongo

				
			

Теперь, когда вы активировали аутентификацию, ни одно из отображавшихся ранее предупреждений не появится:

				
					
[secondary_label Output]

MongoDB shell version v&lt;^&gt;4.4.0&lt;^&gt;

connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&amp;gssapiServiceName=mongodb

Implicit session: session { "id" : UUID("5d50ed96-f7e1-493a-b4da-076067b2d898") }

MongoDB server version: &lt;^&gt;4.4.0&lt;^&gt;

&gt;

				
			

Убедитесь в наличии ограничения доступа, запустив команду show dbs еще раз:

				
					
show dbs

				
			

Как было упомянуто в шаге 1, на вашем сервере есть как минимум несколько баз данных по умолчанию. Однако в этом случае команда не будет выводить данные, поскольку вы не выполнили аутентификацию в качестве пользователя с соответствующими правами.

Поскольку эта команда не возвращает никакой информации, можно с уверенностью сказать, что настройка аутентификации работает согласно ожиданиям. Также вы не сможете создавать пользователей или выполнять другие задачи, требующие наличия определенных прав, без предварительной аутентификации.

Теперь мы можем двигаться дальше и выйти из оболочки MongoDB:

Примечание. Вместо запуска команды exit, которую вы использовали ранее в шаге 1, в качестве альтернативы вы можете закрыть оболочку, просто нажав CTRL + C.

				
					
exit

				
			

Далее необходимо убедиться, что ваш пользователь с правами администратора может корректно выполнять аутентификацию, выполнив следующую команду mongo для подключения с помощью этого пользователя. Эта команда имеет флаг -u, который предшествует имени пользователя, от имени которого вы хотите выполнить подключение. Обязательно замените AdminSammy на имя вашего пользователя с правами администратора. Команда также имеет флаг -p, который будет запрашивать пароль пользователя, и указывает admin в качестве базы данных аутентификации, где было создано соответствующее имя пользователя:

				
					
mongo -u &lt;^&gt;AdminSammy&lt;^&gt; -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.