基于Openwrt(Linux)系统实现SRv6数据包的传输——实验一
基于Openwrt(Linux)系统实现SRv6数据包的传输前言实验准备硬件准备软件准备刷写Openwrt固件安装软件包前言之所以想写这篇博客,是因为之前一直在网上找有关于Openwrt和SRv6的相关材料,结果一直找不到合适的。就在绝望的时候,我在Openwrt官网上看到版本v21.02.0-rc1的简介,居然支持了SRv6数据包的封装与发送,并提供了一句实例配置命令,不过也没有更具体的阐述了。
基于Openwrt(Linux)系统实现SRv6数据包的传输——实验一
前言
之所以想写这篇博客,是因为之前一直在网上找有关于Openwrt和SRv6的相关材料,结果一直找不到合适的。就在绝望的时候,我在Openwrt官网上看到版本v21.02.0-rc1的简介,居然支持了SRv6数据包的封装与发送,并提供了一句实例配置命令,不过也没有更具体的阐述了。经过几天不断的实验和踩坑,终于能够实现在两台运行Openwrt系统的路由器上通过SRv6来实现数据包的封装、传输、解封的整个过程,可以说是相当不容易。
由于本人在Openwrt和SRv6方面都是小白水平,接下来的介绍中可能会出现一些不太专业的用词或者出现一些小错误,欢迎路过的大神前来批评指正。
实验准备
硬件准备
实验要准备的设备还是比较简单的,两台能够刷Openwrt固件的无线路由器就行,这里我们用的是谛听的newifi3(新路由3)。除此之外,还需要有两个公网IPv6地址。
软件准备
刷写Openwrt固件
本次实验中路由器上刷的Openwrt固件是openwrt-21.02.0-rc3-ramips-mt7621-d-team_newifi-d2-squashfs-sysupgrade。在官网上可以下到,这里就不提供下载路径了,当然也可以自己编译OpenWrt固件,网上教程也比较多,关键词可以搜“Openwrt、Ubuntu”。
需要注意的是,不同的路由器刷写的固件是不一样的,所以在刷固件或者编译固件之前一定要知道自己路由器CPU的型号等相关信息,避免后面出现不可预估的错误。
刷完固件后,前往Openwrt配置界面填写相关IP信息,就能够上网了。
安装软件包
在Openwrt官网的SRv6介绍文档中,你需要注意到这几句,“Lwtunnel allow an easy encapsulation of a package. You can just install ip-full package and use it”。这里要用到整个实验中最为核心的网络工具包ip-full,它可以实现在Openwrt(Linux)环境中路由命令的配置,当然它也是支持SRv6封装、解封命令的。后来去搜了一下,ip-full就是iproute2,linux的路由配置被成为高级路由。为了在Openwrt系统上安装ip-full包,你需要用ssh登录到路由器的命令行界面中(luci可视化界面也可以安装,具体大家可以上网搜一下),然后输入以下两条命令:
opkg update # 更新软件包列表
opkg install ip-full # 安装ip-full包
opkg install tcpdump # 安装抓包工具(可选,方便后期排错)
opkg install luci-i18n-base-zh-cn # 安装luci中文界面(可选)
参照另一篇文档“netifd: add segment routing support”,需要在/etc/config/network中修改相关网络接口与SRv6的配置。在option lan和option wan中添加
option ip6segmentrouting '1' # 使接口能够封装并发送SRv6的数据包
重启接口后,使用cat命令在/proc/sys/net/ipv6/conf/<*interface>/中查看seg6_enabled文件,你可以发现值由0变为1。在该路径下可能还会存在其他与SRv6相关的文件,详情可以参考https://www.kernel.org/doc/html/latest/networking/seg6-sysctl.html。在本实验中,只需要改上述两个给出配置命令的文件即可,其他文件留给感兴趣的小伙伴研究[doge]。
实验过程
实验一: “背靠背”连通
实验拓扑
实验拓扑如下,两个监控终端分别连接本地的SRv6 CPE(无线路由器),主要目的是实现两地终端(PC)的连通。
实验原理
终端1发送数据包后,由本地无线路由器封装成SRv6数据包,通过IPv6地址发送至远端SRv6 CPE,另一端无线路由器收到此数据包后进行解封装,通过源数据包中的IPv4地址转发给终端2,由此实现远程两端在逻辑上的连通,原理图如下:
数据包转发过程
路由器配置
理解上述原理后,就可以着手开始做相关的配置了。首先简单介绍一下整个过程中会用到了一些命令:
echo "(表ID) (表名)" >> /etc/iproute2/rt_tables # 在路由表文件中添加表项
ip route add <目的地区网段> encap seg6 mode encap segs <经过的SID> dev wan table <路由表名或编号> # 配置封装SRv6数据包的命令
ip rule add <from,to> <匹配的源(目的)IP地址> table <路由表名或编号> pri <优先级> # 根据数据包的地址段匹配命令与SID列表
ip -6 route add <自身的SID> encap seg6local action End.DX4 nh4 <目的IPv4地址> dev br-lan # 解封装操作
ip -6 route add <下一跳路由器的SID> via <下一跳路由器的IPv6地址> # 配置静态路由,使SID与下一跳的IPv6设备相对应
tcpdump -i any -n -w test.pcap # 抓包命令(tcpdump -i <接口> -n -w <文件名.pcap>)
R1的配置如下:
echo "100 SRv6" >> /etc/iproute2/rt_tables
echo "101 Recive" >> /etc/iproute2/rt_tables
echo "102 SID_IPv6" >> /etc/iproute2/rt_tables
ip route add 192.168.3.0/24 encap seg6 mode encap segs fc00::3 dev wan table 100
ip rule add to 192.168.3.0/24 table 100 pri 10
ip -6 route add fc00::1/128 encap seg6local action End.DX4 nh4 192.168.1.195 dev br-lan table 101
ip -6 route add fc00::3/128 via 2001:250:640b::a05:a84:130 table 102
ip -6 rule add table 101 pri 11
ip -6 rule add table 102 pri 12
R3的配置如下:
echo "100 SRv6" >> /etc/iproute2/rt_tables
echo "101 Recive" >> /etc/iproute2/rt_tables
echo "102 SID_IPv6" >> /etc/iproute2/rt_tables
ip route add 192.168.1.0/24 encap seg6 mode encap segs fc00::1 dev wan table 100
ip rule add to 192.168.1.0/24 table 100 pri 10
ip -6 route add fc00::3/128 encap seg6local action End.DX4 nh4 192.168.3.181 dev br-lan table 101
ip -6 route add fc00::1/128 via 2001:250:640b::a05:a84:110 table 102
ip -6 rule add table 101 pri 11
ip -6 rule add table 102 pri 12
配置命令解析
- 添加路由表项。
- 配置包封装指令,这里需要注意的是SRv6用到的SID不能是接口地址。如果是接口地址会直接导致收到的SRv6包在路由表选择时会与local路由表匹配,因为local路由表具有最高优先级,所以这里必须要自定义SID。自定义SID也能体现出SRv6的可编程性,通过不同的SID与不同服务相关联,能够更好地实现SRv6 Policy。
- 配置IPv6默认路由,将自定义SID与IPv6接口地址相关联。
- 配置路由表应用地址和优先级。
路由器防火墙配置
使用Ping命令测试PC1至PC3的连通性,在R3抓包,会发现封装的ICMP Request、拆分的ICMP Request和未被封装的ICMP Reply,但没有封装的ICMP Reply包。
通过不断测试发现,是Openwrt的防火墙的问题,为了保证实验能够成功运行,需要在Network->Firewall->Traffic Rules中添加规则,如下图所示。
联通性测试
抓包分析
- 主机1数据包
在主机1上可以看到由PC1至PC3发送的ICMP数据包
- 主机2数据包
- 路由器R1
在R1上可以看到PC1发送的ICMP数据包(长度76),以及封装后的ICMP数据包(长度140),R3封装的回程ICMP数据包(长度140)以及 R1解封装后的ICMP数据包(长度76)
- 路由器R3
R3上数据包的类型与R1相似,这里就不作过多的阐述了,直接上图
更多推荐
所有评论(0)