18.9. Защита соединений TCP/IP с применением SSL
В PostgreSQL встроена поддержка SSL для шифрования трафика между клиентом и сервером, что повышает уровень безопасности системы. Для использования этой возможности необходимо, чтобы и на сервере, и на клиенте был установлен OpenSSL, и поддержка SSL была разрешена в PostgreSQL при сборке (см. Главу 16).
Когда в установленном сервере PostgreSQL разрешена поддержка SSL, его можно запустить с включённым механизмом SSL, задав в postgresql.conf
для параметра ssl значение on
. Запущенный сервер будет принимать как обычные, так и SSL-подключения в одном порту TCP и будет согласовывать использование SSL с каждым клиентом. По умолчанию клиент выбирает режим подключения сам; как настроить сервер, чтобы он требовал использования только SSL для всех или некоторых подключений, вы можете узнать в Разделе 20.1.
PostgreSQL читает системный файл конфигурации OpenSSL. По умолчанию этот файл называется openssl.cnf
и находится в каталоге, который сообщает команда openssl version -d
. Если требуется указать другое расположение файла конфигурации, его можно задать в переменной окружения OPENSSL_CONF
.
OpenSSL предоставляет широкий выбор шифров и алгоритмов аутентификации разной защищённости. Хотя список шифров может быть задан непосредственно в файле конфигурации OpenSSL, можно задать отдельные шифры именно для сервера баз данных, указав их в параметре ssl_ciphers в postgresql.conf
.
Примечание
Накладные расходы, связанные с шифрованием, в принципе можно исключить, ограничившись только проверкой подлинности, то есть применяя шифр NULL-SHA
или NULL-MD5
. Однако в этом случае посредник сможет пропускать через себя и читать весь трафик между клиентом и сервером. Кроме того, шифрование привносит минимальную дополнительную нагрузку по сравнению с проверкой подлинности. По этим причинам использовать шифры NULL не рекомендуется.
Чтобы сервер мог работать в режиме SSL, ему необходимы файлы с сертификатом сервера и закрытым ключом. По умолчанию это должны быть файлы server.crt
и server.key
, соответственно, расположенные в каталоге данных, но можно использовать и другие имена и местоположения файлов, задав их в конфигурационных параметрах ssl_cert_file и ssl_key_file.
В Unix-подобных системах к файлу server.key
должен быть запрещён любой доступ группы и всех остальных; чтобы установить такое ограничение, выполните chmod 0600 server.key
. Возможен и другой вариант, когда этим файлом владеет root, а группа имеет доступ на чтение (то есть, маска разрешений 0640
). Данный вариант предназначен для систем, в которых файлами сертификатов и ключей управляет сама операционная система. В этом случае пользователь, запускающий сервер PostgreSQL, должен быть членом группы, имеющей доступ к указанным файлам сертификата и ключа.
Если закрытый ключ защищён паролем, сервер спросит этот пароль и не будет запускаться, пока он не будет введён. Использование такого пароля лишает возможности изменять конфигурацию SSL без перезагрузки сервера. Более того, закрытые ключи, защищённые паролем, не годятся для использования в Windows.
Первым сертификатом в server.crt
должен быть сертификат сервера, так как он должен соответствовать закрытому ключу сервера. В этот файл также могут быть добавлены сертификаты «промежуточных» центров сертификации. Это избавляет от необходимости хранить все промежуточные сертификаты на клиентах, при условии, что корневой и промежуточные сертификаты были созданы с расширениями v3_ca
. (При этом в основных ограничениях сертификата устанавливается свойство CA
, равное true
.) Это также упрощает управление промежуточными сертификатами с истекающим сроком.
Добавлять корневой сертификат в server.crt
нет необходимости. Вместо этого клиенты должны иметь этот сертификат в цепочке сертификатов сервера.
18.9.1. Использование клиентских сертификатов
Чтобы клиенты должны были предоставлять серверу доверенные сертификаты, поместите сертификаты корневых центров сертификации (ЦС), которым вы доверяете, в файл в каталоге данных, укажите в параметре ssl_ca_file в postgresql.conf
имя этого файла и добавьте параметр аутентификации clientcert=1
в соответствующие строки hostssl
в pg_hba.conf
. В результате от клиента в процессе установления SSL-подключения будет затребован сертификат. (Как настроить сертификаты на стороне клиента, описывается в Разделе 33.18.) Получив сертификат, сервер будет проверять, подписан ли этот сертификат одним из доверенным центром сертификации.
Промежуточные сертификаты, которые составляют цепочку с существующими корневыми сертификатами, можно также включить в файл root.crt
, если вы не хотите хранить их на стороне клиента (предполагается, что корневой и промежуточный сертификаты были созданы с расширениями v3_ca
). Если установлен параметр ssl_crl_file, также проверяются списки отзыва сертификатов (Certificate Revocation List, CRL).
Параметр аутентификации clientcert
можно использовать с любым методом проверки подлинности, но только в строках pg_hba.conf
типа hostssl
. Когда clientcert
не задан или равен 0, сервер всё же будет проверять все представленные клиентские сертификаты по своему списку ЦС (если он настроен), но позволит подключаться клиентам без сертификата.
Если вы используете клиентские сертификаты, вы можете также применить метод аутентификации cert
, чтобы сертификаты обеспечивали не только защиту соединений, но и проверку подлинности пользователей. За подробностями обратитесь к Подразделу 20.3.9. (Устанавливать clientcert=1
явно при использовании метода аутентификации cert
не требуется.)
18.9.2. Файлы, используемые SSL-сервером
В Таблице 18.2 кратко описаны все файлы, имеющие отношение к настройке SSL на сервере. (Здесь приведены стандартные или типичные имена файлов. В конкретной системе они могут быть другими.)
Таблица 18.2. Файлы, используемые SSL-сервером
Файл | Содержимое | Назначение |
---|---|---|
ssl_cert_file ($PGDATA/server.crt ) | сертификат сервера | отправляется клиенту для идентификации сервера |
ssl_key_file ($PGDATA/server.key ) | закрытый ключ сервера | подтверждает, что сертификат сервера был передан его владельцем; не гарантирует, что его владельцу можно доверять |
ssl_ca_file ($PGDATA/root.crt ) | сертификаты доверенных ЦС | позволяет проверить, что сертификат клиента подписан доверенным центром сертификации |
ssl_crl_file ($PGDATA/root.crl ) | сертификаты, отозванные центрами сертификации | сертификат клиента должен отсутствовать в этом списке |
Сервер читает эти файлы при запуске или при перезагрузке конфигурации. В системах Windows они также считываются заново, когда для нового клиентского подключения запускается новый обслуживающий процесс.
Если в этих файлах при запуске сервера обнаружится ошибка, сервер откажется запускаться. Но если ошибка обнаруживается при перезагрузке конфигурации, эти файлы игнорируются и продолжает использоваться старая конфигурация SSL. В системах Windows, если в одном из этих файлов обнаруживается ошибка при запуске обслуживающего процесса, этот процесс не сможет устанавливать SSL-соединения. Во всех таких случаях в журнал событий сервера выводится сообщение об ошибке.
18.9.3. Создание сертификатов
Чтобы создать простой самоподписанный сертификат для сервера, действующий 365 дней, выполните следующую команду OpenSSL, заменив dbhost.yourdomain.com
именем компьютера, где размещён сервер:
openssl req -new -x509 -days 365 -nodes -text -out server.crt \
-keyout server.key -subj "/CN=dbhost.yourdomain.com
"
Затем выполните:
chmod og-rwx server.key
так как сервер не примет этот файл, если разрешения будут более либеральными, чем показанные. За дополнительными сведениями относительно создания закрытого ключа и сертификата сервера обратитесь к документации OpenSSL.
Хотя самоподписанный сертификат может успешно применяться при тестировании, в производственной среде следует использовать сертификат, подписанный центром сертификации (ЦС) (обычно это корневой ЦС предприятия).
Чтобы создать сертификат сервера, подлинность которого смогут проверять клиенты, сначала создайте запрос на получение сертификата (CSR) и файлы открытого/закрытого ключа:
openssl req -new -nodes -text -out root.csr \
-keyout root.key -subj "/CN=root.yourdomain.com
"
chmod og-rwx root.key
Затем подпишите запрос ключом, чтобы создать корневой центр сертификации (с файлом конфигурации OpenSSL, помещённым в Linux в расположение по умолчанию):
openssl x509 -req -in root.csr -text -days 3650 \ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \ -signkey root.key -out root.crt
Наконец, создайте сертификат сервера, подписанный новым корневым центром сертификации:
openssl req -new -nodes -text -out server.csr \
-keyout server.key -subj "/CN=dbhost.yourdomain.com
"
chmod og-rwx server.key
openssl x509 -req -in server.csr -text -days 365 \
-CA root.crt -CAkey root.key -CAcreateserial \
-out server.crt
server.crt
и server.key
должны быть сохранены на сервере, а root.crt
— на клиенте, чтобы клиент мог убедиться в том, что конечный сертификат сервера подписан центром сертификации, которому он доверяет. Файл root.key
следует хранить в изолированном месте для создания сертификатов в будущем.
Также возможно создать цепочку доверия, включающую промежуточные сертификаты:
# корневой сертификат openssl req -new -nodes -text -out root.csr \ -keyout root.key -subj "/CN=root.yourdomain.com
" chmod og-rwx root.key openssl x509 -req -in root.csr -text -days 3650 \ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \ -signkey root.key -out root.crt # промежуточный openssl req -new -nodes -text -out intermediate.csr \ -keyout intermediate.key -subj "/CN=intermediate.yourdomain.com
" chmod og-rwx intermediate.key openssl x509 -req -in intermediate.csr -text -days 1825 \ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \ -CA root.crt -CAkey root.key -CAcreateserial \ -out intermediate.crt # конечный openssl req -new -nodes -text -out server.csr \ -keyout server.key -subj "/CN=dbhost.yourdomain.com
" chmod og-rwx server.key openssl x509 -req -in server.csr -text -days 365 \ -CA intermediate.crt -CAkey intermediate.key -CAcreateserial \ -out server.crt
server.crt
и intermediate.crt
следует сложить вместе в пакет сертификатов и сохранить на сервере. Также на сервере следует сохранить server.key
. Файл root.crt
нужно сохранить на клиенте, чтобы клиент мог убедиться в том, что конечный сертификат сервера был подписан по цепочке сертификатов, связанных с корневым сертификатом, которому он доверяет. Файлы root.key
и intermediate.key
следует хранить в изолированном месте для создания сертификатов в будущем.