文档

通过ECS实例RAM角色授权ECS访问其他云资源

更新时间:

当ECS实例或部署在ECS实例上的应用需要访问其他云资源时,必须配置访问凭证,阿里云服务会通过访问凭证验证您的身份信息和访问权限。实例RAM角色允许您将一个角色关联到ECS实例,实现在实例内部自动获取并刷新临时访问凭证,无需直接暴露AccessKey,减少密钥泄露的风险。同时,也可借助RAM角色精细化控制资源访问权限,避免权限过度分配。本文主要介绍如何创建实例RAM角色并授予给ECS实例,以及如何基于实例RAM角色的获取临时访问凭证。

说明

实例RAM角色是一种可信实体为阿里云服务的RAM角色,即允许云服务扮演的角色,用于解决跨服务访问问题。关于RAM角色的详细说明,请参见什么是RAM角色

功能优势

基于实例RAM角色获取临时访问凭证验证身份信息和访问权限控制,有以下优势:

  • 增强通信安全性:使用STS临时凭证代替长期AccessKey,降低凭证泄漏的风险。

  • 跨服务访问并精细化管理权限:通过为不同ECS实例赋予具有特定授权策略的RAM角色,确保实例仅能访问其所需的资源,实现权限最小化。

  • 简化权限维护:无需直接在ECS实例上管理凭据,权限的调整仅需通过修改RAM角色的授权策略来实现,快捷地维护ECS实例拥有的访问权限。

使用限制

为ECS实例授予实例RAM角色存在以下限制:

  • ECS实例的网络类型必须是专有网络VPC。

  • 一台ECS实例只能授予一个实例RAM角色。

实现流程

创建ECS实例RAM角色并授予给ECS

创建一个RAM角色,并为该角色授予所需的阿里云服务访问权限。例如,如果ECS实例需要访问OSS,就要给角色赋予OSS的读写权限。

重要

若您的操作账户为RAM用户(子账号),请先联系阿里云账号(主账号)获取使用和配置实例RAM角色的权限。具体操作,请参见授权RAM用户使用ECS资源

权限策略参考如下

{
    "Version": "1",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecs:[ECS RAM Action]",
                "ecs:CreateInstance",
                "ecs:AttachInstanceRamRole",
                "ecs:DetachInstanceRAMRole"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "ram:PassRole",
            "Resource": "*"
        }
    ]
}

通过控制台创建和授予

  1. 登录RAM控制台,创建实例RAM角色并为其授权。

    1. 创建可信实体为阿里云服务的RAM角色。

      选择身份管理 > 角色,单击创建角色,按照界面提示完成角色创建。注意以下参数(其他参数按需填写,可参见创建普通服务角色):

      • 可信实体类型:选择阿里云服务

      • 角色类型:选择普通服务角色

      • 受信服务:选择云服务器

    2. 为已创建的实例RAM角色授权。

      将系统策略或已创建的自定义权限策略授权给RAM用户,使其拥有相关的资源访问或操作权限。例如,给角色赋予OSS的读写权限(AliyunOSSReadOnlyAccess)。

      说明

      支持添加系统策略自定义策略。若系统策略不满足您的需求,可新建自定义策略。具体操作,请参见创建自定义权限策略

  2. 授予实例RAM角色给ECS实例。

    1. 登录ECS管理控制台

    2. 在左侧导航栏,选择实例与镜像 > 实例

    3. 在页面左侧顶部,选择目标资源所在的资源组和地域。地域

    4. 找到要操作的ECS实例,选择图标 > 实例设置 > 授予/收回RAM角色

    5. 在对话框中,选择创建好的实例RAM角色,单击确定

通过API创建和授予

  1. 创建并配置实例RAM角色

    1. 调用CreateRole接口创建实例RAM角色。

      按如下策略设置参数AssumeRolePolicyDocument

      {
           "Statement": [
           {
               "Action": "sts:AssumeRole",
               "Effect": "Allow",
               "Principal": {
               "Service": [
               "ecs.aliyuncs.com"
               ]
               }
           }
           ],
           "Version": "1"
       }
    2. (可选)调用CreatePolicy接口新建权限策略。

      如果您已有可用权限策略,可跳过该步骤。

      PolicyDocument(权限策略)需按如下设置:

      {
           "Statement": [
               {
               "Action": [
                   "oss:Get*",
                   "oss:List*"
               ],
               "Effect": "Allow",
               "Resource": "*"
               }
           ],
           "Version": "1"
       }
    3. 调用AttachPolicyToRole接口为实例RAM角色授权。

  2. 调用AttachInstanceRamRole接口将RAM角色授予ECS实例。

通过ECS实例RAM角色获取临时访问凭证

获取到临时访问凭证后,应用程序即可使用这些临时凭证安全地调用阿里云API,进行跨服务访问或数据操作。该临时授权访问凭证会自动周期性地更新。

方式一:在SDK中通过Credentials工具获取

Credentials工具会自动获取ECS实例绑定的实例RAM角色,并调用ECS的元数据服务(Meta Data Server)获取临时访问凭证STS Token,该凭证会周期性更新。

下文以Python和Java SDK为例,更多语言SDK示例,请参见使用访问凭据访问阿里云OpenAPI最佳实践

Python
  1. 安装Credentials工具。

    sudo pip install alibabacloud_credentials
  2. 配置ECS的RAM角色作为访问凭证。

    from alibabacloud_credentials.client import Client as CredClient
    from alibabacloud_credentials.models import Config as CredConfig
    
    credentialConfig = CredConfig(
    	type='ecs_ram_role',
    	# 选填,该ECS角色的角色名称,不填会自动获取,但是建议加上以减少请求次数
    	role_name='<RoleName>'
    )
    credentialsClient = CredClient(credentialConfig)

Java

  1. 添加credentials依赖。

    <!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java -->
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>credentials-java</artifactId>
        <version>0.3.4</version>
    </dependency>
  2. 配置ECS实例RAM角色作为访问凭证。

    import com.aliyun.credentials.Client;
    import com.aliyun.credentials.models.Config;
    
    public class DemoTest {
        public static void main(String[] args) throws Exception {
            Config credentialConfig = new Config();
            credentialConfig.setType("ecs_ram_role");
            // 选填,该ECS角色的角色名称,不填会自动获取,但是建议加上以减少请求次数
            credentialConfig.setRoleName("<RoleName>");
            Client credentialClient = new Client(credentialConfig);
        }
    }

方式二:在实例内部获取(通过元数据)

某些场景,如果您没有适配Credentials工具,或需要在脚本中基于实例RAM角色来获取资源临时访问凭证,可直接在实例内部访问元数据服务器获取。

说明

通过元数据服务,您无需登录控制台或调用API,在实例内部即可获取实例信息。详细说明,请参见实例元数据

加固模式

  • Linux实例

    # 获取元数据服务器的访问凭证用于鉴权
    TOKEN=`curl -X PUT "http://100.100.100.200/latest/api/token" -H "X-aliyun-ecs-metadata-token-ttl-seconds:<元数据服务器访问凭证有效期>"` 
    # 获取实例RAM角色的临时授权访问凭证
    curl -H "X-aliyun-ecs-metadata-token: $TOKEN" http://100.100.100.200/latest/meta-data/ram/security-credentials/<实例RAM角色名称>
  • Windows实例(Powershell)

    # 获取元数据服务器的访问凭证用于鉴权
    $token = Invoke-RestMethod -Headers @{"X-aliyun-ecs-metadata-token-ttl-seconds" = "<元数据服务器的访问凭证有效期>"} -Method PUT -Uri http://100.100.100.200/latest/api/token
    # 获取实例RAM角色的临时授权访问凭证
    Invoke-RestMethod -Headers @{"X-aliyun-ecs-metadata-token" = $token} -Method GET -Uri http://100.100.100.200/latest/meta-data/ram/security-credentials/<实例RAM角色名称>

<元数据服务器的访问凭证有效期>:实例RAM角色的临时授权访问凭证是通过元数据服务器获取的,在获取实例RAM角色的临时授权访问凭证之前,先获取元数据服务器的访问凭证并设置其有效期,以加强数据安全。超过有效期后,需要重新获取凭证,否则无法获取实例RAM角色的临时授权访问凭证。

取值范围为1~21600,单位为秒。详细说明,请参见实例元数据

<实例RAM角色名称>需替换为具体的实例RAM角色名称。例如EcsRamRoleDocumentTesting。

普通模式

  • Linux实例

    curl http://100.100.100.200/latest/meta-data/ram/security-credentials/<实例RAM角色名称>
  • Windows实例(Powershell)

    Invoke-RestMethod http://100.100.100.200/latest/meta-data/Invoke-RestMethod http://100.100.100.200/latest/meta-data/ram/security-credentials/<实例RAM角色名称>

    <实例RAM角色名称>需替换为具体的实例RAM角色名称。例如EcsRamRoleDocumentTesting。

返回示例如下,其中:

  • SecurityToken:实例RAM角色的临时Token。

  • Expiration:实例RAM角色的临时授权访问凭证的有效期(非元数据服务器的访问凭证有效期)。

    {
       "AccessKeyId" : "STS.*******6YSE",
       "AccessKeySecret" : "aj******jDU",
       "Expiration" : "2017-11-01T05:20:01Z", 
       "SecurityToken" : "CAISng********",
       "LastUpdated" : "2023-07-18T14:17:28Z",
       "Code" : "Success"
    }

收回/更改ECS的实例RAM角色

通过控制台收回/更改

  1. 登录ECS管理控制台

  2. 在左侧导航栏,选择实例与镜像 > 实例

  3. 在页面左侧顶部,选择目标资源所在的资源组和地域。地域

  4. 找到要操作的ECS实例,选择图标 > 实例设置 > 授予/收回RAM角色

    • 收回实例RAM角色:操作类型选择收回,单击确定

    • 更改实例RAM角色:操作类型选择授予,选择所需的实例RAM角色,单击确定完成更改。

      image.png

通过API收回/更改

应用示例:通过ECS实例RAM角色访问其他云服务

下文以部署在Linux ECS实例上的Python应用程序访问OSS下载图片为例,为您介绍如何通过ECS及部署在ECS实例上的应用如何通过实例RAM角色访问其他云资源。

  1. 准备工作。

    1. 创建ECS实例RAM角色,授予所需资源的访问权限(本文示例AliyunOSSReadOnlyAccess),并将该实例RAM角色授予ECS实例。

      具体操作,可参见创建ECS实例RAM角色并授予给ECS

    2. 在ECS实例所在的地域创建OSS存储空间(Bucket),并记录Bucket名称和EndPoint,可在Bucket概览页获取。具体操作,请参见创建存储空间

      重要

      若需通过外网访问OSS,请确保ECS实例已开通公网。您可以通过更改带宽或绑定EIP方式开通IPv4公网。具体操作,请参见修改固定公网带宽绑定EIP

      image

      image

    3. 上传图片到OSS存储空间(Bucket)。具体操作,请参见上传图片到OSS

  2. 远程连接ECS实例,安装OSS Python SDK和alibabacloud_credentials。

    说明

    本步骤以Alibaba Cloud Linux 3 ECS实例为例,Alibaba Cloud Linux 3默认安装的是Python 3,如果您使用其他Linux操作系统需要根据Python版本适当调整命令。如果您使用的是Windows ECS实例,请参见安装OSS Python SDK

    1. 升级pip和setuptools、wheel工具。

      sudo pip3 install --upgrade pip setuptools wheel
    2. 安装credentials工具。

      sudo pip3 install alibabacloud_credentials  
    3. 安装OSS SDK依赖的python-devel包。

      sudo yum install python3-devel 
    4. 安装OSS Python SDK。

      sudo pip3 install oss2 
  3. 使用实例RAM角色作为临时凭证访问OSS,并下载图片。

    Python示例代码如下(部分信息需参考注释,按实际情况替换):

    import oss2
    from alibabacloud_credentials.client import Client
    from alibabacloud_credentials.models import Config
    from oss2 import CredentialsProvider
    from oss2.credentials import Credentials
    
    class CredentialProviderWarpper(CredentialsProvider):
        def __init__(self, client):
            self.client = client
    
        def get_credentials(self):
            access_key_id = self.client.get_access_key_id()
            access_key_secret = self.client.get_access_key_secret()
            security_token = self.client.get_security_token()
            return Credentials(access_key_id, access_key_secret, security_token)
    
    def download_image_using_instance_role(bucket_name, endpoint, object_key, local_file, role_name):
        config = Config(
            type='ecs_ram_role',      # 访问凭证类型。固定为ecs_ram_role。
            role_name=role_name
        )
        cred = Client(config)
        credentials_provider = CredentialProviderWarpper(cred)
        auth = oss2.ProviderAuth(credentials_provider)
    
        # 初始化 OSS Bucket 对象
        bucket = oss2.Bucket(auth, endpoint, bucket_name)
        # 下载图片到本地
        bucket.get_object_to_file(object_key, local_file)
        print("Image downloaded successfully")
    
    if __name__ == "__main__":  
    
        # 定义全局变量
        role_name = 'role_name'  # 需替换为实例RAM角色名称
        bucket_name = 'bucket_name'  # 需替换为Bucket名称
        endpoint = 'http://oss-cn-beijing-internal.aliyuncs.com'  # 需替换为OSS Bucket的Endpoint
        object_key = 'testfolder/example.png'  # 需替换为你要下载的图片在OSS中的完整存储路径(不包含Bucket名称)
        local_file = '/localpath/to/image.png'  # 需替换为图片需要在ECS上存储的根路径,并定义图片名称
        download_image_using_instance_role(bucket_name, endpoint, object_key, local_file, role_name)

相关文档