我们今天来讲一讲一种互通技术: MPLS L3 VPN.
MPLS 是一种 2.5 层的标签技术, 因为当时IP转发大多靠软件进行,在转发的每一跳都要进行至少一次最长匹配查找,操作复杂导致转发速度比较慢。于是 MPLS 就诞生了。 其优势也是显而易见的, 路由器转发含有 MPLS label 的数据包时,无需再花费大量时间进行路由表查找的动作,只需要查找简单的标签表,就可以查询到转发路径,极大的提升了数据转发速度。 但后来 IP 转发领域有很多新技术产生,如硬件转发与网络处理器的出现,导致现在 MPLS 的速度优势体现不出来,纯 MPLS 转发在实际应用中几乎没有用武之地 。
但 MPLS 是一个很有“潜力”的技术,可灵活扩展。很多新的应用依靠纯 IP 转发实现起来有很大的难度,但用 MPLS 再结合其它技术就可以实现,如:BGP/MPLS VPN、流量工程等技术的产生就是对 MPLS 灵活扩展的结果。 我们今天就来讲其中一种典型的应用:MPLS L3 VPN.
什么是 MPLS L3 VPN?
MPLS VPN的出现主要是为了要解决传统VPN技术的一些固有缺陷,这有很多技术问题需要解决的,其中最重要的是地址重叠的问题。必须有一种技术可以保证不同的用户VPN可以使用相同的私有地址空间,而且可以在公共的骨干网络上互相不影响地交换数据。
ref: 新华三官网 – L3 VPN 基础 http://www.h3c.com/cn/d_201212/922115_30005_0.htm
那么,我们都知道 Cisco 的 IOSXE 与 Juniper 的 vMX 都有成熟的 MPLS L3 VPN 解决方案以及套件,但是这些商业公司的路由器授权都非常的昂贵,一台设备授权动辄几万甚至十几万,对于个人用户学习来说成本实在是太大了,有没有不需要花钱就能学习 MPLS L3 VPN 的方法呢?
答案是:有的。今天我们就用 Debian Linux 来搭建 VPNv4 网络。
拓扑整图如下:
话不多说,我们现在开始配置拓扑。
首先你需要编译安装路由套件(这里选择 frr routing),并在 sysctl 中打开 MPLS mod ( debian 自带的内核已经包含了该 mod ),具体操作可以查看 Jamesit 同学写的 :《使用Linux作为MPLS路由器》
安装并升级好必要组件后,我们在 Kernel level 将 IP 地址如图中所示配置好,然后再开始配置 IGP 协议。这里我们选择使用 IS-IS 作为 IGP 底层( IS-IS 和 OSPF 相比,更适合于大型运营商 )。
由于 Linux 的 persistent net device naming 机制,所以 eve 上 e0 接口会显示 ens3,e1 显示 ens4,以此类推进行配置。
使用 vtysh
命令进路由协议命令行进行配置。
isis circuit-type level-2-only
isis circuit-type level-2-only
isis circuit-type level-2-only
net 47.0000.0000.0000.0001.00
isis circuit-type level-2-only
isis circuit-type level-2-only
net 47.0000.0000.0000.0002.00
isis circuit-type level-2-only
isis circuit-type level-2-only
net 47.0000.0000.0000.0003.00
isis circuit-type level-2-only
isis circuit-type level-2-only
net 47.0000.0000.0000.0004.00
我们在 P 路由器上查看邻居:
localhost# show ip route isis
Codes: K – kernel route, C – connected, S – static, R – RIP,
O – OSPF, I – IS-IS, B – BGP, E – EIGRP, N – NHRP,
T – Table, v – VNC, V – VNC-Direct, A – Babel, D – SHARP,
> – selected route, * – FIB route, q – queued route, r – rejected route
I>* 10.0.0.1/32 [115/20] via 192.168.2.1, ens4, 00:05:18
I>* 10.0.0.3/32 [115/20] via 192.168.3.2, ens5, 00:03:04
I>* 10.0.0.4/32 [115/20] via 192.168.1.1, ens3, 00:17:05
I 192.168.1.0/24 [115/20] via 192.168.1.1, ens3 inactive, 00:17:05
I 192.168.2.0/24 [115/20] via 192.168.2.1, ens4 inactive, 00:05:18
I 192.168.3.0/24 [115/20] via 192.168.3.2, ens5 inactive, 00:03:04
localhost# show isis neighbor
System Id Interface L State Holdtime SNPA
localhost ens3 2 Up 29 0050.0100.0800
localhost ens4 2 Up 29 0050.0100.0300
localhost ens5 2 Up 29 0050.0100.0600
可见路由邻接关系已经建立成功,路由已交换完成。
接下来需要在接口下启动 MPLS address-family:
sysctl net.mpls.conf.ens3.input=1
sysctl net.mpls.conf.ens4.input=1
sysctl net.mpls.conf.ens5.input=1
discovery transport-address 10.0.0.2
sysctl net.mpls.conf.ens3.input=1
discovery transport-address 10.0.0.1
sysctl net.mpls.conf.ens3.input=1
discovery transport-address 10.0.0.3
sysctl net.mpls.conf.ens3.input=1
discovery transport-address 10.0.0.4
配置完毕,我们在核心路由器 P 上检查邻居关系:
localhost# show mpls ldp nei
AF ID State Remote Address Uptime
ipv4 10.0.0.1 OPERATIONAL 10.0.0.1 00:01:53
ipv4 10.0.0.3 OPERATIONAL 10.0.0.3 00:00:05
ipv4 10.0.0.4 OPERATIONAL 10.0.0.4 00:00:46
所有邻居状态以及 remote-address 正确,LDP 配置完成。
IGP 配置完成后,我们来配置内部的 BGP 协议。由于在同一个 domain 内,所以我们采用 iBGP + RR 的方式来组建 iBGP 网络。
no bgp default ipv4-unicast
neighbor 10.0.0.1 remote-as 65000
neighbor 10.0.0.1 update-source dummy0
neighbor 10.0.0.3 remote-as 65000
neighbor 10.0.0.3 update-source dummy0
neighbor 10.0.0.1 activate
neighbor 10.0.0.1 route-reflector-client
neighbor 10.0.0.3 activate
neighbor 10.0.0.3 route-reflector-client
no bgp default ipv4-unicast
neighbor 10.0.0.4 remote-as 65000
neighbor 10.0.0.4 update-source dummy0
neighbor 10.0.0.4 activate
P 路由器无需运行 BGP 协议,使用纯 MPLS 网络转发。
由于我们这种拓扑不需要激活 BGP IPv4 address-family,所以我们就不配置 address-family unicast 了。但是在生产环境中一定要记得配置,为了规范,切记。
配置完成后,我们来检查 RR 的 BGP VPNv4 sesison:
localhost# show bgp summary
BGP router identifier 192.168.1.1, local AS number 65000 vrf-id 0
RIB entries 0, using 0 bytes of memory
Peers 2, using 41 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
10.0.0.1 4 65000 4 4 0 0 0 00:01:08 0
10.0.0.3 4 65000 3 3 0 0 0 00:00:37 0
Total number of neighbors 2
现在内网的 VPNv4 BGP 已经完成了,我们开始配接下来的步骤:先配置 VRF ,再配置与客户的 BGP Session.
ip link add blue type vrf table 100
ip route add vrf blue unreachable default metric 4278198272
ip link set ens4 vrf blue
ip addr add 10.10.1.1/24 dev ens4
ip link add red type vrf table 200
ip route add vrf red unreachable default metric 4278198272
ip addr add 10.10.1.1/24 dev ens5
ip link add red type vrf table 200
ip route add vrf red unreachable default metric 4278198272
ip addr add 10.10.2.1/24 dev ens4
ip link add blue type vrf table 100
ip route add vrf blue unreachable default metric 4278198272
ip link set ens5 vrf blue
ip addr add 10.10.2.1/24 dev ens5
到此,Linux VRF 配置完成。
客户侧已经预配置好与 PE 的 BGP 链接,且宣告了客户路由,于是我们现在来配置 PE1 & PE2 的 VRF leak:
router bgp 65000 vrf blue
neighbor 10.10.1.2 remote-as 65535
address-family ipv4 unicast
neighbor 10.10.1.2 remote-as 65530
address-family ipv4 unicast
router bgp 65000 vrf blue
neighbor 10.10.2.2 remote-as 65535
address-family ipv4 unicast
neighbor 10.10.2.2 remote-as 65530
address-family ipv4 unicast
在 PE 上配置的时候有可能遇到 Zebra.d 报错的问题,不用慌,先 show run
看看配置有没有正确输入进去,配置输入正确的话就可以无视。
查看邻居列表:
localhost# show ip bgp vrf all summary
BGP router identifier 192.168.2.1, local AS number 65000 vrf-id 0
RIB entries 5, using 920 bytes of memory
Peers 1, using 20 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
10.0.0.4 4 65000 82 80 0 0 0 01:13:17 2
Total number of neighbors 1
BGP router identifier 10.10.1.1, local AS number 65000 vrf-id 9
RIB entries 3, using 552 bytes of memory
Peers 1, using 20 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
10.10.1.2 4 65535 31 26 0 0 0 00:20:18 1
Total number of neighbors 1
BGP router identifier 10.10.1.1, local AS number 65000 vrf-id 10
RIB entries 3, using 552 bytes of memory
Peers 1, using 20 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
10.10.1.2 4 65530 37 30 0 0 0 00:18:32 1
Total number of neighbors 1
localhost# show ip bgp vrf all su
BGP router identifier 192.168.3.2, local AS number 65000 vrf-id 0
RIB entries 5, using 920 bytes of memory
Peers 1, using 20 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
10.0.0.4 4 65000 80 76 0 0 0 01:11:57 2
Total number of neighbors 1
BGP router identifier 10.10.2.1, local AS number 65000 vrf-id 10
RIB entries 1, using 184 bytes of memory
Peers 1, using 20 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
10.10.2.2 4 65535 11 8 0 0 0 00:05:43 1
Total number of neighbors 1
BGP router identifier 10.10.2.1, local AS number 65000 vrf-id 9
RIB entries 3, using 552 bytes of memory
Peers 1, using 20 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
10.10.2.2 4 65530 11 9 0 0 0 00:05:43 1
Total number of neighbors 1
可以看到两边 PE 都收到了相连邻居的路由,且从 RR 收到了别的 pop 发过来的路由条目,那么我们就抽查一下深圳边界路由器,看看有没有正常工作吧!
Network Next Hop Metric LocPrf Weight Path
*> 172.19.1.0/24 0.0.0.0 0 32768 i
咦?为什么只有本地发出去的路由在 BGP 数据库内,对端的 172.19.2.0/24
路由呢?想要知道这个问题,我们需要了解一下 BGP 的防环机制。
首先,我们来观察 172.19.2.0/24
路由的 ASPATH 走向:
AS65535 <- AS65000 <- AS65535 i
那么,对于收到的路径里面已经含有自己 ASPATH 的路由,BGP 会将其丢弃,以防止环路,这就是为什么边界路由器收不到路由的原因。要解决这个问题,我们有两种方案:
- CE 上配置 allowas-in
- PE 上配置 as-override
我们来了解一下它们的原理:
allowas-in 就是关闭了 BGP 的水平分割,这样做会有路由环路的危险。
as-override 由运营商替换最末尾的 ASPATH 为运营商的 ASPATH,从而避免触发水平分割导致无法接收路由,环路的危险很小。
于是我们在PE上配置 as-override.
router bgp 65000 vrf blue
address-family ipv4 unicast
neighbor 10.10.1.2 as-override
address-family ipv4 unicast
neighbor 10.10.1.2 as-override
router bgp 65000 vrf blue
address-family ipv4 unicast
neighbor 10.10.2.2 as-override
address-family ipv4 unicast
neighbor 10.10.2.2 as-override
配置完成,再来查看深圳的边界路由:
BGP table version is 5, local router ID is 172.19.1.1
Network Next Hop Metric LocPrf Weight Path
*> 172.19.1.0/24 0.0.0.0 0 32768 i
*> 172.19.2.0/24 10.10.1.1 0 0 65000 65000 i
可见深圳的边界路由已经正常接收路由条目了。于是我们来测试数据传输情况:
数据已经正确的传输到对应的 VRF 了,基于 Debian Linux 的 MPLS L3 VPN 搭建完成。