注意:笔者使用的是python3,Windows10系统,华为USG6300防火墙
背景:当职网络有国内出口跟海外出口(访问google)时,偶尔会遇到部分网站打不开或加载速度慢,大概率是访问国内资源从海外出口走,访问海外资源亦是如此,由于路由不准确导致,笔者之前通过IANA获取的地址合集路由命中率不高(云厂商真会玩),经过多番查找,在github上找到了相对准确的国内地址合集,大概每月更新一次,为什么是获取国内的地址合集,国内地址合集目前大约6千多条,海外合集几万条。
此教程为两篇(上篇基础使用,下篇相对代码偏多)
本篇为如何获取IP地址合集,如何将地址下发给设备
下篇为自动同步地址合集(自动对地址合集做增删操作):下篇 点击跳转
首先配置环境使用pip 安装第三方库
需要使用的python第三方库工两个requests、netmiko
pip install requests (笔者之前已经安装)使用方法请查看官方手册:Requests: HTTP for Humans™
pip install netmiko(笔者之前已经安装)使用方法请参照
@弈心 弈心:网络工程师的Python之路 – Netmiko终极指南
@朱嘉盛 朱嘉盛:专栏入口(阅读目录+故事简介+交流渠道)
获取China IP合集链接
IP地址合计从giuhub上获取https://github.com/17mon/china_ip_list/blob/master/china_ip_list.txt,大概每个月更新一次;
脚本使用地址为:https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
代码如下:
import requests
from netmiko import ConnectHandler
new_ip_list = []
add_dev_ip_address_1 = ['ip address-set IP-CN01 type object']
add_dev_ip_address_2 = ['ip address-set IP-CN02 type object']
url = 'https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt'
try:
header = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,'
'*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/96.0.4664.110 Safari/537.36',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,zh-TW;q=0.2',
'Connection': 'keep-alive',
'path': '/17mon/china_ip_list/master/china_ip_list.tx'
}
r = requests.get(url, headers=header, timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
new_ip_list_01 = r.text
new_ip_list_02 = new_ip_list_01.strip().split('\n')
for new_ip_list_03 in new_ip_list_02:
new_ip_list.append(new_ip_list_03)
except Exception as e:
print(e)
print(f'最新国内IP地址合集条目为: {len(new_ip_list)}\n')
for new_ip_list1 in new_ip_list[:3998]:
add_dev_ip_address_1_1 = new_ip_list1.replace('/', ' mask ')
add_dev_ip_address_1.append(f'address {add_dev_ip_address_1_1}')
for new_ip_list2 in new_ip_list[3998:]:
add_dev_ip_address_2_1 = new_ip_list2.replace('/', ' mask ')
add_dev_ip_address_2.append(f'address {add_dev_ip_address_2_1}')
print(f'----第一个IP合集为:{len(add_dev_ip_address_1)}----\n----第二个IP合集为:{len(add_dev_ip_address_2)}----\n')
try:
device = {'device_type': 'huawei', 'host': '10.10.0.1', 'username': 'python', 'password': '123.com'}
ssh_client = ConnectHandler(**device)
print('---开始下发防火墙现有IP地址集合---\n')
add_address_comm_01_log = ssh_client.send_config_set(add_dev_ip_address_1)
add_address_comm_02_log = ssh_client.send_config_set(add_dev_ip_address_2)
print(f'-----下面是地址组1的命令日志-----\n{add_address_comm_01_log}\n')
print(f'-----下面是地址组2的命令日志-----\n{add_address_comm_02_log}')
except Exception as e:
print(e)
在防火墙上配置地址合集及选路策略
创建一个名为IP-CN 的地址组将IP-CN01 和 IP-CN02 添加到地址组中
创建策略路由
代码讲解:
import requests
from netmiko import ConnectHandler
上述代码 为导入第三方模块
new_ip_list = []
上述代码 用于格式化从guthub上得到的IP地址合集;
add_dev_ip_address_1 = ['ip address-set IP-CN01 type object']
add_dev_ip_address_2 = ['ip address-set IP-CN02 type object']
上述代码 笔者使用华为USG6300防火墙单个地址合集最大支持3999个,当前的地址合集为(6125),所以需要两个列表存放命令;ip address-set IP-CN01 type object 和 ip address-set IP-CN02 type object 在设备上创建两个IP地址合集。
url = ‘https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt’
上述代码 定义一个URL
header = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,'
'*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/96.0.4664.110 Safari/537.36',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,zh-TW;q=0.2',
'Connection': 'keep-alive',
'path': '/17mon/china_ip_list/master/china_ip_list.tx'
}
上述代码 header = {}字段构建https请求头部(太简单会被拒绝),相关信息可以通过谷歌浏览器开发者工具中获取
r = requests.get(url, headers=header, timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
new_ip_list_01 = r.text
上述代码 得到网页上的相关内容通过输出为文本格式
new_ip_list_02 = new_ip_list_01.strip().split('\n')
for new_ip_list_03 in new_ip_list_02:
new_ip_list.append(new_ip_list_03)
strip()函数删除文本中的空白行,split(’\n’) 通过换行符号(\n)将文件切片写入new_ip_list中
for new_ip_list1 in new_ip_list[:3998]:
add_dev_ip_address_1_1 = new_ip_list1.replace('/', ' mask ')
add_dev_ip_address_1.append(f'address {add_dev_ip_address_1_1}')
for new_ip_list2 in new_ip_list[3998:]:
add_dev_ip_address_2_1 = new_ip_list2.replace('/', ' mask ')
add_dev_ip_address_2.append(f'address {add_dev_ip_address_2_1}')
for new_ip_list1 in new_ip_list[:3998] 使用for循环提取new_ip_list 中 1-3999 的值;
for new_ip_list2 in new_ip_list[3998:] 使用for循环提取new_ip_list 中 3999-末尾 的值;
add_dev_ip_address_2_1 = new_ip_list2.replace(’/’, ’ mask ‘) 将单个字符串中的/ 替换为mask;
add_dev_ip_address_2.append(f’address {add_dev_ip_address_2_1}’) 将字符串格式化为address 1.1.1.0 mask 24
上图为部分格式的内容
try:
device = {'device_type': 'huawei', 'host': '10.10.0.1', 'username': 'python', 'password': '123.com'}
ssh_client = ConnectHandler(**device)
print('---开始下发防火墙现有IP地址集合---\n')
add_address_comm_01_log = ssh_client.send_config_set(add_dev_ip_address_1)
add_address_comm_02_log = ssh_client.send_config_set(add_dev_ip_address_2)
print(f'-----下面是地址组1的命令日志-----\n{add_address_comm_01_log}\n')
print(f'-----下面是地址组2的命令日志-----\n{{add_address_comm_02_log}')
except Exception as e:
print(e)
登录网络设备开始下发配置,根据实际情况填写相关信息。