VM で TLS 暗号化を使用してデプロイを作成する

このドキュメントでは、仮想マシン(VM)上の Spanner Omni デプロイに TLS 暗号化を追加する方法について説明します。ネットワーク セキュリティ機能を備えたデプロイでは、Transport Layer Security(TLS)1.3 を使用して、デプロイ内およびクライアントとの通信を暗号化して認証します。Spanner Omni は、セキュリティを強化するために相互 TLS(mTLS)を提供します。これにより、両方の当事者がデータを交換する前に認証を確立します。mTLS はクライアントとサーバー間でオプションですが、Spanner Omni サーバーは mTLS を介して相互に通信します。

始める前に

始める前に、環境が次の要件を満たしていることを確認してください。

  • デプロイ内の各マシンに SSH アクセスできることを確認します。このアクセス権により、Spanner Omni バイナリをダウンロードして実行できます。

  • ネットワークで、ポート 15000 ~ 15030 の TCP 通信を許可する必要があります。

  • 各マシンには、デプロイが処理するデータをホストするのに十分なストレージが必要です。

  • システム要件のページで、設定が要件を満たしていることを確認します。

  • vSphere 仮想化プラットフォームでバイナリを実行する場合は、TSC 仮想化を無効にします。これを行うには、仮想マシンの .vmx 構成ファイルに monitor_control.virtual_rdtsc = FALSE 設定を追加します。

ステップ 1: TLS 暗号化なしでデプロイを作成する

暗号化なしで Spanner Omni VM デプロイを作成するの手順に沿って操作します。暗号化機能とセキュリティ機能を使用しない VM デプロイが正常に動作することを確認します。このページでは、3 つのゾーンを含むリージョン デプロイを作成していることを前提としています。

ステップ 2: 証明書を生成する

次の 3 つの証明書セットを作成する必要があります。

証明書の種類 説明
API 証明書 API 証明書は、Spanner API サーバーの保護に役立ちます。
サーバー証明書 サーバー証明書は、サーバー間の通信を保護するのに役立ちます。
クライアント証明書 エンドユーザーまたはアプリケーションは、クライアント証明書を使用して、Spanner Omni サーバーとの ID と信頼を確立します。

これらの証明書は認証局(CA)が発行します。Spanner Omni には、CA と 3 種類の証明書をすべて作成するためのツールが用意されています。いずれかのマシンで次の手順を行います。

これらの証明書は、Spanner Omni CLI を使用してワークステーションで作成し、証明書ファイルを各 Spanner Omni サーバーに転送できます。詳細については、Spanner Omni CLI の使用に関するクイックスタートをご覧ください。

証明書を生成するには、次の手順を完了する必要があります。

認証局(CA)を作成する

この認証局は、次の手順で生成するすべてのクライアント証明書とサーバー証明書のルート CA です。

spanner certificates create-ca --ca-certificate-directory=certs

certs ディレクトリには CA 証明書が含まれています。この証明書のコピーを作成して、API 証明書の CA として使用します。

cp certs/ca.crt certs/ca-api.crt

ディレクトリ $HOME/.spanner/private-keys には、CA の秘密鍵が含まれています。このディレクトリをバックアップして保護します。秘密鍵にアクセスできるユーザーは、自己署名 CA を信頼するクライアントが信頼する任意の証明書に署名できます。すべての証明書に同じ CA を使用できますが、API 証明書とクライアント証明書には同じ CA を使用する必要があります。必要に応じて、API 証明書用に追加の CA を作成する(または外部で信頼されている CA を使用する)ことができます。証明書を作成する際は、次の手順で適切な CA を使用してください。このドキュメントでは、すべての証明書タイプに同じ CA を使用します。

サーバー証明書を生成する

次の 2 種類のサーバー証明書を生成します。

この設定により、証明書のローテーションなど、これらの証明書をより柔軟に管理できます。

Spanner サーバー証明書を作成する

Spanner Omni サーバーは、サーバー証明書を使用して相互の通信(サーバー間通信)を暗号化します。

次のコマンドを実行して、サーバー証明書を作成します。SERVER_LIST は、Spanner サーバーまたはサフィックスの名前のカンマ区切りリストに置き換えます。

SERVER_NAMES=SERVER_LIST
spanner certificates create-server --hostnames=${SERVER_NAMES} --ca-certificate-directory certs --output-directory certs

このコマンドにより、certs ディレクトリに server.crt と server.key という 2 つのファイルが作成されます。

API 証明書を作成する

API 証明書は、デプロイとやり取りするシステムからの通信を暗号化します。API とサーバー間通信に個別の証明書を使用すると、各タイプを個別に管理してローテーションできます。

次のコマンドを実行して、API 証明書を作成します。LB_DNS は、ロードバランサの DNS に置き換えます。

SERVER_NAMES=LB_DNS
spanner certificates create-server --filename-prefix=api --hostnames=${SERVER_NAMES} --ca-certificate-directory certs --output-directory certs

このコマンドにより、certs ディレクトリに api.crt と api.key という 2 つのファイルが作成されます。必要に応じて、API 証明書に外部で信頼されている CA を使用できます。

証明書をすべてのサーバーに配布する

certs ディレクトリをデプロイ内の他のすべてのサーバーにコピーして、ネットワーク セキュリティ機能を使用して起動します。

scp -r certs REMOTE_HOST:SPANNER_DIR/certs

ステップ 3: クライアント証明書を生成する

クライアント証明書を使用して、Spanner でユーザーとアプリケーションを認証できます。クライアント証明書を使用すると、クライアントとサーバー間の mTLS が有効になります。

クライアント証明書は、API 証明書と同じ CA によって署名されている必要があります。また、認可用のユーザー名が含まれている必要があります。この例では、各データベースのデフォルト ユーザーである admin ユーザーを使用します。ユーザー、ロール、認証オプションの詳細については、Spanner Omni での認証と認可をご覧ください。

USERNAME=admin
spanner certificates create-client $USERNAME --output-directory clientcerts --ca-certificate-directory certs

このコマンドにより、clientcerts ディレクトリに client.crt ファイルと client.key ファイルが作成されます。これらのファイルを、デプロイのサーバーに接続するマシンに送信します。

Java クライアント ライブラリでクライアント証明書を使用する場合は、PKCS#8 形式で証明書鍵を生成する必要があります。次のコマンドを使用します。

USERNAME=admin
spanner certificates create-client $USERNAME \
    --output-directory clientcerts \
    --ca-certificate-directory certs \
    --generate-pkcs8-key

ステップ 4: ラッパー鍵セットを生成する

Spanner Omni は、鍵暗号鍵(KEK)ラッパー鍵セットを使用して、トークン暗号鍵や署名鍵などの内部鍵を暗号化します。Spanner Omni サーバーは、BASE_DIR/kms/wrapper_key からこの鍵セットを読み取ります。

spanner keys create-keyset を使用して新しいラッパー鍵セットファイルを生成するには、次のコマンドを実行します。

spanner keys create-keyset --output-file=kms/wrapper_key

デフォルトでは、spanner keys create-keyset は AES256_GCM 鍵を生成します。別のタイプの鍵を生成するには、--key-template フラグに鍵タイプの値(AES256_GCM、AES128_GCM、AES256_GCM_RAW、CHACHA20_POLY1305、XCHACHA20_POLY1305 のいずれか)を指定します。

ラッパー鍵セットをすべてのサーバーに配布する

デプロイメント内のすべてのサーバーを起動する前に、kms ディレクトリをベース ディレクトリにコピーします。

scp -r kms REMOTE_HOST:BASE_DIR/kms

ステップ 5: サーバーを起動する

デプロイメントでサーバーを起動する手順は次のとおりです。

  1. 証明書とラッパー鍵セットを生成し、デプロイメント内のすべてのサーバーにコピーしたことを確認します。
  2. 各サーバーに、データ、メタデータ、ログを保存するベース ディレクトリを作成します。サーバーを再起動する必要がある場合は、継続性のために同じベース ディレクトリを指定します。
  3. 次のセクションで、デプロイタイプの手順に沿って各サーバーを起動します。

単一サーバーのデプロイ

暗号化を使用して単一サーバーのデプロイを開始するには、初期 admin ユーザーのパスワード ファイルを作成し、サポートされている認証方法と証明書を使用してサーバーを起動します。

  1. 権限を 600 に設定してパスワード ファイルを作成し、オーナーのみが読み取れるようにします。

    printf '%s' 'PASSWORD' > admin_password.txt
    chmod 600 admin_password.txt
    

    パスワードは次の要件を満たす必要があります。

    • 8 ~ 32 文字。
    • 大文字を 1 つ以上含める。
    • 小文字を 1 文字以上。
    • 少なくとも 1 つの数字。
    • 1 つ以上の特殊文字。
  2. TLS と認証を構成して単一サーバーを起動します。

    nohup spanner start-single-server \
        --base-dir=BASE_DIR \
        --certificate-directory=${HOME}/.spanner/certs \
        --auth-methods=password,client-certificate \
        --password-protocol=opaque \
        --initial-admin-password-file=admin_password.txt &
    

    最初の起動時に、spanner start-single-server はサポートされている認証方法とパスワード プロトコルを設定し、指定されたパスワード ファイルを使用して roles/spanner.admin ロールを持つ初期 admin ユーザーを作成します。

デプロイの操作については、ステップ 8: デプロイを操作するをご覧ください。

スケールアウト デプロイ

スケールアウト デプロイの場合は、各マシンでサーバーを起動します。server-address と zone の値は、デプロイ構成の値と一致する必要があります。ネットワークは server-address を解決する必要があります。サーバーは内部通信に server-address を使用します。次のコマンドを実行して、ルートサーバーを起動します。

nohup spanner start \
    --root \
    --server-address=HOST_NAME \
    --zone=ZONE_NAME \
    --base-dir=BASE_DIR \
    --certificate-directory=${HOME}/.spanner/certs &

次のコマンドは、特定の値を使用した例を示しています。

nohup spanner start \
    --root \
    --server-address=rootserver1 \
    --zone=us-central-1a \
    --base-dir=./spanbasedir \
    --certificate-directory=${HOME}/.spanner/certs &

各マシンでサーバーが実行されているので、デプロイを作成する準備が整いました。

ステップ 6: TLS 暗号化を使用してデプロイを作成する

デプロイを作成する手順は次のとおりです。

  1. デフォルトの admin ユーザーのパスワードを含むパスワード ファイルを作成し、権限を 600(オーナーのみが読み取り可能)に設定します。

    printf '%s' 'PASSWORD' > admin_password.txt
    chmod 600 admin_password.txt
    

    パスワードは次の要件を満たす必要があります。

    • 8 ~ 32 文字。
    • 大文字を 1 つ以上含める。
    • 小文字を 1 文字以上。
    • 少なくとも 1 つの数字。
    • 1 つ以上の特殊文字。
  2. deployment.yaml に、選択した認証方法とパスワード プロトコルが含まれていることを確認します。

    deployment_settings:
      security_settings:
        authentication_methods:
          - AUTHENTICATION_METHOD_PASSWORD
          - AUTHENTICATION_METHOD_CLIENT_CERTIFICATE
        password_authentication_protocol: PASSWORD_AUTHENTICATION_PROTOCOL_OPAQUE
    

    次の認証方法を 1 つ以上指定できます。

    • AUTHENTICATION_METHOD_PASSWORD: パスワード認証
    • AUTHENTICATION_METHOD_CLIENT_CERTIFICATE: クライアント証明書認証

    次のパスワード プロトコルを指定できます。

    • PASSWORD_AUTHENTICATION_PROTOCOL_OPAQUE: OPAQUE プロトコル
  3. いずれかのルートサーバーから spanner deployment create コマンドを実行して、デプロイを作成します。--base-dir フラグでベース ディレクトリを指定し(ルートサーバーの起動時に指定した BASE_DIR を使用)、--admin-password-file フラグで管理者パスワード ファイルを指定します。

    spanner deployment create \
        --config-file=deployment.yaml \
        --base-dir=BASE_DIR \
        --admin-password-file=admin_password.txt
    

各マシンのコンソールに、デプロイに TLS 暗号化が含まれていることを示すメッセージが表示されます。すべてのサーバーは、暗号化されたチャネルを介して相互に通信します。

ステップ 7: (省略可)ロードバランサを構成する

デプロイ内のサーバー間でクライアント トラフィックを管理して分散するには、ロードバランサを設定します。ヘルスチェックのロードバランサ構成で、HTTP ではなく HTTPS が使用されていることを確認します。次の構成の詳細を使用します。

パラメータ 値
プロトコル TCP
バックエンド IP サーバーの IP アドレス。
ポート 15000(これはデフォルトのポートです。--server-address フラグで別のポートを使用した場合は、そのポートを使用します。
ヘルスチェック URL https://IP_ADDRESS:15012/healthz
バランシング戦略 roundrobin(サーバー間でリクエストを順番に分散)

ステップ 8: デプロイを操作する

Spanner Omni CLI を使用して、任意の VM から Spanner Omni デプロイを操作できます。

暗号化された接続を確立するには、各コマンドに次のフラグを含める必要があります。

  • --ca-certificate-file=certs/ca-api.crt

クライアントで mTLS を有効にした場合は、各コマンドに次のフラグも含めます。

  • --client-certificate-directory=clientcerts

ログインしてデプロイを操作する手順は次のとおりです。

  1. Spanner Omni にログインする

    spanner auth login admin \
        --ca-certificate-file=certs/ca-api.crt \
        --deployment-endpoint=ENDPOINT
    

    プロンプトが表示されたら、admin_password.txt で構成したパスワードを入力します。

    Successfully logged in as "admin"
    
  2. データベースの作成

    spanner --deployment-endpoint=ENDPOINT databases create mydb --ca-certificate-file=certs/ca-api.crt
    
    Creating database...done.
    
  3. SQL Shell を開く

    spanner sql --database=mydb --ca-certificate-file=certs/ca-api.crt
    
    Connected.
    spanner>
    
  4. テーブルを作成してデータを追加する

    spanner> create table names (nameId INT64 NOT NULL, name String(100)) Primary Key (nameId);
    Query OK, 0 rows affected (4.62 sec)
    
    spanner> insert names (nameId, name) values (1, "Jack");
    Query OK, 1 rows affected (0.18 sec)
    
  5. データを確認する

    データベースを一覧表示します。

    spanner databases list --ca-certificate-file=certs/ca-api.crt
    
    NAME  STATE  VERSION_RETENTION_PERIOD  EARLIEST_VERSION_TIME  KMS_KEY_NAME  ENABLE_DROP_PROTECTION
    mydb  READY  1h                        2025-02-07T12:25:30Z                 false
    

    テーブルからデータを取得します。

    spanner sql --database=mydb --ca-certificate-file=certs/ca-api.crt
    
    Connected.
    spanner> show tables;
    +----------------+
    | Tables_in_mydb |
    +----------------+
    | names          |
    +----------------+
    1 rows in set (0.14 sec)
    
    spanner> select * from names;
    +--------+--------+
    | nameId | name   |
    +--------+--------+
    | 1      | Jack   |
    +--------+--------+
    1 rows in set (18.69 msecs)
    

ステップ 9: (省略可)デプロイをスケーリングする

ゾーンに root 以外のサーバーを追加して、容量をスケーリングできます。非ルートサーバーを追加する手順は次のとおりです。

  1. 非ルートサーバーのサーバー証明書を生成し、証明書をコピーします。詳細については、ステップ 2: 証明書を生成するをご覧ください。

  2. ラッパー鍵セットを非 root サーバーにコピーします。詳細については、ステップ 4: ラッパー鍵セットを生成するをご覧ください。

  3. 非 root サーバーを起動します。

    spanner start \
        --server-address=NON_ROOT_MACHINE \
        --join-servers=ROOT_SERVER1,ROOT_SERVER2,ROOT_SERVER3 \
        --zone=us-central1-a \
        --base-dir=./spandir \
        --certificate-directory=${HOME}/.spanner/certs
    

次のステップ