31.19. Поддержка SSL#
31.19. Поддержка SSL #
Tantor SE-1C имеет встроенную поддержку использования SSL соединений для шифрования клиент-серверного общения с использованием протоколов TLS для повышения безопасности. См. Раздел 17.9 для получения подробной информации о функциональности SSL на стороне сервера.
libpq считывает системный файл конфигурации OpenSSL. По умолчанию этот файл называется openssl.cnf
и находится в каталоге, указанном в выводе команды openssl version -d
. Это значение по умолчанию можно изменить, установив переменную среды OPENSSL_CONF
в имя желаемого файла конфигурации.
31.19.1. Проверка клиентом сертификатов сервера #
По умолчанию, Tantor SE-1C не выполняет проверку серверного сертификата. Это означает, что возможно подделать идентификатор сервера (например, изменить запись 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
. Если отсутствует SAN типа iPAddress
и отсутствует соответствующий SAN типа dNSName
, IP-адрес хоста будет сравниваться с атрибутом Common Name.
Примечание
Для обратной совместимости с более ранними версиями PostgreSQL, IP-адрес хоста
проверяется иначе, чем в RFC 6125.
IP-адрес хоста всегда сопоставляется с dNSName
SANs, а также с iPAddress
SANs, и может быть сопоставлен
с атрибутом Common Name, если соответствующие SANs отсутствуют.
Для разрешения проверки сертификата сервера, один или несколько корневых сертификатов
должны быть помещены в файл ~/.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
.
31.19.2. Сертификаты клиента #
Если сервер пытается проверить подлинность клиента, запросив сертификат клиента, 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
.
Для инструкций по созданию сертификатов см. Раздел 17.9.5.
31.19.3. Защита, предоставляемая в различных режимах #
Различные значения параметра sslmode
обеспечивают разные уровни защиты. SSL может обеспечить защиту от трех типов атак:
- Eavesdropping
Если третья сторона может просматривать сетевой трафик между клиентом и сервером, она может прочитать как информацию о подключении (включая имя пользователя и пароль), так и передаваемые данные. SSL использует шифрование для предотвращения этого.
- Man-in-the-middle (MITM)
Если третья сторона может изменять данные во время передачи между клиентом и сервером, она может притвориться сервером и, следовательно, видеть и изменять данные даже если они зашифрованы. Затем третья сторона может пересылать информацию о соединении и данные на исходный сервер, что делает невозможным обнаружение этой атаки. Обычные векторы для этого включают подмену DNS и захват адреса, при которых клиент направляется на другой сервер, чем предполагалось. Существуют также несколько других методов атаки, которые могут достичь этого. SSL использует проверку сертификата для предотвращения этого путем аутентификации сервера для клиента.
- Impersonation
Если третья сторона может притворяться авторизованным клиентом, она может просто получить доступ к данным, к которым не должна иметь доступа. Обычно это может произойти из-за небезопасного управления паролями. SSL использует клиентские сертификаты для предотвращения этого, убедившись, что только владельцы действительных сертификатов могут получить доступ к серверу.
Для того чтобы соединение было известно как SSL-защищенное, использование SSL должно быть настроено как на клиенте, так и на сервере перед установкой соединения. Если SSL настроен только на сервере, клиент может отправить чувствительную информацию (например, пароли) до того, как узнает, что сервер требует высокой безопасности. В libpq безопасные соединения могут быть обеспечены путем установки параметра sslmode
в значение verify-full
или verify-ca
и предоставления системе корневого сертификата для проверки. Это аналогично использованию
URL с префиксом https
для зашифрованного веб-просмотра.
После аутентификации сервера клиент может передавать конфиденциальные данные. Это означает, что до этого момента клиенту не нужно знать, будут ли использоваться сертификаты для аутентификации, что позволяет безопасно указать это только в конфигурации сервера.
Все параметры SSL несут издержки в виде шифрования и обмена ключами, поэтому существует компромисс между производительностью и безопасностью. Таблица 31.1 иллюстрирует риски, от которых защищают различные значения sslmode
и какое заявление о безопасности и издержках они делают.
Таблица 31.1. Описания режимов SSL
sslmode | Защита от прослушивания | MITM защита | Утверждение |
---|---|---|---|
disable | Нет | Нет | Мне не важна безопасность, и я не хочу платить дополнительные издержки на шифрование. |
allow | Возможно | Нет | Мне безразлична безопасность, но я готов понести издержки на шифрование, если сервер настаивает на этом. |
prefer | Возможно | Нет | Мне не важно шифрование, но я хотел бы понести издержки на шифрование, если сервер его поддерживает. |
require | Да | Нет | Я хочу, чтобы мои данные были зашифрованы, и я согласен на дополнительные издержки. Я уверен, что сеть всегда обеспечивает подключение к нужному серверу. |
verify-ca | Да | Зависит от политики ЦС | Я хочу, чтобы мои данные были зашифрованы, и я согласен на дополнительные издержки. Я хочу быть уверенным, что подключаюсь к серверу, которому доверяю. |
verify-full | Да | Да | Я хочу, чтобы мои данные были зашифрованы, и я согласен на дополнительные издержки. Я хочу быть уверенным, что подключаюсь к доверенному серверу и что это именно тот сервер, который я указываю. |
Разница между verify-ca
и verify-full
зависит от политики корневого CA. Если используется общедоступный
CA, verify-ca
позволяет подключаться к серверу,
который может быть зарегистрирован кем-то другим с использованием CA.
В этом случае всегда следует использовать verify-full
. Если
используется локальный CA или даже самоподписанный сертификат, часто достаточно использовать
verify-ca
для обеспечения достаточной защиты.
Значение по умолчанию для sslmode
- prefer
. Как показано в таблице, это не имеет смысла с точки зрения безопасности, и это влечет дополнительные издержки на производительность, если это возможно. Оно предоставляется только в качестве значения по умолчанию для обратной совместимости и не рекомендуется для безопасных развертываний.
31.19.4. Использование файлов SSL клиента #
Таблица 31.2 подводит итоги файлов, которые относятся к настройке SSL на клиенте.
Таблица 31.2. Использование файлов Libpq/Client SSL
Файл | Содержание | Эффект |
---|---|---|
~/.postgresql/postgresql.crt | клиентский сертификат | отправлен на сервер |
~/.postgresql/postgresql.key | клиентский закрытый ключ | подтверждает клиентский сертификат, отправленный владельцем; не указывает на то, что владелец сертификата надежен |
~/.postgresql/root.crt | доверенные центры сертификации | проверяет, что сертификат сервера подписан доверенным центром сертификации |
~/.postgresql/root.crl | сертификаты, отозванные удостоверяющими центрами | серверный сертификат не должен быть в этом списке |
31.19.5. Инициализация библиотеки SSL #
Если ваше приложение инициализирует библиотеки 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
присутствует с версии PostgreSQL 8.0, в то время какPQinitOpenSSL
был добавлен в PostgreSQL 8.4, поэтомуPQinitSSL
может быть предпочтительным для приложений, которые должны работать с более старыми версиями libpq.