52.3. Аутентификация SASL
SASL — это инфраструктура аутентификации для протоколов, ориентированных на соединения. На данный момент PostgreSQL реализует два механизма SASL: SCRAM-SHA-256 и SCRAM-SHA-256-PLUS, а в будущем могут появиться и другие. Далее описывается, как в принципе осуществляется аутентификация SASL, а в следующем подразделе более подробно рассматриваются SCRAM-SHA-256 и SCRAM-SHA-256-PLUS.
Поток сообщений аутентификации SASL
Чтобы начать обмен по схеме аутентификации SASL, сервер передаёт сообщение AuthenticationSASL. Оно содержит список механизмов аутентификации SASL, с которыми может работать сервер, в порядке предпочтений сервера.
Клиент выбирает один из поддерживаемых механизмов из списка и передаёт серверу сообщение SASLInitialResponse. Это сообщение содержит имя выбранного механизма и может содержать «Начальный ответ клиента», если это использует выбранный механизм.
За этим следует одно или нескольких сообщений вызова со стороны сервера и ответов со стороны клиента. Все вызовы сервер передаёт в сообщениях AuthenticationSASLContinue, а клиент отвечает на них сообщениями SASLResponse. Частные детали сообщений зависят от конкретного механизма.
Наконец, когда обмен аутентификационной информацией заканчивается успешно, сервер передаёт сообщение AuthenticationSASLFinal и сразу за ним сообщение AuthenticationOk. В сообщении AuthenticationSASLFinal передаются дополнительные данные от сервера клиенту, содержимое которых определяется выбранным механизмом аутентификации. Если механизм аутентификации не требует передавать дополнительные данные в завершение обмена, сообщение AuthenticationSASLFinal опускается.
В случае ошибки сервер может прервать процесс аутентификации на любом этапе и передать сообщение ErrorMessage.
52.3.1. Аутентификация SCRAM-SHA-256
На данный момент реализованы два механизма SASL: SCRAM-SHA-256
и его вариация со связыванием каналов, SCRAM-SHA-256-PLUS
. Они подробно описываются в RFC 7677 и в RFC 5802.
Когда в PostgreSQL задействуется SCRAM-SHA-256, сервер игнорирует имя пользователя, которое клиент передаёт в client-first-message
. Вместо этого используется имя, переданное ранее в стартовом сообщении. Согласно спецификации SCRAM, имя пользователя должно быть в UTF-8, но PostgreSQL поддерживает разные кодировки символов, и значит, имя пользователя PostgreSQL не всегда будет представимо в UTF-8.
В спецификации SCRAM говорится, что пароль также должен передаваться в UTF-8 и обрабатываться алгоритмом SASLprep. Однако PostgreSQL не требует, чтобы пароль представлялся в UTF-8. Когда устанавливается пароль пользователя, он обрабатывается алгоритмом SASLprep как пароль в UTF-8, вне зависимости от фактической кодировки. Однако если он представлен недопустимой для UTF-8 последовательностью байтов либо содержит комбинации байтов UTF-8, которые не принимает алгоритм SASLprep, это не будет считаться ошибкой — при аутентификации будет использоваться исходный пароль, без обработки SASLprep. Это позволяет нормализовать пароли, представленные в UTF-8, и при этом использовать пароли не в UTF-8, а также не требует, чтобы система знала, в какой кодировке задан пароль.
Связывание каналов поддерживается в PostgreSQL при сборке с использованием SSL. Для SCRAM со связыванием каналов в качестве имени механизма SASL выбрано SCRAM-SHA-256-PLUS
. PostgreSQL использует тип связывания tls-server-end-point
.
В SCRAM без связывания каналов сервер выбирает случайное число, которое передаётся клиенту для смешивания с введённым пользователем паролем и получения передаваемого в ответ хеша. Хотя это препятствует повторному воспроизведению пароля в последующем сеансе, поддельный сервер между настоящим сервером и клиентом может прозрачно передать случайное число сервера и затем успешно пройти аутентификацию.
SCRAM со связыванием каналов позволяет предотвратить такие атаки посредника, подмешивая подпись сертификата сервера в передаваемый хеш пароля. Хотя поддельный сервер может повторить передачу сертификата настоящего сервера, у него не будет доступа к закрытому ключу, соответствующему этому сертификату, поэтому он не сможет подтвердить, что является его владельцем, и, как следствие, установить SSL-соединение.
Пример
Сервер передаёт сообщение AuthenticationSASL. Оно содержит список механизмов аутентификации SASL, с которыми может работать сервер. Этот список будет включать
SCRAM-SHA-256-PLUS
иSCRAM-SHA-256
, если сервер собран с поддержкой SSL, а иначе — только последнее значение.Клиент в ответ передаёт сообщение SASLInitialResponse, информирующее о выбранном механизме,
SCRAM-SHA-256
илиSCRAM-SHA-256-PLUS
. (Клиент волен выбрать любой механизм, но для большей безопасности следует выбирать вариацию со связыванием каналов, если он это поддерживает.) В поле «Начальный ответ клиента» это сообщение содержит данные SCRAMclient-first-message
. Вclient-first-message
содержится тип связывания каналов, выбранный клиентом.Сервер передаёт сообщение AuthenticationSASLContinue, содержащее данные SCRAM
server-first-message
.Клиент передаёт сообщение SASLResponse, содержащее данные SCRAM
client-final-message
.Сервер передаёт сообщение AuthenticationSASLFinal, содержащее данные SCRAM
server-final-message
, и сразу за ним сообщение AuthenticationOk.