当ECS实例或部署在ECS实例上的应用需要访问其他云资源时,必须先通过访问凭证来验证身份信息和访问权限。实例RAM角色允许您将一个角色关联到ECS实例,使ECS实例及其上的应用基于STS临时凭证访问其他云资源,无需透露长期AccessKey,既可减少密钥泄露的风险,也可借助访问控制RAM精细化控制资源访问权限,避免权限过度分配。本文主要介绍如何创建实例RAM角色并授予给ECS实例,以及如何基于实例RAM角色的获取临时访问凭证。
实例RAM角色是一种可信实体为阿里云服务的RAM角色,即允许云服务扮演的角色,用于解决跨服务访问问题。详细说明,请参见什么是RAM角色。
功能优势
基于实例RAM角色获取临时访问凭证验证身份信息和访问权限控制,有以下优势:
增强通信安全性:使用STS临时凭证代替长期AccessKey,降低凭证泄漏的风险。
跨服务访问并精细化管理权限:通过为不同ECS实例赋予具有特定授权策略的RAM角色,确保实例仅能访问其所需的资源,实现权限最小化。
简化权限维护:无需直接在ECS实例上管理凭据,权限的调整仅需通过修改RAM角色的授权策略来实现,快捷地维护ECS实例拥有的访问权限。
使用限制
为ECS实例授予实例RAM角色存在以下限制:
ECS实例的网络类型必须是专有网络VPC。
一台ECS实例只能授予一个实例RAM角色。
若您的账户为RAM用户(子账号),请先联系阿里云账号(主账号)获取使用实例RAM角色的权限。具体操作,请参见授权RAM用户使用实例RAM角色。
创建实例RAM角色并授予给ECS
通过控制台创建和授予
登录RAM控制台,创建实例RAM角色并为其授权。
创建可信实体为阿里云服务的RAM角色。
选择身份管理 > 角色,单击创建角色,按照界面提示完成角色创建。注意以下参数(其他参数按需填写,可参见创建可信实体为阿里云服务的RAM角色):
可信实体类型:选择阿里云服务。
角色类型:选择普通服务角色。
受信服务:选择云服务器。
为已创建的RAM角色授权。
在角色列表页,找到已创建的RAM角色,单击操作列的新增授权,为已创建的RAM角色添加所需权限。例如授予RAM角色访问OSS的权限:AliyunOSSReadOnlyAccessOSS。
说明支持添加系统策略或自定义策略。如需新建自定义策略,可参见创建自定义权限策略。
授予实例RAM角色给ECS实例。
登录ECS管理控制台。
在左侧导航栏,选择 。
在页面左侧顶部,选择目标资源所在的资源组和地域。
找到要操作的ECS实例,选择
。在对话框中,选择创建好的实例RAM角色,单击确定完成授予。
通过API创建和授予
创建并配置实例RAM角色
调用CreateRole接口创建实例RAM角色。
按如下策略设置参数AssumeRolePolicyDocument:
{ "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": [ "ecs.aliyuncs.com" ] } } ], "Version": "1" }
(可选)调用CreatePolicy接口新建权限策略。
如果您已有可用权限策略,可跳过该步骤。
PolicyDocument
(权限策略)需按如下设置:{ "Statement": [ { "Action": [ "oss:Get*", "oss:List*" ], "Effect": "Allow", "Resource": "*" } ], "Version": "1" }
调用AttachPolicyToRole接口为实例RAM角色授权。
调用AttachInstanceRamRole接口将实例RAM角色授予给ECS实例。
基于实例RAM角色获取临时访问凭证
方式一:在SDK中通过Credentials工具获取
Credentials工具会自动获取ECS实例绑定的实例RAM角色,并调用ECS的元数据服务(Meta Data Server)获取临时访问凭证,该凭证会周期性更新。
通过Credentials工具获取实例RAM角色的访问凭证,需要先安装Credentials工具。
sudo pip install alibabacloud_credentials
下文以Python和Java SDK为例,更多语言SDK示例,请参见示例代码。
from alibabacloud_credentials.client import Client
from alibabacloud_credentials.models import Config
config = Config(
type='ecs_ram_role',
# 选填,该ECS角色的角色名称,不填会自动获取,但是建议加上以减少请求次数
role_name='<RoleName>'
)
cred = Client(config)
access_key_id = cred.get_access_key_id()
access_key_secret = cred.get_access_key_secret()
security_token = cred.get_security_token()
cred_type = cred.get_type
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角色
通过控制台收回/更改
登录ECS管理控制台。
在左侧导航栏,选择 。
在页面左侧顶部,选择目标资源所在的资源组和地域。
找到要操作的ECS实例,选择
。收回实例RAM角色:操作类型选择收回,单击确定。
更改实例RAM角色:操作类型选择授予,选择所需的实例RAM角色,单击确定完成更改。
通过API收回/更改
收回实例RAM角色:调用DetachInstanceRamRole接口收回实例RAM角色。
更改实例RAM角色:
调用DetachInstanceRamRole接口收回实例RAM角色。
调用AttachInstanceRamRole接口重新为实例授予新的RAM角色。
应用示例:使用实例RAM角色访问其他云资源
下文以部署在Linux ECS实例上的Python应用程序访问OSS下载图片到ECS本地为例,为您介绍如何通过实例RAM角色其他云资源。
准备工作。
已创建ECS实例RAM角色,授予所需资源的访问权限(本文示例AliyunOSSReadOnlyAccessOSS),并将该实例RAM角色授予给ECS实例。
具体操作,可参见创建实例RAM角色并授予给ECS。
ECS实例所在的地域已创建了OSS存储空间(Bucket),并已获取Bucket的名称和Endpoint。
具体操作,请参见创建存储空间。
远程连接ECS实例,安装OSS Python SDK和alibabacloud_credentials。
说明下文以Alibaba Cloud Linux操作系统为例,如果您使用的是其他操作系统,安装方式请参见安装OSS Python SDK。
# 升级pip3和setuptools、wheel工具 sudo pip3 install --upgrade pip setuptools wheel # 安credentials工具 sudo pip3 install alibabacloud_credentials # 安装OSS SDK依赖的python-devel包 sudo yum install python3-devel # 安装OSS Python SDK sudo pip3 install oss2
使用实例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 = 'oss-test' # 需替换为实例RAM角色名称 bucket_name = 'ecs-ram' # 需替换为Bucket名称 endpoint = 'http://oss-cn-hangzhou.aliyuncs.com' # 需替换为OSS外网节点 object_key = 'testfolder/example.png' # 需替换为你要下载的图片在OSS中的完整存储路径(不包含Bucket名称) local_file = '/home/image.png' # 需替换为图片需要存储在ECS的根路径,并定义图片名称 download_image_using_instance_role(bucket_name, endpoint, object_key, local_file, role_name)
相关文档
当您的自建应用部署在阿里云ECS服务器上,且需要访问KMS应用时,可以使用ECS实例RAM角色访问KMS。具体操作,请参见使用ECS实例RAM角色安全访问KMS。
当ECS不需要某些资源访问权限时,可以通过移除实例RAM角色的权限,将这些权限移除。具体操作,请参见为RAM角色移除权限。
访问阿里云OpenAPI时,如果在代码中硬编码明文AK,容易因代码仓库权限管理不当造成AK泄露,建议您通过非AccessKey硬编码的方式编程,使用访问凭证访问阿里云OpenAPI,可参见使用访问凭证访问阿里云OpenAPI最佳实践和凭据的安全使用方案。