すべてのプロダクト
Search
ドキュメントセンター

Tair (Redis® OSS-Compatible):KMS を使用したインスタンスの認証情報の管理

最終更新日:Jun 03, 2026

Tair (Redis OSS-compatible) インスタンスの認証情報を KMS に保存することで、アプリケーションは静的認証情報を埋め込む代わりに、SDK を通じてパスワードを動的に取得できます。また、認証情報のローテーションを有効にすることで、漏洩リスクを軽減できます。

仕組み

KMS で管理される Tair (Redis OSS-compatible) インスタンスの認証情報を使用すると、アプリケーションに静的パスワードを保持する必要がなくなります。管理者は KMS でインスタンスの認証情報を作成し、アプリケーションは実行時に GetSecretValue オペレーションを呼び出してアカウントとパスワードを取得します。

例えば、認証情報の名前が username の場合、KMS はインスタンス上に usernameusername_clone の両方のアカウントを作成します。この二重アカウント方式により、より高い可用性とセキュリティを実現します。KMS コンソールでローテーションポリシーを設定できます。デフォルトでは、KMS は 24 時間ごとにアカウントをローテーションし、アクティブなアカウントを切り替えます。詳細については、「Redis/Tair の認証情報」をご参照ください。

重要

サービスの中断を防ぐため、KMS で管理されているアカウントのパスワードを Tair (Redis OSS-compatible) コンソールで変更または削除しないでください。

image

制限事項

  • KMS で管理されているアカウントのパスワードを Tair コンソールで変更することはできません。手動でローテーションするか、KMS コンソールで自動ローテーションを設定してください。詳細については、「Redis/Tair の認証情報のローテーション」をご参照ください。

  • KMS で管理されているアカウントを Tair コンソールで削除することはできません。代わりに KMS コンソールで削除してください。詳細については、「Redis の認証情報の削除」をご参照ください。

  • KMS で管理されているアカウントの説明を Tair コンソールで変更することはできません。

前提条件

  • Tair インスタンスに接続できる ECS インスタンスが必要です。本ドキュメントでは、Java 1.8.0 を搭載した Alibaba Cloud Linux 3.2104 LTS 64 ビットを使用しています。

  • RAM ユーザーまたは RAM ロールを使用してインスタンスの認証情報を管理する場合は、[AliyunKMSSecretAdminAccess] システムポリシーをそのユーザーまたはロールにアタッチしてください。詳細については、「アクセス許可の付与」をご参照ください。

操作手順

  1. KMS インスタンスを作成して有効化します。詳細については、「KMS インスタンスの作成と有効化」をご参照ください。

    KMS インスタンスの作成時には、ECS インスタンスと同じ VPC を選択してください。

    すでに KMS インスタンスをお持ちの場合は、ECS インスタンスの VPC をそれに追加してください。詳細については、「VPC の設定」をご参照ください。

  2. アプリケーションアクセスポイント (AAP) を作成します。詳細については、「アプリケーションアクセスポイントの作成」をご参照ください。

    作成後、ブラウザーから [アプリケーション ID 認証情報コンテンツ (ClientKeyContent、JSON ファイル)] と [認証情報セキュリティトークン (ClientKeyPassword)] がダウンロードされます。これらを安全に保管してください。

  3. [Instance Management] ページで KMS インスタンスの CA 証明書をダウンロードします。詳細については、「KMS インスタンスの CA 証明書の取得」をご参照ください。

  4. [カスタマーマスターキー (CMK)] を作成します。詳細については、「キー管理の開始」をご参照ください。

  5. Tair (Redis OSS-compatible) インスタンスの認証情報を作成します。詳細については、「Redis/Tair の認証情報の作成」をご参照ください。

  6. Java テストコードを作成します。

    1. 以下の Maven 依存関係を追加します。<build> セクションは、すべての依存関係を単一の JAR にパッケージ化します。

          <dependencies>
              <dependency>
                  <groupId>redis.clients</groupId>
                  <artifactId>jedis</artifactId>
                  <version>5.1.0</version>
              </dependency>
              <dependency>
                  <groupId>com.aliyun</groupId>
                  <artifactId>alibabacloud-dkms-gcs-sdk</artifactId>
                  <version>0.5.2</version>
              </dependency>
              <dependency>
                  <groupId>com.aliyun</groupId>
                  <artifactId>tea</artifactId>
                  <version>1.2.3</version>
              </dependency>
              <dependency>
                  <groupId>org.slf4j</groupId>
                  <artifactId>slf4j-api</artifactId>
                  <version>1.7.10</version>
              </dependency>
              <dependency>
                  <groupId>ch.qos.logback</groupId>
                  <artifactId>logback-classic</artifactId>
                  <version>1.2.9</version>
              </dependency>
          </dependencies>
      
          <build>
              <plugins>
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-assembly-plugin</artifactId>
                      <version>3.3.0</version>
                      <configuration>
                          <archive>
                              <manifest>
                                  <mainClass>
                                      com.aliyun.KMSJedisTest
                                  </mainClass>
                              </manifest>
                          </archive>
                          <descriptorRefs>
                              <descriptorRef>jar-with-dependencies</descriptorRef>
                          </descriptorRefs>
                      </configuration>
                      <executions>
                          <execution>
                              <id>assemble-all</id>
                              <phase>package</phase>
                              <goals>
                                  <goal>single</goal>
                              </goals>
                          </execution>
                      </executions>
                  </plugin>
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-compiler-plugin</artifactId>
                      <configuration>
                          <source>1.8</source>
                          <target>1.8</target>
                      </configuration>
                  </plugin>
              </plugins>
          </build>
    2. KMSJedisTest.java にメインコードを記述します。

      説明

      この例では、認証情報を 10 秒間キャッシュします (setCredentialCacheTime で設定可能)。これにより、新しい接続のたびに KMS を呼び出すことを回避します。本番環境では、KMS への頻繁な呼び出しを避けるため、少なくとも 10 分間のキャッシュ時間を推奨します。

      package com.aliyun;
      
      import java.time.Duration;
      
      import redis.clients.jedis.DefaultJedisClientConfig;
      import redis.clients.jedis.HostAndPort;
      import redis.clients.jedis.Jedis;
      import redis.clients.jedis.JedisPool;
      
      public class KMSJedisTest {
          public static void main(String[] args) throws Exception {
              if (args.length < 2) {
                  System.out.println(
                      "kmsEndpoint、clientKeyFilePath、clientKeyPass、caCertPath、secretName、redisHost を入力してください");
                  return;
              }
      
              String endpoint = args[0];
              String clientKeyFilePath = args[1];
              String clientKeyPass = args[2];
              String caCertPath = args[3];
              String secretName = args[4];
              KMSRedisCredentialsProvider kmsRedisCredentialsProvider = new KMSRedisCredentialsProvider(endpoint,
                  clientKeyFilePath, clientKeyPass, caCertPath, secretName);
              kmsRedisCredentialsProvider.setCredentialCacheTime(Duration.ofSeconds(10)); // KMS への頻繁なリクエストを防ぐため、キャッシュ時間を設定します。
      
              String redisHost = args[5];
              JedisPool jedisPool = new JedisPool(HostAndPort.from(redisHost),
                  DefaultJedisClientConfig.builder().credentialsProvider(kmsRedisCredentialsProvider).build());
      
              for (int i = 0; i < Integer.MAX_VALUE; i++) {
                  Thread.sleep(1000);
                  try (Jedis jedis = jedisPool.getResource()) {
                      System.out.println(jedis.set("" + i, "" + i));
                      System.out.println(jedis.get("" + i));
                  } catch (Exception e) {
                      System.out.println(e);
                  }
              }
          }
      }
      
    3. KMSRedisCredentialsProvider.java のコードを記述します。

      package com.aliyun;
      
      import java.time.Duration;
      import java.time.LocalDateTime;
      import java.time.format.DateTimeFormatter;
      
      import org.json.JSONObject;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import redis.clients.jedis.DefaultRedisCredentials;
      import redis.clients.jedis.RedisCredentials;
      import redis.clients.jedis.RedisCredentialsProvider;
      
      import com.aliyun.dkms.gcs.openapi.models.Config;
      import com.aliyun.dkms.gcs.sdk.Client;
      import com.aliyun.dkms.gcs.sdk.models.*;
      
      public class KMSRedisCredentialsProvider implements RedisCredentialsProvider {
          private static final Logger logger = LoggerFactory.getLogger(KMSRedisCredentialsProvider.class);
      
          private final String endpoint;
          private final String clientKeyFilePath;
          private final String clientKeyPass;
          private final String caCertPath;
          private final String secretName;
          private static Client client = null;
      
          // 認証情報のキャッシュ時間
          private Duration credentialCacheTime = Duration.ofSeconds(600);
          private DefaultRedisCredentials cachedCredentials = null;
          private LocalDateTime credentialsExpiration = null;
      
          public KMSRedisCredentialsProvider(String endpoint, String clientKeyFilePath, String clientKeyPass,
              String caCertPath, String secretName) {
              this.endpoint = endpoint;
              this.clientKeyFilePath = clientKeyFilePath;
              this.clientKeyPass = clientKeyPass;
              this.caCertPath = caCertPath;
              this.secretName = secretName;
              createClientInstance(endpoint, clientKeyFilePath, clientKeyPass, caCertPath);
          }
      
          public void setCredentialCacheTime(Duration credentialCacheTime) {
              this.credentialCacheTime = credentialCacheTime;
          }
      
          private static synchronized void createClientInstance(String endpoint, String clientKeyFilePath,
              String clientKeyPass, String caCertPath) {
              if (client == null) {
                  try {
                      client = new Client(new Config()
                          .setProtocol("https")
                          .setEndpoint(endpoint)
                          .setCaFilePath(caCertPath)
                          .setClientKeyFile(clientKeyFilePath)
                          .setPassword(clientKeyPass));
                  } catch (Exception e) {
                      logger.error("KMS クライアントの初期化に失敗しました", e);
                      throw new RuntimeException(e);
                  }
              }
          }
      
          @Override
          public RedisCredentials get() {
              try {
                  LocalDateTime now = LocalDateTime.now();
                  // キャッシュを確認
                  if (cachedCredentials != null && now.isBefore(credentialsExpiration)) {
                      return cachedCredentials;
                  }
      
                  GetSecretValueRequest request = new GetSecretValueRequest().setSecretName(secretName);
                  GetSecretValueResponse getSecretValueResponse = client.getSecretValue(request);
                  logger.debug("現在時刻: " + now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +
                      ", getSecretValueRequest: " + request);
                  String secretData = getSecretValueResponse.getSecretData();
                  JSONObject secretObject = new JSONObject(secretData);
                  if (secretObject.get("AccountName") == null || secretObject.get("AccountPassword") == null) {
                      throw new IllegalArgumentException("secretData には AccountName と AccountPassword を含める必要があります");
                  }
                  cachedCredentials = new DefaultRedisCredentials(secretObject.get("AccountName").toString(),
                      secretObject.get("AccountPassword").toString());
                  credentialsExpiration = now.plusSeconds(credentialCacheTime.getSeconds());
                  return cachedCredentials;
              } catch (Exception e) {
                  logger.error("シークレットの取得に失敗しました", e);
                  throw new RuntimeException(e);
              }
          }
      
          @Override
          public void prepare() {
              // 何もしない
          }
      
          @Override
          public void cleanUp() {
              // 何もしない
          }
      }
      
    4. 次のコマンドを実行して、プロジェクト全体を JAR ファイルにパッケージ化します: mvn package

  7. ECS インスタンス上で JAR を実行して Tair に接続します。

    構文:

    java -jar <kms-redis-jar-with-dependencies.jar> <kmsEndpoint> <clientKeyFilePath> <clientKeyPass> <caCertPath> <secretName> <redisHost>

    パラメーター:

    • kms-redis-jar-with-dependencies.jar: すべての依存関係を含むパッケージ化された JAR ファイルです。

    • kmsEndpoint: KMS インスタンスの VPC エンドポイントです。インスタンスの詳細ページで確認できます。

    • clientKeyFilePath: 手順 2 でダウンロードした AAP ID 認証情報 JSON ファイルです。

    • clientKeyPass: 手順 2 でダウンロードした認証情報セキュリティトークン (TXT ファイル) です。

    • caCertPath: 手順 3 でダウンロードした KMS インスタンスの CA 証明書 (PEM ファイル) です。

    • secretName: 手順 5 で作成したインスタンスの認証情報の名前です。

    • redisHost: VPC 接続アドレスとポートです。 例: r-bp1g727yrai5yh****.redis.rds.aliyuncs.com:6379

    例:

    java -jar kms-redis-samples-1.0-SNAPSHOT-jar-with-dependencies.jar kst-hzz6674e7fbw21x9x****.cryptoservice.kms.aliyuncs.com /root/clientKey_KAAP.6432ddc6-f23a-4d78-ac84-****4598206b.json 267d1****1cda4415058e1d72ec49e0a /root/PrivateKmsCA_kst-hzz6674e7fbw21x9x****.pem kms-redis r-bp1g727yrai5yh****.redis.rds.aliyuncs.com:6379

    接続成功時の出力例:

    0
    OK
    1
    OK
    2
    OK
    3
    OK
    4
    OK
  8. KMS コンソールで認証情報の即時ローテーションをテストします。詳細については、「Redis/Tair の認証情報のローテーション」をご参照ください。

    ローテーションにより、アクティブなアカウントが usernameusername_clone の間で切り替わります。

    ECS の接続が安定している場合、ローテーションは正常に機能しています。

    ...
    30
    OK
    31
    OK
    32
    OK
    33
    OK
  9. インスタンスでマスター/レプリカ HA 切り替えテストを実行し、クライアントを監視します。

    以下の出力は、HA 切り替え中の瞬断と、KMS が認証情報を更新した後の再接続の成功を示しています。

    138
    OK
    139
    redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
    OK
    142
    OK
    143
    OK

関連ドキュメント