一、操作场景
这篇会指导你在本地终端中通过调用接口自动获取本地出口的公网 IP,并将其更新到安全组规则里,减轻运营商更换公网 IP 所带来的影响。
二、前提条件
·完成 TCCLI 工具安装,安装方式参考 安装TCCLI。
·完成 TCCLI 工具配置,配置方式参考 配置TCCLI,通过浏览器登录腾讯云账号并授权以获取凭证。
三、基本原理
CreateSecurityGroupPolicies 接口的 SecurityGroupPolicySet 中源地址(SourceCidr)支持传入字符串 MY_PUBLIC_IP,表示当前访问 API 的公网 IP 地址。你可通过 TCCLI 工具快速将本地公网出口 IP 添加到安全组规则中,创建放通对应 IP 的安全组规则,并添加备注,以便以后根据备注识别和删除旧的安全组规则。
主要操作指令如下:
1. 指定安全组所在地域,地域列表可通过接口 DescribeRegions 获取。
tccli configure set region ap-guangzhou # ap-guangzhou 表示安全组所在地域,可按实际情况替换
2. 添加安全组规则,并添加备注以便后面识别和删除。
tccli vpc CreateSecurityGroupPolicies –SecurityGroupId sg-mdw2qvp3 –SecurityGroupPolicySet '{"Ingress":[{"Protocol":"tcp","Port":"22","CidrBlock":"MY_PUBLIC_IP","Action":"ACCEPT","PolicyIndex":"0","PolicyDescription":""}]}' # 录入信息说明:# sg-mdw2qvp3 表示需要修改的安全组ID# Ingress表示入添加入站规则# tcp表示协议类型 # Port表示远程登录需要放通端口,常见端口包括22,3389等# CidrBlock表示需要放通的源地址,此处输入MY_PUBLIC_IP,表示当前访问云API的通往IP# Action访问动过选择ACCEPT表示允许访问# PolicyIndex输入0,表示将该规则添加到安全组第一条# PolicyDescription表示备注信息,用户可根据实际情况自行填入。若不输入,则通过"MY_PUBLIC_IP"入参创建的安全组,默认备注内容为“Replaced-From-MY_PUBLIC_IP”
3. 查询自动创建的安全组规则,并删除旧的规则。
tccli vpc DescribeSecurityGroupPolicies –SecurityGroupId sg-mdw2qvp3 –Filters '[{"Name":"description","Values":["Replaced-From-MY_PUBLIC_IP"]}]'# sg-mdw2qvp3 表示需要修改的安全组ID,通过Filters字段,填入备注中的"Replaced-From-MY_PUBLIC_IP",快速查看规则添加情况,获取到安全组规则的PolicyIndex值tccli vpc DeleteSecurityGroupPolicies –SecurityGroupId sg-mdw2qvp3 –SecurityGroupPolicySet '{"Ingress":[{"PolicyIndex":"N"}]}'# sg-mdw2qvp3 表示要修改的安全组ID。PolicyIndex值"N"要替换成要删除的安全组规则的实际PolicyIndex值,如"PolicyIndex":"2"
注意:安全组规则变更会影响服务器访问情况,配置前请仔细核对信息是否准确,避免影响业务正常运行。
四、信息确认
通过 安全组控制台,你可以获取到需要自动化配置的安全组 ID 以及地域信息。后续安全组 ID 和地域信息将作为本地脚本的必填参数使用。
五、创建脚这篇件
vi CreateSecurityGroupPolicies.py # CreateSecurityGroupPolicies.py表示脚本名称
注意:说明:
注意:你可以参考 方案说明 中的步骤,编写脚本或使用示例脚本以自动更新安全组规则配置。
六、示例脚本
注意:说明:
注意:1. 我们提供示例脚本供你参考,绝大部分使用场景可直接使用。
注意:2. 考虑到使用场景多样和公网环境复杂,我们针对典型的特殊场景提供了对应的参数供你调整。
#!/usr/bin/env python# -*- coding: utf-8 -*-import jsonimport optparseimport socketimport subprocessimport sys# 默认配置,可直接在此处修改,也可通过传参来调整HOSTNAME = socket.gethostname() # 主机名,用于区分不同客户端的放通策略MAX_RESERVED_NUM = 1 # 自动放通策略的最大保留数量,用于清理过期的策略,存在多个出口IP时,可以按需调整POLICY_PROTOCOL = 'TCP' # 要放通的协议,通常是: TCPPOLICY_PORT = '22' # 要放通的端口,通常是: 22(Linux/Unix)、3389(Windows)def get_policy_description(): return 'Auto-Created-For-Hostname-%s' % HOSTNAMEdef get_describe_filters(): return [{ 'Name': 'direction', 'Values': ['INBOUND'] }, { 'Name': 'poly', 'Values': ['ACCEPT'] }, { 'Name': 'protocol-type', 'Values': [POLICY_PROTOCOL] }, { 'Name': 'port', 'Values': [POLICY_PORT] }, { 'Name': 'description', 'Values': [get_policy_description()] }]def get_create_policy(): return {'Ingress': [{ 'PolicyIndex': 0, 'Action': 'ACCEPT', 'Protocol': POLICY_PROTOCOL, 'Port': POLICY_PORT, 'CidrBlock': 'MY_PUBLIC_IP', # MY_PUBLIC_IP 会自动替换为本地公网IP 'PolicyDescription': get_policy_description(), }]}def get_delete_filters(policies): _registry = {} delete_index_list = [] for item in policies: if len(_registry) < MAX_RESERVED_NUM \\ and item['CidrBlock'] not in _registry: _registry[item['CidrBlock']] = None else: delete_index_list.append(item['PolicyIndex']) delete_filters = {'Ingress': []} for index in delete_index_list: delete_filters['Ingress'].append({ 'PolicyIndex': index, 'Action': 'ACCEPT', 'Protocol': POLICY_PROTOCOL, 'Port': POLICY_PORT, 'PolicyDescription': get_policy_description(), }) return delete_filtersdef tccli_cmd(cmd): p = subprocess.Popen('tccli %s' % cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) std_out, std_err = p.communicate() if p.returncode: sys.stderr.write(std_err.decode('utf-8')) sys.exit(p.returncode) if std_out: return json.loads(std_out.decode('utf-8'))def main(SecurityGroupId): # 添加放通本地公网IP的规则 tccli_cmd('vpc CreateSecurityGroupPolicies ' '–SecurityGroupId %r ' '–SecurityGroupPolicySet %r ' % (SecurityGroupId, json.dumps(get_create_policy()))) # 查询匹配特定条件的规则 r = tccli_cmd('vpc DescribeSecurityGroupPolicies ' '–SecurityGroupId %r ' '–Filters %r ' '–filter "SecurityGroupPolicySet.Ingress" ' '–output json' % (SecurityGroupId, json.dumps(get_describe_filters()))) # 删除最大保留量以外的规则 delete_filters = get_delete_filters(r) if delete_filters['Ingress']: tccli_cmd('vpc DeleteSecurityGroupPolicies ' '–SecurityGroupId %r ' '–SecurityGroupPolicySet %r ' % (SecurityGroupId, json.dumps(delete_filters))) print('done.')if __name__ == '__main__': usage = 'usage: %prog [options] SecurityGroupId [SecurityGroupId …]' parser = optparse.OptionParser(usage=usage) parser.add_option('-r', '–region') parser.add_option('-n', '–max-reserved-num', type=int, help='default %r' % MAX_RESERVED_NUM) parser.add_option('-N', '–hostname', help='default %r' % HOSTNAME) parser.add_option('-p', '–port', help='default %r' % POLICY_PORT) parser.add_option('-P', '–protocol', help='default %r' % POLICY_PROTOCOL) options, args = parser.parse_args() if options.hostname is not None: HOSTNAME = options.hostname if options.max_reserved_num is not None: MAX_RESERVED_NUM = options.max_reserved_num if options.port is not None: POLICY_PORT = options.port if options.protocol is not None: POLICY_PROTOCOL = options.protocol # 设置 TCCLI 工作地域 if options.region: tccli_cmd('configure set region %s' % options.region) for SecurityGroupId in set(args): main(SecurityGroupId)
七、运行示例脚本
情况一:直接使用,覆盖大部分场景。
python CreateSecurityGroupPolicies.py -r ap-guangzhou sg-xxxx -p 22# ap-guangzhou表示安全组所在地域,sg-xxxx表示安全组ID,22表示需要放通的端口
情况二:针对典型的特殊场景,你可以根据实例脚本说明调整对应的参数。
python CreateSecurityGroupPolicies.py -N MY_MAC -n 15 -r ap-guangzhou sg-xxxx -p 22# MY_MAC表示HOSTNAME名字,15表示MAX_RESERVED_NUM数量,ap-guangzhou表示安全组所在地域,sg-xxxx表示安全组ID,22表示需要放通的端口
八、将脚本设置为开机运行或定时运行
注意:说明:
注意:脚本设置为开机运行或定时运行,你可以根据运营商更换公网 IP 的频率,合理设置时间间隔,以便正常登录云服务器。
九、将脚本设置为开机运行
MacOSWindows 系统通过 crontab 工具设置开机运行1. 打开终端,并执行命令 crontab -e。crontab -e2. 编辑定时任务文件,设置开机运行。@reboot /path/to/Python /path/to/your/CreateSecurityGroupPolicies.py -r ap-guangzhou sg-xxxx # 设置开机运行,ap-guangzhou表示安全组所在地域,sg-xxxx表示安全组ID3. 保存并关闭文件。:wq通过 windows 任务计划程序设置开机运行1. 打开任务计划程序。2. 添加计划任务,选择创建任务。2.1 填写计划任务信息以及选择运行账户。2.2 “程序或脚本”选择需要运行的脚本,“添加参数(可选)”填写脚本参数。2.3 配置触发器,选择启动时运行。3.单击确定保存。
十、将脚本设置为定时运行
MacOSWindows 系统通过crontab工具设置定时运行1. 打开终端,并执行命令 crontab -e。crontab -e2. 编辑定时任务文件,每行表示一个定时任务,可根据需要设置合理的运行时间。0 0 * * * /path/to/Python /path/to/CreateSecurityGroupPolicies.py -r ap-guangzhou sg-xxxx #表示每天的0点执行脚本。ap-guangzhou表示安全组所在地域,sg-xxxx表示安全组ID3. 保存。:wq通过 windows 任务计划程序设置定时运行1. 打开任务计划程序。2. 添加计划任务,选择创建任务。2.1 填写计划任务信息以及选择运行账户。2.2 “程序或脚本”选择需要运行的脚本,“添加参数(可选)”填写脚本参数。2.3 设置定时运行。3. 确认保存。