Если нужен только рабочий маршрут без подробных объяснений, ниже — короткая последовательность настройки MongoDB на Ubuntu: от установки и пользователей до безопасного доступа и проверки backup/restore.
- Установите MongoDB Community Edition из официального repository и убедитесь, что сервис
mongodзапущен. - Пока MongoDB принимает подключения только через
127.0.0.1, создайте административного пользователя. После этого включите обязательную авторизацию в/etc/mongod.conf:
security:
authorization: enabledи перезапустите MongoDB.
- Создайте отдельного пользователя приложения с минимально необходимыми правами, например
readWriteтолько для app_db.
Подключение будет выглядеть примерно так:
mongodb://app_user:password@127.0.0.1:27017/app_db?authSource=app_db- Если приложение находится на другом сервере, разрешите MongoDB слушать нужный интерфейс через
bindIpи откройте 27017/tcp в firewall только для доверенного IP. Не публикуйте MongoDB в интернет без сетевых ограничений. - Создайте тестовые данные и убедитесь, что
app_userможет читать и изменять свою database, но не получает административных прав. - Сделайте резервную копию:
mongodump --db app_db --out /var/backups/mongodbЗатем удалите тестовую database и восстановите ее:
mongorestore --db app_db /var/backups/mongodb/app_db- После восстановления снова подключитесь к MongoDB и проверьте, что collections и documents вернулись.
Если вся эта цепочка проходит успешно — сервис запускается, авторизация работает, приложение подключается под отдельным пользователем, а backup реально восстанавливается — базовую установку MongoDB можно считать готовой к дальнейшей эксплуатации.
Что разберем в статье
В этой статье настроим MongoDB на Ubuntu с нуля и сразу доведем установку до состояния, пригодного для небольшого рабочего проекта. Создадим административного пользователя и отдельную учетную запись приложения, включим обязательную авторизацию, ограничим сетевой доступ и отдельно разберем типичные ошибки подключения.
После этого проверим резервное копирование не только созданием файла. Добавим реальные документы, сделаем backup через mongodump, удалим тестовую database, восстановим ее через mongorestore и убедимся, что данные действительно вернулись.
Прежде чем переходить к архитектуре сервера, коротко напомним основные термины.
MongoDB — это документоориентированная база данных. Вместо привычных таблиц и строк данные здесь хранятся в виде документов, которые объединяются в коллекции. Несколько коллекций, относящихся к одному приложению или сервису, находятся внутри database.
Сам сервер MongoDB работает как процесс mongod. Именно он принимает подключения клиентов, выполняет запросы, управляет данными на диске и применяет настройки безопасности.
Как будет устроен MongoDB-сервер
Как обычно, прежде чем устанавливать пакеты и редактировать mongod.conf, разберемся, какую схему мы в итоге хотим получить.
У нас будет один Ubuntu VPS с MongoDB Community Edition. На нем работает серверный процесс mongod, а приложение подключается к своей database под отдельным пользователем с ограниченными правами.
Административную учетную запись будем использовать только для управления самой MongoDB: создания пользователей, изменения прав и других служебных операций.
Таким образом, сразу разделяем две роли:
- admin управляет MongoDB;
app_userработает только с данными приложения.
На первом этапе MongoDB будет доступна только локально через 127.0.0.1. Это позволит спокойно создать пользователей и включить authorization до того, как база станет доступна с других серверов.
А уже после проверки локальной схемы отдельно настроим удаленное подключение — но только если оно действительно понадобится.
Что установим и проверим
Основной серверный процесс MongoDB называется: mongod.
Он отвечает за хранение данных, обработку запросов, пользователей и сетевые подключения.
Для работы с MongoDB из терминала понадобится MongoDB Shell: mongosh
Через него мы будем:
- Создавать пользователей;
- Переключаться между databases;
- Добавлять documents;
- Проверять права;
- Удалять тестовую database;
- Проверять результат восстановления.
Для backup и restore понадобятся отдельные утилиты:
mongodump
mongorestoreВ итоге проверим полный рабочий цикл:

С общей схемой разобрались. Теперь посмотрим, как к MongoDB будет обращаться само приложение.
Как приложение будет подключаться к MongoDB
Приложения обычно подключаются к MongoDB через connection URI.
Для нашей локальной схемы он будет выглядеть примерно так:
mongodb://app_user:password@127.0.0.1:27017/app_db?authSource=app_dbЗдесь указаны:
app_user— пользователь приложения;- password — его пароль;
127.0.0.1— адрес MongoDB;- 27017 — стандартный порт;
app_db— рабочая database;authSource=app_db— database, в которой MongoDB должна искать пользователя.
Последний параметр важен. Пользователь MongoDB создается внутри определенной authentication database, и при неправильном authSource можно получить ошибку авторизации даже с правильным логином и паролем.
Поэтому для приложения создадим отдельного пользователя с понятной областью прав:

Он сможет читать и изменять данные приложения, но не получит административный доступ ко всему серверу.
Прежде чем создавать такую учетную запись, нужно безопасно подготовить саму MongoDB.
Почему сначала настраиваем локальный доступ
Сразу после установки нет смысла открывать MongoDB внешней сети.
Пока мы еще не создали admin и не включили обязательную авторизацию, безопаснее оставить mongod доступным только через: 127.0.0.1
Тогда к базе можно подключиться только с самого VPS.
Последовательность получится простой:
- Устанавливаем MongoDB;
- Проверяем сервис;
- Создаем admin;
- Включаем authorization;
- Создаем
app_user; - Проверяем его права;
- Только после этого решаем, нужен ли внешний доступ.
Если приложение работает на том же VPS, MongoDB вообще можно оставить на localhost.
Если приложение находится на другом сервере, позже разрешим подключение только с его доверенного IP и отдельно ограничим доступ firewall.
Так мы не создаем сначала потенциально открытую базу, а расширяем доступ только после того, как пользователи и авторизация уже настроены.
Что подготовить перед установкой
Перед началом понадобится совсем небольшой набор исходных данных:
| Компонент | Назначение | Что подготовить |
| Ubuntu VPS | Сервер MongoDB | SSH-доступ, CPU, RAM и SSD |
| MongoDB Community Edition | Хранение данных | Поддерживаемая версия Ubuntu |
mongosh | Администрирование | Локальный доступ к серверу |
| MongoDB Database Tools | Backup и restore | mongodump и mongorestore |
| Admin user | Управление MongoDB | Отдельный надежный пароль |
app_user | Доступ приложения | Пароль и права только на app_db |
app_db | Рабочая database | Используем и для тестовых данных |
| Backup storage | Хранение копий | Локальный каталог и желательно внешнее хранилище |
| Trusted IP | Удаленный доступ | Нужен только при подключении с другого сервера |
Теперь логика дальнейшей настройки уже определена: сначала устанавливаем MongoDB и защищаем локальный доступ, затем разделяем административного и прикладного пользователей, а уже после этого переходим к сети и резервному копированию.
Выбираем версию MongoDB и конфигурацию VPS
С общей схемой мы уже разобрались: MongoDB будет работать на одном Ubuntu VPS, приложение подключится под отдельным пользователем, а административные права останутся только у admin. Теперь нужно выбрать конкретную версию MongoDB и понять, сколько ресурсов достаточно для небольшого рабочего сервера.
Здесь важен баланс. Для тестов MongoDB можно запустить и на очень скромном VPS, но для постоянной работы лучше сразу оставить запас по памяти и диску. У базы данных эти два ресурса заметно влияют на отзывчивость, особенно когда появляются indexes, регулярная запись и backup.
В этом руководстве используем MongoDB 8.0 Community Edition на Ubuntu 24.04 LTS.
Какие ресурсы нужны небольшой MongoDB
MongoDB не требует огромного сервера для небольшого проекта.
Если речь идет о тестовом стенде, небольшом внутреннем сервисе или приложении с умеренным числом запросов, вполне можно начинать с нескольких vCPU и нескольких гигабайт RAM.
Практический ориентир для небольшой standalone MongoDB:
- 2 vCPU
- 4 ГБ RAM
- 40–60 ГБ SSD
Этого достаточно, чтобы:
- Запустить сам
mongod; - Хранить небольшую рабочую database;
- Создавать indexes;
- Выполнять
mongodump; - Восстанавливать данные через
mongorestore; - Оставить системе запас под filesystem cache.
Сервер на 1 vCPU и 2 ГБ RAM тоже может работать, особенно для лабораторных задач, но запас там уже небольшой. Как только растут данные, indexes или нагрузка, память заканчивается гораздо быстрее.
Поэтому для статьи не будем брать совсем минимальную конфигурацию. Нам важнее получить предсказуемое окружение, на котором можно спокойно пройти весь цикл от установки до restore.
Почему для MongoDB важны RAM и диск
MongoDB активно использует память для cache.
Storage engine WiredTiger держит часть часто используемых данных в собственном cache, а сама Linux дополнительно использует свободную RAM для filesystem cache. В результате часто читаемые данные не приходится каждый раз забирать с диска.
Поэтому для базы важен не только показатель used, но и то, сколько памяти остается доступной системе.
Если RAM становится мало и сервер начинает постоянно обращаться к swap, задержки растут. Swap лучше воспринимать как аварийный запас, а не как обычное продолжение оперативной памяти.
С диском ситуация похожая.
MongoDB постоянно работает с:
- Data files;
- Indexes;
- Journal;
- Временными файлами;
- Logs.
Если диск медленный, это напрямую отражается на записи и чтении данных.
Поэтому для рабочего сервера лучше использовать SSD. Особенно это заметно, когда database уже не помещается целиком в память и MongoDB чаще обращается к storage.
Кроме скорости важен и запас места. Сегодня база может занимать несколько гигабайт, а позже к ней добавятся indexes, backup и временные данные.
Поэтому диск тоже не стоит выбирать впритык.
Какую конфигурацию используем в статье
Для нашего стенда возьмем:
- Ubuntu 24.04 LTS;
- MongoDB 8.0 Community Edition;
- 2 vCPU;
- 4 ГБ RAM;
- 60 ГБ SSD;
- Один standalone-процесс
mongod; - Стандартный storage engine WiredTiger.
Этого достаточно для небольшой database.
Мы сможем:
- Создать пользователей;
- Добавить данные;
- Проверить indexes и доступ;
- Сделать backup;
- Удалить тестовую database;
- Восстановить ее;
- Оставить на сервере нормальный запас ресурсов.
Если потом MongoDB начнет обслуживать более крупный проект, увеличивать ресурсы нужно уже по фактической нагрузке: смотреть RAM, disk I/O, размер working set и частоту запросов, а как альтернативу - MongoDB поддерживает горизонтальное масштабирование (разные инстансы на разных VPS).
Для ориентира сравним три сценария:
| Ресурс | Минимальный тестовый стенд | Небольшой рабочий сервер | Конфигурация статьи |
| CPU | 1 vCPU | 2+ vCPU | 2 vCPU |
| RAM | 2 ГБ | 4+ ГБ | 4 ГБ |
| Диск | 20–30 ГБ | 40–60+ ГБ SSD | 60 ГБ SSD |
| Swap | Небольшой резерв | Только как страховка | Проверим отдельно |
| Назначение | Lab / тесты | Небольшое приложение | Учебный рабочий стенд |
Осталось проверить, что реальный VPS соответствует выбранным параметрам.
Команды проверки сервера

Сначала посмотрим версию Ubuntu:
lsb_release -aЕсли lsb_release отсутствует, можно использовать:
cat /etc/os-releaseВ нашем случае должна быть установлена Ubuntu 24.04 LTS.
Количество доступных CPU:
nprocБолее подробные характеристики:
lscpuТеперь проверим память:
free -hНас интересуют общий объем RAM и значение available.
Отдельно посмотрим swap:
swapon --showЕсли команда ничего не выводит, активный swap отсутствует.
Теперь диски:
lsblkИ свободное место:
df -hПозже MongoDB будет хранить данные в:
/var/lib/mongodbПоэтому особенно важно проверить раздел, на котором находится этот каталог.
Основные команды можно оставить в коротком справочнике:
| Что проверяем | Зачем | Команда |
| Ubuntu | Проверить версию системы | lsb_release -a |
| CPU | Убедиться, что процессоров достаточно | nproc |
| RAM | Проверить общий и доступный объем памяти | free -h |
| Swap | Посмотреть резерв виртуальной памяти | swapon --show |
| Диски | Увидеть устройства и разделы | lsblk |
| Свободное место | Проверить запас под данные и backup | df -h |
Устанавливаем MongoDB на Ubuntu
С версией и ресурсами определились. Теперь можно переходить к самой установке MongoDB на Ubuntu.
На этом этапе задача простая: подключить официальный repository, установить нужные пакеты, запустить mongod и убедиться, что MongoDB Shell подключается к локальному серверу. Авторизацию пока не включаем — сначала нужно получить рабочую базовую установку.
Почему лучше использовать официальный repository MongoDB
В Ubuntu MongoDB можно встретить в системных пакетах, но для актуальной Community Edition лучше использовать официальный repository MongoDB.
Это дает несколько преимуществ:
- Устанавливается нужная версия MongoDB;
- Пакеты обновляются из того же источника;
- Структура установки соответствует стандартной документации MongoDB;
- Вместе с сервером можно установить
mongoshи Database Tools; - Проще контролировать обновления между версиями.
Для статьи используем MongoDB 8.0, поэтому repository сразу подключим для этой ветки.
После этого MongoDB будет устанавливаться обычным apt, как и остальные пакеты Ubuntu.
Какие пакеты входят в MongoDB
Основной метапакет называется:
mongodb-orgОн устанавливает набор компонентов, необходимых для обычного standalone-сервера.
Ключевые из них:
- mongodb-org-server — серверный процесс
mongod; - mongodb-mongosh — MongoDB Shell;
- mongodb-org-tools — набор дополнительных утилит;
- MongoDB Database Tools — в том числе
mongodumpи mongorestore.
Самая важная часть — mongod.
Именно он принимает подключения, работает с databases и collections, сохраняет документы и управляет storage engine.
mongosh нужен уже администратору и разработчику: через него можно выполнять запросы и управлять MongoDB.
А mongodump и mongorestore понадобятся позже, когда будем проходить полный цикл резервного копирования.
Как работает сервис mongod
После установки MongoDB сервер запускается как systemd service:
mongod.serviceПосмотреть его состояние можно так:
sudo systemctl status mongodДля короткой проверки:
sudo systemctl is-active mongodЕсли сервис работает, получим:
activeЧтобы MongoDB автоматически запускалась после reboot:
sudo systemctl enable mongodУправление стандартное:
sudo systemctl start mongod
sudo systemctl stop mongod
sudo systemctl restart mongodЕсли MongoDB не запускается, первое место для проверки — systemd logs:
sudo journalctl -u mongod -n 100 --no-pagerПозже, когда начнем менять mongod.conf, эта команда особенно пригодится: ошибка YAML или неправильный параметр может помешать сервису стартовать.
Где находятся конфигурация, данные и логи
После стандартной установки основные файлы лежат в предсказуемых местах.
Конфигурация:
/etc/mongod.confИменно здесь позже будем включать authorization и менять сетевые параметры вроде bindIp.
Данные MongoDB по умолчанию находятся в:
/var/lib/mongodbЭтот каталог содержит файлы WiredTiger и другие данные базы.
Логи:
/var/log/mongodb/mongod.logПолучается простая тройка:
/etc/mongod.conf
/var/lib/mongodb
/var/log/mongodb/mongod.logПервый путь отвечает за настройки, второй — за данные, третий — за диагностику.
Именно поэтому при проблемах стоит сразу понимать, где искать причину: конфигурация — в mongod.conf, запуск сервиса — в systemctl и journal, ошибки MongoDB — в mongod.log.
Теперь можно перейти к установке.
Практика: устанавливаем и запускаем MongoDB

Сначала обновим индекс пакетов:
sudo apt updateУстановим утилиты, которые понадобятся для добавления repository:
sudo apt install -y curl gnupgДобавим GPG key MongoDB:
curl -fsSL https://pgp.mongodb.com/server-8.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg \
--dearmorТеперь добавим repository для Ubuntu 24.04:
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0 multiverse" | \
sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.listОбновим индекс пакетов:
sudo apt updateУстановим MongoDB:
sudo apt install -y mongodb-orgПроверим установленную версию сервера:
mongod --versionВерсию shell:
mongosh --versionИ наличие Database Tools:
mongodump --version
mongorestore --versionТеперь запустим MongoDB:
sudo systemctl start mongodДобавим автозапуск:
sudo systemctl enable mongodПроверим состояние:
sudo systemctl status mongodДля краткой проверки:
sudo systemctl is-active mongodТеперь попробуем подключиться:
mongoshЕсли все работает, откроется MongoDB Shell.
Выполним простую проверку:
db.runCommand({ ping: 1 })Успешный ответ будет содержать:
ok: 1Это подтверждает, что mongod работает и принимает локальное соединение.
Выйти из shell можно командой:
exitОсновные команды установки и проверки можно оставить в небольшой таблице:
| Задача | Команда |
| Установить MongoDB | sudo apt install -y mongodb-org |
| Запустить сервис | sudo systemctl start mongod |
| Включить автозапуск | sudo systemctl enable mongod |
| Проверить состояние | sudo systemctl status mongod |
| Подключиться через shell | mongosh |
| Проверить сервер | db.runCommand({ ping: 1 }) |
| Посмотреть log | sudo tail -n 100 /var/log/mongodb/mongod.log |
На этом базовая установка готова: mongod запущен, shell подключается, а основные пути и команды уже понятны.
Следующий шаг — настроить authentication. Сначала разберемся, как в MongoDB устроены пользователи, authentication database и roles, а затем создадим первого административного пользователя.
Разбираемся с аутентификацией MongoDB
Почему MongoDB нельзя оставлять без authentication
Пока authentication не включена, сам факт сетевой доступности MongoDB уже становится риском.
Если mongod слушает только:
127.0.0.1угроза меньше, потому что подключиться можно только с самого сервера.
Но если затем изменить bindIp и открыть MongoDB в сеть, не настроив пользователей, любой клиент, который доберется до порта 27017, потенциально сможет работать с данными без нормальной проверки личности.
Поэтому мы и строим настройку в таком порядке:
- Сначала локальная MongoDB;
- Затем административный пользователь;
- После этого обязательная authentication;
- Потом пользователь приложения;
- И только затем — удаленный доступ, если он вообще нужен.
Так безопаснее и понятнее: сначала создаем механизм доступа, потом расширяем сеть.
Что такое user и authentication database
В MongoDB пользователь создается не просто «на сервере вообще», а внутри определенной database.
Например:
use app_dbа затем:
db.createUser({
user: "app_user",
pwd: "StrongPassword",
roles: [
{ role: "readWrite", db: "app_db" }
]
})В таком случае authentication database для app_user — это:
app_dbИменно там MongoDB хранит учетную запись пользователя и проверяет credentials.
Поэтому connection string должен учитывать не только рабочую database, но и authSource.
Например:
mongodb://app_user:password@127.0.0.1:27017/app_db?authSource=app_dbЗдесь обе database совпадают:
- Приложение работает с
app_db; - Пользователь тоже создан в app_db.
Но это не обязательное правило.
Например, административный пользователь часто создается в:
adminТогда подключение может выглядеть так:
mongodb://admin_user:password@127.0.0.1:27017/?authSource=adminЕсли authSource указан неправильно, MongoDB будет искать пользователя не там, где он создан, и аутентификация завершится ошибкой.
Позже специально воспроизведем такую ситуацию при разборе Authentication failed.
Чем административный пользователь отличается от пользователя приложения
Административный пользователь нужен для управления самим сервером.
Он может:
- Создавать других пользователей;
- Назначать roles;
- Просматривать databases;
- Выполнять административные операции;
- Управлять доступом.
Приложению большая часть этих возможностей вообще не нужна.
Обычному веб-приложению обычно достаточно работать только со своей database:
app_dbи выполнять там операции чтения и записи.
Если приложение подключается под административной учетной записью, любая ошибка или уязвимость приложения получает намного более серьезные последствия.
Условно:

Поэтому разделение пользователей — не формальность.
Для приложения создаем отдельную учетную запись с минимально необходимыми permissions, а admin используем только для администрирования MongoDB.
Чтобы эти права задавать осмысленно, нужно понять, как работают roles.
Как работают roles
Role определяет, какие действия разрешены пользователю.
Одна из самых распространенных ролей приложения:
readWriteОна позволяет читать и изменять данные в указанной database.
Например:
roles: [
{ role: "readWrite", db: "app_db" }
]Такой пользователь сможет:
- Выполнять find;
- Добавлять documents;
- Изменять их;
- Удалять данные;
- Создавать нужные collections и indexes в пределах своих полномочий.
Но это не делает его администратором всего MongoDB-сервера.
Есть и более ограниченная роль: read
Она подходит для сервисов, которым нужно только читать данные.
Административные роли уже дают значительно более широкие возможности. Например, для административной учетной записи можно использовать root, если действительно нужен полный контроль над сервером.
То есть логика простая: role должна соответствовать реальной задаче пользователя.
Не стоит выдавать root, если приложению достаточно readWrite для одной database.
Какую схему пользователей используем в статье
Чтобы дальше не путаться в пользователях и правах, сразу зафиксируем две учетные записи.
Первая:
mongo_adminСоздадим ее в database:
adminи используем для административных операций.
Вторая:
app_userСоздадим в:
app_dbи дадим только:
readWriteна эту database.
Получается такая схема:
| Пользователь | Authentication DB | Role | Назначение |
mongo_admin | admin | root | Управление MongoDB и пользователями |
app_user | app_db | readWrite для app_db | Работа приложения со своими данными |
Такое разделение пригодится практически сразу.
Создаем административного пользователя
Теперь, когда понятны роли и authentication database, можно создать первого пользователя MongoDB — административного.
Этот шаг лучше сделать до включения обязательной authorization. Пока mongod доступен только локально и не принимает внешние подключения, можно спокойно создать admin, проверить его credentials и только после этого закрыть анонимный доступ.
Почему первого пользователя создают до включения authorization
После включения:
security:
authorization: enabledMongoDB начинает требовать учетную запись для операций, которые раньше выполнялись без аутентификации.
Поэтому сначала логично создать пользователя, под которым мы сможем продолжить администрирование.
В нашем случае это:
mongo_adminОн будет создан в authentication database:
adminПосле этого можно включить authorization и уже входить в MongoDB с логином и паролем.
Так последовательность остается предсказуемой:
- Локально подключаемся без credentials;
- Создаем
mongo_admin; - Проверяем, что пользователь существует;
- Включаем authorization;
- Подключаемся уже под admin.
Если перепутать порядок и закрыть доступ раньше времени, настройка становится заметно неудобнее.
Какие права нужны администратору
Для статьи административному пользователю нужен полный контроль над MongoDB-сервером.
Поэтому назначим роль:
rootОна даст mongo_admin права на управление databases, пользователями и другими административными операциями.
Для production можно строить более детальную модель доступа и разделять обязанности между несколькими учетными записями. Но для одного небольшого standalone-сервера отдельный admin с root — понятная и практичная схема.
Главное — не использовать эту учетную запись внутри самого приложения.
Приложение позже получит собственного пользователя:
app_userс readWrite только для app_db.
Теперь создадим admin на практике.
Практика: создаем admin и проверяем вход

Подключаемся локально:
mongoshПереходим в database admin:
use adminСоздаем пользователя:
db.createUser({
user: "mongo_admin",
pwd: passwordPrompt(),
roles: [
{ role: "root", db: "admin" }
]
})passwordPrompt() удобнее, чем записывать пароль прямо в команду: значение не остается в явном виде в примере и не попадает в shell history как часть команды.
MongoDB запросит пароль интерактивно.
После успешного создания можно проверить пользователя:
db.getUser("mongo_admin")В выводе должны быть видны имя пользователя и назначенная роль root.
Теперь выйдем из shell:
exitНа этом этапе authorization еще не включена, поэтому сам факт существования пользователя пока не заставляет MongoDB требовать login при каждом подключении.
Но credentials уже можно проверить явно.
Подключимся так:
mongosh --username mongo_admin --authenticationDatabase admin --passwordПосле ввода пароля откроется MongoDB Shell.
Внутри можно проверить текущего пользователя и выполнить административную команду:
use admin
db.runCommand({ connectionStatus: 1 })В ответе должна присутствовать информация об аутентифицированном пользователе mongo_admin.
Можно также выполнить:
show dbsЕсли команда работает, административные права применились корректно.
Теперь у нас есть рабочая административная учетная запись, и можно переходить к следующему важному шагу — включать обязательную authorization.
После этого обычный mongosh без credentials уже не должен давать полноценный доступ к данным и административным операциям.
Включаем обязательную авторизацию
Что меняется после authorization: enabled
Ключевой параметр выглядит так:
security:
authorization: enabledПосле его включения MongoDB начинает применять role-based access control.
То есть одного подключения к серверу уже недостаточно. Клиенту нужно аутентифицироваться под конкретным пользователем, а затем MongoDB проверит, разрешена ли ему нужная операция.
Например, административный пользователь сможет:
- Создавать пользователей;
- Просматривать databases;
- Менять роли;
- Выполнять административные команды.
А будущий app_user сможет работать только с app_db в рамках роли readWrite.
Именно с этого момента разделение пользователей, которое мы настроили раньше, начинает реально работать.
Где настраивается security в mongod.conf
Основной конфигурационный файл MongoDB находится здесь:
/etc/mongod.confОткроем его:
sudo nano /etc/mongod.confНас интересует секция security.
Если ее еще нет, добавим:
security:
authorization: enabledВажно сохранить правильные отступы. mongod.conf использует YAML, поэтому ошибка в структуре может привести к тому, что mongod вообще не запустится после перезагрузки.
Заодно можно убедиться, что сетевые настройки пока остаются локальными:
net:
port: 27017
bindIp: 127.0.0.1На этом этапе это именно то, что нам нужно: authorization уже включается, но MongoDB все еще не доступна извне.
Следующий вопрос — что увидит пользователь, если попробует подключиться без credentials.
Что произойдет с подключением без credentials
После включения authorization команда:
mongoshпо-прежнему может установить соединение с локальным mongod.
Но это не означает, что клиент получил полноценный доступ к данным.
Например, shell может открыться, но защищенные операции начнут возвращать ошибки авторизации.
Если попытаться посмотреть список databases:
show dbsMongoDB должна отказать в выполнении команды, потому что клиент не аутентифицирован.
То же самое произойдет при попытке выполнять операции, для которых требуются права.
То есть важно различать два понятия:
- Подключение к серверу;
- Авторизованный доступ к данным.
Сетевое соединение может установиться, но MongoDB не даст выполнять защищенные действия без пользователя.
Для нормальной работы после этого нужно подключаться, например, так:
mongosh --username mongo_admin --authenticationDatabase admin --passwordТеперь включим authorization и проверим это поведение на практике.
Практика: включаем authorization и перезапускаем MongoDB
Открываем конфигурацию:
sudo nano /etc/mongod.confДобавляем:
security:
authorization: enabledВместе с текущей сетевой настройкой соответствующая часть файла может выглядеть так:

Сохраняем файл.
Теперь перезапускаем MongoDB:
sudo systemctl restart mongodСразу проверим состояние сервиса:
sudo systemctl status mongodЕсли видим:
active (running)конфигурация принята.
Если сервис не запустился, первым делом смотрим:
sudo journalctl -u mongod -n 100 --no-pagerи:
sudo tail -n 100 /var/log/mongodb/mongod.logТеперь проверим подключение без credentials:
mongoshВнутри попробуем:
show dbsMongoDB должна сообщить, что операция требует authentication.
Выйдем:
exitТеперь подключимся правильно:
mongosh --username mongo_admin --authenticationDatabase admin --passwordПосле ввода пароля проверим:
show dbsи:
db.runCommand({ connectionStatus: 1 })Теперь команды должны выполняться с правами mongo_admin.
Коротко результат можно свести так:
| Изменение | Что происходит | Как проверить |
authorization: enabled | MongoDB начинает проверять пользователей и роли | Перезапустить mongod |
| Подключение без credentials | Соединение возможно, но защищенные операции блокируются | mongosh → show dbs |
| Подключение под admin | Доступ определяется ролью пользователя | mongosh --username mongo_admin --authenticationDatabase admin --password |
Ошибка в mongod.conf | mongod может не запуститься | systemctl status и journalctl |
Теперь анонимный доступ к MongoDB закрыт, а административные операции выполняются только после аутентификации.
Создаем отдельного пользователя приложения
Обязательная авторизация уже включена, а mongo_admin может управлять сервером. Теперь нужно отделить административный доступ от обычной работы приложения.
Это важный момент: приложение не должно подключаться к MongoDB под root-пользователем просто потому, что «так проще». Для него создадим отдельную учетную запись с правами только на рабочую database.
Почему приложение не должно работать от admin
Административный пользователь имеет слишком широкие права для обычного приложения.
Если приложение подключается как mongo_admin, оно потенциально может:
- Работать с чужими databases;
- Создавать и удалять пользователей;
- Менять роли;
- Выполнять административные команды;
- Затронуть весь MongoDB-сервер при ошибке в коде.
Для приложения это лишнее.
Ему обычно нужно гораздо меньше:
- Читать свои данные;
- Добавлять документы;
- Изменять их;
- Удалять их;
- Создавать необходимые indexes.
Поэтому правильнее создать отдельного пользователя:
app_userи ограничить его только:
app_dbЕсли потом приложение будет скомпрометировано, зона поражения хотя бы останется в пределах этой database, а не всего сервера.
Как ограничить пользователя одной database
Пользователь MongoDB создается внутри конкретной authentication database и получает роли с указанием database, к которой они относятся.
Для нашего приложения перейдем в:
use app_dbи создадим пользователя именно там.
Тогда его authentication database тоже будет:
app_dbЭто удобно и для connection string:
mongodb://app_user:password@127.0.0.1:27017/app_db?authSource=app_dbПри таком подходе учетная запись и рабочая database логически находятся в одном месте.
Права задаются через roles.
Например:
roles: [
{ role: "readWrite", db: "app_db" }
]Так пользователь получает доступ к чтению и записи только в app_db.
Он не становится администратором и не получает права на другие databases автоматически.
Какие роли нужны для чтения и записи
Для обычного приложения чаще всего подходит роль:
readWriteОна позволяет работать с данными в конкретной database.
Пользователь с readWrite может:
- Читать documents;
- Вставлять новые;
- Изменять существующие;
- Удалять documents;
- Создавать collections;
- Работать с indexes в рамках своих полномочий.
Если сервису нужно только читать данные, можно использовать более ограниченную роль:
readНапример, для отдельного reporting-сервиса это может быть достаточно.
Но нашему тестовому приложению понадобится полный обычный CRUD, поэтому используем:
readWriteдля app_db.
Теперь создадим пользователя и сразу проверим несколько сценариев: успешную запись, чтение, отсутствие административных прав и ошибку при неправильном пароле.
Практика: создаем app_user и проверяем права

Сначала подключимся под административным пользователем:
mongosh --username mongo_admin --authenticationDatabase admin --passwordПереходим в рабочую database:
use app_dbСоздаем пользователя:
db.createUser({
user: "app_user",
pwd: passwordPrompt(),
roles: [
{ role: "readWrite", db: "app_db" }
]
})После успешного создания проверим учетную запись:
db.getUser("app_user")В выводе должна быть видна роль:
readWriteдля:
app_dbТеперь выходим:
exitИ подключаемся уже как приложение:
mongosh \
--username app_user \
--authenticationDatabase app_db \
--password \
app_dbПосле ввода правильного пароля shell должен открыться.
Теперь проверим запись.
Создадим collection и добавим документ:
db.users.insertOne({
name: "Alice",
email: "alice@example.com",
active: true
})При успешной записи MongoDB вернет результат с acknowledged: true и insertedId.
Теперь проверим чтение:
db.users.find()В выводе должен появиться добавленный документ.
Следом проверим изменение:
db.users.updateOne(
{ name: "Alice" },
{ $set: { active: false } }
)И снова посмотрим данные:
db.users.find({ name: "Alice" })Теперь active должен быть false.
Можно проверить и удаление:
db.users.deleteOne({ name: "Alice" })То есть пользователь действительно умеет работать с данными своей database.
Теперь проверим обратную сторону — отсутствие административных прав.
Например, попробуем перейти в admin и запросить список пользователей:
use admin
db.getUsers()app_user не должен получить административный доступ к управлению пользователями.
Можно также попробовать создать пользователя:
db.createUser({
user: "should_not_work",
pwd: passwordPrompt(),
roles: []
})Операция должна завершиться ошибкой авторизации.
Теперь проверим неправильный пароль.
Выйдем из shell:
exitИ попробуем подключиться так:
mongosh \
--username app_user \
--authenticationDatabase app_db \
--password \
app_dbНа запрос пароля намеренно вводим неверное значение.
В ответ должны получить ошибку вида:
Authentication failedЭто важная проверка: MongoDB не просто знает пользователя, а действительно проверяет credentials.
После этого снова подключаемся с правильным паролем и убеждаемся, что доступ восстановлен.
Для итоговой проверки можно оставить четыре сценария:
| Проверка | Ожидаемый результат |
Запись в app_db | Успешно |
Чтение из app_db | Успешно |
| Административная команда | Access denied / Unauthorized |
| Неправильный пароль | Authentication failed |
Теперь модель доступа работает так, как и планировалось: mongo_admin управляет сервером, а app_user работает только со своей database.
Следующий шаг — сетевой уровень. Разберемся с bindIp, портом 27017 и тем, как открыть удаленный доступ только доверенному адресу, не выставляя MongoDB наружу без ограничений.
Настраиваем безопасный сетевой доступ
Почему MongoDB по умолчанию не стоит открывать всему интернету
MongoDB — это сервер базы данных, а не публичный веб-сервис.
Если открыть порт 27017 для всех адресов, любой клиент из интернета сможет хотя бы попытаться установить соединение с mongod.
Даже при включенной authorization это создает лишнюю поверхность атаки:
- Постоянные попытки подбора credentials;
- Сканирование порта;
- Лишняя нагрузка;
- Риск ошибки в настройках пользователей;
- Риск случайно отключить authentication в будущем и оставить базу открытой.
Поэтому лучше строить доступ по принципу: MongoDB слушает только там, где действительно нужно, а firewall пропускает только доверенные источники.
В идеале оба ограничения работают одновременно.
Первое задается через bindIp.
Второе — через firewall.
Как работает bindIp
Параметр bindIp определяет, на каких сетевых интерфейсах mongod принимает подключения.
Он находится в секции net файла:
/etc/mongod.confНапример:
net:
port: 27017
bindIp: 127.0.0.1В такой конфигурации MongoDB слушает только localhost.
То есть подключиться можно с самого VPS:
mongoshно другой сервер в сети уже не сможет достучаться до 27017.
Если нужно разрешить соединения еще и через private IP сервера, можно указать оба адреса:
net:
port: 27017
bindIp: 127.0.0.1,10.0.0.10Теперь mongod слушает:
- localhost;
- private interface 10.0.0.10.
Важно понимать: bindIp отвечает именно за то, где MongoDB слушает соединения.
Он не заменяет firewall.
Даже если mongod слушает private или public interface, сетевой доступ все равно лучше отдельно ограничить правилами firewall.
Когда достаточно 127.0.0.1
Если приложение работает на том же VPS, ничего открывать наружу вообще не нужно.
Схема тогда простая:

Connection string:
mongodb://app_user:password@127.0.0.1:27017/app_db?authSource=app_dbЭто один из самых безопасных и простых вариантов.
Порт 27017 не доступен снаружи, а приложение общается с базой через loopback interface.
Такую схему стоит оставлять, если нет конкретной причины для удаленного подключения.
Чем меньше сетевых интерфейсов слушает MongoDB, тем меньше настроек нужно защищать и диагностировать.
Когда нужен удаленный доступ
Удаленный доступ нужен, если приложение и MongoDB находятся на разных серверах.
Например: Application VPS → MongoDB VPS
В таком случае база должна принимать соединения по адресу, доступному приложению.
Лучше использовать private network, если облачный провайдер ее предоставляет.
Например:

Тогда в mongod.conf можно оставить:
net:
port: 27017
bindIp: 127.0.0.1,10.0.0.10А приложение будет подключаться к:
mongodb://app_user:password@10.0.0.10:27017/app_db?authSource=app_dbТак database traffic вообще не нужно выводить в публичный интернет.
Если private network нет и приходится использовать public IP, особенно важно ограничить firewall только конкретным доверенным адресом приложения.
То есть нежелательный вариант: 0.0.0.0:27017 → доступно всем
Нормальный вариант: MongoDB public IP:27017 → доступ только с IP приложения
Теперь настроим этот второй уровень защиты.
Как ограничить порт 27017 через firewall
Предположим, доверенный IP приложения:
203.0.113.20Если используется UFW, можно разрешить подключение только с этого адреса:
sudo ufw allow from 203.0.113.20 to any port 27017 proto tcpПроверим правила:
sudo ufw status numberedНе нужно добавлять:
sudo ufw allow 27017/tcpесли MongoDB не должна быть доступна всем.
Такое правило откроет порт для любого источника, что нам как раз не нужно.
Если VPS находится у облачного провайдера с отдельным network firewall или security group, ограничение стоит повторить и там.
Тогда получается два слоя: Cloud firewall → UFW → mongod bindIp
Чтобы соединение прошло, все три уровня должны разрешить нужный маршрут.
Практика: открываем доступ только доверенному адресу
Предположим, MongoDB VPS имеет private IP:
10.0.0.10а приложение:
10.0.0.20Откроем конфигурацию:
sudo nano /etc/mongod.confНастроим секцию net:
net:
port: 27017
bindIp: 127.0.0.1,10.0.0.10Сохраняем файл и перезапускаем MongoDB:
sudo systemctl restart mongodПроверяем:
sudo systemctl is-active mongodТеперь посмотрим, где реально слушает порт:
sudo ss -lntp | grep 27017В выводе должны присутствовать только нужные адреса.
Если используется UFW, разрешаем доступ с сервера приложения:
sudo ufw allow from 10.0.0.20 to any port 27017 proto tcpПроверяем:
sudo ufw statusТеперь с Application VPS можно проверить сам TCP-порт:
nc -vz 10.0.0.10 27017Если nc отсутствует:
sudo apt install -y netcat-openbsdПосле этого уже проверим полноценное подключение:
mongosh \
"mongodb://app_user@10.0.0.10:27017/app_db?authSource=app_db" \
--passwordПри правильном пароле пользователь должен войти и получить доступ к app_db.
С другого, недоверенного адреса порт при этом должен оставаться недоступным.
Для удобства сравним основные варианты:
| Схема | bindIp | Firewall | Когда использовать |
| Localhost | 127.0.0.1 | 27017 наружу закрыт | Приложение и MongoDB на одном VPS |
| Private network | 127.0.0.1,10.0.0.10 | Разрешен только private IP приложения | Лучший вариант для двух VPS в одной private network |
| Public network | Localhost + нужный public interface | 27017 разрешен только доверенному public IP | Если private network недоступна |
Идём дальше.
Проверяем подключение к MongoDB
Сетевой доступ уже настроен: локальный клиент может обращаться к MongoDB через 127.0.0.1, а при необходимости удаленный сервер получает доступ только через доверенный адрес. Теперь осталось проверить, что connection string составлен правильно и MongoDB действительно различает успешное подключение, неверный authSource и неправильный пароль.
Здесь полезно пройти сразу несколько сценариев. Тогда позже при ошибке будет проще понять, проблема в credentials, authentication database или самой сети.
Как выглядит connection string
Для подключения к MongoDB обычно используют URI вида:
mongodb://username:password@host:27017/database?authSource=authentication_databaseВ нашем случае локальная строка выглядит так:
mongodb://app_user:password@127.0.0.1:27017/app_db?authSource=app_dbЗдесь:
app_user— пользователь приложения;- password — его пароль;
127.0.0.1— адрес MongoDB;- 27017 — стандартный порт;
app_db— рабочая database;authSource=app_db— database, где создан пользователь.
Для удаленного подключения меняется в первую очередь host:
mongodb://app_user:password@10.0.0.10:27017/app_db?authSource=app_dbили доверенный public IP, если private network недоступна.
В production лучше не передавать пароль прямо в командной строке, потому что он может попасть в shell history или список процессов. Для ручной проверки удобнее использовать --password и вводить значение интерактивно.
Зачем нужен authSource
MongoDB должна знать, в какой database искать учетную запись пользователя.
Мы создавали:
app_userв:
app_dbПоэтому правильный authSource:
authSource=app_dbЕсли вместо этого указать:
authSource=adminMongoDB будет искать app_user в другой authentication database.
В результате пароль может быть совершенно правильным, но аутентификация все равно завершится ошибкой.
Это одна из причин, почему Authentication failed не всегда означает «неправильный пароль».
Сначала стоит проверить сразу три вещи:
- username;
- password;
- authSource.
Теперь проверим правильный локальный сценарий.
Как проверить локальное подключение
На MongoDB VPS подключимся так:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordПосле запроса вводим пароль app_user.
Если все настроено правильно, откроется MongoDB Shell.
Проверим текущую database:
dbОжидаем:
app_dbТеперь выполним простой запрос:
db.runCommand({ ping: 1 })И проверим доступ к данным:
db.users.find()Если collection еще пустая или отсутствует, это не проблема. Главное, что команда выполняется без Unauthorized.
Так мы подтверждаем сразу три вещи:
- MongoDB доступна локально;
- credentials работают;
- пользователь имеет права на app_db.
После этого можно проверить ту же схему с другого сервера.
Как проверить удаленное подключение
На Application VPS сначала убедимся, что порт доступен:
nc -vz 10.0.0.10 27017Если соединение проходит, переходим к MongoDB authentication:
mongosh \
"mongodb://app_user@10.0.0.10:27017/app_db?authSource=app_db" \
--passwordПосле правильного пароля shell должен открыться так же, как при локальном подключении.
Внутри можно выполнить:
db.runCommand({ ping: 1 })и:
db.users.find()Если TCP-порт недоступен вообще, до authentication дело еще не дошло.
Тогда нужно возвращаться к предыдущему уровню и проверять:
bindIp;- UFW;
- cloud firewall;
- IP MongoDB VPS;
- маршрут между серверами.
То есть ошибка подключения и ошибка авторизации — это два разных этапа.
Что должно происходить при неправильном пароле

Теперь намеренно проверим негативный сценарий.
Выполним ту же команду:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordНо введем неправильный пароль.
MongoDB должна отказать в аутентификации и вернуть ошибку вида:
Authentication failedЭто ожидаемое поведение.
Можно отдельно проверить неправильный authSource:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=admin" \
--passwordДаже с правильным паролем подключение под app_user должно завершиться ошибкой, потому что пользователь создан в app_db, а не в admin.
Таким образом, у нас уже есть несколько контрольных сценариев:
| Сценарий | Строка подключения / проверка | Ожидаемый результат |
| Локально, правильные credentials | mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db | Успешный вход |
| Удаленно с доверенного сервера | mongodb://app_user@10.0.0.10:27017/app_db?authSource=app_db | Успешный вход |
| Неправильный пароль | Та же URI, неверный password | Authentication failed |
Неправильный authSource | authSource=admin для app_user | Authentication failed |
| Недоверенный IP | Проверка 27017 с другого адреса | Соединение блокируется firewall |
Теперь подключение проверено и с сетевой, и с authentication стороны. Следующий шаг — перейти от самой инфраструктуры к данным: создадим тестовую collection, добавим несколько documents и подготовим их для полного цикла backup → удаление → restore.
Записываем тестовые данные
Создаем тестовую database и collection
В MongoDB не требуется заранее создавать database отдельной командой.
Database и collection фактически появляются после первой записи данных. Поэтому достаточно подключиться к app_db:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordПосле ввода пароля убедимся, что выбрана нужная database:
dbОжидаемый результат:
app_dbCollection можно создать явно:
db.createCollection("products")При успешном выполнении получим результат с:
ok: 1Проверим список collections:
show collectionsТеперь среди них должна присутствовать:
productsЯвное создание collection здесь не обязательно — MongoDB могла бы создать ее автоматически при первой вставке. Но для пошаговой проверки удобнее сначала создать структуру, а затем отдельно добавить документы.
Добавляем несколько documents
Добавим сразу несколько записей через insertMany():
db.products.insertMany([
{
sku: "TEST-001",
name: "Mechanical Keyboard",
price: 89.90,
stock: 12,
active: true
},
{
sku: "TEST-002",
name: "Wireless Mouse",
price: 39.50,
stock: 27,
active: true
},
{
sku: "TEST-003",
name: "USB-C Dock",
price: 119.00,
stock: 5,
active: false
}
])Если запись прошла успешно, MongoDB вернет:
acknowledged: trueа также _id созданных документов.
Получается небольшой, но удобный набор данных. Записи легко отличить друг от друга по sku, названию, цене и остатку.
Теперь специально не будем их изменять до backup. Именно это состояние базы понадобится сравнить с результатом после восстановления.
Проверяем записанные данные
Посмотрим все документы:
db.products.find()Для более компактного результата можно вывести только нужные поля:
db.products.find(
{},
{
_id: 0,
sku: 1,
name: 1,
price: 1,
stock: 1,
active: 1
}
)Должны увидеть три записи:
- TEST-001
- TEST-002
- TEST-003
Посчитаем документы:
db.products.countDocuments()Ожидаемый результат: 3
Можно дополнительно проверить конкретную запись:
db.products.findOne({ sku: "TEST-003" })MongoDB должна вернуть документ с USB-C Dock.
Теперь у нас есть несколько удобных контрольных признаков:
- database —
app_db; - collection — products;
- количество документов — 3;
- уникальные sku — TEST-001, TEST-002, TEST-003.
После восстановления проверим те же значения. Если collection снова содержит все три документа с исходными полями, restore действительно вернул данные.
Практика: готовим данные для backup

Перед созданием резервной копии проведем финальную проверку.
Сначала убедимся, что работаем в нужной database:
dbРезультат:
app_dbПроверяем collection:
show collectionsВ списке должна быть:
productsПроверяем количество записей:
db.products.countDocuments()Получаем:
3Теперь выведем контрольный набор:
db.products.find(
{},
{
_id: 0,
sku: 1,
name: 1,
stock: 1
}
).sort({ sku: 1 })Перед backup результат должен соответствовать примерно такой структуре:
{
sku: 'TEST-001',
name: 'Mechanical Keyboard',
stock: 12
}
{
sku: 'TEST-002',
name: 'Wireless Mouse',
stock: 27
}
{
sku: 'TEST-003',
name: 'USB-C Dock',
stock: 5
}На этом тестовый набор готов.
Дальше начнется основной цикл проверки резервного копирования:

Следующий шаг — создать резервную копию через mongodump и убедиться, что backup действительно содержит нашу app_db, прежде чем что-либо удалять.
Создаем резервную копию через mongodump
Что сохраняет mongodump
mongodump подключается к работающей MongoDB и выгружает содержимое databases в BSON.
При обычном backup одной database структура будет примерно такой:

Файл products.bson содержит сами documents.
А products.metadata.json хранит метаданные collection, например информацию об indexes и дополнительных параметрах.
Если в database несколько collections, для каждой появятся соответствующие BSON- и metadata-файлы.
То есть mongodump сохраняет не текстовый экспорт вроде CSV, а структуру, предназначенную именно для последующего восстановления MongoDB.
Чем logical backup отличается от копирования файлов MongoDB
Можно было бы предположить, что достаточно скопировать:
/var/lib/mongodbно это совсем другой подход.
В этом каталоге находятся внутренние файлы WiredTiger, journal и служебные данные работающего storage engine. Простое копирование файлов во время работы mongod не равно корректному logical backup и может дать несогласованное состояние.
mongodump работает на более высоком уровне:

Он подключается к серверу как обычный клиент и выгружает доступные ему данные.
Это удобно для:
- Резервного копирования отдельных databases;
- Переноса данных между MongoDB-серверами;
- Восстановления отдельных collections;
- Небольших и средних объемов данных;
- Тестирования процедуры restore.
Но logical backup тоже не заменяет полноценную стратегию резервирования для любой нагрузки. Чем больше database и интенсивнее запись, тем важнее заранее продумать консистентность, окно backup и способ хранения копий.
Как передать credentials безопаснее
Самый очевидный вариант выглядел бы так:
mongodump \
--username app_user \
--password MySecretPassword \
--authenticationDatabase app_db \
--db app_dbНо пароль в командной строке — плохая идея.
Он может остаться в shell history, попасть в скрипт или быть случайно сохранен вместе с другими командами.
Поэтому лучше передать только имя пользователя и попросить утилиту запросить пароль интерактивно:
mongodump \
--username app_user \
--authenticationDatabase app_db \
--password \
--db app_dbПосле запуска появится запрос пароля.
Другой вариант — использовать URI без пароля:
mongodump \
--uri="mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordВ обоих случаях секрет не записывается прямо в команду.
Если backup автоматизируется через cron или systemd timer, credentials уже нужно хранить отдельно с ограниченными правами, а не вставлять пароль непосредственно в shell-команду.
Куда сохранять backup
По умолчанию mongodump создает каталог dump в текущей директории.
Для разового теста этого достаточно, но на сервере удобнее заранее выделить понятный путь:
/var/backups/mongodbСоздадим его:
sudo install -d \
-m 700 \
-o "$(id -un)" \
-g "$(id -gn)" \
/var/backups/mongodbПрава 700 означают, что читать и изменять содержимое может только владелец каталога.
Это особенно полезно, потому что backup содержит реальные данные приложения.
При этом хранить единственную резервную копию на том же VPS недостаточно. Если сервер потеряет диск, backup исчезнет вместе с MongoDB.
Поэтому для production логика должна быть такой:

Например, второе хранилище, Object Storage или отдельный backup-сервер.
Сначала создадим локальную копию и проверим полный цикл восстановления
Практика: создаем backup app_db

Перед началом еще раз проверим, что исходные данные существуют.
Подключаемся:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordСчитаем документы:
db.products.countDocuments()Ожидаем: 3
Можно еще раз вывести контрольные записи:
db.products.find(
{},
{
_id: 0,
sku: 1,
name: 1,
stock: 1
}
).sort({ sku: 1 })После проверки выходим:
exitТеперь создаем отдельный каталог для этой копии:
mkdir -p /var/backups/mongodb/app-db-backupЗапускаем mongodump:
mongodump \
--host 127.0.0.1 \
--port 27017 \
--username app_user \
--authenticationDatabase app_db \
--password \
--db app_db \
--out /var/backups/mongodb/app-db-backupВводим пароль app_user.
При успешной работе в выводе будут сообщения о выгрузке collection products.
Теперь посмотрим структуру:
find /var/backups/mongodb/app-db-backup -maxdepth 2 -type fДолжны увидеть примерно:
/var/backups/mongodb/app-db-backup/app_db/products.bson
/var/backups/mongodb/app-db-backup/app_db/products.metadata.jsonПроверим размер:
du -sh /var/backups/mongodb/app-db-backupИ отдельно содержимое database:
ls -lh /var/backups/mongodb/app-db-backup/app_dbПеред удалением исходной database важно убедиться хотя бы в трех вещах:
- Mongodump завершился без ошибки;
- Каталог
app_dbдействительно появился; - Внутри есть products.bson.
Для разных сценариев команды выглядят так:
| Сценарий | Пример |
| Dump доступных databases сервера | mongodump --username mongo_admin --authenticationDatabase admin --password --out /var/backups/mongodb/full |
| Dump одной database | mongodump --username app_user --authenticationDatabase app_db --password --db app_db --out /var/backups/mongodb/app-db-backup |
| Один archive-файл | mongodump --username app_user --authenticationDatabase app_db --password --db app_db --archive=/var/backups/mongodb/app_db.archive.gz --gzip |
Archive-режим удобен, если вместо каталога с несколькими BSON-файлами хочется получить один сжатый файл:
app_db.archive.gzДля нашего наглядного теста оставим обычный directory dump — так проще увидеть, что backup действительно содержит products.
Теперь резервная копия существует отдельно от исходной database.
Удаляем тестовую database
Backup уже создан и сохранен отдельно от рабочей MongoDB. Теперь нужно проверить его по-настоящему: удалить исходную database и убедиться, что данных больше нет.
Именно этот шаг отличает реальную проверку восстановления от ситуации, когда mongorestore запускается поверх уже существующих collections и нельзя однозначно понять, что именно вернулось из backup.
Почему перед удалением еще раз проверяем backup
Перед dropDatabase() стоит сделать последнюю контрольную проверку.
После удаления исходной database единственным источником данных останется созданный dump. Если backup оказался пустым, записан не в тот каталог или завершился с ошибкой, восстанавливать будет уже нечего.
Поэтому еще раз проверим файлы:
find /var/backups/mongodb/app-db-backup -maxdepth 2 -type fОжидаем увидеть:
/var/backups/mongodb/app-db-backup/app_db/products.bson
/var/backups/mongodb/app-db-backup/app_db/products.metadata.jsonПроверим размер:
du -sh /var/backups/mongodb/app-db-backupИ отдельно содержимое каталога:
ls -lh /var/backups/mongodb/app-db-backup/app_dbЕсли products.bson существует и mongodump ранее завершился без ошибок, можно переходить к удалению.
Для дополнительной проверки можно еще раз посмотреть исходные данные:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordВнутри shell:
db.products.countDocuments()Ожидаемый результат: 3
И:
db.products.find(
{},
{
_id: 0,
sku: 1,
name: 1
}
).sort({ sku: 1 })После этого можно удалять database.
Практика: выполняем dropDatabase() и убеждаемся, что данных больше нет

Мы уже подключены к:
app_dbПроверим это:
dbОжидаем:
app_dbТеперь выполняем:
db.dropDatabase()При успешном удалении MongoDB вернет результат примерно такого вида:
{ ok: 1, dropped: 'app_db' }На этом database удалена вместе с ее collections и documents.
Проверим список databases:
show dbsapp_db больше не должна появляться в списке.
Теперь попробуем посмотреть collection:
show collectionsИ выполнить запрос:
db.products.find()Так как исходная database уже удалена, прежних документов там больше нет.
Можно также проверить количество:
db.products.countDocuments()Для отсутствующей или заново не созданной collection результат будет: 0
Важно понимать один нюанс: команда:
use app_dbсама по себе не восстанавливает database.
Она лишь переключает текущий контекст shell. Database появится снова только после записи данных или восстановления через mongorestore.
Поэтому после dropDatabase() мы специально ничего не вставляем вручную.
Контрольное состояние теперь такое:

Теперь исходные данные действительно удалены, а единственная копия тестового набора находится в backup.
Следующий шаг — восстановить app_db через mongorestore и проверить, что collection products снова содержит все три исходных документа.
Восстанавливаем MongoDB через mongorestore
Как mongorestore читает данные mongodump
mongorestore работает в паре с mongodump.
Ранее mongodump создал структуру:

Теперь mongorestore читает эти файлы и создает соответствующие databases и collections обратно в MongoDB.
Упрощенно процесс выглядит так:

При этом восстанавливаются сами documents и связанная с collection metadata.
Так как app_db сейчас удалена полностью, ситуация максимально чистая: восстановление должно фактически создать ее заново из dump.
Что происходит с существующими collections
Если database или collection уже существуют, mongorestore не всегда ведет себя так, как ожидает пользователь.
Без дополнительных параметров restore пытается добавить данные из backup в существующие collections.
Это может привести к нескольким сценариям:
- Документы добавятся к существующим;
- Возникнут конфликты по
_id; - Часть записей уже будет присутствовать;
- Результат перестанет быть точной копией состояния backup.
Именно поэтому перед restore нужно понимать, куда именно загружаются данные.
В нашей текущей проверке проблема отсутствует: app_db удалена, поэтому products будет создана заново.
Но если restore выполняется поверх существующей database, часто удобнее заранее очистить нужные collections.
Для этого и используется --drop.
Когда использовать --drop
Параметр:
--dropговорит mongorestore удалить соответствующую collection перед восстановлением ее из backup.
Например:
mongorestore \
--username app_user \
--authenticationDatabase app_db \
--password \
--drop \
/var/backups/mongodb/app-db-backup/app_dbЛогика становится такой:

Это удобно, когда нужно именно заменить текущее состояние данными из dump.
Но --drop стоит использовать осознанно. Если в существующей collection есть новые данные, которых нет в backup, они будут удалены.
В нашем сценарии app_db уже отсутствует, поэтому технически --drop не обязателен. Но сам параметр полезно знать, потому что при повторных restore он часто становится важен.
Теперь восстановим удаленную database.
Практика: восстанавливаем удаленную app_db
Сначала убедимся, что backup на месте:
find /var/backups/mongodb/app-db-backup -maxdepth 2 -type fОжидаем:
/var/backups/mongodb/app-db-backup/app_db/products.bson
/var/backups/mongodb/app-db-backup/app_db/products.metadata.jsonТеперь запускаем restore. Здесь есть важный нюанс: хотя мы полностью удалили app_db через db.dropDatabase(), созданный в ней пользователь app_user не удаляется вместе с данными. MongoDB хранит сведения о пользователях отдельно от пользовательских коллекций, поэтому dropDatabase() удаляет данные базы, но не связанную с ней учетную запись.
Поэтому для восстановления мы по-прежнему можем аутентифицироваться как app_user, указав app_db в качестве authentication database:
mongorestore \
--host 127.0.0.1 \
--port 27017 \
--username app_user \
--authenticationDatabase app_db \
--password \
/var/backups/mongodb/app-db-backup/app_dbПосле запуска вводим пароль app_user.
При успешном восстановлении в выводе должны появиться сообщения о восстановлении app_db.products и количестве успешно импортированных документов.
Так как пользовательские данные app_db были удалены полностью, mongorestore заново создаст необходимые коллекции базы, включая products.
Если нужно восстановить те же данные поверх уже существующей collection, команда выглядела бы так:
mongorestore \
--host 127.0.0.1 \
--port 27017 \
--username app_user \
--authenticationDatabase app_db \
--password \
--drop \
/var/backups/mongodb/app-db-backup/app_dbПосле завершения restore можно сразу переходить к проверке результата.
Проверяем documents после restore

Подключаемся снова:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordПроверяем текущую database:
dbОжидаем:
app_dbТеперь смотрим collections:
show collectionsВ списке снова должна появиться:
productsПроверим количество документов:
db.products.countDocuments()Ожидаемый результат:
3Теперь выведем контрольные записи:
db.products.find(
{},
{
_id: 0,
sku: 1,
name: 1,
price: 1,
stock: 1,
active: 1
}
).sort({ sku: 1 })Должны вернуться те же три документа:
{
sku: 'TEST-001',
name: 'Mechanical Keyboard',
price: 89.9,
stock: 12,
active: true
}
{
sku: 'TEST-002',
name: 'Wireless Mouse',
price: 39.5,
stock: 27,
active: true
}
{
sku: 'TEST-003',
name: 'USB-C Dock',
price: 119,
stock: 5,
active: false
}Для дополнительной проверки можно запросить конкретную запись:
db.products.findOne({ sku: "TEST-003" })Если вернулся USB-C Dock с исходными полями, backup восстановился корректно.
Получается полный цикл:

Или чуть подробнее:

Теперь backup проверен полностью: данные были записаны, выгружены, исходная database удалена, затем восстановлена из dump и снова проверена через запросы.
Исправляем ошибки авторизации
К этому моменту у нас уже есть два пользователя с разными задачами: mongo_admin управляет сервером, а app_user работает только с app_db. Поэтому большинство проблем со входом теперь можно разбирать довольно системно.
Обычно ошибка авторизации возникает из-за одного из четырех факторов:
- Неправильный username;
- Неправильный password;
- Неверный
authSource; - Недостаточные roles.
Важно сначала понять, к какому типу относится ошибка, и только потом менять конфигурацию.
Что означает Authentication failed
Сообщение: Authentication failed, означает, что MongoDB не смогла успешно аутентифицировать пользователя.
Чаще всего причины простые:
- Введен неверный пароль;
- Указано неправильное имя пользователя;
- Выбран неверный
authSource; - Пользователь создан не в той authentication database, которую использует клиент.
Например, наш app_user создан в:
app_dbПоэтому такая команда корректна:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordА здесь уже есть проблема:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=admin" \
--passwordMongoDB будет искать app_user в admin, а там такой учетной записи нет.
Результат — Authentication failed, даже если пароль введен правильно.
Почему важен правильный authSource
authSource указывает database, где хранится учетная запись пользователя.
Это не обязательно та же database, с которой пользователь работает.
Например, административный пользователь:
mongo_adminсоздан в:
adminПоэтому для него используется:
authSource=adminА пользователь приложения:
app_userсоздан в:
app_dbЗначит, для него:
authSource=app_dbПолезно мысленно разделять два параметра: рабочая database ≠ authentication database
Иногда они совпадают, как у app_user.
Иногда нет.
Например, пользователь может быть создан в admin, но иметь права на другую database. Тогда connection string будет содержать рабочую database в пути, а authSource=admin.
Если этот момент перепутать, пароль можно проверять сколько угодно — ошибка не исчезнет.
Что происходит при подключении пользователя не к той database
Здесь важно различать две ситуации.
Первая — неправильная authentication database.
Например: app_user
создан в app_db, а клиент использует:
authSource=adminВ этом случае пользователь вообще не пройдет аутентификацию.
Вторая ситуация — пользователь успешно аутентифицирован, но переключается на database, где у него нет нужной роли.
Например, app_user подключился правильно:
authSource=app_dbа затем выполнил:
use adminСам переход контекста еще не означает, что пользователь получил права на admin.
Если после этого выполнить административную команду:
db.getUsers()MongoDB должна вернуть ошибку авторизации.
То есть: успешный login ≠ права на любую database.
Права определяются назначенными roles.
Как проверить roles пользователя
Проверять пользователя удобнее под mongo_admin.
Подключаемся:
mongosh \
--username mongo_admin \
--authenticationDatabase admin \
--passwordЕсли нужно посмотреть app_user, переходим в его authentication database:
use app_dbТеперь:
db.getUser("app_user")В выводе должна быть роль:
readWriteдля:
app_dbДля более полного списка пользователей можно использовать:
db.getUsers()Если нужно проверить административного пользователя:
use admin
db.getUser("mongo_admin")Так можно быстро ответить на два вопроса:
- Где пользователь создан;
- Какие roles ему назначены.
Если пользователь успешно входит, но конкретная операция завершается Unauthorized, проблема чаще всего уже не в пароле, а именно в правах.
Практика: диагностируем ошибку входа
Разберем типичный сценарий.
Пользователь пытается подключиться:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=admin" \
--passwordПароль вводится правильный, но получаем:
Authentication failedСначала проверяем, существует ли пользователь.
Под mongo_admin:
use app_db
db.getUser("app_user")Если пользователь найден, смотрим, в какой database мы его проверяем.
У нас это:
app_dbЗначит, authentication database должна быть такой же.
Исправляем connection string:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordТеперь вводим тот же пароль.
Подключение должно пройти успешно.
Если нет, проверяем username:
app_userи повторно вводим пароль вручную.
Следующий сценарий — login проходит, но операция запрещена.
Например:
use admin
db.getUsers()и получаем ошибку Unauthorized.
В этом случае аутентификация работает нормально. Просто app_user не имеет административных roles.
Проверяем его права:
use app_db
db.getUser("app_user")Если видим:
readWriteдля app_db, поведение правильное.
Основные ошибки можно свести в одну таблицу:
| Ошибка | Возможная причина | Что проверить | Решение |
Authentication failed | Неверный password | Ввести пароль повторно | Использовать правильные credentials |
Authentication failed | Неверный username | Имя пользователя | Исправить username |
Authentication failed | Неправильный authSource | Где создан пользователь | Указать правильную authentication database |
| Unauthorized | Недостаточно прав | db.getUser() и roles | Назначить нужную role или использовать другого пользователя |
| Login работает, но admin-команда запрещена | Пользователь не admin | Roles пользователя | Использовать mongo_admin |
| Пользователь не найден | Проверяется не та database | Выполнить use <auth_db> | Перейти в правильную authentication database |
Главное различие здесь простое:

Если держать это различие в голове, большинство проблем со входом диагностируются довольно быстро.
Исправляем ошибки подключения
С ошибками авторизации мы уже разобрались. Теперь перейдем к другому классу проблем — когда клиент вообще не может установить соединение с mongod.
Здесь важно разделять уровни диагностики. Если MongoDB отвечает и возвращает Authentication failed, сеть уже работает. А вот Connection refused, timeout или полное отсутствие ответа обычно указывают на сервис, bindIp, порт или firewall.
Что означает Connection refused
Ошибка вида:
Connection refusedобычно означает, что клиент смог обратиться к нужному адресу, но на указанном порту никто не принял соединение.
Чаще всего причины такие:
mongodне запущен;- MongoDB слушает другой interface;
- указан неправильный IP;
- указан неправильный port;
- сервис завершился после ошибки конфигурации.
Сначала проверяем сам mongod:
sudo systemctl status mongodДля короткой проверки:
sudo systemctl is-active mongodОжидаем:
activeЕсли сервис остановлен, пробуем запустить:
sudo systemctl start mongodЕсли запуск завершается ошибкой:
sudo journalctl -u mongod -n 100 --no-pagerПосле изменения mongod.conf это особенно важно: неправильный YAML, неверный IP в bindIp или другая ошибка конфигурации могут не дать серверу запуститься вообще.
Почему MongoDB может слушать только localhost
Даже если mongod работает, удаленное подключение может не проходить из-за:
net:
port: 27017
bindIp: 127.0.0.1В такой конфигурации MongoDB принимает соединения только через loopback interface.
Локально все будет работать:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordНо попытка обратиться к public или private IP сервера извне не пройдет.
Проверить текущую конфигурацию можно так:
grep -A 4 "^net:" /etc/mongod.confИли посмотреть, какие адреса реально слушает процесс:
sudo ss -lntp | grep 27017Если видим только:
127.0.0.1:27017MongoDB доступна исключительно локально.
Если удаленный доступ действительно нужен, добавляем локальный адрес нужного interface:
net:
port: 27017
bindIp: 127.0.0.1,10.0.0.10После изменения:
sudo systemctl restart mongodИ снова проверяем:
sudo ss -lntp | grep 27017Как проверить порт 27017
Диагностику удобнее проводить с двух сторон.
Сначала на самом MongoDB VPS:
sudo ss -lntp | grep 27017Эта команда показывает, слушает ли какой-либо процесс TCP-порт 27017 и на каком адресе.
Например:
127.0.0.1:27017означает только localhost.
А:
10.0.0.10:27017означает, что MongoDB принимает соединения на private interface.
Теперь проверяем порт с Application VPS:
nc -vz 10.0.0.10 27017При успешном соединении получим сообщение о том, что TCP connection установлено.
Если nc отсутствует:
sudo apt install -y netcat-openbsdТолько после успешного TCP-теста имеет смысл проверять mongosh.
Например:
mongosh \
"mongodb://app_user@10.0.0.10:27017/app_db?authSource=app_db" \
--passwordТак намного проще локализовать проблему.
Если nc не соединяется, дело еще не в MongoDB credentials.
Как отличить проблему firewall от MongoDB
Предположим, удаленное подключение не работает.
Сначала проверяем MongoDB локально:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordЕсли локальное подключение работает, значит:
mongodзапущен;- authentication работает;
- пользователь существует.
Следом смотрим:
sudo ss -lntp | grep 27017Если нужный private или public IP присутствует, MongoDB действительно слушает внешний interface.
Теперь проверяем firewall:
sudo ufw status numberedДля нашей private-схемы должно быть разрешение примерно такого вида:
10.0.0.20 → 27017/tcp
Если правила нет:
sudo ufw allow from 10.0.0.20 to any port 27017 proto tcpЕсли UFW настроен правильно, но соединения все равно нет, нужно проверить внешний firewall облачного провайдера.
То есть диагностика идет последовательно:

Если на локальном сервере ss показывает нужный address, а удаленный nc не проходит, подозрение уже смещается в сторону firewall или маршрутизации.
Что делать при timeout
Timeout отличается от Connection refused.
При Connection refused ответ обычно приходит быстро: удаленная сторона сообщает, что соединение принять некому.
При timeout клиент отправляет запрос, но не получает нормального ответа в отведенное время.
Типичные причины:
- firewall silently drops packets;
- cloud firewall блокирует трафик;
- указан неправильный IP;
- нет маршрута между private networks;
- приложение обращается к private IP из сети, которая его не видит;
- проблема в network ACL или routing.
Начнем с IP:
ip addrНа MongoDB VPS проверяем, действительно ли указанный в bindIp адрес существует.
Например, если в конфигурации:
bindIp: 127.0.0.1,10.0.0.10у сервера действительно должен быть адрес:
10.0.0.10Далее с Application VPS:
nc -vz 10.0.0.10 27017Если private network используется впервые, полезно проверить маршрут:
ip routeМожно посмотреть и сам путь до узла:
tracepath 10.0.0.10Но отсутствие ответа на ICMP само по себе еще не доказывает, что MongoDB недоступна: некоторые сети фильтруют диагностический трафик отдельно.
Поэтому ключевой тест остается TCP-подключение именно к 27017.
Команды диагностики подключения
При проблеме с MongoDB удобнее не менять все настройки подряд, а пройти короткую последовательность.
На MongoDB VPS:
sudo systemctl is-active mongodЗатем:
sudo ss -lntp | grep 27017Проверяем конфигурацию:
grep -A 4 "^net:" /etc/mongod.confПроверяем UFW:
sudo ufw status numberedСмотрим последние сообщения сервиса:
sudo journalctl -u mongod -n 100 --no-pagerИ MongoDB log:
sudo tail -n 100 /var/log/mongodb/mongod.logТеперь на Application VPS:
nc -vz 10.0.0.10 27017Если TCP работает, проверяем уже MongoDB:
mongosh \
"mongodb://app_user@10.0.0.10:27017/app_db?authSource=app_db" \
--passwordТак можно быстро определить, на каком именно уровне ломается соединение.
| Симптом | Возможная причина | Команда | Что делать |
Connection refused | mongod остановлен | systemctl status mongod | Запустить сервис и проверить logs |
| Connection refused при удаленном доступе | MongoDB слушает только localhost | ss -lntp | grep 27017 | Добавить нужный server IP в bindIp |
| Timeout | Firewall блокирует трафик | ufw status numbered | Разрешить 27017 только доверенному IP |
| Timeout при private IP | Нет маршрута между серверами | ip route | Проверить private network и routing |
| Локально работает, удаленно нет | bindIp или firewall | ss, ufw, nc | Проверять сеть по уровням |
TCP работает, но mongosh не входит | Authentication problem | mongosh ... --password | Проверить username, password и authSource |
mongod не запускается после правок | Ошибка в mongod.conf | journalctl -u mongod | Исправить конфигурацию и перезапустить сервис |
Главное правило диагностики здесь простое: сначала проверяем сервис и TCP-доступность, а уже потом credentials.
Если 27017 недоступен на сетевом уровне, изменение пароля или authSource ничего не исправит. И наоборот, если TCP-соединение проходит, но MongoDB возвращает Authentication failed, искать проблему в firewall уже не нужно.
Проверяем MongoDB после перезагрузки
Основные настройки уже готовы: MongoDB запускается как systemd service, authorization включена, пользователи созданы, сетевой доступ ограничен, а данные успешно прошли полный цикл backup и restore.
Осталось проверить еще один важный сценарий — что произойдет после обычной перезагрузки VPS. Сервер должен вернуться в рабочее состояние без ручного запуска mongod и без потери настроек.
Что должно запуститься автоматически
Ранее мы включили автозапуск:
sudo systemctl enable mongodПоэтому после reboot systemd должен автоматически запустить:
mongod.serviceПри этом должны сохраниться все настройки из:
/etc/mongod.confВ том числе:
security:
authorization: enabledи текущая секция net.
То есть после перезагрузки мы ожидаем сразу несколько вещей:
- Mongod запущен;
- MongoDB слушает нужный interface;
- Authorization остается включенной;
- Пользователи сохраняются;
app_dbи collection products остаются на месте;- Приложение может подключиться тем же connection string.
Теперь проверим это на практике.
Как проверить service
Перезагружаем VPS:
sudo rebootПосле повторного подключения по SSH сначала проверяем состояние MongoDB:
sudo systemctl status mongodОжидаем:
active (running)Короткий вариант:
sudo systemctl is-active mongodРезультат:
activeОтдельно можно убедиться, что автозапуск действительно включен:
sudo systemctl is-enabled mongodОжидаем:
enabledЕсли mongod после reboot не запустился, смотрим:
sudo journalctl -u mongod -b --no-pagerПараметр:
-bпоказывает сообщения текущей загрузки системы, поэтому здесь удобно искать именно ошибки, возникшие после reboot.
Проверяем авторизацию
Теперь проверим, что MongoDB не вернулась к анонимному доступу.
Подключаемся без credentials:
mongoshВнутри пробуем:
show dbsЗащищенная команда не должна выполняться без аутентификации.
Теперь выходим:
exitИ подключаемся как app_user:
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordПри правильном пароле вход должен пройти успешно.
Это подтверждает сразу две вещи:
authorization: enabledсохранилась после reboot;- Учетная запись
app_userосталась доступна.
При необходимости можно проверить и admin:
mongosh \
--username mongo_admin \
--authenticationDatabase admin \
--passwordПроверяем данные после reboot
Теперь убедимся, что сохраненные данные никуда не исчезли.
Под app_user:
dbОжидаем:
app_dbПроверяем collection:
show collectionsВ списке должна быть:
productsТеперь считаем документы:
db.products.countDocuments()Ожидаемый результат:
3И выводим контрольные записи:
db.products.find(
{},
{
_id: 0,
sku: 1,
name: 1,
stock: 1
}
).sort({ sku: 1 })Снова должны увидеть:
- TEST-001
- TEST-002
- TEST-003
Так мы подтверждаем, что данные пережили не только restore, но и обычный restart всего VPS.
Заодно можно еще раз проверить сетевую часть:
sudo ss -lntp | grep 27017MongoDB должна слушать те же адреса, которые указаны в mongod.conf.
Если используется удаленный Application VPS, оттуда повторяем:
nc -vz 10.0.0.10 27017и затем:
mongosh \
"mongodb://app_user@10.0.0.10:27017/app_db?authSource=app_db" \
--passwordИтоговую проверку удобно свести в четыре уровня:
| Проверка | Команда | Ожидаемый результат |
| Service | systemctl is-active mongod | active |
| Auth | mongosh ... --password | Пользователь успешно входит |
| Data | db.products.countDocuments() | 3 |
| Network | ss -lntp | grep 27017 | MongoDB слушает нужные адреса |
Если все четыре проверки проходят после reboot, MongoDB возвращается в рабочее состояние автоматически: сервис запускается, authorization продолжает действовать, данные сохраняются, а сетевой доступ остается таким же, как до перезагрузки.
Теперь можно перейти к финальной части и собрать основные рекомендации для production: как хранить credentials, ограничивать сетевой доступ, работать с backup и следить за состоянием сервера.
Как безопасно использовать MongoDB в production
Не использовать административного пользователя для приложения
mongo_admin нужен для управления MongoDB, а не для повседневной работы приложения.
Приложение должно подключаться под отдельной учетной записью:
app_userс правами только на свою database:
app_dbПричина простая: если приложение работает под admin, любая ошибка или компрометация приложения получает слишком широкий доступ.
Гораздо безопаснее схема:

Пароли этих учетных записей тоже должны храниться раздельно. Admin credentials не должны попадать в .env приложения, deployment scripts или CI/CD variables, которые используются самим приложением.
Не открывать 27017 всему интернету
MongoDB не должна становиться публичным сервисом только потому, что приложению нужен удаленный доступ.
Если приложение и MongoDB находятся на одном VPS, лучше оставить:
net:
bindIp: 127.0.0.1Если серверы разнесены, предпочтительнее использовать private network.
Например: Application VPS → 10.0.0.10:27017 → MongoDB VPS
И только если private network недоступна, можно использовать public interface, но firewall при этом должен пропускать соединения только с конкретного доверенного IP.
То есть нежелательный вариант: 27017/tcp → доступен всем
а нормальный: 27017/tcp → доступен только Application VPS
Authorization остается обязательной в любом случае. Firewall не заменяет пользователей и roles, а дополняет их.
Ограничивать roles
Каждому пользователю нужно выдавать только те права, которые реально нужны для его задачи.
Для обычного приложения мы использовали:
readWriteна:
app_dbЕсли отдельному сервису нужна только аналитика или чтение, вместо readWrite лучше дать:
readНе стоит выдавать root, если пользователь должен работать только с одной database.
Чем уже права, тем меньше последствий у ошибки приложения, утечки credentials или неправильно написанного запроса.
Для быстрой проверки пользователей можно периодически смотреть:
db.getUser("app_user")и убеждаться, что список roles не разросся со временем без необходимости.
Хранить backup вне MongoDB VPS
Локальный backup удобен:
/var/backups/mongodbно он не должен быть единственной копией.
Если VPS потеряет диск, будет удален или станет недоступен из-за аварии, локальная backup исчезнет вместе с исходными данными.
Поэтому production-схема должна выглядеть примерно так:

В качестве внешнего места подойдет:
- Object Storage;
- отдельный backup VPS;
- другое хранилище в отдельной fault domain;
- защищенное корпоративное backup storage.
Главное — не хранить единственную копию рядом с оригиналом.
Регулярно проверять restore
Создание backup само по себе еще не гарантирует, что данные реально можно восстановить.
Мы уже проверяли это вручную:

В production такую проверку тоже стоит выполнять регулярно, только уже на отдельном тестовом окружении.
Нужно убедиться, что:
- backup читается;
mongorestoreзавершается без ошибок;- collections появляются;
- документы восстанавливаются;
- indexes возвращаются;
- приложение после restore видит нужные данные.
Хорошая backup-стратегия — это не «файл создается каждую ночь», а «мы знаем, что этот файл можно восстановить».
Контролировать диск и логи
MongoDB постоянно растет вместе с данными, indexes и журналами.
Поэтому свободное место нужно контролировать заранее, а не после того, как файловая система заполнится.
Для быстрой проверки:
df -hРазмер данных:
sudo du -sh /var/lib/mongodbРазмер logs:
sudo du -sh /var/log/mongodbСами последние сообщения:
sudo tail -n 100 /var/log/mongodb/mongod.logИ состояние сервиса:
sudo systemctl status mongodОсобенно важно следить за диском перед крупными backup, restore и обновлениями.
Если свободного места почти нет, даже обычная служебная операция может закончиться неприятно.
Обновлять MongoDB по поддерживаемому upgrade path
MongoDB не стоит обновлять скачком через несколько major versions без проверки совместимости.
Перед upgrade нужно заранее посмотреть:
- Текущую версию;
- Целевую версию;
- Поддерживается ли прямой переход;
- Есть ли breaking changes;
- Требуется ли промежуточный upgrade;
- Совместимы ли drivers приложения.
Текущую версию сервера можно посмотреть так:
mongod --versionПеред обновлением полезно обязательно иметь свежий backup и проверенный restore.
Для production лучше придерживаться последовательного upgrade path:

а не пытаться сразу перепрыгнуть через несколько поколений MongoDB.
После обновления стоит повторить знакомые проверки:
sudo systemctl status mongod
mongosh \
"mongodb://app_user@127.0.0.1:27017/app_db?authSource=app_db" \
--passwordи убедиться, что приложение по-прежнему видит свои данные.
Что проверить перед production
Перед тем как приложение начнет постоянно работать с MongoDB, достаточно пройти несколько коротких проверок.
Доступ и права
- authorization включена;
- приложение использует отдельного
app_user; app_userне имеет административных roles;mongo_adminне используется приложением;- credentials не записаны прямо в команды или код.
Сеть и данные
- 27017 не открыт всему интернету;
bindIpсодержит только нужные server interfaces;- firewall пропускает только доверенные источники;
- MongoDB запускается после reboot;
- данные сохраняются и читаются после перезагрузки.
Backup и эксплуатация
mongodumpзапускается регулярно;- копии уходят на внешнее хранилище;
- restore был реально проверен;
- свободное место контролируется;
- logs просматриваются при ошибках;
- major upgrades выполняются последовательно и с backup перед обновлением.
Если эти пункты выполняются, базовая MongoDB-конфигурация уже выглядит достаточно здорово для небольшого production-проекта: приложение работает с минимальными правами, сеть ограничена, а данные резервируются.
Заключение

Standalone MongoDB на одном VPS хорошо подходит для разработки, тестовых окружений, небольших внутренних сервисов и проектов, где допустима ручная работа при отказе сервера. Такая схема проста в обслуживании: один mongod, понятная конфигурация, отдельные пользователи, контролируемый сетевой доступ и обычный backup через mongodump.
Но у standalone-сервера есть принципиальное ограничение — это единственная точка отказа. Если VPS или сам mongod недоступен, приложение теряет доступ к базе до восстановления сервиса. Поэтому для полноценной production-системы, где важны высокая доступность и автоматическое переключение при отказе узла, уже стоит переходить на replica set. В self-managed варианте это обычно несколько MongoDB-узлов, а если не хочется самостоятельно заниматься отказоустойчивостью, обновлениями, мониторингом и резервным копированием, можно рассмотреть managed MongoDB. Replica set обеспечивает избыточность и автоматический failover, тогда как standalone этого не дает.
Независимо от архитектуры базовые принципы остаются теми же: не использовать административного пользователя внутри приложения, не открывать 27017 без необходимости, ограничивать roles, хранить backup отдельно от основного сервера и периодически проверять restore. Тогда даже небольшая MongoDB остается предсказуемой в эксплуатации и значительно проще диагностируется при сбоях.
FAQ
Обязательно ли включать authentication, если MongoDB доступна только с localhost?
Для локального тестового окружения риск действительно ниже, потому что mongod, привязанный к 127.0.0.1, не принимает удаленные подключения.
Но для рабочего сервера authentication все равно лучше включать. Локальный процесс, скомпрометированное приложение или другой пользователь системы иначе сможет обращаться к MongoDB без отдельной проверки credentials.
Кроме того, если позже понадобится удаленный доступ, база уже будет защищена и не придется менять модель безопасности на работающем сервере.
Можно ли использовать одного пользователя для нескольких приложений?
Технически можно, если приложения работают с одной database и им нужны одинаковые права.
Но отдельные учетные записи обычно удобнее.
Например:
backend_user
analytics_user
worker_userТак проще:
- выдавать разные roles;
- менять password одного приложения;
- отключать отдельный сервис;
- понимать, какие credentials где используются и кто что изменил\удалил.
Если один общий пароль утечет, придется менять его сразу во всех приложениях.
Зачем нужен authSource?
authSource указывает database, в которой MongoDB должна искать учетную запись пользователя.
Например, если:
app_userсоздан в:
app_dbто используется:
authSource=app_dbА если mongo_admin создан в admin:
authSource=adminРабочая database и authentication database при этом не обязаны совпадать.
Поэтому неправильный authSource способен вызвать Authentication failed, даже если username и password правильные.
Можно ли делать mongodump без остановки MongoDB?
Да. mongodump подключается к работающему mongod, поэтому останавливать сервер для обычного dump не требуется.
Но есть нюанс: если во время backup продолжаются записи, dump отдельной database или collection не обязательно будет представлять единую точку времени. Для нагруженных систем и строгих требований к консистентности нужно учитывать характер записи и использовать подходящую backup-стратегию. Для replica set доступны дополнительные механизмы с oplog.
Что будет, если выполнить mongorestore поверх существующей database?
Без --drop утилита пытается восстановить данные в уже существующие collections.
Из-за этого могут возникнуть:
- конфликты по
_id; - сочетание старых и восстановленных данных;
- результат, отличающийся от состояния backup.
Если нужно заменить соответствующие collections содержимым dump, можно использовать:
mongorestore --drop ...Перед восстановлением --drop удаляет именно те collections, которые затем будут восстановлены из backup. Collections, отсутствующие в dump, этот параметр сам по себе не удаляет.
Сохраняет ли mongodump пользователей?
Зависит от способа создания dump.
При backup конкретной database через --db определения пользователей и roles можно включить параметром:
--dumpDbUsersAndRolesПри dump всего экземпляра определения пользователей и roles включаются автоматически.
Поэтому не стоит считать, что любой dump одной database по умолчанию обязательно содержит ее пользователей.
Можно ли сделать backup только одной collection?
Да.
Например:
mongodump \
--db app_db \
--collection products \
--out /var/backups/mongodb/products-backupТак в dump попадет только products, а не вся app_db. MongoDB
Такой вариант удобен для точечного переноса или резервного копирования конкретных данных, но для полноценного восстановления приложения нужно заранее понимать зависимости между collections.
Почему mongosh подключается локально, а с другого сервера — нет?
Если локальное подключение работает, а удаленное нет, в первую очередь стоит проверить:
sudo ss -lntp | grep 27017Если MongoDB слушает только:
127.0.0.1:27017удаленный сервер подключиться не сможет.
Дальше проверяются:
bindIp;- UFW;
- cloud firewall;
- private network;
- маршрут между VPS.
То есть работающий локальный mongosh еще не означает, что mongod принимает подключения на внешнем interface.
Что делать, если после включения authorization потерян admin password?
Сначала стоит исключить банальные причины:
- неправильный username;
- неправильный
authSource; - другой сохраненный admin user;
- ошибка при вводе пароля.
Если действующих административных credentials действительно больше нет, потребуется отдельная процедура восстановления административного доступа с контролируемым изменением конфигурации MongoDB (в виде отключения аутентификации, убедившись что MongoDB недоступна снаружи) и созданием или изменением пользователя.
Для production лучше не импровизировать на работающем сервере: перед такими действиями стоит сохранить backup, ограничить сетевой доступ и использовать процедуру восстановления, соответствующую установленной версии MongoDB.
Достаточно ли mongodump для production?
Для небольших баз и ряда backup-сценариев mongodump вполне полезен, но универсальным ответом для любой production-системы он не является.
При большом объеме данных dump может создавать заметную нагрузку, а при активной записи нужно отдельно учитывать консистентность backup. Replica set также дает дополнительные возможности для получения согласованной копии с использованием oplog.
Поэтому production backup нужно выбирать исходя из:
- размера базы;
- частоты записи;
- допустимой потери данных;
- требуемого времени восстановления;
- архитектуры standalone / replica set;
- доступного внешнего хранилища.
И главное — любой выбранный способ должен регулярно проходить реальную проверку restore.


