Обеспечение безопасности MongoDB в Ubuntu 20.04

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

Введение

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 будет выведен текст. Поскольку вы еще не активировали аутентификацию, он будет включать предупреждение о том, что контроль доступа не активирован для базы данных, а доступ для чтения/записи данных и конфигурации базы данных никак не ограничен:

OutputMongoDB shell version v4.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 или уровня доступа к конкретной базе данных, который имеет пользователь. Поскольку аутентификация отключена, команда будет возвращать каждую базу данных, присутствующую в системе, без ограничений:

Outputadmin   0.000GB config  0.000GB local   0.000GB 

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

В рамках устранения этой уязвимости данный шаг описывает добавление пользователя с правами администратора. Для этого необходимо сначала подключиться к базе данных admin. Именно здесь хранится информация о пользователях, например, имена пользователей, пароли и роли:

  • use admin
Outputswitched 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" ] ... } ... ) 

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

OutputEnter password: 

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

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

/etc/mongod.conf

. . . #security:  #operationProfiling:  . . . 

Раскомментируйте эту строку, удалив знак решетки (#):

/etc/mongod.conf

. . . security:  #operationProfiling:  . . . 

Затем добавьте параметр authorization и установите для него значение "enabled". Когда вы закончите, строки должны выглядеть следующим образом:

/etc/mongod.conf

. . . security:   authorization: "enabled" . . . 

Обратите внимание, что у строки security: нет пробелов в начале, а строка authorization: выделена двумя пробелами в начале.

После добавления этих строк сохраните и закройте файл. Если вы использовали nano для редактирования файла, нажмите CTRL + X, Y, а затем ENTER.

Затем перезапустите демон, чтобы изменения вступили в силу:

  • sudo systemctl restart mongod

После этого проверьте состояние службы, чтобы убедиться, что перезапуск был выполнен корректно:

  • sudo systemctl status mongod

Если команда restart была выполнена успешно, вы получите вывод, указывающий, что служба mongod активна и была недавно запущена:

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

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

OutputMongoDB shell version v4.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

Так как вы успешно выполнили аутентификацию, на этот раз команда успешно вернет список всех баз данных на сервере:

Outputadmin   0.000GB config  0.000GB local   0.000GB 

Это служит подтверждением, что аутентификация была успешно активирована.

Заключение

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

Дополнительную информацию об управлении пользователями MongoDB см. в официальной документации по этой теме. Также вам, возможно, будет интересно узнать больше о том, как работает аутентификация в MongoDB.

Если вы планируете взаимодействовать с вашим экземпляром MongoDB удаленно, воспользуйтесь нашим руководством по настройке удаленного доступа для MongoDB в Ubuntu 20.04.