Как обезопасить PostgreSQL от автоматических атак

Вступление

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

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

В этом руководстве мы покажем, как уменьшить конкретный риск, создавая удаленные подключения. Хотя это важный первый шаг, поскольку серверы могут быть скомпрометированы другими способами, мы также рекомендуем вам принять дополнительные меры для защиты ваших данных, указанные вAdditional Security Considerations.

Фон

Чтобы понять конкретный риск, который мы снижаем, представьте сервер как хранилище. Если сервер вообще прослушивает какой-либо порт, это все равно, что включить неоновую вывеску «Открыть». Это делает сам сервер видимым в сети, где его могут найти автоматизированные сценарии.

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

Когда мы ограничиваем локальное прослушивание демона, такого какpostgresql, похоже, что этой конкретной двери снаружи не существует. Там нет следующего шага, чтобы попытаться, по крайней мере, в отношении Postgres. Брандмауэры и VPN защищают аналогичным образом. В этом руководстве мы сосредоточимся на удалении PostgreSQL как общедоступного портала. Чтобы защитить сам демон или данные во время их передачи или хранения, см.Additional Security Considerations.

Предпосылки

В этом руководстве мы будем использоватьtwo Ubuntu installations, один для хоста базы данных, а второй в качестве клиента, который будет подключаться к хосту удаленно. У каждого должен быть пользовательsudo и включен брандмауэр. ГидInitial Server Setup with Ubuntu 16.04 может вам в этом помочь.

One Ubuntu 16.04 PostgreSQL Database Host:

Если вы еще не установили PostgreSQL, вы можете сделать это с помощью следующих команд:

sudo apt-get update
sudo apt-get install postgresql postgresql-contrib

One Ubuntu 16.04 Client Machine:
Чтобы продемонстрировать и протестировать возможность удаленных подключений, мы будем использовать клиент PostgreSQL,psql. Чтобы установить его, используйте следующие команды:

sudo apt-get update
sudo apt-get install postgresql-client

Когда эти предпосылки созданы, вы готовы следовать им.

Понимание конфигурации по умолчанию

Когда PostgreSQL устанавливается из пакетов Ubuntu, по умолчанию он ограничен прослушиванием на локальном хосте. Это значение по умолчанию можно изменить, переопределив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

Эти значения по умолчанию отвечают цели не прослушивания на общедоступном интерфейсе. Если мы оставим их нетронутыми и сохраним наш брандмауэр, все готово! Мы можем перейти непосредственно кAdditional Security Considerations, чтобы узнать, как защитить данные при передаче.

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

Настройка удаленных подключений

Для производственной установки и до того, как мы начнем работать с конфиденциальными данными, в идеале у нас будет трафик PostgreSQL, зашифрованный с помощью SSL при передаче, защищенный внешним брандмауэром или защищенный виртуальной частной сетью (VPN). Работая над этим, мы можем сделать несколько менее сложный шаг - включить брандмауэр на сервере базы данных и ограничить доступ к нужным хостам.

[[step-1 -—- add-a-user-and-database]] == Шаг 1. Добавление пользователя и базы данных

Мы начнем с добавления пользователя и базы данных, которые позволят нам протестировать нашу работу. Для этого мы воспользуемся клиентом PostgreSQL,psql, чтобы подключиться как административный пользовательpostgres. Передав параметр-i вsudo, мы запустим оболочку входа пользователя postgres, которая гарантирует, что мы загружаем параметры из.profile или других ресурсов для входа в систему. -u вид пользователь postgres:

sudo -i -u postgres psql

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

CREATE USER sammy WITH PASSWORD 'password';

Когда пользователь успешно создан, мы должны получить следующий вывод:

OutputCREATE ROLE

[.note] #Note: Начиная с PostgreSQL 8.1, РОЛИ и ПОЛЬЗОВАТЕЛИ являются синонимами. По соглашению роль, у которой есть пароль, по-прежнему называется ПОЛЬЗОВАТЕЛЕМ, а роль, у которой нет пароля, называется РОЛЬ, поэтому иногда мы будем видеть РОЛЬ в выводе там, где мы могли бы ожидать увидеть ПОЛЬЗОВАТЕЛЬ.
#

Далее мы создадим базу данных и предоставим полный доступ нашему новому пользователю. В соответствии с передовой практикой мы предоставляем пользователям только тот доступ, который им нужен, и только на тех ресурсах, где они должны быть, поэтому в зависимости от варианта использования может оказаться целесообразным еще больше ограничить доступ пользователя. Вы можете узнать больше о разрешениях в руководствеHow To Use Roles and Manage Grant Permissions in PostgreSQL on a VPS.

CREATE DATABASE sammydb OWNER sammy;

Когда база данных создана успешно, мы должны получить подтверждение:

OutputCREATE DATABASE

Теперь, когда мы создали пользователя и базу данных, мы выйдем из монитора.

\q

После нажатия ENTER мы будем в командной строке и готовы продолжить.

[[step-2 -—- configuring-ufw]] == Шаг 2 - Настройка UFW

В предварительном требованииInitial Server Setup with Ubuntu 16.04 мы включили UFW и разрешили только SSH-соединения. Прежде чем мы начнем нашу конфигурацию, давайте проверим статус UFW:

sudo ufw status

[.Примечание]##

Note: Если вывод указывает, что межсетевой экранinactive, мы можем активировать его с помощью:

sudo ufw enable

После включения и повторного запуска команды statussudo ufw status покажет текущие правила. При необходимости обязательно разрешите SSH.

sudo ufw allow OpenSSH

Если мы не внесли изменения в предварительные условия, выходные данные должны показать, что разрешен только OpenSSH:

OutputStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

Теперь, когда мы проверили состояние брандмауэра, мы разрешим доступ к порту PostgreSQL и ограничим его хостом или хостами, которые мы хотим разрешить.

Команда ниже добавит правило для порта по умолчанию PostgreSQL, который равен 5432. Если вы изменили этот порт, обязательно обновите его в приведенной ниже команде. Убедитесь, что вы использовали IP-адрес сервера, к которому требуется доступ. При необходимости повторите команду, чтобы добавить IP-адрес каждого клиента, которому требуется доступ:

sudo ufw allow from client_ip_address to any port 5432

Чтобы перепроверить правило, мы можем снова запуститьufw status:

sudo ufw status
OutputTo                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
5432                       ALLOW       client_ip_address
OpenSSH (v6)               ALLOW       Anywhere (v6)

[.note] #Note: Если вы новичок в UFW, вы можете узнать больше в руководствеUFW Essentials: Common Firewall Rules and Commands.
#

С этим правилом брандмауэра мы теперь настроим PostgreSQL для прослушивания его публичного IP-адреса. Для этого требуется комбинация двух настроек: запись для подключающегося хоста вpg_hba.conf и конфигурация listen_addresses вpostgresql.conf.

[[step-3 -—- configuring-the-allowed-hosts]] == Шаг 3 - Настройка разрешенных хостов

Начнем с добавления записи хоста вpg_hba.conf. Если у вас установлена ​​другая версия PostgreSQL, обязательно замените ее по следующему пути:

sudo nano /etc/postgresql/9.5/main/pg_hba.conf

Мы поместим строкиhost под блок комментариев, описывающий, как разрешить нелокальные соединения. Мы также добавим строку с публичным адресом сервера базы данных, чтобы мы могли быстро проверить, правильно ли настроен наш брандмауэр. Обязательно замените имя хоста или IP-адрес машинyour в примере ниже.

Выдержка из pg_hba.conf

# 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  sammydb  sammy   client_ip_address/32   md5

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

  • host Первый параметр,host, устанавливает, что будет использоваться соединение TCP / IP.

  • database `sammydb` Во втором столбце указывается, к каким базам данных может подключиться хост. Можно добавить более одной базы данных, разделив имена запятыми.

  • usersammy указывает пользователя, которому разрешено устанавливать соединение. Как и в столбце базы данных, можно указать несколько пользователей, разделенных запятыми.

  • address Адрес указывает адрес или адреса клиентского компьютера и может содержать имя хоста, диапазон IP-адресов или другиеspecial key words. В приведенном выше примере мы разрешили только один IP-адрес нашего клиента.

  • auth-method Наконец, auth-methodmd5 указывает, чтоdouble-MD5-hashed password будет предоставлен для аутентификации. Вам не нужно ничего делать, кроме как указать пароль, который был создан для подключающегося пользователя.

Для более полного обсуждения этих и дополнительных настроек см. ДокументациюThe pg_hba.conf File PostgreSQL.

Когда вы закончите, сохраните и выйдите из файла.

[[step-4 -—- configuring-the-listen-address]] == Шаг 4 - Настройка адреса прослушивания

Затем мы установим адрес прослушивания в файлеpostgresql.conf:

sudo nano /etc/postgresql/9.5/main/postgresql.conf

Найдите строкуlisten_addresses и под ней определите адреса прослушивания, обязательно подставив вместо имени хоста или IP-адреса хоста вашей базы данных. Возможно, вы захотите еще раз проверить, что вы используете публичный IP-адрес сервера базы данных, а не подключающийся клиент:

postgresql.conf

#listen_addresses = 'localhost'         # what IP address(es) to listen on;
listen_addresses = 'localhost,server_ip_address'

Когда вы закончите, сохраните и выйдите из файла.

[[step-5 -—- restarting-postgresql]] == Шаг 5. Перезапуск PostgreSQL

Наши изменения конфигурации не вступят в силу, пока мы не перезапустим демон PostgreSQL, поэтому мы сделаем это до того, как протестируем:

sudo systemctl restart postgresql

Посколькуsystemctl не предоставляет обратной связи, мы проверим статус, чтобы убедиться, что демон успешно перезапустился:

sudo systemctl status postgresql

Если выходные данные содержат «Active: active» и заканчиваются чем-то вроде следующего, то демон PostgreSQL работает.

Output...
Jan 10 23:02:20 PostgreSQL systemd[1]: Started PostgreSQL RDBMS.

Теперь, когда мы перезапустили демон, мы готовы к тестированию.

[[step-6 -—- testing]] == Шаг 6 - Тестирование

Наконец, давайте проверим, что мы можем подключиться с нашего клиентского компьютера. Для этого мы будем использоватьpsql с-U для указания пользователя,-h для указания IP-адреса клиента и-d для указания базы данных, поскольку мы ' Мы ужесточили нашу безопасность, так чтоsammy могут подключаться только к одной базе данных.

psql -U sammy -h postgres_host_ip -d sammydb

Если все настроено правильно, вы должны получить следующее приглашение:

OutputPassword for user sammy:

Введите пароль, который вы установили ранее при добавлении пользователяsammy в монитор PostgreSQL.

Если вы получите следующее приглашение, вы успешно подключитесь:

[secondary_label]
sammydb=>

Это подтверждает, что мы можем пройти через брандмауэр и подключиться к базе данных. Мы выйдем сейчас:

\q

Так как мы подтвердили нашу конфигурацию, мы закончим очисткой.

[[step-7 -—- remove-the-test-database-and-user]] == Шаг 7 - Удаление тестовой базы данных и пользователя

Вернувшись на хост после завершения тестирования соединения, мы можем использовать следующие команды для удаления базы данных и пользователя.

sudo -i -u postgres psql

Чтобы удалить базу данных:

DROP DATABASE sammydb;

Действие подтверждается следующим выводом:

OutputDROP DATABASE

Чтобы удалить пользователя:

DROP USER sammy;

Успех подтверждается:

OutputDROP ROLE

Мы завершим нашу очистку, удалив запись хоста для базы данныхsammydb из файлаpg_hba.conf, поскольку она нам больше не нужна:

sudo nano /etc/postgresql/9.5/main/pg_hba.conf

Строка для удаления изpg_hba.conf

host  sammydb  sammy   client_ip_address/32   md5

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

sudo systemctl restart postgresl

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

sudo systemctl status postgres

Если мы увидим «Active: active», мы узнаем, что перезагрузка прошла успешно.

На этом этапе мы можем перейти к настройке приложения или службы на клиенте, которому требуется удаленное подключение.

Дополнительные соображения безопасности

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

Перед началом работы с реальными данными мы рекомендуем ознакомиться со следующими ресурсами и предпринять соответствующие шаги для вашего варианта использования.

  • Security within PostgreSQL: операторы GRANT определяют, каким пользователям разрешен доступ к той или иной базе данных, а роли устанавливают привилегии этих пользователей. В сочетании они обеспечивают разделение между несколькими базами данных в одной установке.

  • Setting up SSL with PostgreSQL: Настройка SSL будет шифровать передаваемые данные. Это защищает данные при их отправке.

  • Securing PostgreSQL TCP/IP Connections with SSH Tunnels: туннели SSH полезны при подключении к клиентам, которые не поддерживают SSL. Практически в любой другой ситуации предпочтительнее установить SSL с Postgres.

Заключение

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

Related