文章目录
前言
IPsec的配置依赖关系众多,稍微不注意就容易配置错误,只要配置错误就容易导致IPsec起不来;所以我希望利用一些手段来简化这些复杂的配置;所以我采用学习难度不高,但十分成熟的python语言来解决这类的问题。
git地址
https://gitee.com/peng-lei-lei/routing-switching
一、基础环境
组网环境
配置好各个接口的IP地址
总部出口路由器的主要基础配置
sysname HQ
ip route-static 0.0.0.0 0 100.0.0.100
acl advanced 3000
rule 5 permit ip
interface GigabitEthernet0/2
nat outbound 3000
分支出口路由器的主要基础配置
sysname branch
ip route-static 0.0.0.0 0 200.0.0.2
acl advanced 3000
rule 5 permit ip
interface GigabitEthernet0/0
nat outbound 3000
二、书写IPsec的jinja2配置模板
文件系统的结构
jinjia2的配置模板存放在templates目录下面;python脚本文件于templates在同一个目录下面
{# 创建感兴趣流 #}
acl advanced {{ AclNumber }}
rule permit ip source {{ SouNet }} destination {{ DestNet }}
quit
{# 创建IKE提议 #}
ike proposal 1
authentication-method pre-share
encryption-algorithm aes-cbc-128
quit
{# 创建IKE预共享密钥 #}
ike keychain {{ KPT }}
pre-shared-key address {{ RemotePublicIp }} key simple {{ IkePassword }}
quit
{# 创建IKE-profile,指定本端和对端公网地址,并调用预共享密钥和IKE提议#}
ike profile {{ KPT }}
keychain {{ KPT }}
local-identity address {{ LocalPublicIp }}
match remote identity address {{ RemotePublicIp }}
proposal 1
quit
{# 创建 IPsec 转换集,默认使用隧道模式和esp封装所以不用管 #}
ipsec transform-set {{ KPT }}
esp authentication-algorithm sha1
esp encryption-algorithm aes-cbc-128
quit
{# 创建 IPsec 策略,调用上述配置 #}
ipsec policy {{ KPT }} 1 isakmp
security acl {{ AclNumber }}
ike-profile {{ KPT }}
transform-set {{ KPT }}
remote-address {{ RemotePublicIp }}
quit
{# 在公网接口上下发 IPsec 策略 #}
int {{ IntfPort }}
ipsec apply policy {{ KPT }}
quit
{# 适配IPsec的公网NAT ACL #}
acl advanced {{ NatNum }}
rule 1 deny ip source {{ SouNet }} destination {{ DestNet }}
rule permit ip source any
quit
{# 在公网接口上修改NAT出口ACL #}
int {{ IntfPort }}
nat outbound {{ NatNum }}
quit
为什么需要在适配IPsec的公网NAT ACL规则上先拒绝掉走IPsec的流量
解:因为流量数据如果匹配到NAT后,会默认就走NAT,达不到使流量数据走IPsec,所以需要先拒绝,让其匹配后面IPsec的策略,然后匹配IPsec里面的规则。
二、书写IPsec的渲染脚本
import winreg #得到桌面环境,配置文件直接输出到桌面,方便寻找
from pathlib import Path #创建文件的依赖包,比os好用,所以我用的这
from jinja2 import FileSystemLoader,Environment #使用jinja2渲染所需要的包
def GetDesktop(): #得到桌面路径
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders",)
return Path(winreg.QueryValueEx(key, "Desktop")[0])
def IpsecVPnRender(outputpath): #IpsecVPN渲染
loader = FileSystemLoader("templates") #加载templates模板文件夹
environment = Environment(loader=loader) #加在jinja2的环境
SouDevice = environment.get_template("IpsecVpn.conf.tp")
DestDevice = environment.get_template("IpsecVpn.conf.tp")
AclNumber = int(input("输入匹配IPsec的ACL序列号:"))
SouNet = input("输入本端 私网 网段的网络号/主机+反掩码:") #渲染时这两种方式进行反向操作
DestNet = input("输入目的 私网 网段的网络号/主机+反掩码:")
print("将对以下三个模块进行统一命名:ike-proposal、profile、transform")
KPT = input("输入这三个模块统一的名字:") #Src的策略名
IkePassword = input("输入IKE的密码:")
LocalPublicIp = input("输入本端公网IP地址,不用加掩码:")
RemotePublicIp = input("输入对端公网IP地址,不用加掩码:")
IntfportSrc = input("输入本端应用该IPsec策略的端口(公网出口):") #公网接口
NatNum = input("输入本端应用NAT的ACL序号:") #只支持高级ACL,因为要拒绝掉IPsec的流量
SouDevice.stream(AclNumber = AclNumber,
SouNet = SouNet,
DestNet = DestNet,
KPT = KPT,
IkePassword = IkePassword,
LocalPublicIp = LocalPublicIp,
RemotePublicIp = RemotePublicIp,
IntfPort = IntfportSrc,
NatNum = NatNum).dump(outputpath.format(f"IPSEC {LocalPublicIp}.conf")) #如数jinja2模板所需要的参数
print("本端已经渲染成功,将进行对端的IPsec镜像渲染,是否进行渲染?")
tag = input("输入 y/n:")
if tag == "y":
KPT1 = KPT+"1" #作为Dest的策略名
IntfportDest = input("输入对端应用该IPsec策略的端口(公网出口):") #公网接口
NatNum = input("输入对端应用NAT的ACL序号:")
DestDevice.stream(AclNumber = AclNumber,
SouNet = DestNet,
DestNet = SouNet,
KPT = KPT1,
IkePassword = IkePassword,
LocalPublicIp = RemotePublicIp,
RemotePublicIp = LocalPublicIp,
IntfPort = IntfportDest,
NatNum = NatNum).dump(outputpath.format(f"IPSEC {RemotePublicIp}.conf"))
print("本端+对的端都已渲染完成")
def main():#利用主函数进行执行流程的编排
DesktopPath = GetDesktop() / "config"
DesktopPath.mkdir(parents=True,exist_ok=True)
IpsecVPnRender(str(DesktopPath)+"\\{}")
main() #执行主函数
四、运行python脚本,根据提示输入参数(我的环境用的是jupyter)
在桌面上我们就可以看到已经生成了IPsec的配置文件了;为了好区分,我采用的是以conf结尾的文件,右键使用记事本打开即可,并使用公网地址进行区分,公网地址文件名就是公网地址所在的那一端的配置。
打开文件,里面已经渲染好了配置文件,直接使出我们网络人常用的快捷方式 Ctrl + A 然后 Ctrl + C;进入配置界面 右击粘贴 即可;当然针对与不同的环境还有待改进,所以生成的是配置文件,这样可以再附加一些其它配置进行一并粘贴;也可以针对于不同环境做相应配置的更改。
测试
对端IP地址为2.1;已正常通信。IPsec建立成功。
为什么我不采用yaml来书写配置模块
因为代码量过少,模块也很少,使用yaml来书写配置文件的效率还是比较低下,特别是对于不熟悉yaml的人来说,还需要先学习yaml语法;得不偿失;对于这种交互式环境来说,运行脚本即可以使用;十分方便。