爬取当前IP并且修改阿里云安全组的脚本

动机与脚本

我工位所用的网络是公司特批的海外专线,速度OK还能翻墙出去看看,自从有了这条线爽的飞起,但缺陷就是每周IP地址都会变,IP一变很多的阿里云ecs安全组就要重新配置,因为有一些公网端口比如grafana或者跳板机是只能公司运维人员访问的。这样每周都要手动改一次IP地址太烦了,于是乎,写了下面这个脚本,一劳永逸的解决这个问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#coding=utf-8
#这个脚本在python3.6下自验通过,用途是去爬当前的IP地址然后给阿里云安全组添加新的IP,并且删除掉老的IP
from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526 import AuthorizeSecurityGroupRequest
from aliyunsdkecs.request.v20140526 import RevokeSecurityGroupRequest
from aliyunsdkcore.profile import region_provider
import requests,sys,re,os
from bs4 import BeautifulSoup

clt = client.AcsClient('这里是AK', '这里是SK', 'cn-hangzhou') #鉴权
file = "F:\\ip.txt"

def checkDIR():
global file
if os.path.exists(file) == True: #先判断文件是否存在
with open(file, "r") as f:
old_ip = f.read()
return (old_ip) #获取旧ip
else:
print("ip.txt文件不存在,请手动生成!")
sys.exit() #文件不存在直接退出

def getIP():
global file
r = requests.get('http://www.ip111.cn/') #这里输入要爬的网站域名
soup = BeautifulSoup(r.text, "lxml")
context = []
for link in soup.find_all('td'): #获取所有td标签内容
context.append(link.get_text()) #添加一个列里
str = context[4]
ip = re.split(r'[\n\s]\s*', str)[1] #多符号分割字符串
with open(file, "w") as f:
f.write(ip)
return ip

def addnewRULE(func):
global clt
# 设置参数
for port in ['3000/3000', '34872/34872']: #这里是端口
request = AuthorizeSecurityGroupRequest.AuthorizeSecurityGroupRequest()
request.set_accept_format('json')
request.add_query_param('RegionId', 'cn-hangzhou')
request.add_query_param('SecurityGroupId', '目标安全组ID')
request.add_query_param('IpProtocol', 'tcp')
request.add_query_param('PortRange', port)
request.add_query_param('SourceCidrIp',func())
request.add_query_param('NicType', 'intranet') #如果不加这句话就是公网添加
if port == '3000/3000':
request.add_query_param('Description', 'Grafana使用端口')
else:
request.add_query_param('Description', 'Zabbix和堡垒机使用端口')
# 发起请求
response = clt.do_action(request)
print (response)

def deloldRULE(func):
global clt
# 设置参数
for port in ['3000/3000','34872/34872']:
request = RevokeSecurityGroupRequest.RevokeSecurityGroupRequest()
request.set_accept_format('json')
request.add_query_param('RegionId', 'cn-hangzhou')
request.add_query_param('SecurityGroupId', '目标安全组ID')
request.add_query_param('IpProtocol', 'tcp')
request.add_query_param('PortRange', port)
request.add_query_param('SourceCidrIp', func())
request.add_query_param('NicType', 'intranet') #如果不加这句话就是公网删除
# 发起请求
response = clt.do_action(request)
print (response)

if __name__ == '__main__':
checkDIR()
deloldRULE(checkDIR)
getIP()
addnewRULE(getIP)

整个脚本的逻辑就是先在F盘下有ip.txt里面就保存当前IP地址,然后执行脚本的时候就会先在目标安全组里删除掉这个IP相关的3000端口和34872端口,然后去www.ip111.cn里爬取当前的网址,把新IP写入到ip.txt的同时,再去目标安全组里添加这个新IP相关的3000端口和34872端口。

新的知识点

  1. 把上一个函数结果当作参数在下一个函数里执行的方法:
    akb48

  2. python的退出有两个:os._exit()sys.exit()os._exit()会直接将python程序终止,之后的所有代码都不会执行;sys.exit()会抛出一个异常: SystemExit,如果这个异常没有被捕获,那么python解释器将会退出。如果有捕获该异常的代码,那么这些代码还是会执行。使用sys.exit()来退出程序比较优雅,一般情况下也用这个,os._exit()可以在os.fork()产生的子进程里使用。

  3. 在windows里定时执行python脚本的方法:
    打开控制面板—>系统和安全—>计划任务。如图:
    akb48

点击右侧的创建基本任务,输入任务名称和可选的描述。点击下一步,设置任务的开始时间,可以选择每日执行、每周执行或每月执行。点击下一步操作选择启动程序,点击下一步输入参数。如图:
akb48

1
2
3
程序或脚本:python.exe  
添加参数:输入要执行的python脚本路径(包括文件名)
起始于:输入python.exe的目录(不包括文件名)

最后点击下一步,整个过程搞定。

  1. 目前http://www.ip111.cn/网站已经更改了网页格式,上述的代码有一段已经不好使了,需要将getIP()这个函数改成如下的方法:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def getIP():
    global file
    r = requests.get('http://2018.ip138.com/ic.asp') #改用这个域名
    soup = BeautifulSoup(r.text, "lxml")
    context = []
    for link in soup.find_all('body'): #获取body内容
    context.append(link.get_text()) #添加一个列里
    str = context[0]
    ip = re.split(r'[\[\]]',str)[1] #进行分割
    with open(file, "w") as f:
    f.write(ip)
    return ip
    akb48
感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------