当前位置: 首页 > news >正文

使用GitHub Actions 安全部署到阿里云 ECS

  • 使用GitHub Actions 安全部署到阿里云 ECS

本文介绍了一种通过 GitHub Actions 安全部署到阿里云 ECS 的方案:在自动化部署时,动态获取当前运行器的公网 IP,临时将其加入安全组的 22 端口放行规则中,部署完成后立即自动删除该规则,从而避免长期开放端口带来的安全风险。


1. 概述

  • 目标:在 GitHub Actions 运行部署任务时,自动获取运行器的公网 IP,通过阿里云 API 将该 IP 临时加入安全组(仅允许访问 22 端口),部署完成后立即删除该规则,从而避免长期开放端口带来的安全风险。
  • 优势:避免长期开放 22 端口,大幅降低被扫描和暴力破解的风险。
  • 适用场景:需要从 GitHub Actions 安全地 SSH 登录阿里云 ECS 进行部署的任何项目。

2. 准备工作:阿里云端配置

2.1 确认 ECS 实例和安全组信息
  1. 登录阿里云控制台,进入ECS 管理页面
  2. 找到目标实例,记录以下信息(后续需要填入 GitHub Secrets):
    • 实例所属地域 ID(例如cn-hangzhou,详见第 5 节表格)
    • 实例绑定的安全组 ID(例如sg-xxxxxx
  3. 进入该安全组的入方向规则页面,删除所有允许0.0.0.0/0访问 22 端口的规则。目前可以保持为空,或仅保留内网访问规则。
2.2 创建 RAM 子账号并授权

为 GitHub Actions 创建一个专用的 RAM 子用户,并授予管理安全组的权限。

  1. 访问 RAM 控制台。
  2. 创建用户:
    • 登录名称:例如github-actions
    • 访问配置:勾选使用永久 AccessKey 访问
    • AccessKey:勾选我确认必须创建 AccessKey(系统将生成 AccessKey ID 和 Secret)
  3. 保存 AccessKey ID 和 Secret(务必立即保存,关闭后将无法再次查看)。
  4. 为该用户授权(新增授权):
    • 添加权限AliyunECSFullAccess(系统策略,允许管理 ECS 资源,包括安全组)。
    • 若需更精细的权限,可参考 8.3 节自定义策略。

3. GitHub 仓库配置 Secrets

在 GitHub 仓库的Settings → Secrets and variables → Actions中添加以下敏感信息:

Secret 名称说明
ALIYUN_ACCESS_KEY_ID上一步创建的 RAM 用户的 AccessKey ID
ALIYUN_ACCESS_KEY_SECRET对应的 AccessKey Secret
ALIYUN_REGIONECS 实例所在地域 ID(例如cn-hangzhou
ALIYUN_SECURITY_GROUP_ID安全组 ID(例如sg-xxxxxx

如果你还需要通过 SSH 部署,请额外添加以下 Secrets(可选):

  • REMOTE_HOST:ECS 公网 IP 或域名
  • REMOTE_USER:SSH 用户名
  • SSH_PRIVATE_KEY:SSH 私钥

4. 通用 GitHub Actions 工作流模板

将以下代码片段放入你的工作流文件中(如.github/workflows/deploy.yml),并在# 在这里插入你的构建/部署步骤处替换为你自己的任务。

name:Secure Deploy to Aliyun ECSon:push:branches:[main]# 触发分支,可按需修改jobs:deploy:runs-on:ubuntu-lateststeps:# ---------- 1. 获取当前运行器的公网 IP -----------name:Get Runner Public IPid:iprun:|RUNNER_IP=$(curl -s http://ifconfig.me) echo "CURRENT_IP=$RUNNER_IP" >> $GITHUB_OUTPUT echo "Runner IP: $RUNNER_IP"# ---------- 2. 安装阿里云 CLI(二进制方式)-----------name:Install Aliyun CLIrun:|curl -LO "https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz" tar -xzf aliyun-cli-linux-latest-amd64.tgz mkdir -p $HOME/.local/bin mv aliyun $HOME/.local/bin/ echo "$HOME/.local/bin" >> $GITHUB_PATH aliyun --version# ---------- 3. 临时放行当前 IP(22 端口)-----------name:Authorize Security Group (Add IP)env:ALIBABA_CLOUD_ACCESS_KEY_ID:${{secrets.ALIYUN_ACCESS_KEY_ID}}ALIBABA_CLOUD_ACCESS_KEY_SECRET:${{secrets.ALIYUN_ACCESS_KEY_SECRET}}ALIBABA_CLOUD_REGION_ID:${{secrets.ALIYUN_REGION}}run:|aliyun ecs AuthorizeSecurityGroup \ --RegionId ${{ secrets.ALIYUN_REGION }} \ --SecurityGroupId ${{ secrets.ALIYUN_SECURITY_GROUP_ID }} \ --IpProtocol tcp \ --PortRange 22/22 \ --SourceCidrIp ${{ steps.ip.outputs.CURRENT_IP }}/32 \ --Policy accept \ --NicType intranet# (可选)等待几秒让规则生效-name:Wait for rule to take effectrun:sleep 5# ---------- 在这里插入你的构建/部署步骤 ----------# 例如:# - name: Build and Deploy# run: |# echo "Your deployment commands here" # # 或使用 SSH Action: # # ---------- 验证 SSH 访问成功 ---------- # - name: Verify SSH Connection # uses: appleboy/ssh-action@v1.0.3 # with: # host: ${{ secrets.REMOTE_HOST }} # ECS 公网 IP 或域名 # username: ${{ secrets.REMOTE_USER }} # 登录用户名(如 root 或普通用户) # key: ${{ secrets.SSH_PRIVATE_KEY }} # 私钥内容(需在 secrets 中配置) # port: 22 # SSH 端口,默认 22 # script: | # echo "✅ SSH connection to ECS is successful!" # echo "Hostname: $(hostname)" # echo "Current user: $(whoami)" # echo "Working directory: $(pwd)" # # 可以在此处添加更多验证命令,如检查必要目录是否存在# ---------- 4. 撤销放行(删除刚才添加的规则)-----------name:Revoke Security Group (Remove IP)if:always()env:ALIBABA_CLOUD_ACCESS_KEY_ID:${{secrets.ALIYUN_ACCESS_KEY_ID}}ALIBABA_CLOUD_ACCESS_KEY_SECRET:${{secrets.ALIYUN_ACCESS_KEY_SECRET}}ALIBABA_CLOUD_REGION_ID:${{secrets.ALIYUN_REGION}}run:|aliyun ecs RevokeSecurityGroup \ --RegionId ${{ secrets.ALIYUN_REGION }} \ --SecurityGroupId ${{ secrets.ALIYUN_SECURITY_GROUP_ID }} \ --IpProtocol tcp \ --PortRange 22/22 \ --SourceCidrIp ${{ steps.ip.outputs.CURRENT_IP }}/32 \ --NicType intranet

5. 阿里云地域与可用区对照表

在配置ALIYUN_REGION时,请根据你的 ECS 实例所在地域选择对应的地域 ID(例如cn-hangzhou)。

地域名称地域ID
华北1(青岛)cn-qingdao
华北2(北京)cn-beijing
华北3(张家口)cn-zhangjiakou
华北5(呼和浩特)cn-huhehaote
华北6(乌兰察布)cn-wulanchabu
华东1(杭州)cn-hangzhou
华东2(上海)cn-shanghai
华东5(南京-本地地域)cn-nanjing
华东6(福州-本地地域)cn-fuzhou
华中1(武汉-本地地域)cn-wuhan-lr
华南1(深圳)cn-shenzhen
华南2(河源)cn-heyuan
华南3(广州)cn-guangzhou
西南1(成都)cn-chengdu
中国香港cn-hongkong
新加坡ap-southeast-1
澳大利亚(悉尼)ap-southeast-2
马来西亚(吉隆坡)ap-southeast-3
印度尼西亚(雅加达)ap-southeast-5
菲律宾(马尼拉)ap-southeast-6
泰国(曼谷)ap-southeast-7
印度(孟买)ap-south-1
日本(东京)ap-northeast-1
韩国(首尔)ap-northeast-2
美国(硅谷)us-west-1
美国(弗吉尼亚)us-east-1
德国(法兰克福)eu-central-1
英国(伦敦)eu-west-1
阿联酋(迪拜)me-east-1
沙特(利雅得-合作伙伴运营)me-central-1

注意:安全组授权时只需要地域 ID,无需指定具体的可用区。


6. 步骤详解

步骤 1:获取运行器 IP
  • 使用ifconfig.me服务获取当前 GitHub Actions 运行器的公网出口 IP。
  • 将 IP 保存到steps.ip.outputs.CURRENT_IP中,供后续步骤使用。
  • 也可使用其他服务如ip.sbicanhazip.com
步骤 2:安装阿里云 CLI
  • 直接下载官方最新版 CLI 二进制文件,解压后放入PATH,避免依赖第三方 Action,更稳定可靠。
步骤 3:添加安全组规则
  • 调用AuthorizeSecurityGroup接口,将当前 IP 添加到安全组,协议 TCP,端口 22。
  • --NicType intranet适用于 VPC 网络的实例;如果是经典网络,可能需要改为internet
  • 添加规则后等待几秒,确保规则生效(可选,但推荐)。
步骤 4:插入你的构建/部署步骤
  • 在这里执行你原本的构建、测试、SSH 部署等操作。
  • 由于安全组已临时放行,SSH 连接可以成功。
步骤 5:删除安全组规则
  • 调用RevokeSecurityGroup接口,传入与添加时完全相同的参数,精确删除规则。
  • if: always()确保无论部署步骤成功或失败,都会执行清理,避免规则残留。

7. 注意事项与常见问题

Q1:授权/撤销时返回错误InvalidIpProtocol.MalformedInvalidParameter
  • 检查--PortRange格式是否为22/22--SourceCidrIp是否带/32
  • 确保地域 ID、安全组 ID 正确,且 RAM 用户有相应权限。
  • 确认--NicType与实例网络类型匹配(VPC 用intranet,经典网络用internet)。
Q2:SSH 部署失败(连接超时或权限被拒)
  • 可能原因:安全组规则尚未生效。可在授权后增加sleep 5步骤。
  • 检查 ECS 实例内部防火墙(如 iptables)是否允许 22 端口,安全组只是网络层过滤。
  • 确认 SSH 服务正在运行,且公钥已正确配置到~/.ssh/authorized_keys
Q3:撤销步骤失败,导致规则残留
  • 确保撤销步骤的参数与添加步骤完全一致(包括大小写、空格、掩码等)。
  • 检查if: always()是否正确添加。
Q4:阿里云 CLI 提示权限不足
  • 确认 RAM 用户已授予AliyunECSFullAccess权限,并且 AccessKey 正确无误。
Q5:安全组规则达到上限
  • 每个安全组默认最多添加 200 条规则(以阿里云文档为准)。如果频繁执行且删除失败导致规则堆积,可能达到上限。建议定期检查并手动清理残留规则。
Q6:GitHub Actions IP 变更
  • GitHub 的 runners IP 地址范围可能变化,但每个 job 的出口 IP 是固定的。本方案动态获取当前 IP,无需预知 IP 段,因此不受影响。

8. 进阶优化

8.1 超时保护
  • 在使用 SSH Action 时,可设置timeout参数(如appleboy/ssh-action支持timeout),防止部署任务长时间卡住导致规则一直开放。
8.2 并发处理
  • 多个 workflow 同时运行时,会各自添加和删除自己的 IP 规则,互不影响。但需注意安全组规则数量上限。
8.3 自定义 RAM 策略(最小权限)

若需最小权限,可创建自定义策略,仅允许操作特定安全组。示例策略如下(需将cn-hangzhousg-xxxxxx替换为实际值):

{"Version":"1","Statement":[{"Effect":"Allow","Action":["ecs:AuthorizeSecurityGroup","ecs:RevokeSecurityGroup"],"Resource":"acs:ecs:cn-hangzhou:*:securitygroup/sg-xxxxxx"}]}
8.4 使用 OIDC 代替长期 AccessKey(高级)

GitHub Actions 支持 OIDC 与阿里云 RAM 角色集成,可避免管理 AccessKey Secret,进一步提升安全性。具体配置请参考阿里云官方文档。

http://www.cnnetsun.cn/news/1282370.html

相关文章:

  • 尝试用openclaw完成一个复杂的开发任务(持续更新)
  • “是我!”庆祝马里奥40年来始终坚持的匠心精神
  • 2026高职大数据技术专业考什么证书有用?
  • OpenClaw 超级 AI 实战专栏【基础操作与核心概念】(九)工程结构:目录、文件、模型、数据组织
  • PPT小白必看:从Word到PPT的5分钟高效转换技巧(附字体版权避坑指南)
  • 企业必看:Confluence远程命令执行漏洞(CVE-2022-26134)防御指南与修复方案
  • Hardhat 3测试框架终极选择指南:Node Test Runner vs Mocha实战对比
  • Coordinate Attention: Revolutionizing Lightweight Mobile Networks with Spatial-Channel Synergy
  • 金融风控领域的深度学习模型训练环境实践
  • Qwen2.5-VL-7B-Instruct效果展示:低资源语言(如泰语/越南语)图文理解实测
  • DDR5内存上电初始化全解析:从RESET信号到稳定工作的完整流程(附时序图)
  • 5G网络切片:如何为垂直行业打造定制化虚拟专网
  • 腾讯优图AI解析实测:上传图片自动识别文字、表格、公式、印章
  • Java数据结构|String类(二)+反射枚举Lambda+泛型的进阶
  • 告别TeamViewer?在Ubuntu上使用VNC Viewer实现轻量级远程控制的3种方法
  • 基于微信小程序的优购电商的设计与实现+ssm毕业论文
  • Hbuilder X最新版真机调试全攻略:从安卓到iOS的避坑指南
  • ESP32-H2安全架构解析:寄存器控制、硬件加速与可信启动
  • Swift面试必备:深入解析高频技术点与实战应用
  • OpenWrt UCI 命令行实战:从网络配置到Luci管理界面部署
  • CasRel模型在固件分析报告生成中的应用:自动化提取漏洞与组件关系
  • all-MiniLM-L6-v2多场景落地:客服问答匹配、合同条款相似性分析、简历筛选
  • C# 异步编程太难?一文搞懂回调、轮询、async/await 三种模式
  • 字节:早阶段视觉令牌剪枝EvoPrune
  • Debian安装openclaw
  • yz-女生-角色扮演-造相Z-Turbo与SpringBoot集成实战
  • 优化网络体验:如何手动调整有线与WiFi的跃点数设置
  • 从DCU到SoC:解析汽车电子架构演进中的核心计算单元
  • MP4文件格式深度剖析:从Box结构到媒体流解析
  • 05-RAG 核心概念与向量存储:检索增强生成原理