Blog
clouderatlsopensslkeytoolsecurity

Cloudera 요구사항에 맞는 self-signed TLS 인증서 만들기

sha256WithRSAEncryption, SAN, clientAuth + serverAuth 를 모두 만족하는 내부 CA 와 호스트별 인증서를 openssl 로 만드는 방법.

Data Dynamics2026年4月11日20 min read
This post is not yet translated. The original Korean version is shown below.

공인 CA 에서 인증서를 발급받으려면 며칠씩 걸리는 경우도 있습니다. 내부 테스트 클러스터나 PoC 환경에서는 기다릴 여유가 없죠. 마치 이사 들어가는 날 자물쇠 열쇠를 직접 만드는 것처럼, 자체 CA 를 만들어 호스트별 인증서를 발급 하면 몇 분 만에 준비가 끝납니다. 이 글은 Cloudera CDP Private Cloud Base 의 TLS 인증서 요구사항 문서 를 만족하는 self-signed 인증서를 생성하는 정확한 절차를 정리합니다. 자동화가 필요하면 TheOpenCloudEngine/certificates-generator 를 바로 쓰면 되고, 이 글은 그 스크립트가 내부적으로 무엇을 하는지, 왜 각 옵션이 필요한지를 한 줄씩 풀어서 설명합니다.

이 글에서 배우는 것

  • Cloudera CDP 가 TLS 인증서에 요구하는 조건 7가지
  • openssl 로 내부 CA 를 만들고 호스트별 인증서를 발급하는 정확한 절차
  • .ext 파일로 EKU(clientAuth + serverAuth), SAN 을 올바르게 설정하는 법
  • JKS TrustStore / PKCS12 KeyStore 로 패키징하는 방법
  • 자동화 스크립트 활용 시 주의사항

1. Cloudera 가 요구하는 조건

인증서를 만들기 전에 Cloudera 가 무엇을 요구하는지 먼저 파악해야 합니다. 이 표의 조건 하나라도 빠뜨리면 Cloudera 서비스가 인증서를 거부하니, 생성 스크립트가 이 모든 조건을 동시에 만족하도록 해야 합니다.

항목요구사항
Signature algorithmsha256WithRSAEncryption (SHA-256)
Extended Key Usage (EKU)clientAuthserverAuth 모두 포함
Key UsageDigitalSignature, KeyEncipherment
Subject Alternative Name (SAN)필수. 최소한 호스트의 FQDN 포함. 로드밸런서 FQDN 도 필요 시 추가
Wildcard 인증서사용 불가. 클러스터 노드마다 고유 인증서 발급
KeyStore한 KeyStore 에 PrivateKeyEntry하나만
KeyStore 비밀번호KeyStore 비밀번호와 인증서 비밀번호가 같거나 양쪽 모두 미설정. 클러스터 전체 노드에서 동일

추가로 문서가 권장하는 것은 "가능하면 공인 CA 를 쓰고 self-signed 는 피하라" 이지만, 이 글은 테스트/내부 환경 에서 self-signed 가 필요할 때의 정공법을 다룹니다.

2. 전체 흐름

Loading diagram…

Cloudera 노드는 결국 두 종류의 키스토어 를 필요로 합니다. 학교 신분증(KeyStore)은 학생마다 다르지만, 학교 직인(TrustStore)은 모든 학생이 같은 것을 신뢰하는 것과 비슷한 구조입니다.

  • KeyStore — 그 노드 자신의 private key + 서명된 leaf cert. 노드마다 다름.
  • TrustStore — 공통. 내부 CA 의 public cert 만 들어감. 모든 노드가 동일한 파일을 공유.

3. 내부 CA 생성

CA 는 한 번만 만들면 끝입니다. 한 번 만들어두면 클러스터의 모든 노드 인증서를 이 CA 로 서명할 수 있으니, 만료를 길게 (10년 / 3650일) 잡고 키 크기를 4096 비트 로 크게 가져가는 것이 관행입니다. 일단 CA 를 분실하면 모든 하위 인증서가 의미 없어지기 때문에 CA 키의 보안을 강하게 잡는 것이 맞습니다.

3.1 디렉터리 준비

mkdir -p certs/ca
cd certs/ca

3.2 CA 개인키

openssl genrsa -out ca.key 4096
chmod 600 ca.key

ca.key절대 외부로 유출되면 안 됩니다. 생성 즉시 권한을 600 으로 내려두고, 운영 배포 아티팩트에 포함되지 않도록 주의하세요.

3.3 CA self-signed 인증서

openssl req -x509 -new -nodes \
  -key ca.key \
  -sha256 \
  -days 3650 \
  -out ca.crt \
  -subj "/C=KR/ST=Gyeonggi-do/L=Yongin-si/O=Data Dynamics/OU=Infrastructure/CN=Data Dynamics Internal CA" \
  -extensions v3_ca \
  -config <(cat <<'EOF'
[req]
distinguished_name = req_dn
prompt = no
 
[req_dn]
CN = Data Dynamics Internal CA
 
[v3_ca]
basicConstraints = critical, CA:TRUE
keyUsage = critical, keyCertSign, cRLSign
subjectKeyIdentifier = hash
EOF
)

여기서 중요한 포인트는 세 가지입니다.

  • -sha256: Cloudera 가 요구하는 signature algorithm 을 지정. 이 옵션이 없으면 openssl 기본값이 MD5 나 SHA1 일 수 있어서 검증을 통과하지 못합니다.
  • basicConstraints = critical, CA:TRUE: 이 인증서가 "다른 인증서를 서명할 수 있는 CA" 임을 명시. critical 플래그로 반드시 검사하게 만듭니다.
  • keyUsage = critical, keyCertSign, cRLSign: CA 역할에 필요한 최소 Key Usage 만 부여. 이 CA 는 "다른 인증서 서명" 과 "CRL 서명" 만 할 수 있고 자기 자신이 서버가 되지는 못합니다.

3.4 CA 인증서 확인

openssl x509 -in ca.crt -noout -text | \
  grep -A1 -E "Signature Algorithm|Basic Constraints|Key Usage|Subject:"

출력에 Signature Algorithm: sha256WithRSAEncryption, CA:TRUE, Certificate Sign, CRL Sign 이 모두 보이면 정상입니다.

4. 호스트별 인증서 발급

CA 를 만들었다면 이제 각 노드에 발급할 차례입니다. 이 단계는 클러스터 노드 수만큼 반복됩니다. hosts.txt 같은 파일에 호스트 목록을 적어두고 루프를 돌리는 것이 편합니다.

hosts.txt
---------
node01.example.com
node02.example.com
node03.example.com
cm-server.example.com

4.1 디렉터리와 경로

HOST="node01.example.com"
mkdir -p "certs/${HOST}"
cd "certs/${HOST}"

4.2 노드 개인키

openssl genrsa -out "${HOST}.key" 2048
chmod 600 "${HOST}.key"

노드 인증서는 2048 비트로 충분합니다. CA 와 달리 수명이 짧고 (보통 825일 이내, 이후 설명) 갱신 주기가 있기 때문에 4096 까지 키울 필요는 없습니다.

4.3 CSR (Certificate Signing Request)

openssl req -new \
  -key "${HOST}.key" \
  -out "${HOST}.csr" \
  -subj "/C=KR/ST=Gyeonggi-do/L=Yongin-si/O=Data Dynamics/OU=Infrastructure/CN=${HOST}"
  • CN=${HOST}: 과거에는 CN 을 hostname 으로 쓰는 것이 표준이었습니다. 지금도 관행적으로 채우긴 하지만, 현대 TLS 클라이언트(Java 11+, 최신 브라우저, gRPC 등)는 CN 을 무시하고 SAN 만 본다 는 점을 기억하세요. SAN 이 없으면 CN 만으로는 절대 검증되지 않습니다.

4.4 확장 파일 (.ext) — Cloudera 요구사항의 핵심

이 파일이 이 과정의 핵심입니다. openssl 이 CSR 에 서명할 때 붙일 확장들을 별도 파일로 준비하는데, 이 파일 하나가 Cloudera 요구사항을 만족하는지 여부를 결정 합니다. 한 줄이라도 빠지면 Cloudera 서비스가 인증서를 거부합니다.

cat > "${HOST}.ext" <<EOF
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
 
[alt_names]
DNS.1 = ${HOST}
DNS.2 = ${HOST%%.*}
EOF

각 필드가 Cloudera 요구사항의 어느 항목을 커버하는지 짚고 넘어갑니다.

ext 파일 필드Cloudera 요구사항
basicConstraints = CA:FALSE이 인증서는 leaf 이며 다른 인증서를 서명할 수 없음을 명시
keyUsage = digitalSignature, keyEncipherment요구되는 Key Usage 2종
extendedKeyUsage = serverAuth, clientAuthEKU 양쪽 필수. 하나라도 빠지면 Cloudera 서비스 일부가 인식 못함
subjectAltName = @alt_namesSAN 필수 조건
DNS.1 = ${HOST}FQDN 포함
DNS.2 = ${HOST%%.*}bare hostname (짧은 이름). 노드 간 통신에서 짧은 이름을 쓰는 환경을 위해

주의: 참고한 오픈소스 스크립트는 SAN 에 DNS.3 = *.example.com 같은 와일드카드 를 포함하지만, 이 글이 목표로 하는 Cloudera CDP Private Cloud Base 7.3.1 의 요구사항에는 "certificates must not use wildcards" 가 명시되어 있습니다. 와일드카드 SAN 은 넣지 말고 노드별로 정확한 FQDN 만 나열하세요. 로드밸런서를 앞에 두는 경우에는 DNS.3 = lb.example.com 처럼 LB FQDN 을 추가로 명시하면 됩니다.

4.5 CA 로 CSR 서명

openssl x509 -req \
  -in "${HOST}.csr" \
  -CA ../ca/ca.crt \
  -CAkey ../ca/ca.key \
  -CAcreateserial \
  -out "${HOST}.crt" \
  -days 825 \
  -sha256 \
  -extfile "${HOST}.ext"
  • -sha256: 서명 알고리즘을 SHA-256 으로 명시. Cloudera 요구사항의 핵심.
  • -days 825: 825일. 이는 현재 대부분의 브라우저와 라이브러리가 허용하는 leaf 인증서 최대 유효기간입니다 (Apple/Google 이 2020년 이후 브라우저에 적용한 상한). Cloudera 자체는 이 값을 강제하지 않지만, 같은 인증서를 감시 대시보드의 HTTPS UI 에서 신뢰시키려면 825일 이하로 맞추는 편이 안전합니다.
  • -extfile: 위에서 만든 확장 파일을 주입. 이게 없으면 openssl 은 기본 확장만 붙이고 EKU/SAN 이 모두 사라집니다.
  • -CAcreateserial: 첫 실행 시 CA 의 일련번호 파일(ca.srl)을 자동 생성. 두 번째 호스트부터는 -CAserial ../ca/ca.srl 로 대체해도 동일.

4.6 체인 파일 조립

배포 편의상 "leaf cert + CA cert" 를 한 파일로 합친 체인 파일 을 만들어 두는 것이 일반적입니다.

cat "${HOST}.crt" ../ca/ca.crt > "${HOST}-chain.pem"

또한 "private key + 체인" 을 한 파일로 합친 풀 번들 도 유용합니다 (nginx, HAProxy 등 일부 서버가 이 형식을 요구).

cat "${HOST}.key" "${HOST}.crt" ../ca/ca.crt > "${HOST}-full.pem"
chmod 600 "${HOST}-full.pem"

5. 생성된 인증서 검증

5.1 CA 가 정말로 서명했는가

openssl verify -CAfile ../ca/ca.crt "${HOST}.crt"

node01.example.com.crt: OK 가 나오면 통과입니다.

5.2 Cloudera 요구 확장이 다 들어갔는가

openssl x509 -in "${HOST}.crt" -noout -text | \
  grep -A1 -E "Signature Algorithm|Key Usage|Extended Key Usage|Subject Alternative Name"

출력에서 반드시 확인해야 할 것:

  • Signature Algorithm: sha256WithRSAEncryption — 두 번 나옵니다 (tbsCertificate 와 outer)
  • X509v3 Key Usage: criticalDigital Signature, Key Encipherment
  • X509v3 Extended Key Usage:TLS Web Server Authentication, TLS Web Client Authentication
  • X509v3 Subject Alternative Name:DNS:node01.example.com, DNS:node01

하나라도 빠져 있으면 .ext 파일과 -extfile 옵션을 다시 확인하세요.

6. KeyStore / TrustStore 패키징

인증서를 만들었다고 끝이 아닙니다. Cloudera 서비스와 Java 기반 컴포넌트(HiveServer2, Impala coordinator, KMS 등) 는 Java KeyStore 형식 을 원합니다. openssl 이 만든 .key/.crt 를 JKS 로 옮겨야 비로소 Cloudera 가 인식합니다. 절차는 PKCS12 를 경유하는 두 단계입니다.

6.1 PKCS12 로 먼저 묶기

openssl 은 JKS 를 직접 만들 수 없습니다. 먼저 PKCS12 포맷으로 묶은 뒤 keytool 로 JKS 로 변환하는 2단계 접근을 씁니다.

openssl pkcs12 -export \
  -in "${HOST}-chain.pem" \
  -inkey "${HOST}.key" \
  -name "${HOST}" \
  -out "${HOST}.p12" \
  -password pass:"${STORE_PASSWORD}"
  • -name "${HOST}": KeyStore 내부 alias. 노드 식별용.
  • -password: 프로덕션에서는 env:STORE_PASSWORD 로 바꿔 환경변수에서 읽게 하는 편이 안전합니다.

6.2 JKS 로 변환

keytool -importkeystore \
  -srckeystore "${HOST}.p12" \
  -srcstoretype PKCS12 \
  -srcstorepass "${STORE_PASSWORD}" \
  -destkeystore "${HOST}.jks" \
  -deststoretype JKS \
  -deststorepass "${STORE_PASSWORD}" \
  -noprompt

Cloudera 문서의 "KeyStore password 와 certificate password 가 같거나 둘 다 미설정" 조건은 여기서 충족됩니다. srcstorepassdeststorepass 를 동일한 값으로 맞추세요. keypass 를 별도로 지정하지 않으면 keytool 은 자동으로 storepass 와 동일한 값을 쓰므로 이 조건이 자연스럽게 맞아떨어집니다.

6.3 공용 TrustStore 만들기 (CA 만)

TrustStore 는 클러스터 전체가 공유합니다. 여기에는 CA 인증서만 들어가며 private key 는 들어가지 않습니다.

keytool -importcert -noprompt \
  -file ../ca/ca.crt \
  -alias internal-ca \
  -keystore truststore.jks \
  -storepass "${TRUSTSTORE_PASSWORD}" \
  -storetype JKS

truststore.jks 한 파일을 모든 노드에 배포하면 됩니다.

7. 자동화 — 참고 스크립트

노드가 수십 대라면 위 절차를 매번 손으로 돌리는 건 고문이나 다름없습니다. 저희가 이 글을 준비하면서 참고한 오픈소스 스크립트가 그 반복 작업을 대신해줍니다.

이 스크립트는 hosts.txt 를 입력으로 받아 위에서 설명한 3~6단계를 자동으로 반복 해서 certs/<host>/ 디렉터리 안에 .key, .csr, .crt, .ext, 체인 파일, 풀 번들까지 한꺼번에 생성합니다. 사용 순서는 이렇습니다.

git clone https://github.com/TheOpenCloudEngine/certificates-generator.git
cd certificates-generator
 
# hosts.txt 에 클러스터 노드 FQDN 을 한 줄씩 입력
cat > hosts.txt <<EOF
node01.example.com
node02.example.com
node03.example.com
cm-server.example.com
EOF
 
./generate_certs.sh

단, 그대로 운영에 쓰기 전에 아래 두 가지는 반드시 확인 하세요.

  • 스크립트 상단의 CA Subject (C, ST, O, CN) 가 조직 규칙에 맞는지. 기본값은 샘플이라 회사 정보로 수정이 필요합니다.
  • SAN 에 와일드카드 도메인 을 추가하는 부분이 있다면 제거. 앞서 설명했듯이 Cloudera CDP Private Cloud Base 7.3.1 은 wildcard 를 금지합니다. 노드별 FQDN 만 넣도록 루프를 수정하세요.

이 두 부분만 회사 환경에 맞게 손보면, 사실상 Cloudera 요구사항을 만족하는 인증서 묶음을 5분 안에 발급받을 수 있습니다.

한 문장으로: 자동화 스크립트는 편리하지만, CA Subject 와 와일드카드 SAN 부분을 반드시 수동으로 검토해야 합니다.

8. 운영 주의사항

인증서를 만들었다고 일이 끝난 게 아닙니다. 운영에서는 인증서 관리 자체가 또 하나의 숙제입니다.

  • CA 키 보관: ca.key 는 암호화된 별도 볼트(HashiCorp Vault, AWS KMS, 사내 HSM 등)에 보관하는 것이 원칙입니다. 일반 Git 리포에 절대 커밋하지 마세요. 이 키가 유출되면 이 CA 로 서명된 모든 노드 인증서 가 동시에 신뢰를 잃습니다.
  • 만료 모니터링: leaf 인증서(825일)뿐 아니라 CA 인증서(3650일)도 만료일을 모니터링해야 합니다. CA가 만료되면 재발급해야 하는 범위가 전 노드로 퍼집니다.
  • 일련번호(serial) 파일 관리: ca.srl 은 다음 발급에서 이어서 써야 합니다. 분실하거나 여러 팀이 병렬로 인증서를 발급하면 같은 일련번호가 두 인증서에 부여되어 충돌이 날 수 있습니다. 중앙에서 단일 CA 워크스테이션을 정해두는 편이 안전합니다.
  • 재발급 절차 미리 연습: "만료 2주 전에 갱신" 정책을 문서화해두고, 1년에 한 번 이상 실제 재발급을 돌려 절차가 유효한지 확인하세요. 첫 만료일이 닥쳐서야 스크립트를 찾는 것이 가장 흔한 장애 패턴입니다.

이 글은 인증서를 만드는 쪽만 다뤘습니다. 만든 CA 인증서를 JDBC 클라이언트 쪽에서 신뢰하도록 TrustStore 에 import 하고 실제로 Impala 에 연결하는 과정은 "Cloudera Impala JDBC 에 TLS + LDAP 인증 적용하기" 에서 이어집니다.

마치며 — 핵심 요약

  • Cloudera TLS 인증서는 SHA-256, EKU(clientAuth+serverAuth), SAN 세 가지가 반드시 있어야 합니다.
  • 내부 CA 는 한 번만 만들고, 노드별 인증서는 이 CA 로 서명합니다.
  • .ext 파일이 요구사항을 충족하는 핵심 파일입니다. 와일드카드 SAN(*.example.com)은 넣으면 안 됩니다.
  • openssl → PKCS12 → JKS 변환 순서로 패키징합니다.
  • ca.key 는 절대 Git 에 올리지 마세요. CA 가 유출되면 모든 노드 인증서가 동시에 무효화됩니다.
  • 자동화 스크립트를 쓸 때는 CA Subject 와 와일드카드 SAN 제거 여부를 반드시 확인하세요.

인증서 설정은 한 번 제대로 해두면 한동안 신경 쓸 일이 없습니다. 이 글의 체크포인트를 하나씩 짚어가며 진행해 보세요.

질문이나 사내 환경에서만 나타나는 특이 케이스가 있으면 알려주세요.

— Data Dynamics 엔지니어링 팀