はじめに
GMOコネクトの永田です。
前回に引き続きcontainerlabを試していきます。
「ルーターと言えばBGPでしょ!」ということで、今回はFRRoutingでBGPを試してみます。
BGPであれば、どこのご家庭でもお使いの一般的なProtocolであり、設定例も潤沢にあるかな?と思っていましたが、意外と少なかったのでまとめてみます。
まとめ
- containerlabを使うと、topology図に沿った構成が簡単に実現可能
- 複数Routerでの経路伝搬も簡単に試すことができる
- BGPを設定する場合、FRRoutingではRFC8212の設定もあるので要注意
試したtopology
今回はsrc/dstとも別のRouter(別のAS)に所属し、Router間(AS間)をBGPでの経路伝搬とします。
とてもシンプルな構成ですね!
AS65001などと書いているのがAS番号です。経路制御を行うRouterを一意に識別する番号です。今回は「Private AS番号」と呼ばれるローカルで自由に使える番号を利用しています。
AS番号含め、BGPの用語や概念については、以下のページを参照してください。
topology設定
では早速containerlabでtopologyを組んでいきます。
clab yml
できました!
上記topology図の通り素直に nodes
と links
を記載するだけですね。
bindsに vtysh.conf
が増えていますが、FRRの設定のところで説明します。
name: clab-mini-topo
topology:
nodes:
r1:
kind: linux
image: quay.io/frrouting/frr:10.4.1
binds:
- r1/daemons:/etc/frr/daemons
- r1/frr.conf:/etc/frr/frr.conf
- r1/vtysh.conf:/etc/frr/vtysh.conf
r2:
kind: linux
image: quay.io/frrouting/frr:10.4.1
binds:
- r2/daemons:/etc/frr/daemons
- r2/frr.conf:/etc/frr/frr.conf
- r2/vtysh.conf:/etc/frr/vtysh.conf
src:
kind: linux
image: praqma/network-multitool:latest
exec:
- "ip link set eth1 up"
- "ip addr add 192.168.1.11/24 dev eth1"
- "ip route add 192.168.0.0/16 via 192.168.1.1 dev eth1"
dst:
kind: linux
image: praqma/network-multitool:latest
exec:
- "ip link set eth1 up"
- "ip addr add 192.168.2.11/24 dev eth1"
- "ip route add 192.168.0.0/16 via 192.168.2.1 dev eth1"
links:
# for bgp peering
- endpoints: [r1:eth2, r2:eth2]
# for host connectivity
- endpoints: [src:eth1, r1:eth1]
- endpoints: [dst:eth1, r2:eth1]
FRRouting Config
次にFRRoutingのConfigでBGPをサポートするようにします。
daemons(r1/r2とも同じ)
前回からの差分は、bgpd=yes
に変更したのみです。
zebra=yes
bgpd=yes
ospfd=yes
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
ldpd=yes
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
staticd=no
pbrd=no
bfdd=no
fabricd=no
vtysh_enable=yes
zebra_options=" -s 90000000 --daemon -A 127.0.0.1"
bgpd_options=" --daemon -A 127.0.0.1"
ospfd_options=" --daemon -A 127.0.0.1"
ospf6d_options=" --daemon -A ::1"
ripd_options=" --daemon -A 127.0.0.1"
ripngd_options=" --daemon -A ::1"
isisd_options=" --daemon -A 127.0.0.1"
pimd_options=" --daemon -A 127.0.0.1"
ldpd_options=" --daemon -A 127.0.0.1"
nhrpd_options=" --daemon -A 127.0.0.1"
eigrpd_options=" --daemon -A 127.0.0.1"
babeld_options=" --daemon -A 127.0.0.1"
sharpd_options=" --daemon -A 127.0.0.1"
staticd_options=" --daemon -A 127.0.0.1"
pbrd_options=" --daemon -A 127.0.0.1"
bfdd_options=" --daemon -A 127.0.0.1"
fabricd_options=" --daemon -A 127.0.0.1"
vtysh.conf(r1/r2とも同じ)
この後、FRRのvtyshを使ってBGPの状態を参照したいのですが、/etc/frr/vtysh.conf
が存在しないとエラーとなるため、事前に作成しておきます。
service integrated-vtysh-config
今回はbgpdなどdaemon毎の設定ではなく、frr.conf
に全deamonの設定を集約するので上記としています。
Control whether integrated frr.conf file is written when ‘write file’ is issued.
These commands need to be placed in vtysh.conf to have any effect. Note that since vtysh.conf is not written by FRR itself, they therefore need to be manually placed in that file.
frr.conf(r1)
最後に設定本体のfrr.cof
を見ていきます。
frr version 10.4.1_git
frr defaults traditional
hostname router1
no ipv6 forwarding
!
# I/F settings
interface eth1
ip address 192.168.1.1/24
!
interface eth2
ip address 192.168.12.1/24
!
interface lo
ip address 10.10.10.1/32
!
# AS-PATH filter for outbound (own routes only)
bgp as-path access-list OWN-ROUTES permit ^$
!
route-map BGP-OUT permit 10
match as-path OWN-ROUTES
exit
!
# AS-PATH filter for inbound (only allow routes from neighbor)
bgp as-path access-list IN-ROUTES permit 65002
!
route-map BGP-IN permit 10
match as-path IN-ROUTES
exit
!
# BGP Configuration for Router1(AS65001)
router bgp 65001
# no bgp ebgp-requires-policy
neighbor 192.168.12.2 remote-as 65002
!
address-family ipv4 unicast
network 192.168.1.0/24
neighbor 192.168.12.2 soft-reconfiguration inbound
neighbor 192.168.12.2 route-map BGP-OUT out
neighbor 192.168.12.2 route-map BGP-IN in
exit-address-family
exit
!
line vty
!
I/F settings
I/F settings
からの3つは、topology図に記載があるNIC(src向けとAS65002向けの2つ)+lo(local)であり、それに沿ったNIC名とIPアドレスを指定しています。
BGP setting
次に、ちょっと飛ばしてBGP設定の本体を見ます。
# BGP Configuration for Router1(AS65001)
router bgp 65001
# no bgp ebgp-requires-policy
neighbor 192.168.12.2 remote-as 65002
!
address-family ipv4 unicast
network 192.168.1.0/24
neighbor 192.168.12.2 soft-reconfiguration inbound
neighbor 192.168.12.2 route-map BGP-OUT out
neighbor 192.168.12.2 route-map BGP-IN in
exit-address-family
exit
-
router bgp 65001
からexit
までが、bgp設定です -
neighbor 192.168.12.2 remote-as 65002
- お隣のASを指定します。今回はtopologyで書いた通りのIPとAS番号を指定します
-
address-family ipv4 unicast
の中のnetwork 192.168.1.0/24
が、本ASが起点となって周知したい経路情報です。今回はsrcが所属するIP Rangeになります -
neighbor 192.168.12.2 soft-reconfiguration inbound
- これはOptionalなのですが、受信した経路情報をRouting Tableとは別に保持するかどうかの設定です。今回はdebugしやすように設定をいれています
-
neighbor 192.168.12.2 route-map BGP-OUT out
とneighbor 192.168.12.2 route-map BGP-IN in
- 本ASから出ていく経路情報(
out
)と入ってくる経路情報(in
)のpolicy(フィルタリング条件)となります -
RFC8212 Default External BGP (EBGP) Route Propagation Behavior without Policies
に準拠した設定です(正直めんどくさい)- https://datatracker.ietf.org/doc/html/rfc8212
- みんな大好きTLS1.3がRFC8446ですので、比較的新しいRFCですね!
- in/outそれぞれにpolicyを設定しています。policyの具体的な内容は後述
- なお、
no bgp ebgp-requires-policy
の設定を入れると無視することも可能です(上記サンプルではコメントアウトされているところ)
- 本ASから出ていく経路情報(
bgp ebgp-requires-policy
This command requires incoming and outgoing filters to be applied for eBGP sessions as part of RFC-8212 compliance. Without the incoming filter, no routes will be accepted. Without the outgoing filter, no routes will be announced.
BGP setting - route-map
最後に、先ほど飛ばした設定を見ます。ここが経路情報の送受信policy本体です。
# AS-PATH filter for outbound (own routes only)
bgp as-path access-list OWN-ROUTES permit ^$
!
route-map BGP-OUT permit 10
match as-path OWN-ROUTES
exit
!
# AS-PATH filter for inbound (only allow routes from neighbor)
bgp as-path access-list IN-ROUTES permit 65002
!
route-map BGP-IN permit 10
match as-path IN-ROUTES
exit
!
-
bgp as-path access-list OWN-ROUTES permit ^$
- BGP送信用に、自身が伝搬元となる経路情報のみ許可
- AS_PATHが空のものを指定
- AS_PATHについては、先ほどのJPNICのページを参照してください
-
oute-map BGP-OUT permit 10
match as-path OWN-ROUTES
-
BGP-OUT
という名前で先ほどの「自身が伝搬元」を許可(permit
)
-
-
bgp as-path access-list IN-ROUTES permit 65002
- BGP受信用に、お隣(AS65002)からのみ許可
-
route-map BGP-IN permit 10
match as-path IN-ROUTES
- 上記の受信を許可
policyですが、FFRのドキュメントにサンプルもあるので、参考にするのも良いです。
Bogon ASN filter policy configuration example
bgp as-path access-list 99 permit _0_
bgp as-path access-list 99 permit _23456_
bgp as-path access-list 99 permit _1310[0-6][0-9]_|_13107[0-1]_
bgp as-path access-list 99 seq 20 permit ^65
frr.conf(r2)
設定内容はr1と同じ考え方です。IP RangeやAS番号などをr2向けに変更しています。
frr version 10.4.1_git
frr defaults traditional
hostname router2
no ipv6 forwarding
!
# I/F settings
interface eth1
ip address 192.168.2.1/24
!
interface eth2
ip address 192.168.12.2/24
!
interface lo
ip address 10.10.10.2/32
!
# AS-PATH filter for outbound (own routes only)
bgp as-path access-list OWN-ROUTES permit ^$
!
route-map BGP-OUT permit 10
match as-path OWN-ROUTES
exit
!
# AS-PATH filter for inbound (only allow routes from neighbor)
bgp as-path access-list IN-ROUTES permit 65001
!
route-map BGP-IN permit 10
match as-path IN-ROUTES
exit
!
# BGP Configuration for Router2(AS65002)
router bgp 65002
# no bgp ebgp-requires-policy
neighbor 192.168.12.1 remote-as 65001
!
address-family ipv4 unicast
network 192.168.2.0/24
neighbor 192.168.12.1 soft-reconfiguration inbound
neighbor 192.168.12.1 route-map BGP-OUT out
neighbor 192.168.12.1 route-map BGP-IN in
exit-address-family
exit
!
line vty
!
動かしてみた
topologyの起動
containerlabで起動します。(同じclab nameで起動中の場合は、--reconfigure
optionもつけてください)
❯ containerlab deploy -t bgp-mini-topo.clab.yml
01:42:07 INFO Containerlab started version=0.71.0
01:42:07 INFO Parsing & checking topology file=bgp-mini-topo.clab.yml
01:42:07 INFO Destroying lab name=clab-mini-topo
01:42:07 INFO Removed container name=clab-clab-mini-topo-r1
01:42:07 INFO Removed container name=clab-clab-mini-topo-r2
01:42:07 INFO Removed container name=clab-clab-mini-topo-dst
01:42:07 INFO Removed container name=clab-clab-mini-topo-src
01:42:07 INFO Removing host entries path=/etc/hosts
01:42:07 INFO Removing SSH config path=/etc/ssh/ssh_config.d/clab-clab-mini-topo.conf
01:42:07 INFO Removing directory path=/Users/nagatatakahiko/work/aist/aist-pcs-telemetry/example/clab-bgp-mini-topo/clab-clab-mini-topo
01:42:07 INFO Creating lab directory path=/Users/nagatatakahiko/work/aist/aist-pcs-telemetry/example/clab-bgp-mini-topo/clab-clab-mini-topo
01:42:07 INFO unable to adjust Labdir file ACLs: operation not supported
01:42:07 INFO Creating container name=src
01:42:07 INFO Creating container name=dst
01:42:07 INFO Creating container name=r1
01:42:07 INFO Creating container name=r2
01:42:07 INFO Created link: r1:eth2 ▪┄┄▪ r2:eth2
01:42:07 INFO Created link: dst:eth1 ▪┄┄▪ r2:eth1
01:42:07 INFO Created link: src:eth1 ▪┄┄▪ r1:eth1
01:42:07 INFO Executed command node=src command="ip link set eth1 up" stdout=""
01:42:07 INFO Executed command node=src command="ip addr add 192.168.1.11/24 dev eth1" stdout=""
01:42:07 INFO Executed command node=src command="ip route add 192.168.0.0/16 via 192.168.1.1 dev eth1" stdout=""
01:42:07 INFO Executed command node=dst command="ip link set eth1 up" stdout=""
01:42:07 INFO Executed command node=dst command="ip addr add 192.168.2.11/24 dev eth1" stdout=""
01:42:07 INFO Executed command node=dst command="ip route add 192.168.0.0/16 via 192.168.2.1 dev eth1" stdout=""
01:42:08 INFO Adding host entries path=/etc/hosts
01:42:08 INFO Adding SSH config for nodes path=/etc/ssh/ssh_config.d/clab-clab-mini-topo.conf
You are on the latest version (0.71.0)
╭─────────────────────────┬─────────────────────────────────┬─────────┬───────────────────╮
│ Name │ Kind/Image │ State │ IPv4/6 Address │
├─────────────────────────┼─────────────────────────────────┼─────────┼───────────────────┤
│ clab-clab-mini-topo-dst │ linux │ running │ 172.20.20.2 │
│ │ praqma/network-multitool:latest │ │ 3fff:172:20:20::2 │
├─────────────────────────┼─────────────────────────────────┼─────────┼───────────────────┤
│ clab-clab-mini-topo-r1 │ linux │ running │ 172.20.20.5 │
│ │ quay.io/frrouting/frr:10.4.1 │ │ 3fff:172:20:20::5 │
├─────────────────────────┼─────────────────────────────────┼─────────┼───────────────────┤
│ clab-clab-mini-topo-r2 │ linux │ running │ 172.20.20.4 │
│ │ quay.io/frrouting/frr:10.4.1 │ │ 3fff:172:20:20::4 │
├─────────────────────────┼─────────────────────────────────┼─────────┼───────────────────┤
│ clab-clab-mini-topo-src │ linux │ running │ 172.20.20.3 │
│ │ praqma/network-multitool:latest │ │ 3fff:172:20:20::3 │
╰─────────────────────────┴─────────────────────────────────┴─────────┴───────────────────╯
r1のBGPおよびrouting tableの確認
さて、BGPを確認していきます。
bashで入ってvtyshを呼び出してもいいのですが、直接でも入れるのでそちらの方法にしています。
❯ docker exec -it clab-clab-mini-topo-r1 vtysh
Hello, this is FRRouting (version 10.4.1_git).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
r1#
BGPのsummaryを見てみます。
r1# show bgp summary
IPv4 Unicast Summary:
BGP router identifier 10.10.10.1, local AS number 65001 VRF default vrf-id 0
BGP table version 2
RIB entries 3, using 384 bytes of memory
Peers 1, using 17 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt Desc
192.168.12.2 4 65002 8 9 2 0 0 00:03:28 1 1 N/A
Total number of neighbors 1
State/PfxRcd(受信した経路情報)が1、PfxSnt(送信した経路情報)が1ですので、期待通り動作していそうですね!
送受信した経路情報の詳細をもうちょっと見てみます。
まずは送信した経路情報です。
r1# show ip bgp nei 192.168.12.2 advertised-routes
BGP table version is 2, local router ID is 10.10.10.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, u unsorted, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 192.168.1.0/24 0.0.0.0 0 32768 i
Total number of prefixes 1
srcが所属するIP Range( 192.168.1.0/24
)を送っており、期待通りです。
次に、受信した経路情報です。
r1# show ip bgp nei 192.168.12.2 received-routes
BGP table version is 2, local router ID is 10.10.10.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, u unsorted, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 192.168.2.0/24 192.168.12.2 0 0 65002 i
Total number of prefixes 1
dstが所属するIP Range( 192.168.2.0/24
)を受信しており、こちらも期待通りです。
最後に、r1のip routeを見ます。
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
IPv4 unicast VRF default:
K>* 0.0.0.0/0 [0/0] via 172.20.20.1, eth0, weight 1, 00:07:30
L * 10.10.10.1/32 is directly connected, lo, weight 1, 00:07:29
C>* 10.10.10.1/32 is directly connected, lo, weight 1, 00:07:29
C>* 172.20.20.0/24 is directly connected, eth0, weight 1, 00:07:30
L>* 172.20.20.5/32 is directly connected, eth0, weight 1, 00:07:30
C>* 192.168.1.0/24 is directly connected, eth1, weight 1, 00:07:29
L>* 192.168.1.1/32 is directly connected, eth1, weight 1, 00:07:29
B>* 192.168.2.0/24 [20/0] via 192.168.12.2, eth2, weight 1, 00:07:25
C>* 192.168.12.0/24 is directly connected, eth2, weight 1, 00:07:29
B>* 192.168.2.0/24 [20/0] via 192.168.12.2, eth2, weight 1, 00:07:25
と、BGPで追加された経路情報であること、dstの所属するIP Range向けにeth2経由でr2に行けば良いとなっていて、期待通りですね!😊
src-->dstの疎通確認
最後に、みんな大好きpingで疎通確認してみましょう!
src containerに入ってpingします。
❯ docker exec -it clab-clab-mini-topo-src bash
bash-5.1# ping -c 4 192.168.2.11
PING 192.168.2.11 (192.168.2.11) 56(84) bytes of data.
64 bytes from 192.168.2.11: icmp_seq=1 ttl=62 time=0.058 ms
64 bytes from 192.168.2.11: icmp_seq=2 ttl=62 time=0.145 ms
64 bytes from 192.168.2.11: icmp_seq=3 ttl=62 time=0.193 ms
64 bytes from 192.168.2.11: icmp_seq=4 ttl=62 time=0.174 ms
--- 192.168.2.11 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3055ms
rtt min/avg/max/mdev = 0.058/0.142/0.193/0.051 ms
ついでにみんな大好きtracerouteで経路を確認してみます。
bash-5.1# traceroute 192.168.2.11
traceroute to 192.168.2.11 (192.168.2.11), 30 hops max, 46 byte packets
1 192.168.1.1 (192.168.1.1) 0.009 ms 0.014 ms 0.006 ms
2 192.168.12.2 (192.168.12.2) 0.008 ms 0.025 ms 0.006 ms
3 192.168.2.11 (192.168.2.11) 0.004 ms 0.023 ms 0.005 ms
topology図通りの経路になっていますね!😊
(再掲)まとめ
- containerlabを使うと、topology図に沿った構成が簡単に実現可能
- 複数Routerでの経路伝搬も簡単に試すことができる
- BGPを設定する場合、FRRoutingではRFC8212の設定もあるので要注意
最後に、GMOコネクトでは研究開発や国際標準化に関する支援や技術検証をはじめ、幅広い支援を行っておりますので、何かありましたらお気軽にお問合せください。