菜单

[ Linux ] 使用 Debian Linux 构架 MPLS L3 网络

2020年2月24日 - Linux

这是一篇合作文章,作者是 LittleWolf 和 Jamesits.

我们今天来讲一讲一种互通技术: 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 命令进路由协议命令行进行配置。

#P
interface dummy0
 ip router isis 1
!
interface ens3
 ip router isis 1
 isis circuit-type level-2-only
!
interface ens4
 ip router isis 1
 isis circuit-type level-2-only
!
interface ens5
 ip router isis 1
 isis circuit-type level-2-only
!
router isis 1
 is-type level-2-only
 net 47.0000.0000.0000.0001.00
#PE1
interface dummy0
 ip router isis 1
 isis circuit-type level-2-only
!
interface ens3
 ip router isis 1
 isis circuit-type level-2-only
!
router isis 1
 is-type level-2-only
 net 47.0000.0000.0000.0002.00
#PE2
interface dummy0
 ip router isis 1
 isis circuit-type level-2-only
!
interface ens3
 ip router isis 1
 isis circuit-type level-2-only
!
router isis 1
 is-type level-2-only
 net 47.0000.0000.0000.0003.00
#RR
interface dummy0
 ip router isis 1
 isis circuit-type level-2-only
!
interface ens3
 ip router isis 1
 isis circuit-type level-2-only
!
router isis 1
 is-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,
       F - PBR, f - OpenFabric,
       > - 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
Area 1:
  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:

#P
sysctl net.mpls.conf.ens3.input=1
sysctl net.mpls.conf.ens4.input=1
sysctl net.mpls.conf.ens5.input=1

#vtysh.cli
mpls ldp
 router-id 10.0.0.2
 address-family ipv4
  discovery transport-address 10.0.0.2
  interface ens3
  interface ens4
  interface ens5
#PE1
sysctl net.mpls.conf.ens3.input=1

#vtysh.cli
mpls ldp
 router-id 10.0.0.1
 address-family ipv4
  discovery transport-address 10.0.0.1
  interface ens3
#PE2
sysctl net.mpls.conf.ens3.input=1

#vtysh.cli
mpls ldp
 router-id 10.0.0.3
 address-family ipv4
  discovery transport-address 10.0.0.3
  interface ens3
#PE3
sysctl net.mpls.conf.ens3.input=1

#vtysh.cli
mpls ldp
 router-id 10.0.0.4
 address-family ipv4
  discovery transport-address 10.0.0.4
  interface ens3

配置完毕,我们在核心路由器 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 网络。

#RR
#vtysh.cli
router bgp 65000
 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
 address-family ipv4 vpn
  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
#PE1 & PE2
#vtysh.cli
router bgp 65000
 no bgp default ipv4-unicast
 neighbor 10.0.0.4 remote-as 65000
 neighbor 10.0.0.4 update-source dummy0
 address-family ipv4 vpn
  neighbor 10.0.0.4 activate

P 路由器无需运行 BGP 协议,使用纯 MPLS 网络转发。

由于我们这种拓扑不需要激活 BGP IPv4 address-family,所以我们就不配置 address-family unicast 了。但是在生产环境中一定要记得配置,为了规范,切记。

配置完成后,我们来检查 RR 的 BGP VPNv4 sesison:

#RR
#vtysh.cli
localhost# show bgp summary

IPv4 VPN Summary:
BGP router identifier 192.168.1.1, local AS number 65000 vrf-id 0
BGP table version 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.

#PE1
# linux shell

# VRF BLUE
ip link add blue type vrf table 100
ip link set blue up
ip route add vrf blue unreachable default metric 4278198272
ip link set ens4 vrf blue 
ip link set ens4 up
ip addr add 10.10.1.1/24 dev ens4


# VRF RED
ip link add red type vrf table 200
ip link set red up
ip route add vrf red unreachable default metric 4278198272
ip link set ens5 vrf red 
ip link set ens5 up
ip addr add 10.10.1.1/24 dev ens5
#PE2
#Linux shell

#VRF RED
ip link add red type vrf table 200
ip link set red up
ip route add vrf red unreachable default metric 4278198272
ip link set ens4 vrf red
ip link set ens4 up
ip addr add 10.10.2.1/24 dev ens4

#VRF BLUE
ip link add blue type vrf table 100
ip link set blue up
ip route add vrf blue unreachable default metric 4278198272
ip link set ens5 vrf blue
ip link set ens5 up
ip addr add 10.10.2.1/24 dev ens5

到此,Linux VRF 配置完成。

客户侧已经预配置好与 PE 的 BGP 链接,且宣告了客户路由,于是我们现在来配置 PE1 & PE2 的 VRF leak:

#PE1
#vtysh.cli

router bgp 65000 vrf blue
 neighbor 10.10.1.2 remote-as 65535
 bgp router-id 10.10.1.1
 !
 address-family ipv4 unicast
  label vpn export auto
  rd vpn export 65000:100
  rt vpn both 65000:100
  export vpn
  import vpn
 exit-address-family
!
router bgp 65000 vrf red
 neighbor 10.10.1.2 remote-as 65530
 bgp router-id 10.10.1.1
 !
 address-family ipv4 unicast
  label vpn export auto
  rd vpn export 65000:200
  rt vpn both 65000:200
  export vpn
  import vpn
 exit-address-family
#PE2
#vtysh.cli

router bgp 65000 vrf blue
 bgp router-id 10.10.2.1
 neighbor 10.10.2.2 remote-as 65535
 !
 address-family ipv4 unicast
  label vpn export auto
  rd vpn export 65000:100
  rt vpn both 65000:100
  export vpn
  import vpn
 exit-address-family
!
router bgp 65000 vrf red
 bgp router-id 10.10.2.1
 neighbor 10.10.2.2 remote-as 65530
 !
 address-family ipv4 unicast
  label vpn export auto
  rd vpn export 65000:200
  rt vpn both 65000:200
  export vpn
  import vpn
 exit-address-family

在 PE 上配置的时候有可能遇到 Zebra.d 报错的问题,不用慌,先 show run 看看配置有没有正确输入进去,配置输入正确的话就可以无视。

查看邻居列表:

#PE1

localhost# show ip bgp vrf all summary

Instance default:

IPv4 VPN Summary:
BGP router identifier 192.168.2.1, local AS number 65000 vrf-id 0
BGP table version 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

Instance blue:

IPv4 Unicast Summary:
BGP router identifier 10.10.1.1, local AS number 65000 vrf-id 9
BGP table version 2
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

Instance red:

IPv4 Unicast Summary:
BGP router identifier 10.10.1.1, local AS number 65000 vrf-id 10
BGP table version 4
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
#PE2

localhost# show ip bgp vrf all su

Instance default:

IPv4 VPN Summary:
BGP router identifier 192.168.3.2, local AS number 65000 vrf-id 0
BGP table version 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

Instance blue:

IPv4 Unicast Summary:
BGP router identifier 10.10.2.1, local AS number 65000 vrf-id 10
BGP table version 1
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

Instance red:

IPv4 Unicast Summary:
BGP router identifier 10.10.2.1, local AS number 65000 vrf-id 9
BGP table version 2
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 发过来的路由条目,那么我们就抽查一下深圳边界路由器,看看有没有正常工作吧!

#ShenZhen-Edge

Router#show ip bgp

     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 会将其丢弃,以防止环路,这就是为什么边界路由器收不到路由的原因。要解决这个问题,我们有两种方案:

  1. CE 上配置 allowas-in
  2. PE 上配置 as-override

我们来了解一下它们的原理:

allowas-in 就是关闭了 BGP 的水平分割,这样做会有路由环路的危险。

as-override 由运营商替换最末尾的 ASPATH 为运营商的 ASPATH,从而避免触发水平分割导致无法接收路由,环路的危险很小。

于是我们在PE上配置 as-override.

#PE1
#vtysh.cli

router bgp 65000 vrf blue
 !
 address-family ipv4 unicast
  neighbor 10.10.1.2 as-override
 exit-address-family
!
router bgp 65000 vrf red
 !
 address-family ipv4 unicast
  neighbor 10.10.1.2 as-override
 exit-address-family
#PE2
#vtysh.cli

router bgp 65000 vrf blue
 !
 address-family ipv4 unicast
  neighbor 10.10.2.2 as-override
 exit-address-family
!
router bgp 65000 vrf red
 !
 address-family ipv4 unicast
  neighbor 10.10.2.2 as-override
 exit-address-family

配置完成,再来查看深圳的边界路由:

#Shenzhen-edge

Router#show ip bgp
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 搭建完成。

感谢 Jamesits 与我共同协作完成该实验,在此表示感谢。

参考资料:

使用 Linux 作为 MPLS 路由器》,Jamesits

MPLS及LDP协议基础》,新华三官网

L3 VPN 基础》,新华三官网

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据