阿里云 AccessKey 泄露怎么办?手把手教你规范配置 RAM 角色权限
不少技术团队都遭遇过这样的“午夜惊魂”:忽然收到阿里云的夺命连环 call 或者短信通知,“您的账号检测到 AccessKey 泄露风险,部分资源正被高频异常调用……”
登录控制台一看,账单已经爆了,服务器甚至被黑客批量创建去挖矿。
导致这一切的根源,往往是因为图省事,直接在代码、配置文件或 GitHub 公开仓库里,硬编码了具有最高权限的主账号 AccessKey(AK/SK)。主账号的 AK 就像你家的万能钥匙,一旦泄露,整个云上资产等于对黑客完全敞开。
今天不扯虚的理论,不讲废话。直接手把手带你建立两道防线:第一,AK 泄露后的 5 分钟紧急止血;第二,如何用 RAM 角色(Role)彻底根除硬编码 AK 的隐患。
第一阶段:紧急止血!AccessKey 泄露的 5 分钟应急流
如果你发现或者怀疑 AK 已经泄露,不要犹豫,立刻执行以下操作,多耽误一分钟都是真金白银的损失。
步骤 1:全网禁用或删除涉事 AK
- 立刻登录阿里云控制台,点击右上角头像 $\rightarrow$ 选择 “AccessKey 管理”。
- 找到提示泄露的那个 AccessKey(无论是主账号的还是子账号的)。
- 先点击 “禁用”。此时所有使用该 AK 的外网请求会瞬间报错 403。
- 确认没有影响到核心生产业务后,果断点击 “删除”。
步骤 2:排查黑客留下的“后门”
黑客拿到 AK 后,第一件事往往是利用自动化脚本批量创建资源。
- 去 ECS 实例列表、轻量应用服务器列表,切换各个地域(北京、上海、深圳、香港、美国等),看看有没有莫名其妙多出来的服务器。有的话,立刻彻底释放。
- 去 操作审计(ActionTrail) 控制台,查询过去 24 小时内,该 AK 都调用了哪些 API,把黑客动过手脚的资源一个不漏地揪出来。
第二阶段:治本之策——规范配置 RAM 角色与最小权限
删除了 AK,老的项目代码直接崩了,因为它们需要权限去读写 OSS 或者是调用其他云服务。
我们不能再建一个新的主账号 AK 塞进去了。正确的做法是:使用 RAM 角色(RAM Role),让运行在阿里云上的程序自动、免密钥获取临时权限。
下面我们以“让云服务器 ECS 上的程序能够安全读写 OSS 存储桶”为例,进行实战配置。
步骤 1:创建 RAM 角色(凭空造一个“身份”)
- 在控制台搜索并进入 “RAM 访问控制”。
- 点击左侧菜单的 “角色” $\rightarrow$ “创建角色”。
- 选择可信实体类型为 “阿里云服务”,点击下一步。
- 角色类型:选择 “普通服务角色”。
- 角色名称:起一个易懂的名字,比如 ECS-OSS-Reader-Role。
- 选择受信服务:因为我们要把这个角色贴在云服务器上,所以这里选择 “云服务器”(ECS)。
- 点击确定。
步骤 2:精确授权(不给多余的权限)
刚创建的角色是一张白纸,没有任何权限。我们需要按照“最小权限原则”给它发许可证。
- 在角色列表里找到刚才创建的 ECS-OSS-Reader-Role,点击右侧的 “添加权限”。
- 授权范围:选择整个阿里云账号(默认)。
- 选择策略:如果只需读取 OSS:搜索并勾选 AliyunOSSReadOnlyAccess(只读访问OSS)。如果需要读写 OSS:搜索并勾选 AliyunOSSFullAccess(管理OSS)。
- 点击确定。
步骤 3:把角色绑定到 ECS 云服务器上
这一步非常关键,它相当于把这张“许可证”贴到了特定的服务器脑门上。
- 进入 “云服务器 ECS” 控制台,找到运行你代码的那台实例。
- 点击右侧的 “更多” $\rightarrow$ “实例设置” $\rightarrow$ “授予/收回 RAM 角色”。
- 在下拉菜单里,选择你刚才创建的 ECS-OSS-Reader-Role。
- 点击确定。
第三阶段:代码改造——彻底告别硬编码 AK
现在,你的服务器已经具备了合法身份。我们要去修改项目的代码,把那几行该死的 accessKeyId 和 accessKeySecret 彻底删掉。
阿里云的 SDK 具有自动凭证轮转注入功能。当代码在绑定了 RAM 角色的 ECS 上运行时,SDK 会通过访问服务器内部的一个特殊本地元数据地址
http ://100.100.100.200/latest/meta-data/
全自动获取一个每几个小时就自动过期更换的临时 Token。
哪怕黑客潜入服务器偷走了这个 Token,几小时后也会自动失效,根本无法用来作为持久后门。
以 Java SDK 访问 OSS 为例:
老代码(极度危险 ❌):
Java
// 严禁这样写!一旦代码上传到公开代码托管平台,全家桶瞬间升天
String accessKeyId = "LTAI5tXXXXXX";
String accessKeySecret = "Pn7yXXXXXX";
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
新代码(云原生安全 战略推荐 ):
Java
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
// 完全不需要出现任何明文密钥!
Config credentialConfig = new Config();
credentialConfig.setType("ecs_ram_role"); // 指定凭证类型为 ECS 绑定的 RAM 角色
// 如果留空,SDK 会自动寻找当前服务器绑定的角色名
// credentialConfig.setRoleName("ECS-OSS-Reader-Role");
Client credentialClient = new Client(credentialConfig);
// 使用临时凭证构建 OSS 客户端
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialClient);
终极防线:如何杜绝下一次泄露?
- 绝对、绝对、绝对不要在任何公开代码库(如 GitHub、Gitee)提交包含明文 AK 的配置文件。 哪怕是私有仓库也不行,很多泄露是因为员工把私有仓库错改成了公开。
- 善用 .gitignore。在项目初始化时,立刻把 application-prod.yml、config.json 等包含敏感信息的配置文件加入忽略列表。
- 本地开发怎么搞? 如果本地电脑确实需要 AK 调试,把 AK 配置到你电脑系统的环境变量里(通过 export ALIBABA_CLOUD_ACCESS_KEY_ID="xxx"),在代码中通过 System.getenv() 去读取。这样代码里永远都是干净的。
安全无小事。今晚就去排查一下你维护的项目,把那些硬编码的主账号 AK 统统干掉吧!

