全部產品
Search
文件中心

Key Management Service:從ECS執行個體安全訪問KMS

更新時間:Jul 06, 2024

您可以為VPC網路下的ECS執行個體建立RAM服務角色,使ECS執行個體內的應用程式可以使用STS臨時憑證或者通過SDK訪問KMS。

步驟一:建立執行個體RAM角色並授權

  1. 建立執行個體RAM角色。
    在OpenAPI開發人員門戶中調用RAM的CreateRole介面,建立執行個體RAM角色(EcsRamRoleTest)。請求參數設定如下:
    • RoleName:填寫執行個體RAM角色名稱(EcsRamRoleTest)。
    • AssumeRolePolicyDocument:填寫如下策略內容,表示允許ECS扮演該角色。
      {
          "Statement": [
              {
                  "Action": "sts:AssumeRole", 
                  "Effect": "Allow", 
                  "Principal": {
                      "Service": [
                          "ecs.aliyuncs.com"
                      ]
                  }
              }
          ], 
          "Version": "1"
      }
  2. 授予執行個體RAM角色訪問KMS的許可權。
    在OpenAPI開發人員門戶中調用RAM的AttachPolicyToRole介面,為執行個體RAM角色(EcsRamRoleTest)添加AliyunKMSFullAccess系統許可權。請求參數設定如下:
    • PolicyType:填寫System,表示系統策略。
    • PolicyName:填寫KMS系統策略名稱稱(AliyunKMSFullAccess)。
    • RoleName:填寫執行個體RAM角色名稱(EcsRamRoleTest)。

步驟二:授予執行個體RAM角色

您可以通過如下兩種方式為ECS執行個體授予RAM角色:
  • 為已有ECS執行個體授予執行個體RAM角色

    在OpenAPI開發人員門戶中調用ECS的AttachInstanceRamRole介面,為已有的VPC類型ECS執行個體授予執行個體RAM角色。請求參數設定如下:

    • RegionId:選擇執行個體所在的地區ID。
    • RamRoleName:填寫執行個體RAM角色名稱(EcsRamRoleTest)。
    • InstanceIds:填寫VPC類型ECS執行個體ID(["i-bXXXXXXXX"])。
  • 建立ECS執行個體時指定執行個體RAM角色
    1. 建立執行個體。
      在OpenAPI開發人員門戶中調用ECS的CreateInstance介面,建立ECS執行個體。請求參數設定如下:
      • RegionId:選擇執行個體所在地區(cn-hangzhou)。
      • ImageId:填寫執行個體的鏡像(centos_7_03_64_40G_alibase_20170503.vhd)。
      • InstanceType:填寫執行個體的規格(ecs.g6.large)。
      • VSwitchId:填寫執行個體所在的VPC交換器的ID。
        說明 執行個體RAM角色目前只支援VPC類型ECS執行個體,該參數必填。
      • RamRoleName:填寫執行個體RAM角色名稱(EcsRamRoleTest)。

      您也可以授權RAM使用者使用執行個體RAM角色。具體操作,請參見授權RAM使用者使用執行個體RAM角色

    2. 設定密碼並啟動執行個體。
    3. 使用API或在控制台設定ECS執行個體訪問公網的許可權。

步驟三(可選):擷取臨時授權Token

您可以獲得執行個體RAM角色的臨時授權Token,該臨時授權Token可以執行執行個體RAM角色的許可權和資源,並且自動周期性地更新。操作步驟如下:

  1. 檢索名為EcsRamRoleTest的執行個體RAM角色的臨時授權Token。
    • Linux執行個體:執行命令curl http://100.100.100.200/latest/meta-data/ram/security-credentials/EcsRamRoleTest
    • Windows執行個體:具體操作,請參見執行個體中繼資料
  2. 獲得臨時授權Token。
    返回樣本如下:
    {
       "AccessKeyId" : "STS.J8XXXXXXXXXX4",
       "AccessKeySecret" : "9PjfXXXXXXXXXBf2XAW",
       "Expiration" : "2017-06-09T09:17:19Z",
       "SecurityToken" : "CAIXXXXXXXXXXXwmBkleCTkyI+",
       "LastUpdated" : "2017-06-09T03:17:18Z",
       "Code" : "Success"
    }

步驟四:使用SDK訪問KMS

通過如下三種方式使用SDK訪問KMS:

KMS SDK

package com.aliyuncs.kms.examples;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.auth.AlibabaCloudCredentialsProvider;
import com.aliyuncs.auth.InstanceProfileCredentialsProvider;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.kms.model.v20160120.*;
import com.aliyuncs.profile.DefaultProfile;

public class RamRoleTest {
    public static void main(final String[] args) throws Exception {
        String regionId = "<region-id>";
        DefaultProfile profile = DefaultProfile.getProfile(regionId);

        // 設定RAM角色。
        String roleName = "<your-ecs-ram-role-name>"; // 本樣本使用"EcsRamRoleTest"。

        // 設定ECS執行個體RAM角色的憑證Provider。
        AlibabaCloudCredentialsProvider provider = new InstanceProfileCredentialsProvider(roleName);

        IAcsClient client = new DefaultAcsClient(profile, provider);

        EncryptRequest request = new EncryptRequest();

        // 指定用於加密Hello world的使用者主要金鑰別名或者使用者主要金鑰ID。
        request.setKeyId("alias/Apollo/SalaryEncryptionKey");
        request.setPlaintext("Hello world");

        try {
            EncryptResponse response = client.getAcsResponse(request);
            System.out.println(new Gson().toJson(response));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }
}

加密SDK

package com.aliyun.encryptionsdk.examples.credentials;
 
 import com.aliyun.encryptionsdk.AliyunConfig;
 import com.aliyun.encryptionsdk.AliyunCrypto;
 import com.aliyun.encryptionsdk.exception.InvalidAlgorithmException;
 import com.aliyun.encryptionsdk.exception.UnFoundDataKeyException;
 import com.aliyun.encryptionsdk.model.CryptoResult;
 import com.aliyun.encryptionsdk.provider.dataKey.DefaultDataKeyProvider;
 
 import java.util.Collections;
 
 import static org.junit.Assert.assertArrayEquals;
 
 /**
  *
  * 通過ECS執行個體RAM角色進行訪問認證。
  */
 public class EcsRamRoleSample {
     private static final String PLAIN_TEXT = "this is test.";
     private static final String cmkArn = "acs:kms:RegionId:UserId:key/CmkId";
     private static final String ecRamRoleName = "EcsRamRoleTest";
     public static void main(String[] args) {
         AliyunConfig config = new AliyunConfig();
         //設定RAM角色。
         config.withEcsRamRole(ecRamRoleName);
         
         AliyunCrypto crypto = new AliyunCrypto(config);
         
         DefaultDataKeyProvider defaultDataKeyProvider = new DefaultDataKeyProvider(cmkArn);
         try {
             CryptoResult<byte[]> encryptResult = crypto.encrypt(defaultDataKeyProvider, PLAIN_TEXT.getBytes(), Collections.singletonMap("sample", "Context"));
             CryptoResult<byte[]> decryptResult = crypto.decrypt(defaultDataKeyProvider, encryptResult.getResult());
             assertArrayEquals(decryptResult.getResult(), PLAIN_TEXT.getBytes());
         } catch (InvalidAlgorithmException | UnFoundDataKeyException e) {
             System.out.println("Failed.");
             System.out.println("Error message: " + e.getMessage());
         }
     }
 }

憑據管家用戶端

package com.aliyuncs.kms.secretsmanager.examples;
 
 import com.alibaba.fastjson.JSONObject;
 import com.aliyuncs.auth.InstanceProfileCredentialsProvider;
 import com.aliyuncs.kms.secretsmanager.cacheclient.exception.CacheSecretException;
 import com.aliyuncs.kms.secretsmanager.cacheclient.model.SecretInfo;
 import com.aliyuncs.kms.secretsmanager.cacheclient.service.DefaultSecretManagerClientBuilder;
 
 public class EcsSamples {
 
     public static void main(String[] args) throws CacheSecretException {
         String secretName = "<secret-name>";
         String roleName = "<your-ecs-ram-role-name>";
         String regionId = "<region-id>";
         SecretCacheClient client = SecretCacheClientBuilder.newCacheClientBuilder(
                 DefaultSecretManagerClientBuilder.standard().withCredentialsProvider(new InstanceProfileCredentialsProvider(roleName)).withRegion(regionId)
                         .build()
         ).build();
         SecretInfo secretInfo = client.getSecretInfo(secretName);
         System.out.println("secretInfo:"+JSONObject.toJSONString(secretInfo));
     }
 }