Запуск сервера MongoDB с помощью OpenVPN и Docker в Ubuntu 16.04
Ubuntu | Комментировать запись
MongoDB – это открытая система управления базами данных NoSQL. Безопасность обычной установки MongoDB имеет много уязвимостей, потому безопасность данных нужно повысить.
Существует несколько методов защиты сервера баз данных. Во-первых, можно настроить VPN и ограничить доступ, разрешив его только тем клиентам, которые подключены к VPN. Также можно зашифровать транспортный уровень между клиентом и сервером с помощью сертификатов. Оба эти метода описаны в данном руководстве. Кроме того, здесь вы узнаете, как запустить сервер MongoDB с помощью Docker (и получить возможность повторно использовать конфигурацию MongoDB и сертификаты на нескольких серверах).
Требования
- Сервер OpenVPN (для этого виртуальный сервер должен поддерживать частную сеть).
- Сервер Ubuntu 16.04 (читайте руководство по начальной настройке сервера).
- Пользователь с доступом к sudo.
- Предварительно установленная платформа Docker.
- Система MongoDB на локальной машине.
Читайте также:
1: Настройка VPN и маршрутизации на внутренний IP-адрес
Если сервер OpenVPN передает запросы на открытый сетевой интерфейс, это нужно изменить. В данном руководстве сервер MongoDB будет настроен так, что доступ к нему можно будет получить только через частный интерфейс (который, в свою очередь, доступен только через VPN). Измените правила IP fowarding на VPN-сервере, чтобы трафик VPN-клиентов также направлялся в частную сеть.
Подключитесь к серверу OpenVPN:
ssh 8host@vpn_server_public_ip
В панели управления выберите VPN и найдите внутренний IP-адрес сервера.
Узнав этот IP, выполните следующую команду на сервере OpenVPN, чтобы узнать, какой он использует интерфейс:
sudo nano /etc/ufw/before.rules
ip route | grep vpn_server_private_ip
Команда выведет примерно следующее:
10.132.0.0/16 dev eth1 proto kernel scope link src vpn_server_private_ip
Запишите сетевой интерфейс (в данном случае это eth1).
Теперь отредактируйте файл /etc/ufw/before.rules:
sudo nano /etc/ufw/before.rules
Найдите в нём такой раздел:
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES
Добавьте новое правило для частного интерфейса:
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
-A POSTROUTING -s 10.8.0.0/8 -o eth1 -j MASQUERADE
COMMIT
# END OPENVPN RULES
Примечание: Вместо eth1 укажите свой интерфейс (если он отличается).
Отключите и снова включите брандмауэр:
sudo ufw disable
sudo ufw enable
Покиньте сервер VPN:
exit
Теперь создайте VPN-соединение с локального компьютера к серверу VPN. Это соединение нужно поддерживать до конца руководства.
2: Настройка брандмауэра на сервере MongoDB
Подключаться к серверу MongoDB можно будет по внутреннему IP-адресу. Если вы не выписали этот IP, найдите его в панели управления.
Убедитесь, что вы подключены к серверу VPN. Создайте SSH-подключение к серверу MongoDB с помощью внутреннего IP:
ssh 8host@mongodb_server_private_ip
Затем удалите все текущие правила брандмауэра:
sudo ufw delete limit ssh
sudo ufw delete allow 2375/tcp
sudo ufw delete allow 2376/tcp
Добавьте два новых правила, которые разрешают доступ к SSH и MongoDB только тем серверам, которые подключены к VPN.
sudo ufw allow from vpn_server_private_ip to any port 22 proto tcp
sudo ufw allow from vpn_server_private_ip to any port 28018 proto tcp
Примечание: В правилах нужно указать внутренний IP VPN-сервера.
Убедитесь, что настройки брандмауэра содержат только два правила:
sudo ufw status
To Action From
-- ------ ----
22/tcp ALLOW vpn_server_private_ip
28018/tcp ALLOW vpn_server_private_ip
Включите брандмауэр и отключитесь от сервера:
sudo ufw enable
exit
Снова подключитесь к MongoDB, чтобы убедиться, что вы не заблокировали себе доступ к собственному серверу.
ssh 8host@mongodb_server_private_ip
Если вы не можете подключиться к серверу по SSH, убедитесь, что вы подключены к частной сети и что сервер VPN передаёт трафик в частную сеть. Если же вы не обнаружили ошибок, попробуйте подключиться к серверу через консоль и проверить правила брандмауэра. Убедитесь, что вы указали внутренний IP сервера VPN, а не MongoDB.
Читайте также: Настройка брандмауэра UFW на сервере Ubuntu 14.04
3: Конфигурационный файл MongoDB
Теперь нужно создать пользовательский файл конфигурации MongoDB, чтобы настроить MongoDB для поддержки SSL-сертификатов.
Создайте структуру каталогов для конфигурации и связанных с ней файлов. Можно создать каталог mongoconf, а в нем создать каталог config для конфигурационных файлов. В каталоге config создайте каталог ssl для хранения сертификатов.
mkdir -p ~/mongoconf/config/ssl
Перейдите в ~/mongoconf/config:
cd ~/mongoconf/config
Откройте файл mongod.conf в редакторе:
nano mongod.conf
Привяжите БД к порту 28018 на каждом сетевом интерфейсе. Привязка к 0.0.0.0 не угрожает безопасности в этом случае, так как брандмауэр не поддерживает внешние подключения. Но это позволит поддерживать подключения клиентов внутри VPN. Добавьте в файл следующее:
net:
bindIp: 0.0.0.0
port: 28018
В разделе net нужно указать путь к SSL-сертификатам и парольную фразу (они будут созданы позже):
net:
. . .
ssl:
CAFile: /etc/mongo/ssl/client.pem
PEMKeyFile: /etc/mongo/ssl/server.pem
PEMKeyPassword: test
mode: requireSSL
Укажите каталог по умолчанию и включите журналирование:
. . .
storage:
dbPath: /mongo/db
journal:
enabled: true
Больше информации можно найти в документации MongoDB.
Сохраните и закройте редактор.
4: Генерирование SSL-сертификатов
Чтобы защитить передачу данных, нужно сгенерировать два сертификата для MongoDB: один для сервера, а второй для клиента.
Примечание: В данном руководстве используются самоподписанные сертификаты. В среде производства рекомендуется использовать доверенные сертификаты. Сервис Let’s Encrypt позволяет получить такой сертификат бесплатно.
Читайте также:
- Создание сертификата Let’s Encrypt для Apache в Ubuntu 16.04
- Создание сертификата Let’s Encrypt для Nginx в Ubuntu 16.04
Перейдите в каталог ~/mongoconf/config/ssl и сгенерируйте сертификат и ключ. Заполните появившуюся форму. Особое внимание уделите полям Common Name и PEM Passphrase.
cd ~/mongoconf/config/ssl
openssl req -new -x509 -days 365 -out server.crt -keyout server.key
Вы увидите такой вывод:
. . .
Enter PEM pass phrase: test
Verifying - Enter PEM pass phrase: test
. . .
Common Name (e.g. server FQDN or YOUR name) []: mongodb_server_private_ip
. . .
Также вам будет предложено указать некоторые дополнительные данные.
Когда программа предложит ввести парольную фразу PEM, укажите тот же пароль, который вы использовали в файле конфигурации MongoDB в предыдущем разделе.
MongoDB не поддерживает отдельных сертификатов и ключей, их нужно объединить в один файл .pem.
cat server.crt server.key >> server.pem
Сгенерируйте сертификат и ключ для клиентов:
openssl req -new -x509 -days 365 -out client.crt -keyout client.key
Повторите весь описанный выше процесс, но в этот раз укажите внутренний IP-адрес сервера VPN и любую парольную фразу PEM.
. . .
Enter PEM pass phrase: secret_password
Verifying - Enter PEM pass phrase: secret_password
. . .
Common Name (e.g. server FQDN or YOUR name) []: vpn_server_private_ip
. . .
Объедините сгенерированные файлы в файл .pem.
cat client.crt client.key >> client.pem
Скопируйте оба сертификата на локальную машину, чтобы получить удалённый доступ к серверу MongoDB. На локальной машине запустите:
scp 8host@mongodb_server_private_ip:/home/8hots/mongoconf/config/ssl/\{client.pem,server.pem\} .
Читайте также: Использование SFTP для безопасного обмена файлами с удаленным сервером
5: Создание Docker-образа MongoDB и запуск контейнера
Создайте пользовательский образ MongoDB, запустите контейнер и передайте ему конфигурационный файл и сертификаты.
Чтобы создать образ, необходим Dockerfile.
Примечание: Чтобы запустить docker без sudo, добавьте пользователя в группу docker:
sudo usermod -aG docker 8host
Отключитесь и снова подключитесь к серверу, чтобы обновить настройки.
Откройте root-каталог проекта и в нём откройте пустой Dockerfile.
cd ~/mongoconf
nano Dockerfile
Добавьте в файл следующий код:
FROM ubuntu:xenial
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
RUN echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-3.4.list
RUN apt-get update && apt-get install -y mongodb-org
RUN mkdir -p /mongo/db /etc/mongo
EXPOSE 28018
ENTRYPOINT ["mongod", "--config", "/etc/mongo/mongod.conf"]
Этот файл поможет Docker создать образ на основе Ubuntu 16.04, загрузить последние бинарные файлы MongoDB и создать несколько каталогов для хранения конфигурационных файлов и БД. Порт 28018 будет доступен для хоста. Кроме того, MongoDB будет запускаться после каждого перезапуска контейнера.
Примечание: Для простоты работы этот образ основан на Ubuntu. Однако контейнеры на основе легковесных дистрибутивов типа Alpine Linux занимают меньше дискового пространства.
Сохраните и закройте файл. Соберите образ:
docker build -t mongo .
После этого запустите контейнер на основе этого образа. Смонтируйте каталог config как том внутри контейнера, чтобы пользовательские конфигурации и ключи были доступны установке MongoDB внутри контейнера:
docker run \
--detach \
--publish 28018:28018 \
--volume $PWD/config:/etc/mongo \
--name mongodb \
mongo
6: Доступ к MongoDB
В новом терминале на локальном компьютере подключитесь к базе данных, указав частный IP-адрес сервера MongoDB. Укажите файлы client.pem и server.pem, загруженные на локальный компьютер, а также предоставьте кодовую фразу, которую вы использовали при создании клиентского сертификата. Выполните следующую команду:
mongo \
--ssl \
--sslCAFile path_to_server_pem \
--sslPEMKeyFile path_to_client_pem \
--sslPEMKeyPassword pem_key_passphrase \
--host mongodb_server_private_ip \
--port 28018
Если всё работает правильно, вы увидите на экране командную строку MongoDB.
Если возникла ошибка, убедитесь, что вы указали внутренний IP сервера MongoDB, а не сервера VPN. Также проверьте пути к сертификатам и VPN-соединение.
Заключение
Вы запустили MongoDB в контейнере Docker. Безопасность данных обеспечивается SSL-шифрованием. Дополнительную безопасность обеспечивает брандмауэр.
Такая настройка отлично подходит для тестирования. Но в среде производства настоятельно рекомендуется использовать доверенные сертификаты. Также настройка во многом зависит от индивидуальных потребностей сервера и проекта. Вам могут понадобиться дополнительные пользователи, пароли и роли БД.
Читайте также: Установка и защита MongoDB в Ubuntu 16.04
Tags: Docker, MongoDB, OpenVPN, SSL, Ubuntu 16.04