Другое

Полное руководство: исправление ошибки конфигурации SSL в Cassandra с PEMBasedSslContextFactory

Узнайте, как исправить ошибку 'Must provide outbound_keystore or outbound_private_key' в конфигурации SSL Cassandra. Полное руководство по правильной настройке PEMBasedSslContextFactory для шифрования клиент-сервер.

Настройка Cassandra с PEMBasedSslContextFactory: ошибка конфигурации SSL

Я пытаюсь настроить шифрование “клиент-сервер” для Cassandra с использованием PEMBasedSslContextFactory, но столкнулся с ошибкой конфигурации SSL. Следуя официальной документации по адресу https://cassandra.apache.org/doc/stable/cassandra/managing/operating/security.html#using-pem-based-key-material, я настроил параметры следующим образом:

yaml
client_encryption_options:
  ssl_context_factory:
    class_name: org.apache.cassandra.security.PEMBasedSslContextFactory
  keystore: /etc/letsencrypt/live/example.com/combined.pem
  truststore: /etc/letsencrypt/live/example.com/chain.pem
  enabled: True
  require_client_auth: False
  optional: false

Файл combined.pem содержит fullchain и приватный ключ в указанном порядке. Однако при запуске Cassandra я получаю следующую ошибку:

ERROR [main] 2025-11-08 09:43:19,527 CassandraDaemon.java:887 - Exception encountered during startup
org.apache.cassandra.exceptions.ConfigurationException: Failed to initialize SSL
    at org.apache.cassandra.config.DatabaseDescriptor.applySslContext(DatabaseDescriptor.java:1283)
    at org.apache.cassandra.config.DatabaseDescriptor.applyAll(DatabaseDescriptor.java:468)
    at org.apache.cassandra.config.DatabaseDescriptor.daemonInitialization(DatabaseDescriptor.java:262)
    at org.apache.cassandra.config.DatabaseDescriptor.daemonInitialization(DatabaseDescriptor.java:246)
    at org.apache.cassandra.service.CassandraDaemon.applyConfig(CassandraDaemon.java:780)
    at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:723)
    at org.apache.cassandra.service.CassandraDaemon.main(CassandraDaemon.java:865)
Caused by: java.io.IOException: Failed to create SSL context using Native transport
    at org.apache.cassandra.security.SSLFactory.validateSslContext(SSLFactory.java:414)
    at org.apache.cassandra.config.DatabaseDescriptor.applySslContext(DatabaseDescriptor.java:1278)
    ... 6 common frames omitted
Caused by: javax.net.ssl.SSLException: Failed to build key manager store for secure connections
    at org.apache.cassandra.security.PEMBasedSslContextFactory.buildKeyManagerFactory(PEMBasedSslContextFactory.java:261)
    at org.apache.cassandra.security.PEMBasedSslContextFactory.buildKeyManagerFactory(PEMBasedSslContextFactory.java:223)
    at org.apache.cassandra.security.AbstractSslContextFactory.createNettySslContext(AbstractSslContextFactory.java:186)
    at org.apache.cassandra.security.SSLFactory.createNettySslContext(SSLFactory.java:170)
    at org.apache.cassandra.security.SSLFactory.validateSslContext(SSLFactory.java:364)
    ... 7 common frames omitted
Caused by: javax.net.ssl.SSLException: Must provide outbound_keystore or outbound_private_key in configuration for PEMBasedSSlContextFactory
    at org.apache.cassandra.security.PEMBasedSslContextFactory.buildKeyManagerFactory(PEMBasedSslContextFactory.java:256)
    ... 11 common frames omitted

Ошибка указывает на то, что мне необходимо предоставить либо outbound_keystore, либо outbound_private_key в конфигурации. Однако, когда я пытаюсь добавить эти параметры либо в параметры класса ssl_context_factory, либо в секцию client_encryption_options, Cassandra выдает ошибку, говоря, что эти параметры не должны там присутствовать и должны быть удалены.

Что я упускаю в своей конфигурации SSL для Cassandra с использованием PEMBasedSslContextFactory? Как можно исправить эту ошибку и правильно настроить шифрование “клиент-сервер”?

Ошибка, с которой вы столкнулись, является распространенной проблемой конфигурации с PEMBasedSslContextFactory в Cassandra. Проблема заключается в том, что параметры outbound_keystore и outbound_private_key должны быть размещены именно в секции конфигурации ssl_context_factory, а не в основном блоке client_encryption_options.

Ключ к решению этой ошибки - понимание того, что конфигурация SSL на основе PEM в Cassandra требует специфической структуры параметров, которая отличается от традиционного подхода с использованием хранилища ключей (keystore).

Содержание

Правильная конфигурация PEMBasedSslContextFactory

Для решения ошибки необходимо перестроить вашу YAML-конфигурацию, чтобы правильно разместить исходящие параметры в секции ssl_context_factory. Вот правильная структура:

yaml
client_encryption_options:
  enabled: True
  require_client_auth: False
  optional: false
  ssl_context_factory:
    class_name: org.apache.cassandra.security.PEMBasedSslContextFactory
    outbound_keystore: /etc/letsencrypt/live/example.com/combined.pem
    outbound_private_key: /etc/letsencrypt/live/example.com/privkey.pem
  keystore: /etc/letsencrypt/live/example.com/combined.pem
  truststore: /etc/letsencrypt/live/example.com/chain.pem

Ключевое отличие заключается в том, что outbound_keystore и outbound_private_key теперь находятся с отступом под ssl_context_factory, что делает их параметрами, специфичными для класса, а не общими параметрами шифрования.

Понимание структуры параметров

Конфигурация SSL в Cassandra имеет две различные области параметров:

  1. Уровень параметров шифрования клиента - keystore, truststore, enabled, require_client_auth, optional
  2. Уровень фабрики контекста SSL - outbound_keystore, outbound_private_key, class_name

Сообщение об ошибке “Must provide outbound_keystore or outbound_private_key in configuration for PEMBasedSSlContextFactory” указывает на то, что эти параметры должны быть связаны с конкретным классом фабрики контекста SSL, а не с общими параметрами шифрования.

Вот почему это различие важно:

yaml
# Неправильно - параметры на неправильном уровне
client_encryption_options:
  outbound_keystore: /path/to.pem  # ❌ Должно быть под ssl_context_factory
  ssl_context_factory:
    class_name: org.apache.cassandra.security.PEMBasedSslContextFactory

# Правильно - параметры на правильном уровне
client_encryption_options:
  ssl_context_factory:
    class_name: org.apache.cassandra.security.PEMBasedSslContextFactory
    outbound_keystore: /path/to.pem  # ✌️ Правильное размещение

Требования к структуре файлов

Ваша структура PEM-файлов должна быть правильной для работы конфигурации. Исходя из вашего описания, у вас есть:

  • combined.pem - содержит полный цепочку и закрытый ключ
  • chain.pem - содержит цепочку сертификатов
  • privkey.pem - содержит закрытый ключ (отдельно)

Для подхода с outbound_keystore убедитесь, что ваш файл combined.pem имеет следующую структуру:

pem
-----BEGIN CERTIFICATE-----
# Ваш сертификат сервера
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
# Промежуточные сертификаты (если есть)
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
# Ваш закрытый ключ
-----END PRIVATE KEY-----

Альтернативно, если вы используете отдельные файлы:

yaml
ssl_context_factory:
  class_name: org.apache.cassandra.security.PEMBasedSslContextFactory
  outbound_keystore: /etc/letsencrypt/live/example.com/fullchain.pem
  outbound_private_key: /etc/letsencrypt/live/example.com/privkey.pem

Полный пример рабочей конфигурации

Вот полный, рабочий пример конфигурации:

yaml
client_encryption_options:
  enabled: true
  require_client_auth: false
  optional: false
  ssl_context_factory:
    class_name: org.apache.cassandra.security.PEMBasedSslContextFactory
    outbound_keystore: /etc/letsencrypt/live/example.com/combined.pem
  keystore: /etc/letsencrypt/live/example.com/combined.pem
  truststore: /etc/letsencrypt/live/example.com/chain.pem
  protocol: TLS
  cipher_suites: [TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
  enabled_algorithms: [TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]

Ключевые моменты в этой конфигурации:

  • Параметр outbound_keystore правильно размещен под ssl_context_factory
  • И keystore, и truststore остаются на уровне параметров шифрования клиента
  • Дополнительные параметры SSL, такие как protocol и cipher_suites, могут быть добавлены по необходимости

Устранение распространенных проблем

1. Проблемы с правами доступа к файлам

Убедитесь, что Cassandra может читать ваши PEM-файлы:

bash
# Установка соответствующих прав доступа
sudo chmod 644 /etc/letsencrypt/live/example.com/*.pem
sudo chown cassandra:cassandra /etc/letsencrypt/live/example.com/*.pem

2. Проверка формата PEM-файлов

Проверьте ваши PEM-файлы с помощью OpenSSL:

bash
# Проверка сертификата
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -text -noout

# Проверка закрытого ключа
openssl rsa -in /etc/letsencrypt/live/example.com/privkey.pem -check

# Проверка структуры combined.pem
openssl x509 -in /etc/letsencrypt/live/example.com/combined.pem -text -noout

3. Отладка конфигурации SSL

Включите отладку SSL в Cassandra, добавив в cassandra-env.sh:

bash
export JVM_OPTS="$JVM_OPTS -Djavax.net.debug=ssl:handshake:keymanager"

4. Проверка синтаксиса конфигурации

Проверьте вашу YAML-конфигурацию перед запуском Cassandra:

bash
# Используйте yq или подобный инструмент для проверки структуры YAML
yq eval '."client_encryption_options"."ssl_context_factory"' cassandra.yaml

Альтернативные подходы

Использование формата JKS

Если вы продолжаете испытывать проблемы с PEM-файлами, рассмотрите возможность преобразования в формат JKS:

bash
# Преобразование PEM в JKS
keytool -importkeystore -srckeystore /etc/letsencrypt/live/example.com/combined.pem \
  -destkeystore /path/to/keystore.jks -srcstoretype PEM -deststoretype JKS

# Затем используйте традиционную конфигурацию JKS
client_encryption_options:
  keystore: /path/to/keystore.jks
  keystore_password: ваш_пароль
  truststore: /path/to/truststore.jks
  truststore_password: ваш_пароль

Использование переменных окружения

Для чувствительных параметров, таких как пароли, рассмотрите использование переменных окружения:

yaml
client_encryption_options:
  ssl_context_factory:
    class_name: org.apache.cassandra.security.PEMBasedSslContextFactory
    outbound_keystore: ${CASSANDRA_OUTBOUND_KEYSTORE}

Лучшие практики

  1. Организация файлов: Храните ваши SSL-сертификаты в отдельном каталоге с соответствующими правами доступа
  2. Резервное копирование конфигурации: Всегда создавайте резервную копию вашего файла cassandra.yaml перед внесением изменений
  3. Тестирование: Тестируйте конфигурацию SSL в непроизводственной среде сначала
  4. Мониторинг: Мониторьте метрики подключения SSL и логи ошибок
  5. Ротация сертификатов: Реализуйте процессы ротации сертификатов для сертификатов Let’s Encrypt

Ключевой вывод заключается в том, что PEMBasedSslContextFactory в Cassandra требует специфического размещения параметров, которое отличается от традиционных конфигураций на основе хранилища ключей. Размещая outbound_keystore или outbound_private_key в секции ssl_context_factory, а не на верхнем уровне client_encryption_options, вы должны решить ошибку конфигурации SSL и успешно установить шифрование от клиента к серверу.

Источники

  1. Документация Apache Cassandra - Использование ключевого материала на основе PEM
  2. Руководство по конфигурации SSL в Cassandra
  3. Примеры конфигурации SSL на основе PEM
  4. Лучшие практики конфигурации SSL/TLS
  5. Управление сертификатами Let’s Encrypt
Авторы
Проверено модерацией
Модерация