Digital Q.DataBase имеет встроенную поддержку использования SSL соединений для шифрования обмена данными между клиентом и сервером с помощью TLS протоколов в целях повышения безопасности. Подробные сведения см. в Раздел 3.3.9 разделе, описывающем серверную SSL функциональность.
libpq считывает общесистемный
OpenSSL конфигурационный файл. По умолчанию данный
файл имеет имя openssl.cnf и располагается в
каталоге, возвращаемом командой openssl version -d. Данное значение по умолчанию
может быть переопределено с помощью переменной окружения
OPENSSL_CONF к имени нужного конфигурационного файла.
По умолчанию, Digital Q.DataBase никакая проверка сертификата сервера выполняться не будет. Это означает, что возможна подмена идентификационных данных сервера (например, путем изменения записи DNS или захвата IP-адреса сервера) без ведома клиента. Для предотвращения подмены клиент должен иметь возможность проверить подлинность сервера с помощью цепочки доверия. Цепочка доверия устанавливается путем размещения сертификата корневого (самоподписанного) центра сертификации (CA) на одном компьютере и конечного сертификата подписанного корневым сертификатом на другом компьютере. Также можно использовать «промежуточный» сертификат, который подписан корневым сертификатом и используется для подписания конечных сертификатов.
Для обеспечения проверки подлинности сервера на стороне клиента следует разместить корневой сертификат на клиенте, а подписанный им конечный сертификат — на сервере. Чтобы позволить серверу проверить подлинность клиента, следует поместить корневой сертификат на сервер, а подписанный этим корневым сертификатом конечный сертификат — на сторону клиента. Для связывания конечного сертификата с корневым сертификатом могут также применяться один или несколько промежуточных сертификатов (которые обычно хранятся вместе с конечным сертификатом).
После установления цепочки доверия существует два способа проверки клиентом конечного сертификата, отправленного сервером. Если параметр sslmode имеет значение verify-ca, библиотека libpq подтвердит надежность сервера посредством проверки цепочки сертификатов вплоть до корневого сертификата, хранящегося на стороне клиента. Если sslmode имеет значение verify-full,
библиотека libpq также проверит соответствие имени хоста сервера имени, указанному в сертификате сервера. В случае невозможности проверки сертификата сервера SSL-соединение завершится ошибкой. verify-full рекомендуется к использованию в большинстве сред
с высокими требованиями к безопасности.
В режиме verify-full имя хоста сверяется с атрибутами Subject Alternative Name (SAN) сертификата или с атрибутом Common Name, если отсутствует SAN типа dNSName присутствует. Если атрибут имени в сертификате начинается со звездочки
(*), эта звездочка будет интерпретироваться как
символ подстановки, соответствующий любым символам за исключением точки
(.). Это означает, что данный сертификат не будет соответствовать поддоменам. Если соединение устанавливается с использованием IP-адреса вместо имени узла, то сопоставление этого IP-адреса (без выполнения DNS-запросов) будет производиться с расширениями SAN типа iPAddress или dNSName. Если
iPAddress расширение SAN присутствует, и ни одно соответствующее dNSName SAN не найдено, IP-адрес хоста сопоставляется с атрибутом Common Name.
Для обеспечения обратной совместимости с предыдущими версиями PostgreSQL проверка IP-адреса хоста выполняется способом, отличным от RFC 6125.
IP-адрес хоста всегда сопоставляется с расширениями dNSName
SAN, а также iPAddress SAN, и может быть сопоставлен с атрибутом Common Name при отсутствии соответствующих расширений SAN.
Для обеспечения проверки сертификата сервера один или несколько корневых сертификатов должны быть помещены в файл ~/.postgresql/root.crt
в домашнем каталоге пользователя. (В операционной системе Microsoft Windows этот файл называется
%APPDATA%\postgresql\root.crt.) Если для связывания переданной сервером цепочки сертификатов с корневыми сертификатами, хранящимися на стороне клиента, требуются промежуточные сертификаты, их также следует добавить в этот файл.
Записи списка отзыва сертификатов (CRL) также проверяются,
если файл ~/.postgresql/root.crl существует
(%APPDATA%\postgresql\root.crl в системе Microsoft
Windows).
Местоположение файла корневых сертификатов и списка CRL можно изменить, задав параметры соединения sslrootcert и sslcrl
или переменные окружения PGSSLROOTCERT и PGSSLCRL.
sslcrldir или переменную окружения PGSSLCRLDIR
также может использоваться для указания каталога, содержащего файлы CRL.
Для обеспечения обратной совместимости с предыдущими версиями PostgreSQL, если файл корневого центра сертификации (CA) существует, поведение
sslmode=require будет таким же,
как у verify-ca, что означает проверку сертификата сервера
на соответствие центру сертификации (CA). Полагаться на такое поведение не рекомендуется,
и приложениям, требующим проверки сертификата, всегда следует использовать
verify-ca или verify-full.
Если сервер пытается проверить подлинность клиента, запрашивая его конечный сертификат,
libpq отправит сертификаты, хранящиеся в
файле ~/.postgresql/postgresql.crt в домашнем каталоге
пользователя. Сертификаты должны образовывать цепочку до доверенного сервером корневого сертификата. Соответствующий
файл закрытого ключа ~/.postgresql/postgresql.key также должен
присутствовать.
В операционной системе Microsoft Windows эти файлы называются
%APPDATA%\postgresql\postgresql.crt и
%APPDATA%\postgresql\postgresql.key. Расположение файлов сертификата и ключа можно переопределить через параметры соединения sslcert
и sslkey, или через
переменные окружения PGSSLCERT и PGSSLKEY.
В системах Unix права доступа к файлу закрытого ключа должны запрещать любой доступ для группы или прочих пользователей; добиться этого можно с помощью команды
chmod 0600 ~/.postgresql/postgresql.key.
В качестве альтернативы владельцем файла может быть пользователь root, а самому файлу может быть предоставлен доступ на чтение для группы
(то есть, 0640 права доступа). Такая конфигурация предназначена
для систем, в которых файлы сертификатов и ключей управляются
операционной системой. Пользователь libpq в этом случае
должен быть включен в группу, имеющую доступ к этим файлам сертификатов
и ключей. (В операционной системе Microsoft Windows проверка прав доступа к файлам не выполняется, так как каталог %APPDATA%\postgresql считается
защищенным.)
Первым сертификатом в файле postgresql.crt должен быть сертификат клиента, так как он должен соответствовать закрытому ключу клиента.
«Промежуточные» сертификаты могут быть дополнительно добавлены
в конец файла — это позволяет избежать необходимости хранения промежуточных сертификатов на сервере (ssl_ca_file).
Сертификат и ключ могут быть представлены в формате PEM или ASN.1 DER.
Ключ может храниться в открытом виде или быть зашифрован с использованием пароля любым алгоритмом, поддерживаемым библиотекой OpenSSL, например AES-128. Если ключ хранится в зашифрованном виде, кодовая фраза может быть передана в
sslpassword параметре соединения. Если предоставлен
зашифрованный ключ, а sslpassword параметр
отсутствует или не заполнен, пароль будет запрошен в интерактивном режиме посредством
OpenSSL через
Enter PEM pass phrase: запрос при наличии терминала TTY. Приложения могут переопределять запрос пароля клиентского сертификата и обработку sslpassword параметра, предоставив собственную
функцию обратного вызова для пароля ключа; см.
PQsetSSLKeyPassHook_OpenSSL.
Инструкции по созданию сертификатов приведены в Раздел 3.3.9.5.
Различные значения sslmode параметра обеспечивают разные уровни защиты. SSL может обеспечить
защиту от атак трёх типов:
Если третья сторона может анализировать сетевой трафик между клиентом и сервером, она может прочитать как сведения о соединении (включая имя пользователя и пароль), так и передаваемые данные. SSL для предотвращения этого использует шифрование.
Если третья сторона имеет возможность изменять данные при их передаче между клиентом и сервером, она может имитировать сервер и, как следствие, просматривать и изменять эти данные, даже если они зашифрованы.. В таком случае третья сторона может пересылать сведения о соединении и данные на исходный сервер, вследствие чего обнаружить данную атаку становится невозможно. К распространенным векторам реализации подобных атак относятся подмена записей DNS и перехват адресов, при которых клиент направляется на сервер, отличный от целевого. Существует также несколько других методов атак, позволяющих реализовать данный сценарий. SSL использует проверку сертификатов для предотвращения подобных атак путем аутентификации сервера для клиента.
Если третья сторона может выдать себя за авторизованного клиента, она получает возможность несанкционированно получить доступ к данным. Как правило, это происходит вследствие небезопасного управления паролями. SSL использует клиентские сертификаты для предотвращения подобных ситуаций, гарантируя доступ к серверу только владельцам действительных сертификатов.
Чтобы соединение гарантированно было защищено по протоколу SSL, использование SSL должно быть настроено
как на стороне клиента, так и на стороне сервера до установления
соединения. Если SSL настроен только на сервере, клиент может отправить конфиденциальную информацию (например, пароли) до того, как получит сведения о требовании сервером высокого уровня безопасности. В библиотеке libpq обеспечить защищенные соединения можно путем настройки параметра sslmode параметра равным verify-full или
verify-ca, а также путем предоставления системе корневого сертификата для проведения проверки. Это аналогично использованию https
URL для безопасного просмотра веб-страниц в зашифрованном виде.
После прохождения сервером аутентификации клиент может передавать конфиденциальные данные. Это означает, что до данного момента клиенту не требуется знать, будут ли сертификаты использоваться для аутентификации, благодаря чему эти настройки можно безопасно указывать только в конфигурации сервера.
Все SSL параметры влекут за собой накладные расходы в виде шифрования и обмена ключами, поэтому необходимо достичь компромисса между производительностью и безопасностью. Таблица 4.1.1
иллюстрирует риски, которые предотвращают различные sslmode значения
, а также их влияние на безопасность и накладные расходы.
Таблица 4.1.1. Описания режимов SSL
sslmode | Защита от перехвата | MITM защита | Описание |
|---|---|---|---|
disable | Нет | Нет | Безопасность не имеет значения, и дополнительные расходы ресурсов на шифрование нежелательны. |
allow | Возможно | Нет | Безопасность не имеет значения, но накладные расходы на шифрование допустимы, если сервер требует его использования. |
prefer | Возможно | Нет | Шифрование не является обязательным, но накладные расходы на шифрование приемлемы, если сервер поддерживает его. |
require | Да | Нет | Данные должны передаваться в зашифрованном виде, и накладные расходы допустимы. Я доверяю что сетевая инфраструктура обеспечит соединение именно с требуемым сервером. |
verify-ca | Да | Зависит от политики центра сертификации (CA) | Требуется шифрование данных при допустимости сопутствующих накладных расходов. Необходимо быть уверенным в установке соединения с доверенным сервером. |
verify-full | Да | Да | Требуется шифрование данных при допустимости сопутствующих накладных расходов. Необходимо быть уверенным в установке соединения с доверенным сервером, причем именно с тем, который был указан. |
Различие между verify-ca и verify-full
зависит от политики корневого центра сертификации CA. Если используется общедоступный
CA центр сертификации, verify-ca допускает соединения с сервером,
который стороннее лицо могло зарегистрировать в данном CAцентре.
В этом случае verify-full следует использовать всегда. Если
используется локальный CA центр или даже самоподписанный сертификат, использование параметра
verify-ca часто обеспечивает достаточный уровень защиты.
Значение по умолчанию для sslmode имеет значение NULL prefer. Как показано в таблице, это не имеет смысла с точки зрения безопасности и лишь приводит к увеличению накладных расходов на производительность. Данное значение используется по умолчанию только для обеспечения обратной совместимости и не рекомендуется для применения в защищенных средах.
Таблица 4.1.2 обобщает сведения о файлах, имеющих отношение к настройке протокола SSL на стороне клиента.
Таблица 4.1.2. Использование SSL-файлов клиента в библиотеке libpq
| Файл | Содержимое | Назначение |
|---|---|---|
~/.postgresql/postgresql.crt | клиентский сертификат | передаётся серверу |
~/.postgresql/postgresql.key | закрытый ключ клиента | подтверждает, что клиентский сертификат отправлен его владельцем; не гарантирует, что владелец сертификата заслуживает доверия |
~/.postgresql/root.crt | доверенные центры сертификации | проверяется наличие подписи доверенного центра сертификации у сертификата сервера |
~/.postgresql/root.crl | сертификаты, отозванные центрами сертификации | сертификат сервера не должен фигурировать в данном списке |
Если приложение инициализирует libssl и/или
libcrypto библиотеки и libpq
собрано с SSL поддержкой, следует вызвать функцию
PQinitOpenSSL чтобы сообщить библиотеке libpq
что libssl и/или libcrypto библиотеки
были инициализированы приложением, и функция
libpq не выполняла повторную инициализацию этих библиотек.
Однако это не требуется при использовании OpenSSL
версии 1.1.0 или выше, так как дублирование инициализации более не является проблемой.
PQinitOpenSSL #Позволяет приложениям выбирать библиотеки безопасности для инициализации.
void PQinitOpenSSL(int do_ssl, int do_crypto);
Когда do_ssl имеет ненулевое значение, libpq
инициализирует библиотеку OpenSSL библиотеки перед первым
открытием соединения с базой данных. В случае когда do_crypto имеет
имеет ненулевое значение, то libcrypto библиотека будет инициализирована. По
умолчанию (если PQinitOpenSSL функция не вызывается), обе библиотеки
инициализируются. Если поддержка SSL не была включена при компиляции, данная функция
присутствует в коде, но не выполняет никаких действий.
Если приложение использует и инициализирует либо OpenSSL
либо лежащую в её основе libcrypto библиотеку, вам должен
следует вызвать данную функцию с нулевыми значениями соответствующих параметров
перед первым открытием соединения с базой данных. Также необходимо убедиться, что вы
выполнили инициализацию до открытия соединения с базой данных.
PQinitSSL #Позволяет приложениям выбирать библиотеки безопасности для инициализации.
void PQinitSSL(int do_ssl);
Данная функция эквивалентна функции
PQinitOpenSSL(do_ssl, do_ssl).
Этого достаточно для приложений, которые инициализируют оба компонента либо не инициализируют ни одного из них
параметра OpenSSL и libcrypto.
PQinitSSL присутствует начиная с версии
Digital Q.DataBase 8.0, тогда как функция PQinitOpenSSL
была добавлена в версии Digital Q.DataBase 8.4, поэтому параметр PQinitSSL
может быть предпочтительным для приложений, которым необходимо работать с более старыми
версиями libpq.