全部產品
Search
文件中心

Key Management Service:使用ECS執行個體RAM角色安全訪問KMS

更新時間:Jul 06, 2024

ECS執行個體RAM角色是RAM角色的一種,它讓ECS執行個體扮演具有某些許可權的角色。當您的自建應用部署在阿里雲ECS伺服器上時,可以使用ECS執行個體RAM角色訪問KMS。本文介紹了如何使用ECS執行個體RAM角色訪問KMS。

支援ECS執行個體RAM角色的SDK

  • 阿里雲SDK:用於執行管控類操作。

  • 憑據SDK:包含憑據用戶端、憑據JDBC用戶端、RAM憑據外掛程式,用於擷取憑據值。

注意事項

  • ECS執行個體的網路類型為Virtual Private Cloud。

  • 一個ECS執行個體只能授予一個RAM角色。

  • 若您的賬戶為RAM使用者(子帳號),請先聯絡阿里雲帳號(主帳號)擷取配置RAM角色的許可權。具體操作,請參見授權RAM使用者使用執行個體RAM角色

步驟一:建立RAM角色並授權

通過RAM控制台

  1. 建立可信實體為阿里雲服務的RAM角色。

    1. 登入RAM控制台

    2. 在左側導覽列,選擇身份管理 > 角色

    3. 角色頁面,單擊建立角色,按照介面提示完成角色建立。注意以下參數,其他參數按需填寫。

      • 角色名稱:本文樣本為EcsRamRoleTest。

      • 可信實體類型:選擇阿里雲服務

      • 角色類型:選擇普通服務角色

      • 受信服務:選擇雲端服務器

  2. 授予RAM角色訪問KMS的許可權。

    成功建立RAM角色後,該RAM角色沒有任何許可權,您需要為該RAM角色授權。

    1. 角色頁面,單擊目標RAM角色操作列的新增授權

    2. 新增授權頁面,在系統策略上填寫KMS系統策略名稱稱(AliyunKMSFullAccess),然後單擊確定

通過RAM OpenAPI

  1. 建立可信實體為阿里雲服務的RAM角色。

    調用RAM的CreateRole - 建立角色介面,請求參數設定如下:

    • RoleName:填寫RAM角色名稱(本文樣本為EcsRamRoleTest)。

    • AssumeRolePolicyDocument:填寫如下策略內容,表示允許ECS扮演該角色。

      {
          "Statement": [
              {
                  "Action": "sts:AssumeRole", 
                  "Effect": "Allow", 
                  "Principal": {
                      "Service": [
                          "ecs.aliyuncs.com"
                      ]
                  }
              }
          ], 
          "Version": "1"
      }
  2. 授予RAM角色訪問KMS的許可權。

    調用RAM的AttachPolicyToRole - 為指定角色添加許可權介面,為執行個體RAM角色(EcsRamRoleTest)添加AliyunKMSFullAccess系統許可權。請求參數設定如下:

    • PolicyType:填寫System,表示系統策略。

    • PolicyName:填寫KMS系統策略名稱稱(AliyunKMSFullAccess)。

    • RoleName:填寫RAM角色名稱(EcsRamRoleTest)。

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

通過ECS控制台

說明

如果您還未購買ECS執行個體,請先購買ECS執行個體。具體操作,請參見自訂購買執行個體

  1. 登入ECS管理主控台

  2. 在左側導覽列,選擇執行個體與鏡像 > 執行個體

  3. 在頁面左側頂部,選擇ECS執行個體所在的資源群組和地區。

  4. 定位到目標ECS執行個體,選擇表徵圖 > 執行個體設定 > 授予/收回RAM角色

  5. 在對話方塊中,選擇建立好的RAM角色,單擊確定完成授予。

通過ECS OpenAPI

步驟三:使用ECS執行個體RAM角色訪問KMS

以使用Java語言,調用KMS ListKeys介面查詢當前地區的所有密鑰ID為例。更詳細的SDK使用指導請參見SDK參考

阿里雲SDK(V1.0)

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角色。本文樣本使用"EcsRamRoleTest"。
        String roleName = "EcsRamRoleTest"; 

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

        IAcsClient client = new DefaultAcsClient(profile, provider);

        ListKeysRequest request = new ListKeysRequest();
      
        try {
            ListKeysResponse 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(V2.0)

package com.aliyun.sample;

import com.aliyun.tea.*;

public class Sample {

    public static com.aliyun.kms20160120.Client createClient() throws Exception {
        com.aliyun.credentials.models.Config credentialConfig = new com.aliyun.credentials.models.Config();
        // 憑證類型
        credentialConfig.type = "ecs_ram_role";
        // 選填,該ECS執行個體角色名稱,不填會自動擷取,但是建議加上以減少請求次數
        credentialConfig.roleName = "<your-ecsRamRoleName>";
        com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialConfig);

        com.aliyun.teaopenapi.models.Config kmsClientConfig = new com.aliyun.teaopenapi.models.Config()
        //設定KMS endpoint,例如:kms.cn-hangzhou.aliyuncs.com
        .setEndpoint( "kms.cn-hangzhou.aliyuncs.com").
                setCredential(credentialClient);
        return new com.aliyun.kms20160120.Client(kmsClientConfig);

    }

    public static void main(String[] args_) throws Exception {
        java.util.List<String> args = java.util.Arrays.asList(args_);
        com.aliyun.kms20160120.Client client = Sample.createClient();
        com.aliyun.kms20160120.models.ListKeysRequest listKeysRequest = new com.aliyun.kms20160120.models.ListKeysRequest();
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            client.listKeysWithOptions(listKeysRequest, runtime);
        } catch (TeaException error) {
            System.out.println(error.getMessage());
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            _error.printStackTrace();
        }        
    }
}

憑據用戶端

更多詳細資料,請參見憑據用戶端

  1. 通過系統內容變數或設定檔secretsmanager.properties配置以下參數。

    參數

    參數值

    credentials_type

    固定取值ecs_ram_role。

    credentials_role_session_name

    RAM角色名稱。

    cache_client_region_id

    格式為[{"regionId":"<your region id>"}],請將<your region id>替換為您真實的地區ID。

  2. 構建用戶端擷取憑據值。

    import com.aliyuncs.kms.secretsmanager.client.SecretCacheClient;
    import com.aliyuncs.kms.secretsmanager.client.SecretCacheClientBuilder;
    import com.aliyuncs.kms.secretsmanager.client.exception.CacheSecretException;
    import com.aliyuncs.kms.secretsmanager.client.model.SecretInfo;
    
    public class CacheClientEnvironmentSample {
    
        public static void main(String[] args) {
            try {
                //構建憑據用戶端
                SecretCacheClient client = SecretCacheClientBuilder.newClient();
                //使用構建好的用戶端擷取憑據資訊
                SecretInfo secretInfo = client.getSecretInfo("#secretName#");
                System.out.println(secretInfo);
            } catch (CacheSecretException e) {
                e.printStackTrace();
            }
        }
    }

憑據JDBC用戶端

以通過JDBC方式串連MySQL資料庫為例介紹。詳細資料,請參見憑據JDBC用戶端

  1. 在專案的運行代碼中新增設定檔secretsmanager.properties

    ## 訪問憑據類型
    credentials_type=ecs_ram_role
    ## ECS RAM Role名稱
    credentials_role_name=#credentials_role_name#
    ## 關聯的KMS服務地區
    cache_client_region_id=[{"regionId":"#regionId#"}]
    ## 使用者自訂的重新整理頻率, 預設為6小時,最小值為5分鐘,單位為毫秒
    refresh_secret_ttl=21600000
  2. 通過JDBC方式串連MySQL資料庫。

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    public class SecretManagerJDBCSample {
        public static void main(String[] args) throws Exception {
            // 載入阿里雲憑據管家JDBC Load the JDBC Driver com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver
            Class.forName("com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver");
            Connection connect = null;
            try {
                connect = DriverManager.getConnection("secrets-manager:mysql://<YOUR-MYSQL-IP>:<YOUR-MYSQL-PORT>/<YOUR-DATABASE-NAME>", "#your-mysql-secret-name#","");
            } catch(SQLException e) {
                e.printStackTrace();
            }
        }
    }

RAM憑據外掛程式

更多詳細資料,請參見RAM憑據外掛程式

  1. 在專案的運行代碼中新增設定檔managed_credentials_providers.properties

    credentials_type=ecs_ram_role
    ## ECS RAM Role名稱
    credentials_role_name=#credentials_role_name#
    ## 關聯的KMS服務地區
    cache_client_region_id=[{"regionId":"#regionId#"}]
  2. 獲得阿里雲Java SDK用戶端並調用雲端服務。

    以調用ECS DescribeInstanceStatus為例:

    運行以下範例程式碼時,請自行在pom.xml中添加雲端服務器aliyun-java-sdk-ecs依賴。

    import com.aliyuncs.IAcsClient;
    import com.aliyuncs.ecs.model.v20140526.DescribeInstanceStatusRequest;
    import com.aliyuncs.ecs.model.v20140526.DescribeInstanceStatusResponse;
    import com.aliyun.kms.secretsmanager.plugin.sdkcore.ProxyAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.exceptions.ServerException;
    
    public class AliyunSdkProviderSample {
        public static void main(String[]args) {
            String secretName="******";
            /*
              如果應用無法設定從classpath和可執行jar包中讀取預設設定檔(managed_credentials_providers.properties),
              或需自訂設定檔名稱時,可調用以下代碼設定自訂設定檔,並按以下順序讀取:
              1."your-config-name"配置絕對路徑+檔案名稱,即讀取絕對路徑下的檔案
              2."your-config-name"僅設定檔名稱,預設先讀取classpath下的設定檔,再讀取可執行jar包中的設定檔
            */
            //ConfigLoader.setConfigName("your-config-name");
            
            // 1. 擷取ACSClient by aliyun-java-sdk-managed-credentials-provider
            IAcsClient client = null;
            try {
                client = new ProxyAcsClient("<the regionId of ECS>", secretName);
            } catch (ClientException e) {
                 e.printStackTrace();
             }
            // 2. 調用ECS的OpenAPI實現業務功能
            DescribeInstanceStatusRequest request = new DescribeInstanceStatusRequest();
            DescribeInstanceStatusResponse response;
            try {
                 response = client.getAcsResponse(request);
            } catch (ServerException e) {
                 e.printStackTrace();
             } catch (ClientException e) {
                 e.printStackTrace();
             }
            // 3. 通過下面方法關閉用戶端來釋放外掛程式關聯的資源 
            client.shutdown();
        }
    }

相關文檔