Установка защищенной базы данных QHB

При установке СУБД в ИТ-инфраструктуре в тестовых целях можно ограничиться настройками по умолчанию. Однако если планируется использовать СУБД продолжительное время и/или в продуктивном контуре, следует выполнить несколько рекомендаций по установке базовой защиты экземпляра базы данных. Все необходимые действия можно разделить на несколько этапов:

  • Настройка защищенного (SSL) соединения;
  • Осмысленное разграничение прав ролей, групп и пользователей в базе данных;
  • Избавление от всех паролей «по умолчанию»;
  • Защита контура иными средствами если необходимо.

Данное руководство содержит:

  • базовую защиту самой системы QHB;
  • инструкцию по настройке подключения через SSL;
  • инструкцию по выпуску сертификатов для подключения через SSL;
  • примеры и рекомендации разграничения прав ролей, групп и пользователей.


Настройка защищенного соединения

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

Установка необходимых библиотек

Для начала необходимо убедиться, что требуемые пакеты/библиотеки установлены в системе. Проверить наличие openssl можно командой:

openssl version

При отсутствии необходимого пакета следует установить его. Для примера, на CentOS 7 нужно выполнить команду:

yum install openssl

Пример команды для установки на Ubuntu:

apt-get install openssl

Пакет openssl должен быть установлен как на сервере СУБД, так и на компьютере, с которого производится клиентское подключение.


Шифрование соединения с помощью SSL

Для шифрования соединения между клиентом и сервером должны быть созданы соответствующие сертификаты сервера и клиента(ов). В данном контексте под ключом понимается закрытый ключ, а под сертификатом — открытый ключ.

ВНИМАНИЕ!
Важно понимать, что закрытый ключ необходимо держать в тайне и не распространять.

Создание корневого ключа и корневого сертификата

# Данная команда создает файл корневого ключа длиной 1024 бит
openssl genrsa -out rootCA.key 1024
# Данная команда создает сертификат 'rootCA.crt' со сроком жизни 365 дней
openssl req -x509 -new -key rootCA.key -days 365 -out rootCA.crt -subj '/C=XX/L=Default City/O=Default Company Ltd/CN=root'

Первая команда, genrsa, генерирует закрытый ключ. Аргумент -out rootCA.key 1024 — это файл, который будет сгенерирован после выполнения команды. Число в конце означает размер последовательности ключа в битах, можно использовать число 2048 или 4096.

Вторая команда, req, генерирует сертификат. В ней нужно передать следующие аргументы:

  • -x509 — указывает на необходимость создания корневого или тестового сертификата.
  • -new — указывает на необходимость создания нового сертификата.
  • -key rootCA.key — указание на файл закрытого ключа.
  • -days 365 — срок жизни сертификата; если не указывать данный параметр, будет указан срок 30 дней.
  • -out rootCA.crt — файл открытого ключа, который будет создан по завершении команды.
  • -subj — информация для создаваемого сертификата. Содержит следующие поля:
    • C=XX — код страны.
    • L=Default City — город.
    • O=Default Company Ltd — название компании.

Можно вписывать любые данные, но для последующего удобства желательно вписать настоящие.

Создание сертификата сервера подписанного rootCA

# Данная команда создает файл ключа сервера длинной 1024 бит
openssl genrsa -out server.key 1024
# Создается неподписанный сертификат сервера (запрос на сертификат)
openssl req -new -key server.key -out server.csr -subj '/C=XX/L=Default City/O=Default Company Ltd/CN=servername'
# Сертификат сервера подписывается корневым сертификатом
openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 365

Используемые аргументы первых двух команд аналогичны прошлому блоку, но в аргумент -subj команды req добавляется поле CN=servername, представляющее собой название объекта. Можно вписать любое, но для последующего удобства желательно использовать название сервера.

Третья команда, x509, в данном контексте используется для подписи сертификата. В ней нужно передать следующие аргументы:

  • -req — означает, что на вход подается неподписанный сертификат.
  • -in server.csr — файл, который необходимо подписать.
  • -CA rootCA.crt — файл, которым будет производится подпись.
  • -CAkey rootCA.key — файл закрытого ключа, сертификатом которого будет производится подпись.
  • -CAcreateserial — создание файла серийного номера центра сертификации.
  • -out server.crt — файл открытого ключа, который будет создан по завершении команды.
  • -days 365 — срок жизни сертификата; если не указывать данный параметр, будет указан срок 30 дней.

Создание сертификата клиента подписанного rootCA

openssl genrsa -out qhb.key 1024
openssl req -new -key qhb.key -out qhb.csr -subj '/C=XX/L=Default City/O=Default Company Ltd/CN=servername'
openssl x509 -req -in qhb.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out qhb.crt -days 365

Используемые аргументы команды аналогичны прошлому блоку. Данный сертификат потребуется при настройке соединения клиента с базой данных.

Копирование сертификата сервера, приватного ключа сервера и rootCA

Скопируйте сертификат сервера, приватный ключ сервера и rootCA в директорию кластера QHB и после копирования назначьте им права доступа только на чтение:

cd $PGDATA
chmod 0400 server.crt server.key rootCA.crt

Включение SSL в QHB

В интерактивном терминале psql выполните команды:

qhb=# ALTER SYSTEM SET ssl TO 'ON';
qhb=# ALTER SYSTEM SET ssl_ca_file TO 'rootCA.crt';
qhb=# ALTER SYSTEM SET ssl_cert_file TO 'server.crt';
qhb=# ALTER SYSTEM SET ssl_key_file TO 'server.key';

Также эти параметры можно изменять в файле qhb.conf. Подробную информацию см. в подразделе SSL.

Использование специфичного шифра

Примечание
Данный этап необязателен. Выполните его, если есть необходимость использовать специфичный шифр

В интерактивном терминале psql выполните команду:

qhb=# ALTER SYSTEM SET ssl_ciphers TO 'желаемый_шифр';

В параметре желаемый_шифр необходимо написать набор параметров, разделенных двоеточием (:). По умолчанию данная строка содержит набор параметров HIGH:MEDIUM:+3DES:!aNULL. Значение по умолчанию является самым оптимальным, если у вас нет особых требований к безопасности.

Пояснения по стандартным параметрам:

  • HIGH — наборы шифров, которые используют шифры из группы HIGH (например, AES, Camellia, 3DES).
  • MEDIUM — наборы шифров, использующие шифры из группы MEDIUM (например, RC4, SEED).
  • +3DES — порядок шифров для группы HIGH по умолчанию в OpenSSL определен некорректно. В нем 3DES оказывается выше AES128, что неправильно, так как он считается менее безопасным, чем AES128, и работает гораздо медленнее. Соответственно, данная запись изменяет последовательность использования шифров, чтобы шифр Triple DES использовался после наборов шифров High и Medium.
  • !aNULL — Отключает наборы анонимных шифров, не требующие проверки подлинности. Такие наборы уязвимы для атак с посредником, поэтому использовать их не следует.

Также эти параметры можно изменять в файле qhb.conf. Подробную информацию см. в подразделе SSL.

Перезагрузка сервера QHB

psql -c "select pg_reload_conf();"

или:

qhb_ctl -D DATADIR restart -mf

Редактирование файла qhb_hba.conf

Для включения ssl необходимо заменить host на hostssl в файле $PGDATA/qhb_hba.conf:

Со стороны сервера:

# IPv4 local connections:
# host all all 127.0.0.1/32 trust
hostssl all all 127.0.0.1/32 trust

Аналогичные действия необходимо произвести с клиентской стороны:

# IPv4 local connections:
# host all all 127.0.0.1/32 trust
hostssl all all 127.0.0.1/32 trust
hostssl all all app_server_1/32 md5
hostssl all all app_server_2/32 md5

Подробное описание файла qhb_hba.conf представлено в описании каталога pg_hba_file_rules.

Применение обновленной конфигурации

После редактирования файла qhb_hba.conf на шаге Редактирование файла qhb_hba.conf выполните:

psql -c "select pg_reload_conf();"

Тестирование соединения

Если все настроено правильно, то соединение должно выглядеть так:

psql -h localhost
psql (10.4)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
#

Если оно выглядит так:

psql (10.4)
Type "help" for help.
#

т. е. отсутствует строка с указанием протокола SSL: SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off), то настройка не была произведена окончательно.


Включение аутентификации клиента по сертификату

Копирование сертификата на клиентскую часть

На данном шаге необходимо скопировать сертификат клиента, который был создан на шаге Создание сертификата клиента. Для примера, следующая строка кода показывает копирование на удаленную машину с адресом 192.168.0.13:

scp qhb.crt qhb.key rootCA.crt qhb@192.168.0.13:/usr/local/qhb

Далее этим файлам необходимо задать права только на чтение на удаленной машине:

cd /usr/local/qhb
chmod 0400 qhb.crt qhb.key rootCA.crt

Настройка qhb_hba.conf

Для использования аутентификации клиента по сертификату необходимо на сервере добавить строку с подключением клиента с удаленной машины qhb_hba.conf. Для примера используется IP машины из предыдущего шага:

hostssl all all 192.168.0.13/32 cert clientcert=1

Отличия от шага Редактирование файла qhb_hba.conf прошлой части в том, что на данном шаге сертификат необходим для подтверждения, что соединение происходит между двумя доверенными сторонами. Для того чтобы изменения вступили в силу, необходимо перезагрузить QHB.

qhb_ctl -D DATADIR reload

Проверка удаленного соединения

Как и в шаге Тестирование соединения прошлой части, после ввода команды:

psql "port=5432 host=192.168.0.12 user=qhb sslcert=/usr/local/qhb/qhb.crt sslkey=/usr/local/qhb/qhb.key sslrootcert=/usr/local/qhb/rootCA.crt sslmode=require"

текст в консоли должен выглядеть так:

psql (10.4)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-DES-CBC3-SHA, bits: 168, compression: off)
Type "help" for help.
#

Если упоминания SSL нет или соединение не происходит, то, скорее всего, не все шаги выполнены правильно.



Создание ролей групп и пользователей

В QHB, как и в любой другой СУБД, необходимо обеспечивать разграничение прав. Для понимания данного вопроса ниже описаны способы создания пользователей, групп и ролей.

Создание роли или пользователя

Пользователь QHB — это роль с правом CONNECT. Для создания нового пользователя QHB хорошо подходят команды CREATE USER и CREATE ROLE. Однако у пользователя должна быть роль LOGIN. Роль входа назначается пользователю при использовании любого из следующих трех подходов на интерактивном терминале psql:

qhb=# CREATE USER percuser WITH ENCRYPTED PASSWORD 'secret';
qhb=# CREATE ROLE percuser WITH ENCRYPTED PASSWORD 'secret';
qhb=# CREATE ROLE percuser;
qhb=# ALTER ROLE percuser WITH LOGIN ENCRYPTED PASSWORD 'secret';

После ввода любого из вышеуказанных примеров QHB автоматически добавляет код на указанный ниже

qhb=# CREATE ROLE percuser
WITH NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB LOGIN NOREPLICATION NOBYPASSRLS
ENCRYPTED PASSWORD 'secret';

В данном примере видно, что нет ролей, которые давали бы возможность изменять базу. После создания пользователя или роли вы можете использовать следующий запрос, чтобы узнать, может ли пользователь войти в систему (имеет ли право на подключение):

qhb=# select rolcanlogin from pg_roles where rolname = 'percuser';
rolcanlogin
-------------
t
(1 row)

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

qhb=# CREATE ROLE percrole;
CREATE ROLE
qhb=# select rolcanlogin from pg_roles where rolname = 'percrole';
rolcanlogin
-------------
f
(1 row)

Различия создания роли и создания пользователя

При использовании CREATE USER происходит автоматическое добавление роли возможности логина.

qhb=# CREATE USER percuser WITH ENCRYPTED PASSWORD 'secret';
CREATE ROLE
qhb=# select rolcanlogin from pg_roles where rolname = 'percuser';
rolcanlogin
-------------
t
(1 row)

А при использовании CREATE ROLE ее необходимо добавлять вручную.

qhb=# CREATE ROLE percuser WITH ENCRYPTED PASSWORD 'secret';
CREATE ROLE
qhb=# select rolcanlogin from pg_roles where rolname = 'percuser';
rolcanlogin
-------------
f
(1 row)
qhb=# ALTER ROLE percuser WITH LOGIN;
ALTER ROLE
qhb=# select rolcanlogin from pg_roles where rolname = 'percuser';
rolcanlogin
-------------
t
(1 row)

Создание группы и групповой роли

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

Всегда рекомендуется предоставлять права доступа пользователям с помощью групповых ролей.

Рассмотрим пример:

  • 1 база db1;
  • 2 схемы sh1 и sh2.

Допустим, нам нужно создать 10 отдельных пользователей и 10 пользователей приложений, соблюдая следующие требования:

  • Пять пользователей приложения должны иметь доступ только для чтения к таблицам схемы sh1 и доступ для чтения и записи к таблицам схемы sh2.
  • Остальные пять пользователей приложения должны иметь доступ для чтения и записи к таблицам схемы sh1 и доступ только для чтения к таблицам схемы sh2.
  • Все 10 индивидуальных учетных записей пользователей могут иметь доступ только для чтения к таблицам обеих схем.

В этой ситуации можно создать четыре групповых роли, например:

sh1_readonly:

qhb=# CREATE ROLE sh1_readonly;
qhb=# GRANT USAGE, SELECT ON ALL TABLES IN SCHEMA sh1 TO sh1_readonly;

sh1_readwrite:

qhb=# CREATE ROLE sh1_readwrite;
qhb=# GRANT USAGE, SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA sh1 TO sh1_readwrite;

sh2_readonly:

qhb=# CREATE ROLE sh2_readonly;
qhb=# GRANT USAGE, SELECT ON ALL TABLES IN SCHEMA sh2 TO sh2_readonly;

sh2_readwrite:

qhb=# CREATE ROLE sh2_readwrite;
qhb=# GRANT USAGE, SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA sh2 TO sh2_readwrite;

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

qhb=# GRANT sh1_readonly,sh2_readonly TO user1, user2, user3, ..., user10;
qhb=# GRANT sh1_readonly,sh2_readwrite TO appuser1, appuser2, ..., appuser5;
qhb=# GRANT sh1_readwrite,sh2_readonly TO appuser6, appuser7, ..., appuser10;

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


Распределение прав

QHB поддерживает множество прав.

Например:

  • SELECT
  • INSERT
  • UPDATE
  • DELETE
  • TRUNCATE
  • REFERENCES
  • TRIGGER
  • CREATE
  • USAGE
  • EXECUTE

Эти права могут быть предоставлены с помощью команды GRANT.