Как настроить Elasticsearch, чтобы не было утечек
За последний год возникало много утечек из баз Elasticsearch (вот, вот и вот). Во многих случаях в базе хранились персональные данные. Этих утечек можно было избежать, если бы после разворачивания базы администраторы потрудились проверить несколько несложных настроек. Сегодня о них и поговорим.
Сразу оговоримся, что в своей практике используем Elasticsearch для хранения логов и анализа журналов средств защиты информации, ОС и ПО в нашей IaaS-платформе, соответствующей требования 152-ФЗ, Cloud-152.
Проверяем, «не торчит» ли база в интернет
В большинстве известных случаев утечек (вот, вот) злоумышленник получил доступ к данным просто и незатейливо: база была опубликована в интернете, и к ней можно было подключиться без аутентификации.
Сначала разберемся с публикацией в интернете. Почему так получается? Дело в том, что для более гибкой работы Elasticsearch рекомендуется создавать кластер из трех серверов. Чтобы БД общались между собой, нужно открывать порты. В итоге администраторы никак не ограничивают доступ к базе, и к БД можно подключиться отовсюду. Проверить, нет ли к базе доступа извне, легко. Просто в браузере вводим http://[IP/Имя Elasticsearch]:9200/_cat/nodes? v
Если получается зайти, значит бегом закрывать.
Защищаем подключение к БД
Теперь сделаем так, чтобы к базе нельзя было подключиться без аутентификации.
У Elasticsearch есть модуль аутентификации, который ограничивает доступ к базе, но он только в платном наборе плагинов X-Pack (1 месяц бесплатного использования).
Хорошие новости в том, что осенью 2019 года Amazon открыл свои наработки, которые пересекаются с X-Pack. Функция аутентификации при подключении к базе стала доступна под свободной лицензией для версии Elasticsearch 7.3.2., и уже в работе новый релиз для Elasticsearch 7.4.0.
Устанавливается этот плагин просто. Заходим в консоль сервера и подключаем репозиторий:
RPM Based:
curl d3g5vo6xdbdb9a.cloudfront.net/yum/opendistroforelasticsearch-artifacts.repo -o /etc/yum.repos.d/opendistroforelasticsearch-artifacts.repo
yum update
yum install opendistro-security
DEB Based:
wget -qO ‐ d3g5vo6xdbdb9a.cloudfront.net/GPG-KEY-opendistroforelasticsearch | sudo apt-key add -
Настраиваем взаимодействие между серверами через SSL
При установке плагина меняется конфигурация порта подключения к базе. На нем включается шифрование SSL. Чтобы сервера кластера смогли и дальше друг с другом работать, нужно настроить взаимодействие между ними с помощью SSL.
Доверие между хостами можно установить с помощью собственного удостоверяющего центра или без него. С первым способом все понятно: просто нужно обратиться к специалистам по CA. Перейдем сразу ко второму.
- Создаем переменную с полным именем домена:
export DOMAIN_CN=«example.com» - Создаем приватный ключ:
openssl genrsa -out root-ca-key.pem 4096 - Подписываем корневой сертификат. Храните его как зеницу ока: при его утере или компрометации доверие между всеми хостами нужно будет перенастраивать.
openssl req -new -x509 -sha256 \
-subj »/C=RU/ST=Moscow/O=Moscow, Inc./CN=${DOMAIN_CN}» \
-key root-ca-key.pem -out root-ca.pem - Создаем ключ администратора:
openssl genrsa -out admin-key-temp.pem 4096
openssl pkcs8 -inform PEM -outform PEM -in admin-key-temp.pem \
-topk8 -nocrypt -v1 PBE-SHA1–3DES -out admin-key.pem - Создаем запрос для подписи сертификата:
openssl req -new -subj »/C=RU/ST=Moscow/O=Moscow
Inc./CN=${DOMAIN_CN}/CN=admin » \
-key admin-key.pem -out admin.csr - Создаем сертификат администратора:
openssl x509 -req -extensions usr_cert -in admin.csr \
-CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out admin.pem - Создаем сертификаты для ноды Elasticsearch:
export NODENAME=«node-01»
openssl genrsa -out ${NODENAME}-key-temp.pem 4096
openssl pkcs8 -inform PEM -outform PEM -in ${NODENAME}-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1–3DES -out ${NODENAME}-key.pem - Создаем запрос на подпись:
openssl req -new -subj »/C=RU/ST=Moscow/O=Moscow
Inc./CN=${NODENAME}.${DOMAIN_CN}» -addext
«subjectAltName=DNS:${NODENAME}.${DOMAIN_CN}, DNS: www.${NODENAME}.${DOMAIN_CN}» -key ${NODENAME}-key.pem -out ${NODENAME}.csr - Подписываем сертификат:
openssl x509 -req -in node.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out node.pem - Раскладываем сертификат между нодами Elasticsearch в папку:
/etc/elasticsearch/
нам понадобятся:
node-01-key.pem
node-01.pem
admin-key.pem
admin.pem
root-ca.pem - Настраиваем /etc/elasticsearch/elasticsearch.yml — меняем название файлов с сертификатами, на сгенерированные нами:
opendistro_security.ssl.transport.pemcert_filepath: node-01.pem
opendistro_security.ssl.transport.pemkey_filepath: node-01-key.pem
opendistro_security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
opendistro_security.ssl.transport.enforce_hostname_verification: false
opendistro_security.ssl.http.enabled: true
opendistro_security.ssl.http.pemcert_filepath: node-01.pem
opendistro_security.ssl.http.pemkey_filepath: node-01-key.pem
opendistro_security.ssl.http.pemtrustedcas_filepath: root-ca.pem
opendistro_security.allow_unsafe_democertificates: false
opendistro_security.allow_default_init_securityindex: true
opendistro_security.authcz.admin_dn:
− CN=admin, CN=example.com, O=Moscow Inc., ST=Moscow, C=RU
opendistro_security.nodes_dn:
− CN=node-01.example.com, O=Moscow Inc., ST=Moscow, C=RU
Меняем пароли внутренних пользователей
- С помощью команды ниже выводим в консоль хеш пароля:
sh ${OD_SEC}/tools/hash.sh -p [пароль] - Меняем хеш в файле на полученный: /usr/share/elasticsearch/plugins/opendistro_security/securityconfig/internal_users.yml
Настраиваем межсетевой экран в ОС
- Разрешаем запуск межсетевого экрана:
systemctl enable firewalld - Запускаем его:
systemctl start firewalld - Разрешаем подключение к Elasticsearch:
firewall-cmd --set-default-zone work
firewall-cmd --zone=work --add-port=9200/TCP --permanent - Перезагружаем правила межсетевого экрана:
firewall-cmd --reload - Выводим работающие правила:
firewall-cmd --list-all
Применяем все наши изменения к Elasticsearch
- Создаем переменную с полным путем до папки с плагином:
OD_SEC=»/usr/share/elasticsearch/plugins/opendistro_security/» - Запускаем скрипт, который обновит пароли и проверит настройки:
${OD_SEC}/tools/securityadmin.sh -cd ${OD_SEC}/securityconfig/ \
-icl -nhnv -cacert /etc/elasticsearch/root-ca.pem \
-cert /etc/elasticsearch/admin.pem -key
/etc/elasticsearch/admin-key.pem - Проверяем, применились ли изменения:
curl -XGET https://[IP/Имя Elasticsearch]:9200/_cat/nodes? v -u admin:[пароль] --insecure
Все, это минимальные настройки, которые закрывают Elasticsearch от неавторизованного подключения.