見出し画像

containerlab + FRRoutingでstatic route


概要

containerlabでFRRoutingを2台起動させてstatic routeを設定して2台のルータのloopbackアドレス間で疎通性を持たせる。

topology.yml

前回の https://note.com/ya04su/n/ncc1d94f093c3 で作ったYAMLを流用します

name: test01

topology:
  nodes:
    r1:
      kind: linux
      image: quay.io/frrouting/frr:master
      binds:
        - daemons:/etc/frr/daemons
        - r1.log:/var/log/frr.log
        - r1.conf:/etc/frr/frr.conf
    r2:
      kind: linux
      image: quay.io/frrouting/frr:master
      binds:
        - daemons:/etc/frr/daemons
        - r2.log:/var/log/frr.log
        - r2.conf:/etc/frr/frr.conf
  links:
    - endpoints: ["r1:eth1", "r2:eth1"]

FRRoutingの設定

r1 config

コンテナへの入り方は docker exec -ti "コンテナホスト名" bash でFRRoutingが動いているlinuxにログインできます。
ルータモードに入るには vtysh をshell上で実行します。
shellを介さずにルータモードに入るには docker exec -ti "コンテナホスト名" bash -c vtyshで入ることができます。
コンテナホスト名は clab-ラボ名-ホスト名 の命名規則になっています。

guest@vm-docker2:~/clab/test01$ sudo docker exec -ti clab-test01-r1 bash -c vtysh
% Can't open configuration file /etc/frr/vtysh.conf due to 'No such file or directory'.
Configuration file[/etc/frr/frr.conf] processing failure: 11

Hello, this is FRRouting (version 10.3-dev_git20241208).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

r1# conf t
r1(config)# inter lo
r1(config-if)# ip address 1.1.1.1/32
r1(config-if)# description r1
r1(config-if)# exit
r1(config)# inter eth1
r1(config-if)# ip address 10.0.0.0/31
r1(config-if)# description r2_eth1
r1(config-if)# no shut
r1(config-if)# exit
r1(config)# ip route 2.2.2.2/32 10.0.0.1 eth1
r1(config)# exit
r1# wri mem
Note: this version of vtysh never writes vtysh.conf
% Can't open configuration file /etc/frr/vtysh.conf due to 'No such file or directory'.
Configuration file[/etc/frr/frr.conf] processing failure: 11
Building Configuration...
Error renaming /etc/frr/frr.conf to /etc/frr/frr.conf.sav: Resource busy
Integrated configuration saved to /etc/frr/frr.conf
[OK]
r1#

r1の設定確認

r1# show inter descr

        VRF default(0)

Interface       Status  Protocol  Description
eth0            up      up
eth1            up      up        r2_eth1
lo              up      up        r1
pimreg          up      up
r1# show ip route
Codes: K - kernel route, C - connected, L - local, S - static,
       R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
       f - OpenFabric, t - Table-Direct,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

K>* 0.0.0.0/0 [0/0] via 172.20.20.1, eth0, weight 1, 00:22:45
L * 1.1.1.1/32 is directly connected, lo, weight 1, 00:01:08
C>* 1.1.1.1/32 is directly connected, lo, weight 1, 00:01:08
S>* 2.2.2.2/32 [1/0] via 10.0.0.1, eth1, weight 1, 00:00:38
C>* 10.0.0.0/31 is directly connected, eth1, weight 1, 00:00:59
L>* 10.0.0.0/32 is directly connected, eth1, weight 1, 00:00:59
C>* 172.20.20.0/24 is directly connected, eth0, weight 1, 00:22:45
L>* 172.20.20.2/32 is directly connected, eth0, weight 1, 00:22:45
r1#

設定していないeth0のip addrやデフォルトルートの設定が見える
コンテナが内部通信用のために設定したもの
煩わしいので以下の通りvrf mgmtを作ることでdefault RIBから消し去ることができる

vrf mgmtの作成、管理IFへの適用

Linuxの話なのでFRRoutingやcontainerlabとは直接関係ないがipコマンドでLinux上にvrfを作ることができる

guest@vm-docker2:~/clab/test01$ sudo docker exec -ti clab-test01-r1 bash
r1:/# ip link add mgmt type vrf table 11
r1:/# ip link set dev mgmt up
r1:/# ip link set dev eth0 master mgmt
r1:/# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: pimreg@NONE: <NOARP,UP,LOWER_UP> mtu 1472 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/pimreg
3: mgmt: <NOARP,MASTER,UP,LOWER_UP> mtu 65575 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 4a:e6:77:87:6b:8f brd ff:ff:ff:ff:ff:ff
4: pimreg11@NONE: <NOARP,ALLMULTI,UP,LOWER_UP> mtu 1472 qdisc noqueue master mgmt state UNKNOWN mode DEFAULT group default qlen 1000
    link/pimreg
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master mgmt state UP mode DEFAULT group default
    link/ether 02:42:ac:14:14:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
17: eth1@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9500 qdisc noqueue state UP mode DEFAULT group default
    link/ether aa:c1:ab:39:f9:f5 brd ff:ff:ff:ff:ff:ff link-netnsid 1
r1:/#

r1の設定確認②

r1:/# vtysh
% Can't open configuration file /etc/frr/vtysh.conf due to 'No such file or directory'.
Configuration file[/etc/frr/frr.conf] processing failure: 11

Hello, this is FRRouting (version 10.3-dev_git20241208).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

r1# show inter descr

        VRF default(0)

Interface       Status  Protocol  Description
eth1            up      up        r2_eth1
lo              up      up        r1
pimreg          up      up

        VRF mgmt(3)

Interface       Status  Protocol  Description
eth0            up      up
mgmt            up      up
pimreg11        up      up
r1# show ip route
Codes: K - kernel route, C - connected, L - local, S - static,
       R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
       f - OpenFabric, t - Table-Direct,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

L * 1.1.1.1/32 is directly connected, lo, weight 1, 00:09:04
C>* 1.1.1.1/32 is directly connected, lo, weight 1, 00:09:04
S>* 2.2.2.2/32 [1/0] via 10.0.0.1, eth1, weight 1, 00:08:34
C>* 10.0.0.0/31 is directly connected, eth1, weight 1, 00:08:55
L>* 10.0.0.0/32 is directly connected, eth1, weight 1, 00:08:55
r1#

eth0がvrf mgmtに変更されてshow ip routeの結果から消えてくれた
合わせてデフォルトルートも消えた

r2 config→設定確認

r1と同様に設定してみる

guest@vm-docker2:~/clab/test01$ sudo docker exec -ti clab-test01-r2 bash
[sudo] password for guest:
r2:/#
# vrf mgmt を作って eth0 に適用
r2:/# ip link add mgmt type vrf table 11
r2:/# ip link set dev mgmt up
r2:/# ip link set dev eth0 master mgmt
r2:/# vtysh
% Can't open configuration file /etc/frr/vtysh.conf due to 'No such file or directory'.
Configuration file[/etc/frr/frr.conf] processing failure: 11

Hello, this is FRRouting (version 10.3-dev_git20241208).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

r2# conf t
r2(config)# inter lo
r2(config-if)# ip address 2.2.2.2/32
r2(config-if)# descr r2
r2(config-if)# exit
r2(config)# inter eth1
r2(config-if)# ip address 10.0.0.1/31
r2(config-if)# description r1_eth1
r2(config-if)# no shut
r2(config-if)# exit
r2(config)# ip route 1.1.1.1/32 10.0.0.0 eth1
r2(config)# end
r2# show ip route
Codes: K - kernel route, C - connected, L - local, S - static,
       R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
       f - OpenFabric, t - Table-Direct,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

S>* 1.1.1.1/32 [1/0] via 10.0.0.0, eth1, weight 1, 00:00:04
L * 2.2.2.2/32 is directly connected, lo, weight 1, 00:00:32
C>* 2.2.2.2/32 is directly connected, lo, weight 1, 00:00:32
C>* 10.0.0.0/31 is directly connected, eth1, weight 1, 00:00:20
L>* 10.0.0.1/32 is directly connected, eth1, weight 1, 00:00:20
r2# show inter descr

        VRF default(0)

Interface       Status  Protocol  Description
eth1            up      up        r1_eth1
lo              up      up        r2
pimreg          up      up

        VRF mgmt(3)

Interface       Status  Protocol  Description
eth0            up      up
mgmt            up      up
pimreg11        up      up
# frroutingではpingが無限に続くのでCtrl + Cで抜ける
r2# ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 56 data bytes
64 bytes from 1.1.1.1: seq=0 ttl=64 time=0.123 ms
64 bytes from 1.1.1.1: seq=1 ttl=64 time=0.082 ms
64 bytes from 1.1.1.1: seq=2 ttl=64 time=0.118 ms
^C
--- 1.1.1.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.082/0.107/0.123 ms
r2# exit
# source指定pingをしたい場合はshellモードで実施
r2:/# ping -I 2.2.2.2 1.1.1.1 -c 5
PING 1.1.1.1 (1.1.1.1) from 2.2.2.2: 56 data bytes
64 bytes from 1.1.1.1: seq=0 ttl=64 time=0.085 ms
64 bytes from 1.1.1.1: seq=1 ttl=64 time=0.161 ms
64 bytes from 1.1.1.1: seq=2 ttl=64 time=0.080 ms
64 bytes from 1.1.1.1: seq=3 ttl=64 time=0.109 ms
64 bytes from 1.1.1.1: seq=4 ttl=64 time=0.112 ms

--- 1.1.1.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 0.080/0.109/0.161 ms
r2:/#

キャプチャする

以下のコマンドでコンテナ間の通信をキャプチャすることができる

guest@vm-docker2:~/clab/test01$ sudo ip netns exec clab-test01-r1 tcpdump -nni eth1 -w r1_eth1_`date +%Y%m%d_%H%M%S`.pcap
tcpdump: listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes

キャプチャの結果

guest@vm-docker2:~/clab/test01$ tcpdump -r r1_eth1_20241208_110854.pcap
reading from file r1_eth1_20241208_110854.pcap, link-type EN10MB (Ethernet), snapshot length 262144
11:12:43.119171 ARP, Request who-has 10.0.0.0 tell 10.0.0.1, length 28
11:12:43.119201 ARP, Reply 10.0.0.0 is-at aa:c1:ab:39:f9:f5 (oui Unknown), length 28
11:12:43.119206 IP 10.0.0.1 > one.one.one.one: ICMP echo request, id 110, seq 0, length 64
11:12:43.119234 IP one.one.one.one > 10.0.0.1: ICMP echo reply, id 110, seq 0, length 64
11:12:45.739472 IP 10.0.0.1 > one.one.one.one: ICMP echo request, id 110, seq 1, length 64
11:12:45.739496 IP one.one.one.one > 10.0.0.1: ICMP echo reply, id 110, seq 1, length 64
11:12:46.863656 IP 10.0.0.1 > one.one.one.one: ICMP echo request, id 110, seq 2, length 64
11:12:46.863690 IP one.one.one.one > 10.0.0.1: ICMP echo reply, id 110, seq 2, length 64
11:12:48.581533 ARP, Request who-has 10.0.0.1 tell 10.0.0.0, length 28
11:12:48.581609 ARP, Reply 10.0.0.1 is-at aa:c1:ab:f8:06:9e (oui Unknown), length 28
11:13:13.048843 IP 2.2.2.2 > one.one.one.one: ICMP echo request, id 112, seq 0, length 64
11:13:13.048871 IP one.one.one.one > 2.2.2.2: ICMP echo reply, id 112, seq 0, length 64
11:13:14.050970 IP 2.2.2.2 > one.one.one.one: ICMP echo request, id 112, seq 1, length 64
11:13:14.051003 IP one.one.one.one > 2.2.2.2: ICMP echo reply, id 112, seq 1, length 64
11:13:15.058354 IP 2.2.2.2 > one.one.one.one: ICMP echo request, id 112, seq 2, length 64
11:13:15.058386 IP one.one.one.one > 2.2.2.2: ICMP echo reply, id 112, seq 2, length 64
11:13:17.418429 IP 2.2.2.2 > one.one.one.one: ICMP echo request, id 113, seq 0, length 64
11:13:17.418456 IP one.one.one.one > 2.2.2.2: ICMP echo reply, id 113, seq 0, length 64
11:13:18.113691 ARP, Request who-has 10.0.0.0 tell 10.0.0.1, length 28
11:13:18.113755 ARP, Reply 10.0.0.0 is-at aa:c1:ab:39:f9:f5 (oui Unknown), length 28
11:13:18.454474 IP 2.2.2.2 > one.one.one.one: ICMP echo request, id 113, seq 1, length 64
11:13:18.454506 IP one.one.one.one > 2.2.2.2: ICMP echo reply, id 113, seq 1, length 64
11:13:19.682538 IP 2.2.2.2 > one.one.one.one: ICMP echo request, id 113, seq 2, length 64
11:13:19.682561 IP one.one.one.one > 2.2.2.2: ICMP echo reply, id 113, seq 2, length 64
11:13:21.003563 IP 2.2.2.2 > one.one.one.one: ICMP echo request, id 113, seq 3, length 64
11:13:21.003596 IP one.one.one.one > 2.2.2.2: ICMP echo reply, id 113, seq 3, length 64
11:13:22.868733 IP 2.2.2.2 > one.one.one.one: ICMP echo request, id 113, seq 4, length 64
11:13:22.868766 IP one.one.one.one > 2.2.2.2: ICMP echo reply, id 113, seq 4, length 64
guest@vm-docker2:~/clab/test01$

pcapファイルが生成されるのでwireshark/tsharkで見ることもできます。

最後に

FRRoutingを使ってstatic routeを設定してみました。
containerlabを使うと簡単にPoC環境を作ることができて、再現も簡単です。
次回以降ではIGP/BGP等のRouting Protocolを動かす環境を掲載していこうと思います。

いいなと思ったら応援しよう!