Защита PostgreSQL от автоматизированных хакерских атак

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

Поддержка удаленных соединений – одна из наиболее распространенных ошибок, которые могут привести к взлому базы данных 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 от взлома. Это уменьшает риск некоторых видов атак. Однако это довольно примитивный способ защиты данных; мы рекомендуем рассмотреть дополнительные меры безопасности, изложенные выше, и внедрить некоторые из них.

Tags:

Добавить комментарий