Truststore keystore что это
Определения Truststore и Keystore
В чем разница между хранилищем ключей и хранилищем доверенных сертификатов?
Хранилище ключей содержит закрытые ключи и сертификаты с соответствующими им открытыми ключами.
Склад доверенных сертификатов содержит сертификаты от других сторон, с которыми вы собираетесь общаться, или от центров сертификации, которым вы доверяете для идентификации других сторон.
Хранилище ключей содержит закрытые ключи. Это необходимо только в том случае, если вы являетесь сервером или если сервер требует аутентификации клиента.
Склад доверенных сертификатов содержит сертификаты CA для доверия. Если сертификат вашего сервера подписан распознанным центром сертификации, хранилище доверенных сертификатов по умолчанию, которое поставляется вместе с JRE, уже будет доверять ему (потому что оно уже доверяет надежным центрам сертификации), поэтому вам не нужно создавать собственный или добавлять что-либо к нему. от JRE.
KeyStore
keyStore в Java хранит закрытый ключ и сертификаты, соответствующие их открытым ключам, и требует, если вы являетесь сервером SSL или SSL требует аутентификации клиента.
доверенные сертификаты
TrustStore хранит сертификаты от третьих лиц, ваше Java-приложение или сертификаты, подписанные CA (центрами сертификации, такими как Verisign, Thawte, Geotrust или GoDaddy), которые можно использовать для идентификации третьих лиц.
TrustManager
TrustManager определяет, следует ли доверять удаленному соединению, т. Е. Является ли удаленная сторона тем, на кого она претендует, и KeyManager решает, какие учетные данные для аутентификации следует отправить на удаленный хост для аутентификации во время SSL-квитирования.
Вас также может заинтересовать рецензия от Sun как часть стандартной документации JSSE:
Как правило, хранилище доверенных сертификатов используется для хранения только открытых ключей в целях проверки, например, при проверке подлинности X.509. Для удобства управления администраторы и разработчики часто просто объединяют их в одном магазине.
В Java, в чем разница между хранилищем ключей и хранилищем доверенных сертификатов?
Хранилище ключей / доверенное хранилище
Вообще говоря, информация о хранилище ключей может быть сгруппирована в две категории: записи ключей и записи доверенных сертификатов. Запись ключа состоит из идентификатора объекта и его закрытого ключа и может использоваться для различных криптографических целей. Напротив, запись доверенного сертификата содержит только открытый ключ в дополнение к идентификатору объекта. Таким образом, запись доверенного сертификата не может использоваться там, где требуется закрытый ключ, например, в javax.net.ssl.KeyManager. В реализации JKS JDK хранилище ключей может содержать как записи ключей, так и записи доверенных сертификатов.
Запись должна быть добавлена в доверенное хранилище, только если пользователь доверяет этой сущности. Генерируя пару ключей или импортируя сертификат, пользователь доверяет этой записи. Любая запись в хранилище доверенных сертификатов считается доверенной.
Первое и основное различие между trustStore и keyStore заключается в том, что trustStore используется TrustManager, чтобы определить, следует ли доверять удаленному соединению, keyStore используется из KeyManager, решая, какие учетные данные для аутентификации следует отправлять на удаленный хост для аутентификации во время рукопожатия SSL.
Другое отличие состоит в том, что keyStore теоретически содержит закрытые ключи, необходимые только в том случае, если вы запускаете сервер в соединении SSL или вы включили аутентификацию клиента на стороне сервера, а с другой стороны trustStore хранит открытый ключ или сертификаты от CA (Certificate Authorities), которые используются для доверяйте удаленной стороне или соединению SSL.
Изучаем ELK. Часть III — Безопасность
Вступительное слово
В первой и второй частях данной серии статей была описана процедура установки и настройки кластера Elasticsearch, Kibana и Logstash, но не был освящен вопрос безопасности.
В этой статье я расскажу, как настроить шифрование трафика между узлами кластера Elasticsearch и его клиентам, шифрование трафика между Kibana и клиентами, покажу, как создавать роли и пользователей, а так же выдавать API ключи для доступа к кластеру Elasticsearch.
План действий
«Включаем» безопасность
Чтобы использовать функции безопасности в Elasticsearch, их необходимо активировать. Для этого на каждом узле в файле конфигурации указывается следующая настройка:
Настраиваем шифрование между узлами Elasticsearch
Следующим шагом необходимо настроить шифрование трафика между узлами Elasticsearch. Для этого выполняем несколько шагов:
Создаем CA (Certificate Authority) для кластера Elasticsearch:
Во время генерации корневого сертификата можно задать имя PKCS#12 файла, по умолчанию это elastic-stack-ca.p12 и пароль к нему.
Полученный корневой сертификат (для PEM формата еще и ключ) надо переместить на все узлы кластера для генерации сертификата узла.
Генерируем на каждом узле кластера сертификат и ключ:
Включаем TLS в файле конфигурации Elasticsearch:
Если сертификаты CA и/или узла в формате PEM, то необходимо изменить последние два параметра на следующие:
Cоздаем keystore и добавляем пароли от сертификатов(если они были заданы):
Для PKCS#12 формата:
Для PEM сертификата:
В логах Elasticsearch должны появится записи о создании кластера:
Если обратиться к API, то будет ошибка «missing authentication credentials for REST request». С момента включения функций безопасности для обращения к кластер необходимо пройти аутентификацию.
Настраиваем аутентификацию
Elasticsearch имеет несколько встроенных пользователей:
Пользователь
Описание
Используется для коммуникации между Kibana и Elasticsearch
Пользователь, которого использует Logstash сервер, когда сохраняет информацию в Elasticsearch
Пользователь, которого использует агент Beats, когда сохраняет информацию в Elasticsearch
Пользователь, которого использует APM сервер, когда сохраняет информацию в Elasticsearch
Пользователь Metricbeat, который используется при сборе и хранении информации мониторинга в Elasticsearch
Второй раз elasticsearch-setup-passwords запустить не получится, так как bootstrap password изменился. Чтобы изменить пароль пользователям можно воспользоваться API.
Попробуем сделать API запрос к любому узлу Elasticsearch с использованием учетной записи elastic и пароля к от неё:
Настраиваем шифрование клиентского трафика Elasticsearch
Для шифрования клиентского трафика необходимо выпустить сертификат, который будет использоваться для шифрования трафика между узлом Elasticsearch и клиентом. При этом для Kibana будет сформирован отдельный сертификат, чтобы настроить соединение с Elasticsearch. Для этого делаем следующее:
В процессе генерации необходимо определить:
1) Необходимо ли сгенерировать Certificate Signing Request (CSR). Потребуется, если сертификат будет выпускаться сторонним CA (Certificate Authority).
2) Использовать ли собственный CA (Certificate Authority). Если да, то указываем путь до ключа, которым будет подписаны будущие сертификаты.
3) Срок действия сертификата. По умолчанию 5 лет. Можно определить дни(D), месяцы (M), года (Y).
4) Как выпустить сертификат, на каждый узел или общий. Если все узлы имеют общий домен, то можно выпустить wildcard сертификат (например *.domain.local). Если общего домена нет и в будущем возможно добавление узлов, то необходимо генерировать на каждый узел, указав имя узла и его адрес. В будущем можно выпустить отдельный сертификат для нового узла.
На выходе получаем архив сертификатами, в моём случае со всеми сертификатам для каждого узла Elasticsearch, а так же сертификат для подключения Kibana к Elasticsearch:
В архиве также лежит инструкция по дальнейшим действиям с сертификатом (README.txt) и пример конфигурационного файла (sample-. yml).
Сертификат elasticsearch-ca.pem из директории kibana потребуется в следующем шаге.
Размещаем сертификаты на узлах и добавляем необходимые настройки в файле конфигурации:
Добавляем пароль от сгенерированного сертификата в keystore:
Проверяем, что все работает по https :
Подключаем Kibana к Elasticsearch
Если сейчас обратиться к Kibana, то ответом будет «Kibana server is not ready yet«.
В конфигурационном файле Kibana указываем ключ к сертификату elasticsearch-ca.pem (из предыдущего шага) и меняем протокол http на https :
В примере выше я использую адрес Coordinating only узла для балансировки нагрузки между Kibana и Elasticsearch, который был настроен в предыдущей части.
Создаем keystore для хранения пользователя и пароля:
Команда выполняются из директории /usr/share/kibana
Kibana keystore не имеет пароля. Для ограничения доступа используем стандартные средства Linux.
Добавляем пользователя kibana_system(встроенный пользователь Elasticsearch) и пароль учетной записи в Kibana keystore:
Можно использовать так же пользователя kibana, однако, он в системе считается устаревшим (deprecated).
перезапускаем Kibana и проверяем открыв нужный адрес в браузере:
Kibana
Для входа используем учетную запись elastic.
Как можно заменить, трафик между браузером и Kibana не шифруется.
Настраиваем шифрование трафика между Kibana и клиентами
Данная процедура максимально похожа на ту, которую выполняли для получения сертификатов для узлов Elasticsearch.
Получаем сертификат при помощи elsticsearch-certutil :
При необходимости можем использовать CA (Certificate Authority). В процессе генерации сертификата указываем пароль от CA, если используется, имя будущего сертификата и пароль к нему.
Указываем путь к сертификату в файле kibana.yml :
Так как я использовал ранее полученный CA, то указываю путь и к нему ( server.ssl.truststore.path ).
Не забывайте о правах доступа, пользователь kibana должен иметь права на чтения.
Включаем использование TLS:
Добавляем пароли от сертификатов в keystore:
Перезагружаем Kibana и проверяем:
Доступ к Kibana по https
Создаем пользователей и роли
Ранее мы активировали встроенные учетные записи и сгенерировали для них пароли, но использовать пользователя elastic (superuser) не лучшая практика, поэтому рассмотрим, как создавать пользователей и роли к ним.
Для примера создадим администратора Kibana. Открываем Menu > Management > Stack Management, выбираем Users и нажимаем Create user. Заполняем все поля и жмем Create User.
Создание пользователя в Kibana
Или же можно воспользоваться API. Делать запросы к кластеру можно через консоль Dev Tools инструмента Kibana. Для этого перейдите Menu > Management > Dev Tools. В открывшейся консоли можно писать запросы к Elasticsearch.
Создание пользователя kibana_admin через API
После создания пользователя, можно его использовать.
Далее создадим роль для работы с данными в ранее созданном индексом logstash-logs*. Открываем Menu > Management > Stack Management. Слева выбираем Roles и нажимаем Create role. Настраиваем привилегии, указав в качестве индекса logstash-logs*:
Index privileges
Read only права на индекс
Предоставляем пользователю доступ к Kibana, для этого ниже наживаем Add Kibana privilege и выбираем требуемые привилегии:
В поле Spaces указываю All spaces. Что такое Space (пространства) можно почитать на официальном сайте. В рамках данной серии статей Space будет описан в статье о Kibana dashboard.
Чтобы создать роль с привилегиями в Elasticsearch и Kibana через API, делаем запрос к Kibana:
Создаем пользователя logstash_reader и связываем его с созданной ролью (это мы уже научились делать) и заходим данным пользователем в Kibana.
Главная страница Kibana для пользователя logstash_reader
Как видно, у данного пользователя не так много прав. Он может просматривать индексы logstash-logs*, строить графики, создавать панели и делать GET запросы к этому индексам через Dev Tools.
Настраиваем пользовательские сессии Kibana
Закрываем неактивные сессии:
Устанавливаем максимальную продолжительность одной сессии:
Настраиваем интервал принудительной очистки данных о неактивных или просроченных сессиях из сессионного индекса:
Для всех параметров формат времени может быть следующим: ms | s | m | h | d | w | M | Y
Данные о сессии удаляются после того, как пользователь осуществляет закрытие сессии. Если не настроить закрытие неактивных сессий или не ограничить максимальную длительность сессии, то информация об этих сессиях будет накапливаться в сессионном индексе, и Kibana не сможет автоматически удалить данные.
Настраиваем Logstash
На данный момент Logstash не отправляет данные в кластер Elasticsearch, и чтобы это исправить, сделаем несколько настроек.
Создаем роль для подключения к кластеру:
В Kibana открываем Menu > Management > Stack Management. Слева выбираем Roles и нажимаем Create role. Указываем имя роли и настраиваем привелегии:
Cluster privileges
Все операции над шаблонами индексов
Read-only права на получение информации о кластере
Index privileges
Индексирование, обновление и удаление индексов
Мониторинг и управление индексом
Управление жизненным циклом индексов (IML)
Создаем пользователя для подключения к кластер:
Открываем Menu > Management > Stack Management, выбираем Users и нажимаем Create user. Заполняем требуемые данные, указав в качестве роли созданную выше роль.
Создание пользователя logstash_user
Создаем Logstash keystore, и добавляем туда пользователя и пароль от него:
Настраиваем аутентификацию в output плагине:
Настраиваем TLS в Logstash:
Перезагружаем Logstash и проверяем новые записи в индексе
Проверку можно сделать в Kibana через Discovery, как делали в прошлой статье, или через API:
Создание API ключей
Для работы с Elasticsearch можно не только использовать учетные записи пользователей, но и генерировать API ключ. Для этого необходимо сделать POST запрос:
В качестве параметров указывают:
Для примера заменим базовую аутентификацию в Logstash на API ключ.
Создаем API ключ в Kibana Dev Tool:
Получаем следующий результат:
Помещаем ключ в формате id:api_key в Keystore:
Указываем API ключ в конфигурационном файле конвейера:
Информацию по ключам можно получить в Kibana Menu > Management > API Keys или через API запрос:
Заключение
В рамках данной статьи были рассмотрены основные функции безопасности стека Elastic, позволяющие обезопасить работу нашего кластера, научились создавать пользователей и пользовательские роли, производить настройку пользовательских сессий, настройку шифрования трафика между узлами кластера и между кластером и клиентами, работать с API ключами и keystore.
В следующей статье будет рассмотрена процедура создание кластера ELK с помощью Docker.
Простая настройка взаимной проверки подлинности клиента и сервера с использованием TLS
Это руководство посвящено настройке защиты приложений с помощью TLS-аутентификации. При таком подходе возможность работы пользователей с приложением зависит от имеющихся у них сертификатов. То есть — разработчик может самостоятельно принимать решения о том, каким пользователям разрешено обращаться к приложению.
В учебном проекте, который будет здесь разобран, показаны основные настройки сервера и клиента. Их взаимодействие изначально осуществляется посредством HTTP. А это значит, что данные между ними передаются в незашифрованном виде. Наша задача заключается в том, чтобы обеспечить шифрование всего того, чем обмениваются клиент и сервер.
Мы рассмотрим следующие вопросы:
1. Запуск сервера
Для того чтобы организовать работу сервера — нам понадобится следующее:
В данном проекте содержится Maven-обёртка, поэтому запустить его можно и не устанавливая Maven. Тут будут приведены сведения и о стандартных командах, рассчитанных на mvn, и о командах, ориентированных на использование Maven-обёртки.
Если вы хотите запустить этот проект с использованием Java 8 — вы можете переключиться на более старую его версию с использованием нижеприведённой команды.
При работе с этой версией проекта рекомендовано следовать инструкциям, подготовленным специально для него. Найти их можно здесь.
Сервер можно привести в рабочее состояние, вызвав метод main класса App или выполнив следующую команду в корневой директории проекта:
Вот команда, рассчитанная на Maven-обёртку:
2. Отправка приветствия серверу (без шифрования)
Ответ должен выглядеть примерно так:
В клиенте реализован интеграционный тест, основанный на Cucumber. Его можно запустить, обратившись к классу ClientRunnerIT из IDE, или выполнив в корневой директории следующую команду:
При использовании Maven-обёртки это будет такая команда:
Тут имеется файл Hello.feature, который описывает шаги интеграционного теста. Этот файл можно найти в папке ресурсов теста клиентского проекта.
Есть и другой метод запуска и клиента, и сервера. Он представлен следующей командой, выполняемой в корневой директории проекта:
Вариант этой команды для Maven-обёртки выглядит так:
3. Включение HTTPS на сервере (односторонний TLS)
Речь идёт о следующих настройках:
Для того чтобы вышеописанные настройки вступили в силу — сервер надо перезапустить. Возможно, при этом вы увидите следующее исключение:
Причина его появления заключается в том, что серверу, для установки защищённого соединения с внешними сущностями, нужно хранилище ключей с сертификатом сервера. Сервер может предоставить более подробную информацию об этом в том случае, если воспользоваться следующими аргументами VM:
Для того решения этой проблемы нужно создать хранилище ключей, содержащее открытый и закрытый ключи для сервера. Открытый ключ будет передаваться пользователям. Так они смогут зашифровать данные, передаваемые серверу. Зашифрованные данные могут быть расшифрованы с использованием закрытого ключа сервера. Закрытый ключ сервера нельзя никому передавать, так как, имея этот ключ, злоумышленник может перехватить зашифрованные данные, которыми обмениваются клиент и сервер, и расшифровать их.
Создать хранилище ключей с открытым и закрытым ключами можно с помощью следующей команды:
Теперь нужно сообщить серверу о том, где именно находится хранилище ключей, и указать пароли. Сделаем это, отредактировав наш файл application.yml :
Замечательно! Только что мы настроили TLS-шифрование соединений между сервером и клиентом! Испытать сервер можно так:
Клиент можно запустить и прибегнув к классу ClientRunnerIT.
В результате можно будет увидеть следующее сообщение:
И приведём её к такому виду:
Попробуем снова запустить клиент. Это приведёт к выдаче такого сообщения:
Дело тут в том, что клиент собирается наладить обмен данными по HTTPS. Он, при выполнении процедуры рукопожатия, получает сертификат сервера, который он пока не может распознать. А это значит, что нам ещё нужно создать хранилище TrustStore. В таких хранилищах находятся доверенные сертификаты. Клиент сопоставляет то, что он получает в ходе процедуры рукопожатия, с тем, что есть в TrustStore. Если полученный им сертификат входит в список доверенных сертификатов — процедура продолжается. А прежде чем создавать TrustStore — нужно обзавестись сертификатом сервера.
Экспортировать сертификат сервера можно такой командой:
Теперь можно создать TrustStore для клиента и импортировать туда сертификат сервера такой командой:
TrustStore для клиента мы создали, но сам клиент пока об этом не знает. А это значит, что клиенту надо сообщить о том, что ему следует пользоваться TrustStore, указав адрес хранилища и пароль. Клиенту надо сообщить и о том, что включена аутентификация. Всё это делается путём приведения файла application.yml клиентского приложения к такому виду:
4. Аутентификация клиента (двусторонний TLS)
Приведём файл сервера application.yml к такому виду:
Если после этого запустить клиент, то он выдаст следующее сообщение об ошибке:
Это указывает на то, что клиент не обладает подходящим сертификатом. Точнее — у клиента пока вообще нет сертификата. Поэтому создадим сертификат следующей командой:
Нам ещё нужно создать TrustStore для сервера. Но, прежде чем создавать это хранилище, нужно иметь сертификат клиента. Экспортировать его можно так:
Теперь создадим TrustStore сервера, в котором будет сертификат клиента:
Мы создали для клиента дополнительное хранилище ключей, но клиент об этом не знает. Сообщим ему сведения об этом хранилище. Кроме того, клиенту нужно сообщить о том, что включена двусторонняя аутентификация.
Приведём файл application.yml клиента к такому виду:
Сервер тоже не знает о только что созданном для него TrustStore. Приведём его файл application.yml к такому виду:
Если снова запустить клиент — можно будет убедиться в том, что тест завершается успешно, и что клиент получает данные от сервера в защищённом виде.
Примите поздравления! Только что вы настроили двусторонний TLS!
5. Установление двустороннего TLS-соединения с использованием доверенного удостоверяющего центра
Есть и другой способ организации двусторонней аутентификации. Он основан на использовании доверенного удостоверяющего центра. У такого подхода есть сильные и слабые стороны.
1. Создание удостоверяющего центра
Обычно работают с уже существующими удостоверяющими центрами, которым, для подписи, нужно передавать сертификаты. Здесь же мы создадим собственный удостоверяющий центр и подпишем с его помощью сертификаты клиента и сервера. Для создания удостоверяющего центра воспользуемся такой командой:
Ещё можно воспользоваться существующим удостоверяющим центром.
2. Создание файла запроса на подпись сертификата
Вот её вариант для сервера:
Вот — эта команда для клиента:
Такой файл нужен удостоверяющему центру для подписи сертификата. Следующий шаг нашей работы заключается в подписании сертификата.
3. Подписание сертификата с помощью запроса на подпись сертификата
Вот соответствующая команда для клиента:
Вот команда для сервера:
4. Замена неподписанного сертификата подписанным
Экспортируем подписанный сертификат:
Выполним на клиенте следующие команды:
На сервере выполним такие команды:
5. Организация взаимодействия клиента и сервера, основанного исключительно на доверии к удостоверяющему центру
Теперь нужно настроить клиент и сервер так, чтобы они доверяли бы только удостоверяющему центру. Сделать это можно, импортировав сертификат удостоверяющего центра в хранилища TrustStore клиента и сервера.
Сделаем это, выполнив на клиенте следующую команду:
На сервере выполним такую команду:
В хранилищах TrustStore всё ещё хранятся собственные сертификаты клиента и сервера. Эти сертификаты нужно удалить.
Выполним на клиенте такую команду:
Вот — команда для сервера:
Если снова запустить клиент — можно видеть успешное прохождение теста. А это значит, что клиент и сервер успешно обмениваются данными, используя сертификаты, подписанные удостоверяющим центром.
6. Автоматизация различных подходов к аутентификации
Всё, о чём мы говорили выше, можно автоматизировать с помощью скриптов, которые находятся в папке script рассматриваемого нами проекта. Для запуска скриптов можете воспользоваться следующими командами:
Протестированные клиенты
Ниже приведён список протестированных клиентов. Настройки для HTTP-клиента, написанного на чистом Java, можно найти в классе ClientConfig. В директории service нашего проекта содержатся отдельные HTTP-клиенты, выполняющие демонстрационные запросы. Настройки HTTP-клиентов, основанных на Kotlin и Scala, включены в состав проекта в виде вложенных классов. Все примеры клиентов используют одну и ту же базовую конфигурацию SSL, созданную в классе SSLConfig.