Требования к SSL-сертификатам
Для реализации шифрования между узлами выполните шаги, описанные ниже.
-
Создайте сертификат для каждого узла, используя алгоритм RSA. Длина ключа должна быть 2048 бит, значение CN должно содержать FQDN соответствующего узла. Не рекомендуется использовать алгоритм DSA, а также алгоритм ECDSA из-за того, что этот алгоритм не очень широко поддерживается сертификационными центрами.
Длина ключа, равная 2048 битам, является необходимой и достаточной для реализации надежного шифрования.
-
Создайте хранилище ключей 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, а не короткое имя.
-
-
Включите трафик между узлами в соответствии с приведенной ниже таблицей.
Приведенный ниже скрипт создает все необходимые сущности и может быть использован для справки:
#!/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!"
#!/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"
)
| Сервис | Компонент/Сервер | Порт | Протокол | Описание |
|---|---|---|---|---|
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 |