- 后端
- 云原生
【免费下载链接】boto
For the latest version of boto, see https://github.com/boto/boto3 -- Python interface to Amazon Web Services
本篇指南围绕 boto 项目中的 EC2 Security Groups 官方文档,系统讲解如何通过 boto 的 Python 接口列举、创建、授权与撤销 EC2 安全组规则。你将掌握get_all_security_groups、create_security_group、authorize、revoke等核心 API 的完整用法,并能独立复现 AWS EC2 Developer's Guide 中经典的"三层 Web 服务"安全组搭建流程。
什么是 EC2 Security Group
Amazon 对安全组(Security Group)的定义如下:
"A security group is a named collection of access rules. These access rules specify which ingress, i.e. incoming, network traffic should be delivered to your instance." (安全组是一组命名的访问规则集合,这些规则指定哪些入站(ingress,即流入)网络流量应被送达你的实例。)
在 boto 中,安全组由 boto/ec2/securitygroup.py 中的SecurityGroup类表示,它是TaggedEC2Object的子类,核心属性包括:
id/group_id:安全组的唯一标识(如sg-1a2b3c4d)owner_id:安全组所属账号 IDname:安全组名称(如appserver、default)description:安全组描述vpc_id:若安全组创建于 VPC 中,则为所属 VPC 的 IDrules:入站规则列表(IPPermissionsList)rules_egress:出站规则列表(IPPermissionsList)
从源码看,SecurityGroup.__repr__返回'SecurityGroup:%s' % self.name,因此文档中打印安全组列表时会看到SecurityGroup:appserver这样的格式。
建立 EC2 连接
所有安全组操作都基于一个EC2Connection连接对象。按 EC2 入门教程 的推荐方式,连接可以显式传入凭证:
>>> import boto.ec2 >>> conn = boto.ec2.connect_to_region("us-west-2", ... aws_access_key_id='<aws access key>', ... aws_secret_access_key='<aws secret key>')也可以在 boto 配置中设置好环境变量后仅指定区域:
>>> conn = boto.ec2.connect_to_region("us-west-2")后续所有示例中的conn均指这个EC2Connection对象。
列出所有安全组
调用get_all_security_groups()即可获取当前账号在当前区域内的全部安全组:
>>> rs = conn.get_all_security_groups() >>> print rs [SecurityGroup:appserver, SecurityGroup:default, SecurityGroup:vnc, SecurityGroup:webserver]在底层,这个方法通过DescribeSecurityGroupsAPI 请求实现。查看 boto/ec2/connection.py 的源码,它还支持三个可选参数:
groupnames:名称列表,只返回指定名称的安全组;group_ids:ID 列表,用于检索 VPC 内的安全组;filters:过滤条件字典,例如{'group-name': 'webserver'};dry_run:设为True时只校验操作而不实际执行。
响应中的每个<item>会被解析为SecurityGroup对象并放入IPPermissionsList,最终返回SecurityGroup对象的列表。
查看安全组的规则
每个安全组可以包含任意数量的规则,每条规则对应一个被放开的网络端口。通过rules属性可以查看某一安全组的规则:
>>> sg = rs[1] >>> sg.name u'default' >>> sg.rules [IPPermissions:tcp(0-65535), IPPermissions:udp(0-65535), IPPermissions:icmp(-1--1), IPPermissions:tcp(22-22), IPPermissions:tcp(80-80)]这里的IPPermissions是源码中定义的权限规则对象(见 boto/ec2/securitygroup.py),其__repr__输出格式为IPPermissions:<protocol>(<from_port>-<to_port>)。每个IPPermissions对象包含:
ip_protocol:协议,tcp、udp或icmpfrom_port:端口范围起始值to_port:端口范围结束值grants:授权对象列表(GroupOrCIDR,可以是 CIDR 网段或另一个安全组)
GroupOrCIDR用于表示一条规则的授权来源,可以是 CIDR 网段(cidr_ip非空)或安全组(name/group_id+owner_id)。上述示例表明default组默认放行了全部端口的 tcp/udp,全部 icmp,以及 22、80 端口。
创建安全组
除列举外,boto 还支持创建新的安全组。下面跟随 AWS EC2 Developer's Guide 中"三层 Web 服务"(Three Tier Web Service)的例子,完整演示创建安全组并添加规则的过程。
创建 Web 服务器组
先为 Apache Web 服务器创建一个允许全世界 HTTP 访问的安全组:
>>> web = conn.create_security_group('apache', 'Our Apache Group') >>> web SecurityGroup:apache >>> web.authorize('tcp', 80, 80, '0.0.0.0/0') Truecreate_security_group(name, description)的两个参数分别是安全组名称和描述。查看 boto/ec2/connection.py 的实现,它还支持vpc_id参数(在指定 VPC 中创建)和dry_run参数;创建成功后返回一个SecurityGroup对象。
authorize方法(实现在 boto/ec2/securitygroup.py)的参数含义为:
- 第一个参数
ip_protocol:IP 协议,取值tcp、udp或icmp - 第二个参数
from_port:端口范围起始值 - 第三个参数
to_port:端口范围结束值 - 最后一个参数
cidr_ip:被授权访问的 CIDR IP 网段
因此web.authorize('tcp', 80, 80, '0.0.0.0/0')的含义是:允许所有 IP(0.0.0.0/0)通过 tcp 协议访问 80 端口。authorize返回True表示授权成功,并且成功后会把规则同步更新到本地对象的rules列表中(add_rule方法只修改本地对象,而真正的规则下发发生在authorize_security_groupAPI 调用中)。
创建应用服务器组并实现组间授权
接下来创建应用服务器所在的安全组:
>>> app = conn.create_security_group('appserver', 'The application tier')我们希望在 Web 服务器组与应用服务器组之间互访。与上一个例子传入 IP 地址不同,这次直接把另一个SecurityGroup对象作为src_group传入:
>>> app.authorize(src_group=web) True这行代码的语义是:允许web(apache)组中的实例访问appserver组中的实例。从源码看,当传入src_group时,authorize会取出src_group.owner_id与src_group.name(EC2 经典网络场景)或src_group.id(VPC 场景),并调用底层AuthorizeSecurityGroupIngressAPI。这也是 boto 中文档明确指出的"二选一"规则:要么提供ip_protocol/from_port/to_port/cidr_ip授权某个 IP 网段,要么提供src_group授权另一个安全组,两者不能混用。
临时开放 SSH 并验证
为了测试 Web 服务器到应用服务器的连通性,需要从本机临时开放 SSH 访问。假设本机 IP 为192.168.1.130(与 EC2 Developer's Guide 一致):
>>> web.authorize(ip_protocol='tcp', from_port=22, to_port=22, cidr_ip='192.168.1.130/32') True注意这里使用了关键字参数形式,与位置参数形式完全等价,语义是:允许192.168.1.130/32这一个 IP 通过 tcp 访问 22 端口。此时web组应该同时具备 80 和 22 两条入站规则:
>>> web.rules [IPPermissions:tcp(80-80), IPPermissions:tcp(22-22)]至此,你可以 SSH 进入运行在web组中的实例,再按 EC2 Developer's Guide 的步骤 telnet 到appserver组中实例的特定端口,验证组间授权是否生效。
撤销安全组规则
测试完成后,应立即撤销临时开放的 SSH 权限,避免长期暴露管理端口。调用revoke并传入与授权时相同的参数即可:
>>> web.revoke('tcp', 22, 22, cidr_ip='192.168.1.130/32') True >>> web.rules [IPPermissions:tcp(80-80)]撤销成功后,web.rules中不再包含 22 端口规则,只剩最初授权的 80 端口规则。
revoke方法(见 boto/ec2/securitygroup.py)与authorize参数一致,同样支持src_group形式的组间撤销。它内部调用底层RevokeSecurityGroupIngressAPI,成功后通过remove_rule同步更新本地规则列表。remove_rule会按协议、端口与授权对象精确匹配待删除的规则;如果安全组本身没有任何规则就调用remove_rule,会抛出ValueError("The security group has no rules"),这一点在 tests/unit/ec2/test_securitygroup.py 的单元测试中有明确验证。
从源码理解规则对象与数据模型
安全组相关的三个核心类都定义在 boto/ec2/securitygroup.py 中,它们构成了"安全组 → 权限规则 → 授权对象"的三层结构:
| 类 | 职责 | 关键字段 |
|---|---|---|
SecurityGroup | 安全组本体 | id、owner_id、name、description、vpc_id、rules、rules_egress |
IPPermissions | 一条端口/协议规则 | ip_protocol、from_port、to_port、grants |
GroupOrCIDR | 规则的授权来源 | owner_id、group_id、name、cidr_ip |
这条解析链与 EC2 API 响应一一对应:DescribeSecurityGroups响应中的ipPermissions被解析进SecurityGroup.rules,ipPermissionsEgress被解析进rules_egress。在 tests/unit/ec2/test_securitygroup.py 的单元测试中,模拟的响应数据同时包含ipPermissions(tcp 80 端口对0.0.0.0/0)与ipPermissionsEgress,验证了get_all_security_groups的解析结果。
进阶:VPC 场景、删除与跨区域复制
VPC 中的安全组
创建 VPC 内的安全组时,create_security_group需要传入vpc_id:
>>> sg_vpc = conn.create_security_group('vpc-web', 'VPC web tier', vpc_id='vpc-12345678')对于 VPC 安全组,后续的授权与撤销改用group_id与src_group_group_id参数(底层走GroupId字段而非GroupName)。SecurityGroup.authorize源码中对此有明确分支:当self.vpc_id存在时使用group_id定位本组、用src_group.id定位授权来源组;同时 VPC 安全组还支持通过authorize_security_group_egress/revoke_security_group_egress(见 boto/ec2/connection.py)管理出站规则。
删除安全组
SecurityGroup.delete()方法(见 boto/ec2/securitygroup.py)会自动判断:VPC 安全组用group_id删除,经典网络安全组用name删除。底层调用delete_security_group(见 boto/ec2/connection.py),也支持显式传入name或group_id直接删除。
跨区域复制
SecurityGroup.copy_to_region(region, name=None)(见 boto/ec2/securitygroup.py)可以把当前安全组复制到另一个区域:它先连接目标区域,用相同名称与描述创建新组,再遍历self.rules中每条规则的每个授权对象,对 CIDR 网段按协议端口逐条授权、对组授权直接传入grant对象。注意文档注释中的提醒:复制后新旧两个组是相互独立的实体,不会自动保持同步。
查询组内实例
SecurityGroup.instances()(见 boto/ec2/securitygroup.py)会通过get_all_reservations配合过滤器(VPC 场景用instance.group-id,经典场景用group-id)找出当前运行在该安全组内的全部实例,返回Instance对象列表。这一功能在单元测试 tests/unit/ec2/test_securitygroup.py 中有覆盖:模拟DescribeSecurityGroups与DescribeInstances两次响应,验证组内实例查询能正确命中并保持groupId一致。
将安全组应用到实例
安全组创建并授权完毕后,在启动实例时通过run_instances的security_groups参数指定(见 EC2 入门教程):
>>> conn.run_instances( '<ami-image-id>', key_name='myKey', instance_type='c1.xlarge', security_groups=['your-security-group-here'])需要注意的是:如果不指定任何安全组,启动的实例将无法 SSH 登录,因为没有任何入站规则放行 22 端口。此外,指定的 AMI 与实例类型之间也可能存在兼容性限制,实际使用时需一并确认。
小结
围绕 docs/source/security_groups.rst 的内容,本文完整覆盖了 boto 管理 EC2 安全组的全生命周期:
- 列举:
get_all_security_groups()查看区域内全部安全组,结合groupnames/filters精确筛选; - 创建:
create_security_group(name, description),VPC 场景追加vpc_id; - 授权:
authorize支持两种模式——按协议/端口/CIDR 网段授权,或传src_group实现安全组间互访; - 验证与撤销:通过
rules属性核对规则,用revoke精确回收临时权限; - 进阶管理:VPC 出站规则、跨区域复制、组内实例查询与删除。
这些 API 的底层实现与数据结构都可以在 boto/ec2/securitygroup.py 和 boto/ec2/connection.py 中直接查阅,单元测试 tests/unit/ec2/test_securitygroup.py 则为规则的解析与增删逻辑提供了可运行的验证样例。掌握这套接口,即可用纯 Python 脚本自动化编排 AWS 网络访问策略,而无须在控制台逐条手工配置。
- 后端
- 云原生
【免费下载链接】boto
For the latest version of boto, see https://github.com/boto/boto3 -- Python interface to Amazon Web Services
相关推荐
devops-exercises 实战指南:AWS EC2 安全组(Security Groups)入站规则增删与连通性验证
devops exercises 实战指南:AWS EC2 安全组(Security Groups)入站规则增删与连通性验证 导读 本指南基于 devops e
文档教程DevOps运维my-arsenal-of-aws-security-tools与AWS WAF集成:Web应用防火墙规则管理
my arsenal of aws security tools与AWS WAF集成:Web应用防火墙规则管理 1. 为什么需要AWS WAF规则管理工具? A
文档网络安全云原生Boto3 实战:使用 AWS SDK for Python 管理 Amazon EC2 安全组(Security Group)
Boto3 实战:使用 AWS SDK for Python 管理 Amazon EC2 安全组(Security Group) 本指南基于 Boto3 官方指
后端云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考