06 Занятие 06: Методы аутентификации / Использование SSL
Эта страница извлечена из официального PDF в нативный Markdown. Текст слайдов, код и комментарии сохранены в порядке чтения; исходные PDF и HTML остаются эталоном макета. HTML source: dbs_06_auth_ssl.html Archive: DBS-handouts-16.zip Страниц PDF: 29
Page 1: Методы аутентификации / Использование SSL
Авторские права
© Postgres Professional, 2017–2026 Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов, Алексей Береснев Фото: Олег Бартунов (монастырь Пху и пик Бхрикути, Непал)
Использование материалов курса
Некоммерческое использование материалов курса (презентации, демонстрации) разрешается без ограничений. Коммерческое использование возможно только с письменного разрешения компании Postgres Professional. Запрещается внесение изменений в материалы курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу: edu@postgrespro.ru
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за любые повреждения и убытки, включая потерю дохода, нанесенные прямым или непрямым, специальным или случайным использованием материалов курса. Компания Postgres Professional не предоставляет каких-либо гарантий на материалы курса. Материалы курса предоставляются на основе принципа «как есть» и компания Postgres Professional не обязана предоставлять сопровождение, поддержку, обновления, расширения и изменения.
Page 2: Темы
- Введение в прикладную криптографию
- Подключение SSL: защита трафика и аутентификация
Page 3: Введение в криптографию
Симметричное и асимметричное шифрование
- Цифровая подпись
- Сертификат
- Цепочка сертификатов
Page 4: Симметричный шифр
{#source-figure-004 caption=“Source slide page 4: Симметричный шифр”}
Задача: защита трафика от прослушивания
Комментарии преподавателя
Прежде чем приступить к основному вопросу темы — использованию SSL для шифрования и аутентификации, — сделаем очень краткое введение в прикладную криптографию.
Начнем со схемы с симметричным шифрованием. В ней один и тот же ключ используется и для шифрования, и для расшифровывания. Алиса может зашифровать сообщение и переслать его Бобу по незащищенному каналу связи. Если Чарли перехватит такое сообщение, он не сможет расшифровать его, не имея ключа.
Симметричное шифрование работает быстро, но Алиса и Боб должны каким-то образом получить идентичные ключи. Ключ может сгенерировать один из них (например, Алиса), но она не может передать ключ по незащищенному каналу, поскольку Чарли сможет перехватить его. Для обмена ключами подходит только надежный канал — например, передать при личной встрече на флешке. Во многих случаях это неудобно.
Page 5: Асимметричный шифр
{#source-figure-005 caption=“Source slide page 5: Асимметричный шифр”}
Задача: коммуникация при отсутствии общего секрета
- A
- A
- B
Комментарии преподавателя
Поэтому еще в 1976 году была придумана схема с асимметричным шифрованием.
Алиса генерирует пару ключей: закрытый (приватный, темный на рисунке) и открытый (публичный, светлый). Закрытый ключ она хранит только у себя, а публичный раздает всем, включая Чарли.
То же делает Боб.
В самом упрощенном виде асимметричная криптография работает так: если сообщение зашифровано открытым ключом, расшифровать его может только закрытый. Наоборот — открытый ключ расшифровывает зашифрованное только соответствующим закрытым. Под «шифрованием» здесь понимаются математические преобразования, в которые мы не будем вдаваться.
Итак, Алиса зашифровывает документ открытым ключом Боба. Расшифровать его может только Боб, у которого есть его закрытый ключ.
Задача передавать сообщения так, чтобы их не мог расшифровать Чарли, решена.
Page 6: Цифровая подпись
{#source-figure-006 caption=“Source slide page 6: Цифровая подпись”}
Задача: защита от подмены
- A3F602
- A3F602
- A3F602
- A
- A
- A
- B
Комментарии преподавателя
Но есть другая проблема: поскольку открытый ключ Боба есть у всех (в том числе и у Чарли), Чарли может отправлять сообщение Бобу, прикидываясь Алисой (а Алисе — прикидываясь Бобом; такая атака называется MITM — Man-in-the-Middle). Как Бобу убедиться в том, что сообщение отправила именно Алиса?
Алиса вычисляет хеш-функцию от документа, который она переслала Бобу, и зашифровывает это хеш-значение своим закрытым ключом. Такое сообщение называется цифровой подписью Алисы.
Боб расшифровывает сообщение открытым ключом Алисы — таким образом он уверен, что только Алиса могла его послать, ведь закрытого ключа Алисы больше ни у кого нет.
Затем Боб вычисляет хеш-функцию от полученного ранее документа и сравнивает с тем значением, которое получил от Алисы. Если значения совпадают, Боб уверен, что исходный документ был отправлен Алисой и дошел до него в неизменном виде.
Алиса может отправить подпись вместе с документом, зашифровав и то, и другое открытым ключом Боба, но даже если отправить подпись отдельно, ничего страшного не случится. Чарли имеет открытый ключ Алисы и сможет прочитать хеш-значение, но он не сможет восстановить по нему исходный документ.
Page 7: Сертификат
{#source-figure-007 caption=“Source slide page 7: Сертификат”}
Проблема доверия
- A
- A A
- B
- C
Комментарии преподавателя
Но есть и еще одна проблема. Откуда Боб знает, что открытый ключ Алисы, который он получил (например, скачал с сайта Алисы), действительно принадлежит Алисе, а не сфабрикован Чарли (который мог взломать сайт)? Доверять можно только информации, которую получил лично от знакомого человека. А ведь существуют тысячи Алис и Бобов, каждый из которых не может знать в лицо всех остальных.
Проблему доверия решают центры сертификации (ЦС или CA, Certification Authority), называемые иначе удостоверяющие центры. У Алисы и Боба должен быть посредник, которому они оба доверяют и открытый ключ которого имеют. Такой ключ, конечно, должен передаваться по надежному каналу связи. Это неудобно, но требуется всего один раз.
Алиса обращается в центр сертификации. Центр проверяет личность Алисы и подписывает ее открытый ключ и метаинформацию о владельце (имя, срок действия ключа и т. п.) своим закрытым ключом. Такой документ называется сертификатом.
Теперь Алиса может послать Бобу свой сертификат. Он расшифрует его открытым ключом центра сертификации, получит открытый ключ Алисы и удостоверится, что он действительно принадлежит Алисе.
Page 8: Сертификат
{#source-figure-008 caption=“Source slide page 8: Сертификат”}
Задача: перевыпуск сертификатов
- A
- A A A B B
- B
- C
- R
- C
- R
- Алиса
Комментарии преподавателя
На практике вместо открытого ключа ЦС используют сертификат ЦС, который содержит открытый ключ ЦС и метаинформацию, подписанные закрытым ключом вышестоящего ЦС. В принципе, достаточно и просто открытого ключа, но сертификат более удобен: в частности, он содержит срок действия ключа. Сертификат корневого ЦС подписывается ключом самого корневого ЦС, такой сертификат называется самоподписанным.
Несколько центров сертификации могут образовывать иерархию. Например, свои ЦС могут иметь разные подразделения компании.
Промежуточный ЦС, удостоверяя личность Алисы, подписывает ее открытый ключ и метаинформацию своим закрытым ключом. Вместе со своим сертификатом Алиса получает и всю цепочку сертификатов промежуточных ЦС.
У Боба могут отсутствовать сертификаты промежуточных ЦС, поэтому Алиса, подтверждая идентичность, вместе со своим сертификатом посылает Бобу и полученную цепочку сертификатов промежуточных ЦС. Таким образом Боб может проверить все сертификаты в цепочке вплоть до корневого, сертификат которого у него имеется.
Цепочка доверия позволяет менять ключи промежуточных ЦС (периодически для профилактики или в случае компрометации), не перегенерируя вообще все ключи в компании.
Далее мы рассмотрим, как эти технологии применяются на практике.
Page 9: Подключение SSL
Схема SSL-подключения
- Настройки сервера
- Настройки клиента
- Проверка сервера
Page 10: Схема SSL-подключения
{#source-figure-010 caption=“Source slide page 10: Схема SSL-подключения”}
TLS-рукопожатие
- A
- A
- C
Комментарии преподавателя
Трафик между клиентом и сервером может быть перехвачен программами-снифферами, такими, как tcpdump или Wireshark. Если трафик не защищен, злоумышленник увидит все команды и ответы сервера (и даже пароли в случае метода аутентификации password).
PostgreSQL поддерживает криптографическую защиту SSL (Secure Sockets Layer). Это историческое название протокола; сейчас он называется TLS (Transport Layer Security), но старое название привычно и по-прежнему широко используется. PostgreSQL позволяет использовать разные библиотеки, но наиболее популярной является OpenSSL: https://docs.openssl.org/master/man7/ossl-guide-introduction/
Когда клиент подключается к серверу, он с помощью клиент-серверного протокола может попросить (или потребовать) защищенное SSL-соединение. Если сервер отвечает, что готов к SSL-соединению, выполняется так называемое TLS-рукопожатие:
Клиент пересылает серверу свой открытый ключ и набор параметров, которые он поддерживает (версию протокола TLS, доступные алгоритмы шифрования и т. п.).
В ответ сервер отправляет клиенту свой сертификат и набор параметров, которые он выбрал для продолжения общения из предложенных клиентом. Из сертификата клиент извлекает открытый ключ сервера, по метаинформации он также может проверить, что подключился именно к тому серверу, к которому ожидал.
TLS-рукопожатие требует нескольких пересылок между клиентом и сервером и может занимать десятки миллисекунд.
Page 11: Схема SSL-подключения
{#source-figure-011 caption=“Source slide page 11: Схема SSL-подключения”}
Защита трафика
Комментарии преподавателя
Теперь между клиентом и сервером установлено защищенное соединение. Они выбирают ключ для симметричного шифрования, которое и используется для дальнейшего обмена информацией (поскольку симметричное шифрование работает быстрее).
Далее порожденный обслуживающий процесс выполняет аутентификацию и в случае успеха начинает сеанс.
Page 12: Настройки клиента
Параметр sslmode библиотеки libpq
- disable
- не использовать SSL
- allow
- попытка соединиться без SSL,
- при неудаче — попытка использовать SSL
- prefer
- попытка использовать SSL,
- при неудаче — попытка соединиться без него
- (по умолчанию)
- require
- потребовать SSL
Комментарии преподавателя
При подключении клиент высказывает свои пожелания по использованию SSL. Они определяются значением параметра sslmode библиотеки libpq, которое может, например, указываться в строке подключения.
Клиент может запретить SSL-соединение (disable) или потребовать его (require). Если сервер не разрешает желаемое соединение, оно не будет установлено.
Клиент также может объявить, что готов на любой вариант, и установить предпочтения: сначала просить либо SSL-соединение (prefer, по умолчанию), либо незащищенное соединение (allow). Какое соединение будет установлено, зависит в таком случае от возможностей сервера.
(Есть еще два значения параметра sslmode, verify-ca и verify-full, которые будут рассмотрены ниже на слайде «Проверка сервера»).
https://postgrespro.ru/docs/postgresql/16/libpq-ssl
https://postgrespro.ru/docs/postgresql/16/libpq-connect#LIBPQ-CONNECT-SSLMODE
Page 13: Настройки сервера
Параметры
- ssl = off
- разрешены ли подключения SSL
- ssl_ca_file
- файл с сертификатами ЦС
- ssl_cert_file = server.crt
- файл с сертификатом сервера
- ssl_key_file = server.key
- файл с закрытым ключом сервера
- Типы сетевых подключений в pg_hba.conf
- hostnossl
- подключение без SSL
- hostssl
- подключение с SSL
- host
- любое сетевое подключение
Комментарии преподавателя
Минимально необходимые параметры настройки сервера для SSL:
● ssl — разрешает подключаться к серверу, используя SSL;
● ssl_ca_file — имя файла с сертификатами ЦС;
● ssl_cert_file — файл, содержащий сертификат сервера;
● ssl_key_file — файл с закрытым ключом сервера.
Могут быть указаны и другие параметры, указывающие расположение списка отзыва сертификатов, настройки преобразования и прочее.
https://postgrespro.ru/docs/postgresql/16/ssl-tcp#SSL-SETUP
https://postgrespro.ru/docs/postgresql/16/runtime-config-connection#GUC-S SL
Можно ограничиться простым самоподписанным сертификатом сервера, как это показано в документации:
https://postgrespro.ru/docs/postgresql/16/ssl-tcp#SSL-CERTIFICATE-CREA TION
Если параметры сервера допускают SSL-подключения, возможность установки такого соединения зависит и от настроек в pg_hba.conf, как рассматривалось в теме «Подключение и аутентификация». Записи с типом hostssl соответствуют SSL-подключению, а host — любому сетевому подключению, в том числе и SSL. Записи с типом hostnossl относятся к подключению без SSL; такие подключения разумно разрешать только в защищенных сетях, для которых SSL излишен.
https://postgrespro.ru/docs/postgresql/16/auth-pg-hba-conf
Page 14: Настройки сервера
В Ubuntu конфигурация по умолчанию использует сертификат и ключ, созданные при установке ОС:
Сертификат является самоподписанным: он выдан без участия центра сертификации. Такой сертификат можно использовать для шифрования трафика, но не для проверки аутентичности сервера. Поэтому мы будем использовать другой набор файлов, подготовленный для курса в виртуальной машине: /etc/pgssl/root/root.crt — корневой сертификат центра сертификации; /etc/pgssl/serv/serv.crt — сертификат сервера PostgreSQL; /etc/pgssl/serv/serv.key — закрытый ключ сервера PostgreSQL. Заглянем в сертификат сервера serv.crt (мы не выводим открытый ключ, который в нем содержится):
сертификат выпустил ЦС PPG_EDU_CA (Issuer CN; CN — Common Name, основное имя); сертификат выдан серверу с доменным именем course.local (Subject CN); срок действия сертификата — 10 лет (Validity). Имя course.local соответствует доменному имени нашего сервера:
Расширенные атрибуты сертификата SAN (Subject Alternative Name), определенные стандартом RFC 5280, позволяют указывать несколько доменных имен или IP адресов сервера. Добавим параметры конфигурации сервера в дополнительный файл в подкаталоге conf.d. Сервер должен прослушивать все интерфейсы.
Перезапустим сервер, поскольку был изменен параметр listen_addresses.
Page 15: Page 15
Откроем новый сеанс без SSL. Для этого в строке соединения укажем параметр sslmode=disable (или allow):
Представление pg_stat_ssl показывает статистику использования SSL сеансами:
В поле ssl видим значение false — SSL не используется. Напомним, что администратор сервера может запретить нешифрованные соединения, поместив в начало конфигурационного файла аутентификации соответствующее правило:
Теперь попробуем подключиться с SSL. Для этого достаточно установить параметр соединения sslmode=prefer (или require):
Трафик этого сеанса защищен. Аналогичную информацию дает и представление:
Page 16: Page 16
Поле cipher сообщает, что используется протокол TLS, применяется симметричное шифрование AES с длиной ключа 256 битов и другие подробности.
Page 17: Проверка сервера
Параметр sslmode библиотеки libpq
- verify-ca
- проверить, что сертификат сервера подписан
- доверенным ЦС
- verify-full
- также проверить, что доменное имя сервера
- соответствует имени в сертификате
- Расположение файла сертификата ЦС
- ~/.postgresql/root.crt
- параметр sslrootcert библиотеки libpq
- переменная окружения PGSSLROOTCERT
Комментарии преподавателя
Обращение к серверу не гарантирует, что соединение будет установлено именно с этим сервером: существуют атаки как на DNS (службу разрешения доменных имен), так и на коммутационное оборудование и маршрутизацию.
https://ru.wikipedia.org/wiki/DNS\_hijacking
Но, как мы говорили выше, клиент может проверить аутентичность сервера, получив его сертификат.
Возможны два вида проверки, которые выбираются параметром sslmode библиотеки libpq.
В первом случае (значение verify-ca) клиент проверяет подпись ЦС — такая проверка гарантирует, что сервер знаком центру сертификации. Для этого у клиента должен быть сертификат центра сертификации. Имя файла по умолчанию ~/.postgresql/root.crt, другое имя можно указать в параметре соединения sslrootcert или в переменной окружения PGSSLROOTCERT.
Во втором случае (verify-full) в дополнение к проверке подписи ЦС клиент проверяет, что доменное имя сервера, к которому он подключается, совпадает с доменным именем, указанным в сертификате.
Page 18: Проверка сервера
Каталог для клиентских сертификатов ~student/.postgresql уже существует в виртуальной машине и содержит сертификат центра сертификации, а также сертификаты для пользователей student, alice и bob — они понадобятся нам чуть позже:
Пробуем подключиться в режиме проверки сертификата ЦС, которым подписан сертификат сервера:
Обратите внимание, что мы подключились через loopback-интерфейс, которому соответствует имя localhost, хотя в сертификате сервера указано другое имя — course.local. Повторим эксперимент в режиме полной проверки:
На этот раз соединение запрещено, поскольку доменное имя в сертификате не совпадает с именем сервера. Теперь подключимся в режиме полной проверки, но используем то имя сервера, которое указано в сертификате:
Так все работает.
Page 19: Проверка клиента
Параметр clientcert любого метода аутентификации
- verify-ca
- проверить, что клиентский сертификат подписан
- доверенным ЦС
- verify-full
- также проверить, что имя пользователя БД
- соответствует имени в сертификате
- Метод аутентификации cert
- работает как trust и clientcert = verify-full
- Файл сопоставления имен pg_ident.conf
Комментарии преподавателя
Точно так же, как клиент проверяет сертификат сервера, сервер может запросить клиентский сертификат и проверить его.
https://postgrespro.ru/docs/postgresql/16/ssl-tcp#SSL-CLIENT-CERTIFICAT ES
Для этого в pg_hba.conf к обычному (например, парольному) методу аутентификации добавляется параметр clientcert:
● verify-ca — проверить только подпись ЦС;
● verify-full — проверить подпись ЦС и потребовать, чтобы имя пользователя БД совпадало с именем, указанным в сертификате.
Но в этом случае запрашивать пароль избыточно, ведь подлинность клиента удостоверяет само наличие сертификата. Поэтому обычно используется метод аутентификации cert, который подразумевает проверку уровня verify-full и не запрашивает пароль.
В обоих случаях требуется, чтобы соответствующая запись pg_hba.conf имела тип hostssl (просто host недостаточно).
https://postgrespro.ru/docs/postgresql/16/auth-cert
Если же имя клиента в сертификате отличается от имени пользователя базы данных, в файле pg_ident.conf можно указать сопоставление имен.
https://postgrespro.ru/docs/postgresql/16/auth-username-maps
Page 20: Проверка клиента
В предыдущих примерах клиент проверял сертификат сервера. Теперь посмотрим, как сервер может проверить сертификат клиента. Есть два способа: указать в строке pg_hba.conf параметр clientcert; использовать метод аутентификации cert. Опробуем второй вариант:
Заглянем в клиентский сертификат student:
Сертификат выдан на имя student (Subject CN). Попробуем подключиться от имени student.
Обратите внимание: клиентский сертификат предоставлен; показаны атрибуты, которые мы видели в сертификате. Метод cert позволяет подключиться к базе данных с именем пользователя, отличающимся от имени в сертификате. В этом случае понадобится дополнительный файл сопоставления имен:
И нужно указать имя отображения в параметре map строки конфигурации pg_hba:
Пробуем подключиться как student с сертификатом Алисы:
Page 21: Page 21
Все получилось.
Page 22: Итоги
Основные криптографические понятия: открытый и закрытый ключи, подпись, сертификат
- SSL применяется для защиты трафика и аутентификации
- Серверный сертификат удостоверяет аутентичность сервера
- Метод cert позволяет аутентифицировать пользователя по клиентскому сертификату
Page 23: Практика
- По аналогии с демонстрацией настройте сервер для возможности работы с SSL. 2. Проверьте, сколько времени занимает установка сетевого соединения с PostgreSQL: – без SSL, метод аутентификации trust; – с шифрованием SSL, метод аутентификации trust; – с аутентификацией по сертификату и проверкой сервера.
Комментарии преподавателя
- Используйте утилиту эталонного тестирования pgbench. С параметром –connect каждый запрос выполняется в отдельном соединении. В числе прочих показателей, утилита выводит усредненное время установки соединения.
https://postgrespro.ru/docs/postgresql/16/pgbench
Page 24: 1. Настройка SSL
Запишем в каталог /etc/postgresql/16/main/conf.d параметры конфигурации сервера для SSL. Настроим сервер для прослушивания всех интерфейсов.
Перезагрузим сервер.
2a. Соединение без SSL (trust)
Создадим конфигурационный файл аутентификации с методом trust для сетевых соединений:
Выполним инициализацию таблиц, которые используются эталонным тестом pgbench:
Запускаем эталонный тест на 30 секунд в режиме, при котором для каждой транзакции устанавливается новое соединение:
Note Внимание надо обратить на значение показателя average connection time.
Page 25: 2b. Соединение с шифрованием SSL (trust)
2c. Соединение с аутентификацией по сертификату и проверкой сервера.
Потребуется изменить настройку аутентификации:
В первом случае установка соединения происходит быстрее всего. Во втором случае добавляется время на обмен сообщениями между клиентом и сервером, в ходе которых они договариваются о режиме шифрования. В третьем случае установка соединения самая медленная, поскольку сервер дополнительно аутентифицирует клиента по сертификату. В нашем случае сетевые задержки сведены к минимуму, поскольку клиент и сервер находятся на одном компьютере. В реальности они вносят существенный вклад во время установки соединения.
Уборка
Page 26: Практика+
- По аналогии с демонстрацией настройте сервер для возможности работы с SSL. 2. Зарегистрируйте роль alice с правом подключения и паролем SECRET. 3. Проверьте, можно ли подсмотреть в трафике имя пользователя, пароль или команды SQL для следующих вариантов подключения пользователя alice: – без SSL, метод аутентификации password; – с SSL, метод аутентификации password; – без SSL, метод аутентификации scram-sha-256.
Комментарии преподавателя
- Для перехвата трафика используйте команду: sudo tcpdump -w ~/tmp/tcpdump.bin -i any “dst port 5432” >& ~/tmp/tcpdump.log &
Здесь ключ -w указывает файл для сохранения перехваченных пакетов, ключ -i указывает прослушиваемые интерфейсы. Далее в командной строке указано правило фильтрации перехватываемого трафика: порт назначения 5432. С помощью >& поток вывода и поток ошибок перенаправлены в файл отчета. Заключительный амперсанд указывает, что команда запускается в фоновом режиме.
Для завершения перехвата трафика необходимо остановить команду следующим образом: sudo killall tcpdump
Для просмотра сохраненного трафика можно выполнить команду: tcpdump -Aqr ~/tmp/tcpdump.bin 2> /dev/null
Перед очередным запуском не забывайте удалять файлы перехвата и отчета. Например, так: sudo rm -f ~/tmp/tcpdump.{bin,log}
Page 27: 1. Настройка SSL
Запишем в каталог /etc/postgresql/16/main/conf.d параметры конфигурации сервера для SSL. Настроим сервер для прослушивания всех интерфейсов.
Перезагрузим сервер.
2. Регистрация роли
3a. Без SSL, метод password
Создадим файл HBA с разрешением alice подключаться к базе данных student при успешной аутентификации методом password. SSL выключен.
Перечитаем конфигурацию.
Запустим перехват трафика, направленного на порт TCP 5432, на всех сетевых интерфейсах.
Выполним код SQL в сеансе alice, используя аутентификацию password при отсутствии шифрования.
Завершим перехват трафика после небольшой паузы.
Проверим, видны ли в трафике имена пользователей, пароли и команды:
Page 28: 3b. С SSL, метод password
В перехваченном трафике вся информация открыта. Теперь включим шифрование SSL.
Снова запустим перехват.
Проверим перехваченный трафик:
На этот раз ничего не выведено. Трафик зашифрован, подсмотреть конфиденциальную информацию не получится.
3c. Без SSL, метод scram-sha-256
Теперь повторим первый эксперимент, но с методом аутентификации scram-sha-256.
Page 29: Page 29
Запустим перехват.
Проверим перехваченный трафик:
Трафик не шифруется, но пароль в открытом виде не передается.