Установка защищённой базы данных 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 добавился параметр 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 и, после копирования, назначьте им права доступа readonly:

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 'your_desired_cipher';

Вместо your_desired_cipher необходимо написать набор параметров, разделённых между собой знаком :. По умолчанию, данная строка содержит набор параметров: 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 представлено в разделе Сводка по аутентификации.

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

После редактирования файла 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. И CREATE USER, и CREATE ROLE хорошо подходят для создания нового пользователя QHB. Однако у пользователя должна быть роль 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.