Ncloud Kubernetes Service(NKS) 의 Pod에서 HSM에 연결하는 방법을 설명합니다.
NKS 연동은 Thales 공식 문서를 기반으로 작성했습니다. 사용 가이드에서 안내하는 내용 외에 더 많은 내용을 살펴보려면 Docker Container - Integration Guide를 참조해 주십시오.
지원 환경
HSM 과 NKS를 연동하기 위한 환경은 다음과 같습니다.
전제 조건
NKS 연동을 시작하기 전에 다음의 전제 조건을 준수해 주십시오.
- HSM 파티션의 초기설정 모두 완료
- NKS 구성이 모두 완료
Node HSM 연결 설정
InitScript 설정을 이용하여 Node에 HSM 연결을 설정합니다.
-
lunaclient, HSM 연결 설정 스크립트 실행
install_lunaclient_certs.sh작성#!/bin/bash sudo apt update -y sudo apt-get install -y build-essential alien set -e ### [1] Luna Client 설치 및 설정 ### DOWNLOAD_URL="http://init.fin-ncloud.com/server/app/hsm/610-000397-019_SW_Linux_Luna_Client_V10.9.3_RevA.tar" API_URL="https://fin-hardwaresecuritymodule.apigw.fin-ntruss.com/api/v1/client/configs" WORK_DIR="$HOME" ARCHIVE_NAME=$(basename "$DOWNLOAD_URL") PYTHON="" if command -v python3 &>/dev/null; then PYTHON=python3 elif command -v python &>/dev/null; then PYTHON=python else echo "Error: python3 또는 python 이 필요합니다." exit 1 fi echo "Fetching HSM server configs from API..." result=$(curl --silent --fail --location --request GET "$API_URL") SERVER_CERT_DIR=$(mktemp -d) server_ips=$($PYTHON -c " import sys, json, os data = json.loads(sys.argv[1]) cert_dir = sys.argv[2] servers = data.get('servers', []) if not servers: print('ERROR: No HSM servers found', file=sys.stderr) sys.exit(1) for i, s in enumerate(servers): with open(os.path.join(cert_dir, 'hsm-server-{}.pem'.format(i)), 'w') as f: f.write(s['cert']) print(s['ip']) " "$result" "$SERVER_CERT_DIR") || { echo "Error: API 응답 파싱 실패"; exit 1; } cd "$WORK_DIR" || { echo "Error: Could not change to $WORK_DIR"; exit 1; } echo "Downloading Luna Client from $DOWNLOAD_URL..." wget -q "$DOWNLOAD_URL" -O "$ARCHIVE_NAME" || { echo "Error: Failed to download Luna Client"; exit 1; } echo "Extracting archive $ARCHIVE_NAME..." tar -xf "$ARCHIVE_NAME" || { echo "Error: Failed to extract archive"; exit 1; } rm -f "$ARCHIVE_NAME" INSTALL_DIR=$(find "$WORK_DIR" -maxdepth 1 -type d -name "*Luna*Client*" | head -1) if [[ -z "$INSTALL_DIR" ]]; then echo "Error: Could not find extracted installation directory" exit 1 fi cd "$INSTALL_DIR/64" || { echo "Error: Installation directory not found"; exit 1; } echo "Running installation script..." (echo y) | sudo sh install.sh -p network -c all || { echo "Error: Installation failed"; exit 1; } EULA_FILE=$(find "$INSTALL_DIR" -maxdepth 1 -name "*EULA*" -type f | head -1) if [[ -n "$EULA_FILE" ]]; then echo "Moving EULA file..." sudo mv "$EULA_FILE" /usr/safenet/lunaclient/ || { echo "Error: Failed to move EULA file"; exit 1; } fi i=0 while IFS= read -r server_ip; do cert_file="$SERVER_CERT_DIR/hsm-server-${i}.pem" echo "Adding VTL server $server_ip..." vtl_output=$(/usr/safenet/lunaclient/bin/vtl addServer -n "$server_ip" -c "$cert_file" 2>&1) && true if [[ $? -ne 0 ]]; then if echo "$vtl_output" | grep -q "already registered"; then echo "Warning: $server_ip 는 이미 등록되어 있습니다. 건너뜁니다." else echo "$vtl_output" echo "Error: Failed to add server $server_ip" exit 1 fi fi i=$((i + 1)) done <<< "$server_ips" cd "$WORK_DIR" || { echo "Error: Could not return to $WORK_DIR"; exit 1; } rm -rf "$INSTALL_DIR" rm -rf "$SERVER_CERT_DIR" ### [2] 클라이언트 인증서 및 개인키 직접 생성 ### CLIENT_CERT_DIR="/usr/safenet/lunaclient/cert/client" mkdir -p "$CLIENT_CERT_DIR" # 개인 키 생성 cat <<'EOF' > "$CLIENT_CERT_DIR/{privateKey}.pem" -----BEGIN RSA PRIVATE KEY----- ..... -----END RSA PRIVATE KEY----- EOF # 인증서 생성 cat <<'EOF' > "$CLIENT_CERT_DIR/{certificate}.pem" -----BEGIN CERTIFICATE----- ..... -----END CERTIFICATE----- EOF chmod 600 "$CLIENT_CERT_DIR/{privateKey}.pem" chmod 644 "$CLIENT_CERT_DIR/{certificate}.pem" ### [3] /etc/Chrystoki.conf 수정 ### CHRYSTOKI_CONF="/etc/Chrystoki.conf" if grep -q "ClientPrivKeyFile" "$CHRYSTOKI_CONF"; then sed -i "s|ClientPrivKeyFile *= *.*|ClientPrivKeyFile = $CLIENT_CERT_DIR/{privateKey}.pem;|" "$CHRYSTOKI_CONF" else sed -i "/LunaSA Client = {/a\ ClientPrivKeyFile = $CLIENT_CERT_DIR/{privateKey}.pem;" "$CHRYSTOKI_CONF" fi if grep -q "ClientCertFile" "$CHRYSTOKI_CONF"; then sed -i "s|ClientCertFile *= *.*|ClientCertFile = $CLIENT_CERT_DIR/{certificate}.pem;|" "$CHRYSTOKI_CONF" else sed -i "/LunaSA Client = {/a\ ClientCertFile = $CLIENT_CERT_DIR/{certificate}.pem;" "$CHRYSTOKI_CONF" fi echo "[SUCCESS] Luna Client 설치 및 인증서 설정 완료."- initScript 등록
kubectl --kubeconfig=$KUBE_CONFIG apply -f https://raw.githubusercontent.com/NaverCloudPlatform/nks-examples/main/examples/initscript/fin/fkr.yml - daemonSet env 수정
kubectl --kubeconfig=$KUBE_CONFIG set env daemonset/init-script -n kube-system STARTUP_SCRIPT=$(base64 -i install_lunaclient_certs.sh -w 0)
스크립트 내에
{privateKey}.pem,{certificate}.pem은 HSM 연결에 사용된 값으로 대체해야 합니다.
스크립트가 성공적으로 수행되면 node 에서 HSM 으로 접근 가능한 상태가 됩니다. -
node 의 lunaclient 를 이용하여 HSM에 접근하는 pod
pod-with-lunaclient을 생성합니다.lunaclient.yaml작성apiVersion: v1 kind: Pod metadata: name: pod-with-lunaclient spec: containers: - name: pod-with-lunaclient image: registry.access.redhat.com/ubi8/ubi:latest # RHEL UBI 이미지 command: [ "/bin/bash", "-c", "--" ] args: [ "while true; do sleep 30; done;" ] volumeMounts: - name: lunaclient-config mountPath: /etc/Chrystoki.conf readOnly: true - name: lunaclient mountPath: /usr/safenet/lunaclient env: - name: LC_ALL value: C volumes: - name: lunaclient-config hostPath: path: /etc/Chrystoki.conf type: File - name: lunaclient hostPath: path: /usr/safenet/lunaclient type: Directorypod-with-lunaclient생성kubectl --kubeconfig=$KUBE_CONFIG create -f lunaclient.yaml
위 설정은 참고용이며 사용 환경에 따라 다른 설정 값이 추가될 수 있습니다.
-
pod 의 동작을 확인하고 pod 에 접근하여 HSM 연결을 확인합니다.
- pod 동작 확인
kubectl --kubeconfig=$KUBE_CONFIG get pods NAME READY STATUS RESTARTS AGE pod-with-lunaclient 1/1 Running 0 58s - pod 접속
kubectl --kubeconfig=$KUBE_CONFIG exec -it pod-with-lunaclient -- /bin/bash - HSM 연결 확인
[root@pod-with-lunaclient /]# cd /usr/safenet/lunaclient/ [root@pod-with-lunaclient bin]# ./vtl verify vtl (64-bit) v10.9.3-43. Copyright (c) 2026 Thales Group. All rights reserved. The following Luna SA Slots/Partitions were found: Slot Serial # Label ==== ================ ===== 0 146*******711 n*****l
- pod 동작 확인
-
정상적으로 접근이 되기 위해서는 아래 사항 모두를 확인할 수 있어야합니다.
/etc/Chrystoki.conf파일 존재/etc/Chrystoki.conf파일 내ClientPrivKeyFile,ClientCertFile값의 파일명이 스크립트에 작성한 파일명과 동일참고LunaSA Client = {
...
ClientPrivKeyFile = /usr/safenet/lunaclient/cert/client/testHsmKey.pem;
ClientCertFile = /usr/safenet/lunaclient/cert/client/testHsm.pem;
...
}/usr/safenet/lunaclient/경로 존재/usr/safenet/lunaclient/cert/client경로에{privateKey}.pem,{certificate}.pem파일이 있고 올바른 개인키, 인증서 내용