17.9. Защита соединений TCP/IP с применением SSL
В PostgreSQL встроена поддержка SSL для шифрования трафика между клиентом и сервером, что повышает уровень безопасности системы. Для использования этой возможности необходимо, чтобы и на сервере, и на клиенте был установлен OpenSSL, и поддержка SSL была разрешена в PostgreSQL при сборке (см. Главу 15).
Когда в установленном сервере PostgreSQL разрешена поддержка SSL, его можно запустить с включённым механизмом SSL, задав в postgresql.conf
для параметра ssl значение on
. Запущенный сервер будет принимать как обычные, так и SSL-подключения в одном порту TCP и будет согласовывать использование SSL с каждым клиентом. По умолчанию клиент выбирает режим подключения сам; как настроить сервер, чтобы он требовал использования только SSL для всех или некоторых подключений, вы можете узнать в Разделе 19.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
. Если закрытый ключ защищён паролем, сервер запросит пароль и не запустится, пока этот пароль не будет введён.
Первым сертификатом в server.crt
должен быть сертификат сервера, так как он должен соответствовать закрытому ключу сервера. В этот файл также могут быть добавлены сертификаты «промежуточных» центров сертификации. Это избавляет от необходимости хранить все промежуточные сертификаты на клиентах, при условии, что корневой и промежуточные сертификаты были созданы с расширениями v3_ca
. (При этом в основных ограничениях сертификата устанавливается свойство CA
, равное true
.) Это также упрощает управление промежуточными сертификатами с истекающим сроком.
Добавлять корневой сертификат в server.crt
нет необходимости. Вместо этого клиенты должны иметь этот сертификат в цепочке сертификатов сервера.
17.9.1. Использование клиентских сертификатов
Чтобы клиенты должны были предоставлять серверу доверенные сертификаты, поместите сертификаты корневых центров сертификации (ЦС), которым вы доверяете, в файл в каталоге данных, укажите в параметре ssl_ca_file в postgresql.conf
имя этого файла и добавьте параметр аутентификации clientcert=1
в соответствующие строки hostssl
в pg_hba.conf
. В результате от клиента в процессе установления SSL-подключения будет затребован сертификат. (Как настроить сертификаты на стороне клиента, описывается в Разделе 31.18.) Получив сертификат, сервер будет проверять, подписан ли этот сертификат одним из доверенным центром сертификации.
Промежуточные сертификаты, которые составляют цепочку с существующими корневыми сертификатами, можно также включить в файл root.crt
, если вы не хотите хранить их на стороне клиента (предполагается, что корневой и промежуточный сертификаты были созданы с расширениями v3_ca
). Если установлен параметр ssl_crl_file, также проверяются списки отзыва сертификатов (Certificate Revocation List, CRL).
Параметр clientcert
в файле конфигурации pg_hba.conf
можно использовать с любым методом аутентификации, но только для строк hostssl
. Когда clientcert
не задан или равен 0, сервер, тем не менее, будет проверять представленный клиентом сертификат по своему списку доверенных ЦС (если он настроен), но позволит клиенту подключиться без сертификата.
Если вы используете клиентские сертификаты, вы можете также применить метод аутентификации cert
, чтобы сертификаты обеспечивали не только защиту соединений, но и проверку подлинности пользователей. За подробностями обратитесь к Подразделу 19.3.9.
17.9.2. Файлы, используемые SSL-сервером
В Таблице 17.2 кратко описаны все файлы, имеющие отношение к настройке SSL на сервере. (Здесь приведены стандартные или типичные имена файлов. В конкретной системе они могут быть другими.)
Таблица 17.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 ) | сертификаты, отозванные центрами сертификации | сертификат клиента должен отсутствовать в этом списке |
Файлы server.key
, server.crt
, root.crt
и root.crl
(или альтернативные файлы, заменяющие их) считываются только при запуске сервера; поэтому сервер необходимо перезапустить, чтобы изменения в них вступили в силу.
17.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
следует хранить в изолированном месте для создания сертификатов в будущем.