Python实现ISE批量添加网络设备
- ISE简介
- API
-
- 启用ERS
- 创建ERS账号
- 构建请求
- 实现批处理
不知道大家是否有过ISE替换ACS或新部署ISE的经历,如果关联的NAS设备众多,需要手动添加成百上千台那真是苦不堪言,这也是我最近遇到的问题,懒惰的我是不可能手动进行添加的,于是便写了今天这个实例,顺便跟大家分享一下;原理是通过Python调用API对ISE进行批处理,ISE
API十分丰富,大家如果有其他批处理需求,也可以举一反三进行实现~
ISE简介
思科® 身份服务引擎 (ISE) 可帮助 IT 专业人员应对企业移动性挑战,并为不断发展的网络提供涵盖整个攻击过程的 保护。Cisco ISE 是市场领先的安全策略管理平台,它能以统一且自动化的方式实现高度安全的访问控制,帮助实施 基于角色的网络访问及网络资源访问。它提供出色的用户可视性和设备可视性,可实现简化的企业移动性体验。它 采用基于思科平台交换网格 (pxGrid) 技术的集成生态系统合作伙伴解决方案共享至关重要的情景数据,可更快地识 别和缓解威胁,并采取补救措施。
以上是CISCO官网中ISE的中文简介,大家可以简单的把ISE理解为一台AAA服务器,用于实现认证授权审计的功能。详情请查阅思科官网
API
还是老套路,我们先找到对应API,再做请求。我们可以从CISCO的DevNet社区文档中很容易的找到ISE专栏,链接如下:
https://developer.cisco.com/docs/identity-services-engine/ 上述文章中明确的指出了,我们需要先启用ISE ERS功能以及创建ERS Admin账号,后续才能调用API;
启用ERS
ERS在HTTPS端口9060上使用,该端口默认为关闭。尝试访问该端口而不先启用ERS的客户端将面临服务器超时。因此,第一个要求是从ISE管理员UI启用ERS。转到管理->设置-> ERS设置。选中“为读取/写入启用ERS”单选按钮,如下面的屏幕截图所示。
创建ERS账号
构建请求
准备就绪后,我们可以开始确认需要用到的API,查看API 文档,如下REST API即可实现我们的需求:
https://10.56.60.175:9060/ers/config/networkdevice
我们按照提示内容对headers进行封装,并采用json的格式进行输入:
url = r'https://192.168.231.51:9060/ers/config/networkdevice'
headers = {
'Content-Type': 'application/xml ',
'Accept': 'application/xml',
'ERS-Media-Type': 'network.networkdevicegroup.1.1',
'X-CSRF-TOKEN': 'fetch',
}
clear_json = {
"NetworkDevice": {
"name": 'Test',
"description": 'For Test',
# "authenticationSettings": {
# "radiusSharedSecret": "aaa",
# "enableKeyWrap": True,
# "dtlsRequired": True,
# "keyEncryptionKey": "1234567890123456",
# "messageAuthenticatorCodeKey": "12345678901234567890",
# "keyInputFormat": "ASCII"
# },
# "snmpsettings": {
# "version": "ONE",
# "roCommunity": "aaa",
# "pollingInterval": 3600,
# "linkTrapQuery": True,
# "macTrapQuery": True,
# "originatingPolicyServicesNode": "Auto"
# },
# "trustsecsettings": {
# "deviceAuthenticationSettings": {
# "sgaDeviceId": "networkDevice1",
# "sgaDevicePassword": "aaa"
# },
# "sgaNotificationAndUpdates": {
# "downlaodEnvironmentDataEveryXSeconds": 86400,
# "downlaodPeerAuthorizationPolicyEveryXSeconds": 86400,
# "reAuthenticationEveryXSeconds": 86400,
# "downloadSGACLListsEveryXSeconds": 86400,
# "otherSGADevicesToTrustThisDevice": False,
# "sendConfigurationToDevice": False,
# "sendConfigurationToDeviceUsing": "ENABLE_USING_COA",
# "coaSourceHost": "YourIseNode"
# },
# "deviceConfigurationDeployment": {
# "includeWhenDeployingSGTUpdates": True,
# "enableModePassword": "aaa",
# "execModePassword": "aaa",
# "execModeUsername": "aaa"
# }
# },
"tacacsSettings": {
"sharedSecret": "Tacacs",
"connectModeOptions": "ON_LEGACY"
},
"profileName": "Cisco",
"coaPort": 1700,
# "dtlsDnsName": "ISE213.il.com",
"NetworkDeviceIPList": [
{
"ipaddress": "192.168.60.66",
"mask": 32
},
],
"NetworkDeviceGroupList": [
"Location#All Locations",
"Device Type#All Device Types"
]
}
}
req = requests.post(url, headers=headers, auth=('Username','Password'), data=json.dumps(clear_json), verify=False)
运行后,我们在ISE Network Device界面上可以看到有新增的设备信息:
实现批处理
基本功能实现后,我们只需要将准备添加的设备IP或者网段存放至TXT或者EXCEL以便调取,再简单的加上循环即可实现批量添加的效果,一次性几百上千的进行添加了:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/05/26 22:40
# @Author : Walton
# @FileName: NetworkDevice.py
# @Software: PyCharm
# @Blog :https://vonten.github.io
import os
import ssl
import json
import requests
ssl._create_default_https_context = ssl._create_unverified_context
def getNetworkInfo(file):
iplist = []
with open(file, 'r') as f:
ips = f.read().splitlines()
for ip in ips:
try:
(ipaddress, mask) = ip.split('/')
dict = {
'ipaddress': ipaddress.strip(),
"mask": int(mask)
}
iplist.append(dict)
except ValueError:
dict = {
'ipaddress': ip.strip(),
"mask": 32
}
iplist.append(dict)
return iplist
def clearNetworkDevice(name, des, file):
iplist = getNetworkInfo(file)
url = r'https://192.168.231.51:9060/ers/config/networkdevice'
headers = {
'Content-Type': 'application/json ',
'Accept': 'application/json',
# 'ERS-Media-Type': 'network.networkdevicegroup.1.1',
'X-CSRF-TOKEN': 'fetch',
}
clear_json = {
"NetworkDevice": {
"name": name,
"description": des,
# "authenticationSettings": {
# "radiusSharedSecret": "aaa",
# "enableKeyWrap": True,
# "dtlsRequired": True,
# "keyEncryptionKey": "1234567890123456",
# "messageAuthenticatorCodeKey": "12345678901234567890",
# "keyInputFormat": "ASCII"
# },
# "snmpsettings": {
# "version": "ONE",
# "roCommunity": "aaa",
# "pollingInterval": 3600,
# "linkTrapQuery": True,
# "macTrapQuery": True,
# "originatingPolicyServicesNode": "Auto"
# },
# "trustsecsettings": {
# "deviceAuthenticationSettings": {
# "sgaDeviceId": "networkDevice1",
# "sgaDevicePassword": "aaa"
# },
# "sgaNotificationAndUpdates": {
# "downlaodEnvironmentDataEveryXSeconds": 86400,
# "downlaodPeerAuthorizationPolicyEveryXSeconds": 86400,
# "reAuthenticationEveryXSeconds": 86400,
# "downloadSGACLListsEveryXSeconds": 86400,
# "otherSGADevicesToTrustThisDevice": False,
# "sendConfigurationToDevice": False,
# "sendConfigurationToDeviceUsing": "ENABLE_USING_COA",
# "coaSourceHost": "YourIseNode"
# },
# "deviceConfigurationDeployment": {
# "includeWhenDeployingSGTUpdates": True,
# "enableModePassword": "aaa",
# "execModePassword": "aaa",
# "execModeUsername": "aaa"
# }
# },
"tacacsSettings": {
"sharedSecret": "Tacacs",
"connectModeOptions": "ON_LEGACY"
},
"profileName": "Cisco",
"coaPort": 1700,
"NetworkDeviceIPList": iplist,
"NetworkDeviceGroupList": [
"Location#All Locations",
"Device Type#All Device Types"
]
}
}
req = requests.post(url, headers=headers, auth=('Username','Password'), data=json.dumps(clear_json), verify=False)
print(req.text)
def main(path):
files = os.listdir(path)
for file in files:
name = file.split('.')[0]
des = file.split('.')[1]
file_path = path + '\\' + file
clearNetworkDevice(name, des, file_path)
if __name__ == '__main__':
main('filePtah')
以上是本期的所有内容,感谢您的阅读~
希望每个看完本文的您都能有所收获,如果您觉得本文不错,可以点一波关注或者关注一下我的公众号~
您的支持是我最大的动力!