То, что новый сервер получает мало трафика и в целом не представляет особого интереса для хакеров, не значит, что он остается незамеченным. Существует множество автоматизированных программ для взлома, которые предназначены для поиска ошибок и лазеек в конфигурации сервера. Такие программы сканируют сеть и обнаруживают слабо защищённые серверы.
Поддержка удаленных соединений – одна из наиболее распространенных ошибок, которые могут привести к взлому базы данных PostgreSQL. Это происходит потому, что некоторые настройки СУБД помогают автоматизированным программам найти уязвимости сервера.
Данное руководство поможет снизить риск взлома сервера, отключив поддержку удалённых соединений с БД.
Общие сведения о проблеме
Чтобы лучше разобраться в вопросе, представьте, что сервер – это магазин. Прослушивание сервером всех портов – это табличка «Открыто» на двери магазина. Такой сервер заметен в сети, и любая программа взлома может найти его.
Представьте, что каждый порт – это вход в магазин (дверь или окно). Эти входы могут быть открыты, закрыты или заблокированы, но их также можно и взломать (в зависимости от состояния программного обеспечения, которое прослушивает порт). Прослушивание открытого интерфейса позволяет сценарию взлома начать поиск уязвимостей. К примеру, сценарий может попробовать аутентифицироваться с помощью стандартных учётных данных, и если эти данные не были изменены, взлом быстро состоится. Также сценарий может проверить сервер на наличие самых распространённых уязвимостей. В любом случае, если сценарий обнаруживает какую-либо уязвимость, злоумышленник может попасть на сервер.
Ограничить демонов (как postgresql) прослушиванием локальных интерфейсов – это то же самое, что заложить окно или дверь в магазин кирпичом: злоумышленник не воспользуется этим входом, потому что входа просто не существует. Это самый простой и надёжный способ защитить Postgres. Брандмауэры и VPN работают аналогичным образом. Данное руководство поможет полностью отключить внешний доступ к PostgreSQL.
Требования
Для выполнения руководства необходимо иметь два сервера Ubuntu: первый будет использован в качестве хоста базы данных, а второй – как клиент, который будет подключаться к хосту удаленно. На каждом сервере нужен пользователь с доступом к sudo и настроенный брандмауэр. Все инструкции можно найти здесь.
Сервер 1: хост PostgreSQL
Установите PostgreSQL с помощью команд:
sudo apt-get update
sudo apt-get install postgresql postgresql-contrib
Сервер 2: клиент PostgreSQL
Для тестирования удалённых соединений в руководстве используется клиент psql. Чтобы установить его, введите:
sudo apt-get update
sudo apt-get install postgresql-client
Стандартные настройки PostgreSQL
СУБД PostgreSQL, установленная из официального репозитория Ubuntu, по умолчанию прослушивает localhost. Этот стандартный параметр блокирует автоматическое прослушивание открытых интерфейсов. Его можно изменить переопределением listen_addresses в файле postgresql.conf.
Кроме того, файл pg_hba.conf поддерживает только локальный адрес замыкания и соединения с сокетами домена Unix/Linux. Потому сервер не будет принимать соединения от внешних хостов.
# Put your actual configuration here
# ----------------------------------
#
# If you want to allow non-local connections, you need to add more
# "host" records. In that case you will also need to make PostgreSQL
# listen on a non-local interface via the listen_addresses
# configuration parameter, or via the -i or -h command line switches.
# DO NOT DISABLE!
# If you change this first entry you will need to make sure that the
# database superuser can access the database using some other method.
# Noninteractive access to all databases is required during automatic
# maintenance (custom daily cronjobs, replication, and similar tasks).
#
# Database administrative login by Unix domain socket
local all postgres peer
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
Эти параметры блокируют прослушивание публичных интерфейсов. Используя такие настройки и включив брандмауэр, вы сможете полностью защитить сервер от взаимодействия с публичными интерфейсами. Дополнительные рекомендации по безопасности сервера вы найдёте в последнем разделе этого руководства.
Настройка удалённых подключений
На этапе производства и при работе с конфиденциальными данными рекомендуется шифровать трафик PostgreSQL с помощью SSL (в дополнение к брандмауэру или виртуальной частной сети, VPN).
Мы используем чуть менее сложный вариант настройки безопасности сервера: для этого нужно включить брандмауэр на сервере баз данных и ограничить доступ к нему до заведомо безопасных хостов.
1: Создание пользователя и БД
Для работы вам понадобится тестовая БД и пользователь. Подключитесь к администратору СУБД, postgres, с помощью клиента psql. Флаг –i запускает интерактивный режим, что позволяет ввести учётные данные пользователя postgres; флаг –u позволяет указать пользователя.
sudo -i -u postgres psql
Теперь можно создать пользователя и пароль для него.
CREATE USER 8host WITH PASSWORD 'password';
Примечание: Замените условное имя пользователя и пароль более надёжными учётными данными.
Команда должна вывести:
CREATE ROLE
Примечание: Начиная с PostgreSQL 8.1, роли и пользователи совпадают. По соглашению, роль, которая защищена паролем, является пользователем, а роль, которая не имеет пароля – это просто роль. Потому иногда в выводе вместо USER указывается ROLE.
Теперь нужно создать БД и передать все права на неё новому пользователю. С точки зрения безопасности пользователи должны иметь тот уровень доступа, который необходим им для работы, и только к необходимым ресурсам. То есть, если пользователь должен читать файлы service_1, не нужно давать ему права на запись и исполнение файлов service_1 и service_2.
Читайте также: Использование ролей и управление доступом в PostgreSQL
CREATE DATABASE 8hostdb OWNER 8host;
Вы получите подтверждение:
CREATE DATABASE
Закройте оболочку СУБД:
\q
Нажмите ENTER, чтобы вернуться в командную строку системы.
2: Настройка UFW
Если вы следовали руководству по начальной настройке сервера, вы включили брандмауэр UFW, и на данный момент он должен поддерживать только SSH-соединения.
Проверьте состояние брандмауэра:
sudo ufw status
Примечание: Если брандмауэр отключен (inactive), включите его:
sudo ufw enable
После этого снова запросите состояние брандмауэра. Чтобы разблокировать SSH, введите:
sudo ufw allow OpenSSH
На данный момент брандмауэр поддерживает только сервис OpenSSH:
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Теперь нужно разблокировать доступ к порту PostgreSQL и ограничить его только до заведомо безопасных хостов.
Приведенная ниже команда добавит правило, которое разблокирует порт PostgreSQL по умолчанию, 5432. Если вы изменили этот порт, не забудьте обновить его в следующей команде. Также вместо client_ip_address укажите IP-адрес клиента, которому нужен доступ к хосту. В случае необходимости повторно запустите эту команду, чтобы добавить другие IP-адреса безопасных клиентов.
sudo ufw allow from client_ip_address to any port 5432
После этого запросите правила брандмауэра:
sudo ufw status
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
5432 ALLOW client_ip_address
OpenSSH (v6) ALLOW Anywhere (v6)
Читайте также: Основы UFW: общие правила и команды фаервола
Теперь нужно настроить PostgreSQL для прослушивания внешнего IP-адреса. Для этого нужно добавить две настройки: вход для подключения к хосту в файл pg_hba.conf и параметр listen_addresses в postgresql.conf.
3: Настройка доступ к хосту
Добавьте настройки в файл pg_hba.conf.
sudo nano /etc/postgresql/9.5/main/pg_hba.conf
Примечание: Версия PostgreSQL может отличаться.
Добавьте строки host под закомментированным блоком, который описывает настройки нелокальных соединений. Также нужно добавить внешний IP-адрес сервера базы данных, чтобы быстро проверить настройку брандмауэра.
# If you want to allow non-local connections, you need to add more
# "host" records. In that case you will also need to make PostgreSQL
# listen on a non-local interface via the listen_addresses
# configuration parameter, or via the -i or -h command line switches.
host 8hostdb 8host client_ip_address/32 md5
Примечание: Обязательно замените имя хоста и IP-адрес машины.
Прежде чем сохранить новые параметры, рассмотрим их подробнее:
- host: первый параметр определяет, что будет использоваться TCP/IP соединение.
- database (в данном случае имеет значение 8hostdb): указывает, к каким базам данных может подключиться хост. Чтобы добавить сразу несколько БД, разделите их имена запятыми.
- user (в данном случае 8host): указывает имя пользователя, который может создавать подключение. Чтобы добавить сразу несколько имен, разделите их запятыми.
- address: адреса клиентов. Можно указать имя хоста, диапазон IP-адресов или другие специальные ключевые слова (в приведенном выше примере используется только IP-адрес клиента).
- auth-method: настраивает метод аутентификации. В данном случае это двойной md5. Для аутентификации достаточно ввести пароль пользователя.
Больше информации об этих и других настройках можно найти в документации файла pg_hba.conf.
4: Настройка listen_addresses
Теперь нужно настроить прослушивание адресов в файле postgresql.conf:
sudo nano /etc/postgresql/9.5/main/postgresql.conf
Найдите строку listen_addresses и определите в ней адреса, которые нужно прослушивать. Укажите имя хоста или IP-адрес сервера БД. Убедитесь, что используете внешний IP-адрес сервера БД, а не клиента.
#listen_addresses = 'localhost' # what IP address(es) to listen on;
listen_addresses = 'localhost,server_ip_address'
Сохраните и закройте файл.
5: Перезапуск PostgreSQL
Чтобы обновить настройки СУБД, перезапустите PostgreSQL.
sudo systemctl restart postgresql
Утилита systemctl не выводит результат некоторых команд. Чтобы убедиться, что сервер успешно перезапущен, запросите его состояние:
sudo systemctl status postgresql
Команда должна вернуть «Active: active», в целом вывод будет заканчиваться такими строками:
...
Jan 10 23:02:20 PostgreSQL systemd[1]: Started PostgreSQL RDBMS.
6: Тестирование
Примечание: Данный раздел нужно выполнить на клиентском сервере.
Теперь нужно убедиться, что настройки работают должным образом. Для этого подключитесь к хосту БД с помощью клиента psql. Флаг –U позволяет указать пользователя, -h задаёт IP-адрес клиента, -d указывает имя БД.
psql -U 8host -h postgres_host_ip -d 8hostdb
Если все настройки указаны правильно, команда вернёт:
Password for user 8host:
Укажите пароль пользователя, который создаёт подключение.
Если подключение состоялось, вы увидите такую командную строку:
[secondary_label]
8hostdb =>
Чтобы прервать соединение, введите:
\q
7: Удаление тестового пользователя и БД
Вернитесь на хост БД (сервер 1) и удалите тестовую БД и пользователя, они вам больше не понадобятся.
sudo -i -u postgres psql
Чтобы удалить БД, введите:
DROP DATABASE 8hostdb;
DROP DATABASE
Чтобы удалить пользователя:
DROP USER 8host;
DROP ROLE
Теперь нужно почистить файлы от записей удалённых БД и пользователя. Откройте pg_hba.conf:
sudo nano /etc/postgresql/9.5/main/pg_hba.conf
Удалите:
host 8hostdb 8host client_ip_address/32 md5
Перезапустите сервер баз данных:
sudo systemctl restart postgresl
Проверьте состояние сервера:
sudo systemctl status postgres
Дополнительные рекомендации
Данное руководство помогает снизить риск взлома сервера через незащищённые удалённые соединения к PostgreSQL.
Однако ограничение доступа к прослушиваемым портам не устраняет ряда других проблем и уязвимостей (например, данные всё ещё передаются в незашифрованном виде).
Прежде чем приступит к работе с настоящими базами данных, мы рекомендуем вам рассмотреть несколько дополнительных вариантов повышения безопасности сервера:
- Защита PostgreSQL на сервере Ubuntu: выражения GRANT позволяют определить, какие пользователи имеют доступ к той или иной БД, а роли устанавливают уровень доступа.
- SSL-сертификат для PostgreSQL позволит шифровать данные.
- SSH-туннель для PostgreSQL защитит подключения клиентов, несовместимых с SSL.
Заключение
Теперь вы знакомы с базовым методом защиты PostgreSQL от взлома. Это уменьшает риск некоторых видов атак. Однако это довольно примитивный способ защиты данных; мы рекомендуем рассмотреть дополнительные меры безопасности, изложенные выше, и внедрить некоторые из них.