Шифрование SSL
==============
Шифрование соединений Клиент/Сервер
-----------------------------------
**ADB** обладает нативной поддержкой соединения **SSL** между клиентом и мастер-сервером. Соединение **SSL** предотвращает доступ к пакетам третьей стороны и предотвращает атаки посредника. **SSL** должно использоваться, когда соединение проходит по незащищенной ссылке, а также когда используется аутентификация сертификата клиента.
Для включения **SSL** требуется установленный **OpenSSL** как на клиенте, так и на мастер-сервере. **ADB** может запускаться с включенным **SSL** если настроить параметры конфигурации сервера ssl=on в мастере *postgresql.conf*. При запуске в режиме **SSL**, сервер будет искать файлы *server.key* (частный ключ сервера) и *server.crt* (сертификат сервера) в папке master data. Эти файлы должны быть настроены для запуска системы **ADB** с включенным **SSL**.
.. warning::
Не используйте пароль для защиты частного ключа. Сервер не запрашивает пароля для частного ключа и БД не сможет запуститься, если должна затребовать его.
Для тестирования системы можно использовать самоподписанный сертификат, но в штатной работе необходим сертификат подписанный **certificate authority** (CA), чтобы клиент мог подтвердить сервер. CA может быть локальный и глобальный. Если все клиенты принадлежат локальной организации, рекомендуется использовать локальный CA.
Настройка аутентификации SSL
----------------------------
В процессе аутентификации **SSL** сравниваются *Common Name* (cn) сертификата, который предоставляет программа-клиент при подключении, и запрашиваемое имя пользователя Базы данных. Пользователь не должен существовать в БД. Для обеспечения соединения между системой и БД можно использовать map-файл.
Параметры аутентификации SSL
............................
При аутентификации по сертификату доступны следующие опции:
* *Hostssl* - тип подключения должен быть *hostssl*.
* *map* - маппинг. Указывается в *pg_ident.conf*, или в файле, указанном в настройках сервера *ident_file*.
Пример *pg_hba.conf*:
::
Hostssl testdb certuser 192.168.0.0/16 cert
Hostssl testdb all 192.168.0.0/16 cert map=gpuser
Конфигурация OpenSSL
....................
**ADB** считывает файл конфигурации **OpenSSL**, указанный в *$GP_HOME/etc/openssl.cnf* по умолчанию. Для изменения настроек **OpenSSL** нужно внести изменения в конфигурационный файл и перезапустить сервер.
Пример создания самоподписанного сертификата
............................................
.. warning::
Использовать самоподписанный сертификат рекомендуется только в целях тестирования системы! Для продуктивного окружения используйте проверенные удостоверяющие центры (CA) для подписания сертификатов.
Для создания самоподписанного сертификата необходимо:
1. Ввести команду openssl:
::
openssl req -new -text -out server.req
2. Ввести запрашиваемую информацию. Убедитесь, что вы указали локальный хост в качестве *Common Name*. Пароль можно оставить пустым.
3. Программа создает ключ, защищенный паролем, который должен быть не короче четырех символов. Его необходимо отключить для автоматического запуска, для чего ввести команду:
::
openssl rsa -in privkey.pem -out server.key
rm privkey.pem
4. Ввести старый пароль, чтобы разблокировать существующий ключ.
5. Выполнить команду:
::
openssl req -x509 -in server.req -text -key server.key -out server.crt
Данная команда превращает сертификат в самоподписанный и копирует ключ и сертификат туда, где сервер будет их искать.
6. Выполнить команду:
::
chmod og-rwx server.key
7. Скопировать доверенный сертификат *root.crt* на базе *server.crt*:
::
cp server.crt root.crt
8. Перенести *root.crt* на клиентскую машину (например через scp) для проверки работы **SSL** в различных режимах. Файл *root.crt* размещается на клиенте в домашнем каталоге пользователя (в **Microsoft Windows** эта директория называется *%APPDATA%\postgresql*).
Более подробно о создании частного ключа и сертификата, см. `документацию OpenSSL `_.
Конфигурация postgresql.conf для аутентификации SSL
...................................................
Следующие настройки сервера должны быть указаны в конфигурационном файле *postgresql.conf*:
* *ssl [boolean]* - включить соединение **SSL**.
* *ssl_renegotiation_limit [integer]* - предел передачи данных до нового запроса ключа.
* *ssl_ciphers [string]* - список разрешенных шифрований **SSL**.
В папке *$MASTER_DATA_DIRECTORY* присутствуют следующие серверные файлы:
* *server.crt* - сертификат сервера.
* *server.key* - ключ сервера.
* *root.crt* - доверенные авторизации сертификата.
* *root.crl* - сертификаты, отозванные доверенными авторизациями.
Файлы *server.crt* и *server.key* сохраняются на сервере.
Файлы *root.crt* и *root.crl* сохраняются на клиенте в домашнем каталоге пользователя (в **Microsoft Windows** эта директория называется *%APPDATA%\postgresql*). Это делается, чтобы клиент мог убедиться в том, что конечный сертификат сервера подписан центром сертификации, которому он доверяет. Если на клиенте существует файл *root.crl*, при проверке также учитывается содержащийся в нём список отозванных сертификатов **Certificate Revocation List** (**CRL**).
Более подробно о настройках сертификатов **SSL** на сервере см. `документацию Postgres `_.
Конфигурация соединения SSL клиента
...................................
Доступны следующие опции **SSL**:
* *sslmode* - устанавливает уровень защиты (режимы подключения по **SSL**). Доступны следующие значения:
+-----------------+-------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``sslmode`` | Защита от прослушивания | Защита от MITM | Политика применения |
| | | | |
+=================+=========================+========================+====================================================================================================================================================================================+
| ``disable`` | Нет | Нет | Мне не важна безопасность и я не приемлю издержки, связанные с шифрованием. |
+-----------------+-------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``allow`` | Возможно | Нет | Мне не важна безопасность, но я приемлю издержки, связанные с шифрованием, если на этом настаивает сервер. |
+-----------------+-------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``prefer`` | Возможно | Нет | Мне не важна безопасность, но я предпочитаю шифрование (и приемлю связанные издержки), если это поддерживает сервер. |
+-----------------+-------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``require`` | Да | Нет | Я хочу, чтобы мои данные шифровались, и я приемлю сопутствующие издержки. Я доверяю сети в том, что она обеспечивает подключение к нужному серверу. |
+-----------------+-------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``verify-ca`` | Да | Зависит от политики ЦС | Я хочу, чтобы мои данные шифровались, и я приемлю сопутствующие издержки. Мне нужна уверенность в том, что я подключаюсь к доверенному серверу. |
+-----------------+-------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``verify-full`` | Да | Да | Я хочу, чтобы мои данные шифровались, и я приемлю сопутствующие издержки. Мне нужна уверенность в том, что я подключаюсь к доверенному серверу и это именно указанный мной сервер. |
+-----------------+-------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
* *sslcert* - имя файла клиентского сертификата **SSL**. Расположение по умолчанию: *~/.postgresql/postgresql.crt*.
* *sslkey* - тайный ключ, используемый клиентским сертификатом. Расположение по умолчанию: *~/.postgresql/postgresql.key*.
* *sslrootcert* - имя файла, содержащего сертификат(ы) **SSL Certificate Authority**. Расположение по умолчанию: *~/.postgresql/root.crt*.
* *sslcrl* - имя списка отозванных сертификатов **SSL**. Расположение по умолчанию: *~/.postgresql/root.crl*.
Для настройки клиентских параметров можно использовать следующие переменные:
* *sslmode* – PGSSLMODE
* *sslkey* – PGSSLKEY
* *sslrootcert* – PGSSLROOTCERT
* *sslcert* – PGSSLCERT
* *sslcrl* – PGSSLCRL
Более подробно о настройках сертификатов **SSL** на сервере см. `документацию Postgres `_.
Примеры подключения с клиента на сервер ADB в различных режимах SSL
...................................................................
В режиме *require* наличие *root.crt* сертификата на клиенте не требуется:
::
psql "sslmode=require host=test-ssl dbname=gpadmin user=gpadmin"
psql (9.4.24)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
gpadmin=#
В режиме *verify-ca* отсутствие *root.crt* сертификата на клиенте приведет к отказу подключения:
::
psql "sslmode=verify-ca host=test-ssl dbname=gpadmin user=gpadmin"
psql: root certificate file "/home/gpadmin/.postgresql/root.crt" does not exist
Either provide the file or change sslmode to disable server certificate verification.
После добавления *root.crt* подключение станет возможным:
::
psql "sslmode=verify-ca host=test-ssl dbname=gpadmin user=gpadmin"
psql (9.4.24)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
gpadmin=#
В режиме *verify-full* требуется наличие *root.crt* сертификата на клиенте и совпадение *hostname* и *server CN*, иначе в подключении будет отказано:
::
psql "sslmode=verify-full host=test-ssl dbname=gpadmin user=gpadmin"
psql: server common name "ssl-server" does not match host name "test-ssl"
Если пересоздать сертификаты, указав при создании сертификата *Server CN*, который будем использовать при подключении, станет возможным соединение по **SSL**:
::
psql "sslmode=verify-full host=test-ssl dbname=gpadmin user=gpadmin"
psql (9.4.24)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
gpadmin=#
Проверка SSL соединения с помощью расширения sslinfo
....................................................
Проверить, использует ли текущее соединение **SSL** можно с помощью функций расширения ``sslinfo``, например:
::
gpadmin=# create extension sslinfo;
CREATE EXTENSION
gpadmin=# select ssl_is_used();
ssl_is_used
-------------
t
(1 row)
Более подробную информацию по расширению ``sslinfo`` см. `документацию Postgres `_.