Требования к SSL-сертификатам

Для реализации шифрования между узлами выполните шаги, описанные ниже.

  1. Создайте сертификат для каждого узла, используя алгоритм RSA. Длина ключа должна быть 2048 бит, значение CN должно содержать FQDN соответствующего узла. Не рекомендуется использовать алгоритм DSA, а также алгоритм ECDSA из-за того, что этот алгоритм не очень широко поддерживается сертификационными центрами.

    Длина ключа, равная 2048 битам, является необходимой и достаточной для реализации надежного шифрования.

  2. Создайте хранилище ключей trustore.jks, которое будет содержать необходимые сертификаты. Путь к этому хранилищу должен быть указан для запуска SSL.

    ПРИМЕЧАНИЕ
    • Сертификаты должны быть подписаны ключом, принадлежащим одному из доверенных корневых сертификатов, включенных в хранилище сертификатов Java.

    • Самоподписанные сертификаты разрешены. В этом случае корневой сертификат должен быть добавлен в хранилище trustore.jks.

    • Nginx требует сертификат не Java-формата. Если ваш кластер использует Nginx (с Hive Tez UI или Airflow), сгенерируйте ключи и сертификаты другого типа. SSL-сертификат для вашего хоста следует добавить в хранилище доверенных системных сертификатов.

    • Учетная запись, используемая для установки сертификатов, должна иметь права на запись в следующие директории:

      • /etc/pki/tls/certs/

      • /etc/pki/java/

    • В качестве alias ключа в keystore.jks используйте FQDN, а не короткое имя.

  3. Включите трафик между узлами в соответствии с приведенной ниже таблицей.

    Приведенный ниже скрипт создает все необходимые сущности и может быть использован для справки:

Скрипт для настройки SSL
#!/bin/bash
set -euo pipefail

echo "# SSL preparation script started"

if [ -f ./crtdistr-config.cfg ]; then
  echo "## Config found"
else
  echo "## Error: configuration file ./crtdistr-config.cfg not found"
  exit 1
fi

HOSTS_MAKE="${HOSTS-}"

source ./crtdistr-config.cfg

if [ -n "$HOSTS_MAKE" ]; then
  echo "## HOSTS provided from MakeFile"
  read -r -a HOSTS <<< "$HOSTS_MAKE"
fi

SSH_HOSTS=()
SSH_OPTS='-o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=error'
TMP_DIR="/tmp/crtdistr"
CA_KEY="$TMP_DIR/ca_admprom.key"
CA_CERT="$TMP_DIR/ca_certs.crt"
CA_ALIAS="root-ca"

get_cert_paths() {
  local host="$1"

  if ssh $SSH_OPTS "$host" 'grep "^ID=" /etc/os-release' 2>/dev/null | grep -qE 'astra'; then
    CA_CERTS_PATH="/usr/local/share/ca-certificates/"
    CA_UPDATE_CMD="update-ca-certificates"
    HOST_CERT_NAME="host_cert.crt"
    JAVA_CA_PATH="/usr/lib/jvm/java-arenadata-openjdk-8/jre/lib/security/cacerts"
    JAVA_CA_PATH_17="/usr/lib/jvm/java-arenadata-openjdk-17/lib/security/cacerts"
  elif ssh $SSH_OPTS "$host" 'grep "^ID=" /etc/os-release' 2>/dev/null | grep -qE 'ubuntu'; then
    CA_CERTS_PATH="/usr/local/share/ca-certificates"
    CA_UPDATE_CMD="update-ca-certificates"
    HOST_CERT_NAME="host_cert.crt"
    JAVA_CA_PATH="/usr/lib/jvm/java-arenadata-openjdk-8/jre/lib/security/cacerts"
    JAVA_CA_PATH_17="/usr/lib/jvm/java-arenadata-openjdk-17/lib/security/cacerts"
  elif ssh $SSH_OPTS "$host" 'grep "^ID=" /etc/os-release' 2>/dev/null | grep -qE 'rhel|centos|altlinux|redos'; then
    CA_CERTS_PATH="/etc/pki/ca-trust/source/anchors"
    CA_UPDATE_CMD="update-ca-trust"
    HOST_CERT_NAME="host_cert.cert"
    JAVA_CA_PATH="/usr/lib/jvm/java-arenadata-openjdk-8/jre/lib/security/cacerts"
    JAVA_CA_PATH_17="/usr/lib/jvm/java-arenadata-openjdk-17/lib/security/cacerts"
  else
    CA_CERTS_PATH=""
    CA_UPDATE_CMD=""
    HOST_CERT_NAME=""
    JAVA_CA_PATH=""
    JAVA_CA_PATH_17=""
  fi
}

echo "# Pre-check"
for HOST in "${HOSTS[@]}"; do
  echo "## Checking ssh connection to host $HOST"
  if ssh $SSH_OPTS -q "$HOST" "exit"; then
    get_cert_paths "$HOST"
    if [[ -z "$CA_CERTS_PATH" ]]; then
      echo "### Unknown OS type on $HOST, skipped"
    elif [[ -z "$JAVA_CA_PATH" ]]; then
      echo "### Java cacerts path not detected on $HOST, skipped"
    else
      echo "### $HOST is OK"
      SSH_HOSTS+=("$HOST")
    fi
  else
    echo "### SSH connection failed for $HOST"
  fi
done

if [[ "${#SSH_HOSTS[@]}" -eq 0 ]]; then
  echo "## No reachable hosts found"
  exit 1
fi

rm -rf "$TMP_DIR"
mkdir -p "$TMP_DIR"

echo "# Creating local CA"
openssl genrsa -out "$CA_KEY" 4096
openssl req -x509 \
  -nodes \
  -key "$CA_KEY" \
  -days 1095 \
  -out "$CA_CERT" \
  -subj "/CN=marsnet.local CA"

echo "# Creating server certificates"
for SSH_HOST in "${SSH_HOSTS[@]}"; do
  echo "## Generate key and CSR for $SSH_HOST"
  openssl req \
    -newkey rsa:4096 \
    -nodes \
    -keyout "$TMP_DIR/$SSH_HOST.key" \
    -out "$TMP_DIR/$SSH_HOST.host.csr" \
    -subj "/C=RU/ST=Denial/L=MSK/O=AD/CN=$SSH_HOST"

  echo "## Sign certificate for $SSH_HOST"
  openssl x509 \
    -req \
    -in "$TMP_DIR/$SSH_HOST.host.csr" \
    -CA "$CA_CERT" \
    -CAkey "$CA_KEY" \
    -CAcreateserial \
    -out "$TMP_DIR/$SSH_HOST.crt" \
    -days 365 \
    -extfile <(printf "basicConstraints=critical,CA:FALSE\nkeyUsage=digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth,clientAuth\nsubjectAltName=DNS:$SSH_HOST\n")
done

echo "# Distributing certificates"
for SSH_HOST in "${SSH_HOSTS[@]}"; do
  echo "## Copy files to $SSH_HOST"
  scp $SSH_OPTS "$TMP_DIR/$SSH_HOST.crt" "$SSH_HOST:/tmp/"
  scp $SSH_OPTS "$TMP_DIR/$SSH_HOST.key" "$SSH_HOST:/tmp/"
  scp $SSH_OPTS "$CA_CERT" "$SSH_HOST:/tmp/"

  for node in "${SSH_HOSTS[@]}"; do
    if [[ "$SSH_HOST" != "$node" ]]; then
      scp $SSH_OPTS "$TMP_DIR/$node.crt" "$SSH_HOST:/tmp/$node.crt"
    fi
  done
done

echo "# Configuring remote hosts"
for SSH_HOST in "${SSH_HOSTS[@]}"; do
  echo "## Install certificate and build keystore/truststore on $SSH_HOST"
  get_cert_paths "$SSH_HOST"

  ssh $SSH_OPTS "$SSH_HOST" "
    set -eo pipefail
    export KEYSTOREPASS='$KEYSTOREPASS'
    export TRUSTSTOREPASS='$TRUSTSTOREPASS'

    sudo rm -f /etc/ssl/host.pem /etc/ssl/host.key /etc/ssl/ca_certs.crt

    sudo mkdir -p /etc/ssl

    sudo cp /tmp/$SSH_HOST.crt /etc/ssl/host.pem
    sudo cp /tmp/$SSH_HOST.key /etc/ssl/host.key
    sudo cp /tmp/ca_certs.crt /etc/ssl/ca_certs.crt

    set +u
    source /usr/lib/bigtop-utils/bigtop-detect-javahome
    set -u

    # Удаление старых алиасов в keystore
    sudo \$JAVA_HOME/bin/keytool -delete \
      -alias $SSH_HOST \
      -keystore $KEYSTOREPATH \
      -storepass \$KEYSTOREPASS >/dev/null 2>&1 || true

    sudo \$JAVA_HOME/bin/keytool -delete \
      -alias $CA_ALIAS \
      -keystore $KEYSTOREPATH \
      -storepass \$KEYSTOREPASS >/dev/null 2>&1 || true

    # Удаление старого алиаса CA в truststore
    sudo \$JAVA_HOME/bin/keytool -delete \
      -alias $CA_ALIAS \
      -keystore $TRUSTSTOREPATH \
      -storepass \$TRUSTSTOREPASS >/dev/null 2>&1 || true

    sudo cp /etc/ssl/host.pem $CA_CERTS_PATH/$HOST_CERT_NAME
    sudo cp /tmp/ca_certs.crt $CA_CERTS_PATH/ca_certs.crt
    sudo $CA_UPDATE_CMD
    sudo chmod 644 /etc/ssl/host.key

    openssl pkcs12 -export \
      -in /tmp/$SSH_HOST.crt \
      -inkey /tmp/$SSH_HOST.key \
      -certfile /tmp/ca_certs.crt \
      -name $SSH_HOST \
      -out /tmp/$SSH_HOST.p12 \
      -password pass:\$KEYSTOREPASS

    sudo \$JAVA_HOME/bin/keytool -importkeystore \
      -srckeystore /tmp/$SSH_HOST.p12 \
      -srcstoretype PKCS12 \
      -srcstorepass \$KEYSTOREPASS \
      -destkeystore $KEYSTOREPATH \
      -deststoretype JKS \
      -deststorepass \$KEYSTOREPASS \
      -alias $SSH_HOST \
      -noprompt

    sudo \$JAVA_HOME/bin/keytool -import \
      -noprompt \
      -alias $CA_ALIAS \
      -file /tmp/ca_certs.crt \
      -keystore $KEYSTOREPATH \
      -storepass \$KEYSTOREPASS \
      -trustcacerts

    sudo \$JAVA_HOME/bin/keytool -import \
      -noprompt \
      -alias $CA_ALIAS \
      -file /tmp/ca_certs.crt \
      -keystore $TRUSTSTOREPATH \
      -storepass \$TRUSTSTOREPASS \
      -trustcacerts

    # Для Haproxy
    sudo bash -c 'cat /etc/ssl/host.key /etc/ssl/host.pem /etc/ssl/ca_certs.crt > /etc/ssl/serverkey.pem'
    sudo chmod 600 /etc/ssl/serverkey.pem
  "

  # Импорт сертификатов всех узлов в truststore с удалением старых алиасов
  for node in "${SSH_HOSTS[@]}"; do
    ssh $SSH_OPTS "$SSH_HOST" "
      set +u
      source /usr/lib/bigtop-utils/bigtop-detect-javahome
      set -u

      sudo \$JAVA_HOME/bin/keytool -delete \
        -alias $node \
        -keystore $TRUSTSTOREPATH \
        -storepass $TRUSTSTOREPASS >/dev/null 2>&1 || true

      sudo \$JAVA_HOME/bin/keytool -import \
        -noprompt \
        -alias $node \
        -file /tmp/$node.crt \
        -keystore $TRUSTSTOREPATH \
        -storepass $TRUSTSTOREPASS \
        -trustcacerts
    "
  done

  # Импорт truststore в системные Java cacerts с предварительным удалением алиасов
  ssh $SSH_OPTS "$SSH_HOST" "
    set -eo pipefail

    set +u
    source /usr/lib/bigtop-utils/bigtop-detect-javahome
    set -u

    # Удаление всех известных алиасов из целевых cacerts перед импортом
    for ALIAS in $CA_ALIAS ${SSH_HOSTS[@]}; do
      sudo \$JAVA_HOME/bin/keytool -delete \
        -alias \$ALIAS \
        -keystore $JAVA_CA_PATH_17 \
        -storepass changeit >/dev/null 2>&1 || true
      sudo \$JAVA_HOME/bin/keytool -delete \
        -alias \$ALIAS \
        -keystore $JAVA_CA_PATH \
        -storepass changeit >/dev/null 2>&1 || true
    done

    # Импорт в Java 17 cacerts
    sudo \$JAVA_HOME/bin/keytool -importkeystore \
      -noprompt \
      -srckeystore $TRUSTSTOREPATH \
      -srcstorepass $TRUSTSTOREPASS \
      -destkeystore $JAVA_CA_PATH_17 \
      -deststorepass changeit || true

    # Импорт в Java 8 cacerts
    sudo \$JAVA_HOME/bin/keytool -importkeystore \
      -noprompt \
      -srckeystore $TRUSTSTOREPATH \
      -srcstorepass $TRUSTSTOREPASS \
      -destkeystore $JAVA_CA_PATH \
      -deststorepass changeit || true

    sudo rm -f /tmp/$SSH_HOST.p12 /tmp/*.crt /tmp/*.key
  " || {
    echo "Failed to configure certs on $SSH_HOST"
    exit 1
  }
done

echo "# Cleanup local temp files"
rm -rf "$TMP_DIR"

echo "# All done successfully!"
Конфигурационный файл crtdistr-config.cfg для скрипта
#!/usr/bin/env sh
# Пароль KEYSTORE
KEYSTOREPASS='bigdata'
# Путь создания KEYSTORE
KEYSTOREPATH='/etc/ssl/keystore.jks'
# Пароль TRUSTORE
TRUSTSTOREPASS='bigdata'
# Путь создания TRUSTORE
TRUSTSTOREPATH='/etc/ssl/truststore.jks'
# DNS-имена хостов для выполнения раскладки сертификатов
HOSTS=(
    "prefix-adh-1.ru-central1.internal"
    "prefix-adh-2.ru-central1.internal"
    "prefix-adh-3.ru-central1.internal"
    "prefix-adps-1.ru-central1.internal"
    )
Сопоставление портов и служб HTTP/HTTPS
Сервис Компонент/Сервер Порт Протокол Описание

Airflow

Server

8080/8080

HTTP/HTTPS

Порт веб-интерфейса Airflow Server

Server/Worker

8793/8793

HTTP/HTTPS

Порт для доступа к Celery Worker API

Server/Flower

5555/5555

HTTP/HTTPS

Порт веб-интерфейса Flower

Flink

Job Manager

8081/8081

HTTP/HTTPS

Порт веб-интерфейса Flink Job Manager

HBase

HBase Region

16030/16030

HTTP/HTTPS

Порт веб-интерфейса HBase Region Server

Phoenix Query Server

8765/8765

HTTP/HTTPS

Порт для доступа к API

HBase REST Server

60080/60080

HTTP/HTTPS

Порт для доступа к API

HBase REST Server

8085/8085

HTTP/HTTPS

Web UI Port

HBase Master

16010/16010

HTTP/HTTPS

Порт веб-интерфейса HBase Master

HBaseThrift2Server

Trift2 Server

9095/9095

HTTP/HTTPS

Порт веб-интерфейса Thrift2 Server

HDFS

NameNode

9870/9871

HTTP/HTTPS

Порт веб-интерфейса NameNode

DataNode

9864/9865

HTTP/HTTPS

Порт веб-интерфейса DataNode

JournalNode

8480/8481

HTTP/HTTPS

Порт веб-интерфейса JournalNode

HTTPfs server

14000/14000

HTTP/HTTPS

Порт для доступа к HTTPfs API

Monitoring

Grafana

11210

HTTP/HTTPS

Порт веб-интерфейса Grafana

Node Exporter

11203

HTTP/HTTPS

Порт Node Exporter

Prometheus Server

11200

HTTP/HTTPS

Порт веб-интерфейса Prometheus

Hive

Hive Server

10002/10002

HTTP/HTTPS

Порт веб-интерфейса Hive Server

Tez

9999/9999

HTTP/HTTPS

Порт веб-интерфейса Tez

Knox

Knox Gateway

8443

HTTPS

Порт шлюза

Ranger

Ranger Admin

6080/6182

HTTP/HTTPS

Порт для доступа к API и веб-интерфейсу Ranger Admin

Ranger KMS

9292/9393

HTTP/HTTPS

Порт для Ranger KMS

Solr

Solr Server

8983/8985

HTTP/HTTPS

Порт для доступа к веб-интерфейсу и API Solr Server

Spark

History Server

18082/18082

HTTP/HTTPS

Порт веб-интерфейса History Server

Thrift Server

4040/4040

HTTP/HTTPS

Порт веб-интерфейса Thrift Server

Livy Server

8998/8998

HTTP/HTTPS

Порт веб-интерфейса Livy Server

YARN

Resource Manager

8088/8090

HTTP/HTTPS

Порт веб-интерфейса Resource Manager

Node Manager

8042/8044

HTTP/HTTPS

Порт веб-интерфейса Node Manager

MapReduce History Server

19888/19890

HTTP/HTTPS

Порт веб-интерфейса History Server

Timeline Server

8188/8190

HTTP/HTTPS

Порт веб-интерфейса Timeline Server

Zeppelin

Server

8180/8180

HTTP/HTTPS

Порт веб-интерфейса Zeppelin

Нашли ошибку? Выделите текст и нажмите Ctrl+Enter чтобы сообщить о ней