Documentation Index

Fetch the complete documentation index at: https://guide-fin.ncloud-docs.com/llms.txt

Use this file to discover all available pages before exploring further.

NKS 연동

Prev Next

Ncloud Kubernetes Service(NKS) 의 Pod에서 HSM에 연결하는 방법을 설명합니다.

참고

NKS 연동은 Thales 공식 문서를 기반으로 작성했습니다. 사용 가이드에서 안내하는 내용 외에 더 많은 내용을 살펴보려면 Docker Container - Integration Guide를 참조해 주십시오.

지원 환경

HSM 과 NKS를 연동하기 위한 환경은 다음과 같습니다.

전제 조건

NKS 연동을 시작하기 전에 다음의 전제 조건을 준수해 주십시오.

Node HSM 연결 설정

InitScript 설정을 이용하여 Node에 HSM 연결을 설정합니다.

  1. 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 으로 접근 가능한 상태가 됩니다.

  2. 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: Directory
    

    pod-with-lunaclient 생성

    kubectl --kubeconfig=$KUBE_CONFIG create -f lunaclient.yaml
    
참고

위 설정은 참고용이며 사용 환경에 따라 다른 설정 값이 추가될 수 있습니다.

  1. 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
      
  2. 정상적으로 접근이 되기 위해서는 아래 사항 모두를 확인할 수 있어야합니다.

    • /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 파일이 있고 올바른 개인키, 인증서 내용