如果有两个用户,用户A有一个安全组A1,另外一个安全组A2, 另外一个用户B有一个安全组B1,安全组A2和安全组B1的云服务器想要实现对安全组A中的云服务器进行网络访问,需要进行下面的设置。
访问经典网络user-A-sg-1安全组内资源的入网规则设置如下表所示,您可以通过控制台直接操作也可以调用OpenApi来实现.
设置同一用户的安全组 user-A-sg-1的服务器同一用户的安全组 user-A-sg-2的服务器另一个用户B的安全组 user-B-sg-1 服务器入方向访问互通不通不通入方向设置不需要设置1. 在user-A-sg-1的安全组内网入规则加一条规则, ["SourceGroupId": "user-A-sg-2", "IpProtocol": "tcp", "PortRange": "80/80"] 2. 在user-A-sg-1的安全组内网入规则加一条规则, ["SourceCidrIp": "IP地址/32", "IpProtocol": "tcp", "PortRange": "80/80"]1. 在user-A-sg-1的安全组内网入规则加一条规则, ["SourceGroupId": "user-B-sg-1", "SourceGroupOwnerId": "user-B", "IpProtocol": "tcp", "PortRange": "80/80"] 2. 在user-A-sg-1的安全组内网入规则加一条规则, ["SourceCidrIp": "IP地址/32", "IpProtocol": "tcp", "PortRange": "80/80"]操作指引 参见 安全组设置内网互通的方法
如果之前已经在经典网络上设置了允许过大的入网网段访问,例如 0.0.0.0/0 或者 10.0.0.0/8。如果你没有授权其他的用户访问当前安全组内资源的计划,你可以选择添加其他的安全组作为入网的授权规则,逐个添加完其他的安全组之后测试您的应用,逐个删除之前过大的CIDR网段。
下面提供了一个脚本,它将会根据您的入参安全组ID,将本region内其他的有云服务器的安全组作为入网规则加入您的安全组之中。目前这个版本有如下限制, 附件中包含所有的代码。
不支持VPC类型的安全组不支持已添加和即将添加的规则超过100条的场景您可以选择ignore一些安全组,不加入只支持单个region 50个安全组的场景 # coding=utf-8 # if the python sdk is not install using 'sudo pip install aliyun-python-sdk-ecs' # if the python sdk is install using 'sudo pip install --upgrade aliyun-python-sdk-ecs' # make sure the sdk version is 2.1.2, you can use command 'pip show aliyun-python-sdk-ecs' to check import json import logging from aliyunsdkcore import client from aliyunsdkecs.request.v20140526.AuthorizeSecurityGroupRequest import \ AuthorizeSecurityGroupRequest from aliyunsdkecs.request.v20140526.DescribeSecurityGroupAttributeRequest import \ DescribeSecurityGroupAttributeRequest from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest # configuration the log output formatter, if you want to save the output to file, # append ",filename='ecs_invoke.log'" after datefmt. from aliyunsdkecs.request.v20140526.DescribeSecurityGroupsRequest import \ DescribeSecurityGroupsRequest logging.basicConfig(level=logging.INFO, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S') clt = client.AcsClient('Your Access Key Id', 'Your Access Key Secrect', 'cn-beijing') TOTAL_COUNT = 'TotalCount' # 需要开放的端口范围 协议为tcp、udp时默认端口号,取值范围为1~65535;例如“1/200”意思是端口号范围为1~200,若输入值为:“200/1”接口调用将报错。 # 协议为icmp时端口号范围值为-1/-1; # gre协议时端口号范围值为-1/-1; # 协议为all时端口号范围值为-1/-1 PORT_RANGE = '-1/-1' # IP协议,取值:tcp | udp | icmp | gre | all; # all表示同时支持四种协议 IP_PROTOCOL = 'all' # 网络协议,这里只设置经典网络的安全组的内网规则 NIC_TYPE = 'intranet' # 接受协议 POLICY = 'accept' # 优先级 1-100, 1最高 100最容易被覆盖 PRIORITY = 10 # 经典网络的ID不需要添加到规则里面的接受规则里面的 SECURITY_GROUP_IDS_IGNORE_ADD = ['sg-ignore-1', 'sg-ignore-2', 'sg-ignore-3'] # 这个工具用来扫描您的经典网络安全组,并且将同一个Region下其它有ECS的经典网络的安全组ID添加到您的内网入规则中, # 以实现您的一个region内的所有的ECS内网互通。目前这个脚本只支持单region下50个安全组。 # dry run 仅仅计算不执行 def add_security_group_rule(sg_id, priority=10, dry_run=True): request = DescribeSecurityGroupsRequest() request.set_SecurityGroupId(sg_id) response = _send_request(request) security_groups = response.get('SecurityGroups').get('SecurityGroup') if len(security_groups) == 0: logging.error("Current input security group id %s can not be found in current region", sg_id) else: sg_detail = security_groups[0] if sg_detail is not None: vpc_id = sg_detail.get('VpcId') if vpc_id != '': logging.error( "The tools is only for classical security group now, not support vpc security group %s.", sg_id) else: current_permissions = query_sg_rules_for_sg(sg_id) logging.info(current_permissions) SECURITY_GROUP_IDS_IGNORE_ADD.append(sg_id) sg_ids = query_all_classical_security_group_include_instance( SECURITY_GROUP_IDS_IGNORE_ADD) if len(current_permissions) + len(sg_ids) > 100: logging.error( "Current security group %s already with too many rules, the max rules is 100 for all the ruels.", sg_id) logging.info("it will add %s total in %d rules for security group %s.", sg_ids, len(sg_ids), sg_id) if dry_run == False: for sg_id_in in sg_ids: execute_add_classical_intranat_ingress(sg_id, sg_id_in, priority, dry_run) # 为经典网络的云服务器添加内网的入规则 def execute_add_classical_intranat_ingress(source_sg_id, in_sg_id, priority, dry_run): request = AuthorizeSecurityGroupRequest() request.set_SecurityGroupId(source_sg_id) request.set_IpProtocol(IP_PROTOCOL) request.set_Policy(POLICY) request.set_NicType(NIC_TYPE) request.set_Priority(priority) request.set_PortRange(PORT_RANGE) request.set_SourceGroupId(in_sg_id) if dry_run: logging.info("add sg id %s as the in security group id %s", in_sg_id, source_sg_id) else: response = _send_request(request) return response # 查询当前的安全组下有多少条规则 def query_sg_rules_for_sg(security_group_id): request = DescribeSecurityGroupAttributeRequest() request.set_SecurityGroupId(security_group_id) response = _send_request(request) permissions = response.get('Permissions').get('Permission') total_count = len(permissions) logging.info("Current security group %s with rule %d", security_group_id, total_count) return permissions # 过滤那些安全组有云服务器实例 def query_all_classical_security_group_include_instance(exclude_security_group_ids=[]): request = DescribeSecurityGroupsRequest() request.set_PageSize(50) response = _send_request(request) with_instance_sg_ids = [] total_count = response.get(TOTAL_COUNT) if total_count > 100: logging.warning("you have more than 100 security group in current region....") security_groups = response.get('SecurityGroups').get('SecurityGroup') for security_group in security_groups: vpc_id = security_group.get('VpcId') sg_id = security_group.get('SecurityGroupId') if vpc_id == '': request = DescribeInstancesRequest() request.set_PageSize(1) request.set_SecurityGroupId(sg_id) list_instance_response = _send_request(request) sg_with_instance_count = list_instance_response.get(TOTAL_COUNT) if sg_with_instance_count > 0: with_instance_sg_ids.append(sg_id) else: logging.info("security group %s is vpc ", sg_id) return list(set(with_instance_sg_ids).difference(set(exclude_security_group_ids))) # send open api request def _send_request(request): request.set_accept_format('json') try: response_str = clt.do_action(request) logging.info(response_str) response_detail = json.loads(response_str) return response_detail except Exception as e: logging.error(e) if __name__ == '__main__': logging.info("Hello!") # 实际运行中,请选择您的安全组Id,并将Dry_Run设置为False # 如果为VPC的安全组就会报错。 add_security_group_rule('sg-add-rules', PRIORITY, True) 相关资源:python入门教程(PDF版)