Перейти к основному содержимому

Аутентификация SASL

SASL - это основа для аутентификации в протоколах, ориентированных на соединение. На данный момент в PostgreSQL реализовано два механизма аутентификации SASL: SCRAM-SHA-256 и SCRAM-SHA-256-PLUS. В будущем могут быть добавлены другие. Приведенные ниже шаги иллюстрируют, как формируется аутентификация SASL в целом, а в следующем подразделе более подробно рассматриваются SCRAM-SHA-256 и SCRAM-SHA-256-PLUS.

Поток сообщений аутентификации SASL:

  1. Чтобы начать обмен аутентификацией SASL, сервер отправляет сообщение AuthenticationSASL. Оно содержит список механизмов аутентификации SASL, которые сервер может принять, в предпочтительном для сервера порядке.
  2. Клиент выбирает один из поддерживаемых механизмов из списка и отправляет серверу сообщение SASLInitialResponse. Сообщение содержит имя выбранного механизма и необязательный Начальный ответ клиента, если выбранный механизм его использует.
  3. Далее следует одно или несколько сообщений с вызовом сервера и ответом клиента. Каждый вызов сервера отправляется в сообщении AuthenticationSASLContinue, за которым следует ответ клиента в сообщении SASLResponse. Детали сообщений зависят от механизма.
  4. Наконец, когда обмен аутентификацией успешно завершен, сервер отправляет сообщение AuthenticationSASLFinal, за которым сразу же следует сообщение AuthenticationOk. AuthenticationSASLFinal содержит дополнительные данные от сервера к клиенту, содержимое которых имеет особый характер выбранному механизму аутентификации. Если механизм аутентификации не использует дополнительные данные, отправляемые при завершении, сообщение AuthenticationSASLFinal не отправляется.

При ошибке сервер может прервать аутентификацию на любом этапе и отправить сообщение ErrorMessage.

Аутентификация SCRAM-SHA-256

На данный момент реализованными механизмами SASL являются SCRAM-SHA-256 и его вариант с привязкой к переменной SCRAM-SHA-256-PLUS. Они подробно описаны в RFC 7677 и RFC 5802.

Когда в PostgreSQL используется SCRAM-SHA-256, сервер игнорирует имя пользователя, которое клиент отправляет в сообщении client-first-message. Вместо этого будет использоваться имя пользователя, которое уже было отправлено в стартовом сообщении. PostgreSQL поддерживает несколько кодировок символов, в то время как SCRAM предписывает использовать UTF-8 для имени пользователя, поэтому может оказаться невозможным представить имя пользователя 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. Имя механизма SASL для SCRAM с привязкой к каналу - SCRAM-SHA-256-PLUS. Тип привязки канала, используемый PostgreSQL, - tls-server-end-point.

В SCRAM без привязки к каналу сервер выбирает случайное число, которое передается клиенту и смешивается с паролем пользователя в передаваемом хэше пароля. Хотя это предохраняет хэш пароля от успешной повторной передачи в последующем сеансе, это не мешает поддельному серверу между реальным сервером и клиентом пройти через случайное значение сервера и успешно аутентифицироваться.

SCRAM с привязкой к каналу предотвращает такие атаки типа "человек посередине", подмешивая подпись сертификата сервера в передаваемый хэш пароля. Хотя поддельный сервер может повторно передать сертификат настоящего сервера, у него нет доступа к закрытому ключу, соответствующему этому сертификату, и поэтому он не может доказать, что является его владельцем, что приводит к разрыву SSL-соединения.

Пример

  1. Сервер отправляет сообщение AuthenticationSASL. Оно содержит список механизмов аутентификации SASL, которые сервер может принимать. Это будут SCRAM-SHA-256-PLUS и SCRAM-SHA-256, если сервер построен с поддержкой SSL, или только последний.
  2. В ответ клиент отправляет сообщение SASLInitialResponse, в котором указывает выбранный механизм, SCRAM-SHA-256 или SCRAM-SHA-256-PLUS. (Клиент может выбрать любой механизм, но для большей безопасности ему следует выбрать вариант с привязкой к каналу, если он может его поддерживать). В поле Initial Client response сообщение содержит сообщение SCRAM client-first-message. Сообщение client-first-message также содержит тип связывания каналов, выбранный клиентом.
  3. Сервер отправляет сообщение AuthenticationSASLContinue, содержимым которого является сообщение SCRAM server-first-message.
  4. Клиент отправляет сообщение SASLResponse, содержащее SCRAM client-final-message в качестве контента.
  5. Сервер отправляет сообщение AuthenticationSASLFinal, содержащее SCRAM server-final-message, за которым сразу же следует сообщение AuthenticationOk.