VyOS で BGP を喋らせる

# はじめに

VyOS は、Linux ベースのソフトウェアルーターで、単なるルーティング以外にも、豊富な機能を持っているので、自身やチームのラボを構築する際に、非常に便利です。
個人的には、vSphere のラボを構築する際にも、必須級のソフトウェアになっています。

↓こちらの記事で、簡単な紹介もしています。

https://qiita.com/iwaseyusuke/items/0ac51439f476a36fb3ff

この便利な VyOS ですが、ラボの数であったり、VyOS 自体の数増えてくると、その間のルーティング管理も大変になったりするかと思います。
それ以外のケースでも、VyOS で BPG を喋らせたい場面はあると思いますので、VyOS での基本的な BGP 設定について、ここではご紹介します。


# 手順

参考にしている VyOS 公式ドキュメントは、こちらです。

https://docs.vyos.io/en/latest/configuration/protocols/bgp.html


## TL;DR;

例によって、VyOS の操作がわかる方には、実際の設定例を見ていただく方が早いかと思います。
ここでは、本当に基本的な例として、IPv4 の Connected (VyOS が直接接続されている) ネットワークに関して、BGP で経路広告する設定になります。


```text: フォーマット
protocols {
    bgp {
        address-family {
            ipv4-unicast {
                redistribute {
                    connected {
                    }
                }
            }
        }
        neighbor <address|interface> {
            address-family {
                ipv4-unicast {
                    nexthop-self {
                    }
                }
            }
            remote-as <asn>
        }
        system-as <asn>
    }
}
```

```text: 設定例
protocols {
    bgp {
        address-family {
            ipv4-unicast {
                redistribute {
                    connected {
                    }
                }
            }
        }
        neighbor 10.0.0.2 {
            address-family {
                ipv4-unicast {
                    nexthop-self {
                    }
                }
            }
            remote-as 65002
        }
        system-as 65001
    }
}
```


## NW 構成

想定している NW 構成は、下記のようなイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245234/6d5fff3b-fef5-17ee-8f65-1ebdf66b99ac.png)

異なるラボ、Lab A と Lab B があり、それぞれに VyOS がデプロイされており、外部との接続用に `10.0.0.0/24` のネットワークに繋がっています。
そして、VyOS にぶら下がるネットワーク上に、踏み台 (Jump Box) や ESXi が繋がっています。
さらには、この VyOS にぶら下がっているこのネットワークには、VLAN が切られていて、ラボ毎に独自の生態系 (ネットワーク構成) が形成されているとします。

この構成において、例えば、Lab A に居る VM A が、Lab B に居る VM B と通信したい場合、VyOS A と VyOS B に Static Route を書けば、ルーティングできなくはないです。
が、VLAN でネットワークを増やして、別の VLAN 上の VM 同士で通信させようと思ったら、都度 Static Route を書かないといけないので、非常に面倒です。

そこで、VyOS 配下で VLAN を切ったら、その情報が動的に、対向の VyOS に広告され、通信できるようになれば、非常に便利です。
「そのために BGP を使っていこう」という条件で、VyOS A に投入する設定として、上記の設定例を書いています。


## 設定解説

BGP プロトコルの特性上、「設定例を上から順番に」ではない点に、ご注意ください。

```bash
# フォーマット
set protocols bgp system-as <asn>

# 設定例
set protocols bgp system-as 65001
```

まず、BGP と言ったら、AS 番号 (Autonomous System Number) をしないことには、だと思います。
文字通りですが、今操作している VyOS が所属する AS 番号を設定します。

internal BGP (iBGP) で設定するのか、external BGP (eBGP) で設定するのかで、AS 番号の割り当てを考える必要がありますが、一旦、「シンプルに IPv4 ネットワークの情報を広告し合うだけ」という想定で、Lab A に 65001、Lab B に 65002 を振っています。

iBGP と eBGP の違いについては、ネットワーク関係では皆さんお世話になっているであろう「ネットワークエンジニアとして」のページの解説が、分かりやすいと思います。

https://www.infraexpert.com/study/bgpz03.html


```bash
# フォーマット
set protocols bgp address-family <ipv4-unicast|ipv6-unicast> redistribute <route source>

# 設定例
set protocols bgp address-family ipv4-unicast redistribute connected
```

BGP で経路広告するネットワークの種類 (Address Family) を設定しています。

今回は、基本中の基本ということで、IPv4 ユニキャストのネットワーク、かつ Connected (VyOS が直接接続されている) ネットワークについて、経路広告するように設定しています。

```bash
# フォーマット
set protocols bgp neighbor <address|interface> remote-as <asn>

# 設定例
set protocols bgp neighbor 10.0.0.2 remote-as 65002
```

対向の BGP ルータ (Neighbor) の IP アドレスと AS 番号について、設定しています。

AS 番号について、実際の番号の他に、`internal` と `external` も使えます。
`internal` を指定した場合、internal BGP (iBGP) による接続を想定、つまり Neighbor の AS 番号が、自分の AS 番号と同じであれば、接続できます。一方、`external` を指定した場合は、external BGP (eBGP) による接続を想定し、AS 番号が違う場合に接続できる設定になります。
「いちいち、対向ルータの AS 番号を設定するのが面倒だなぁ」という場合に、とても便利です。

```bash
# フォーマット
set protocols bgp neighbor <address|interface> address-family ipv4-unicast nexthop-self

# 設定例
set protocols bgp neighbor 10.0.0.2 address-family ipv4-unicast nexthop-self
```

対向の BGP ルータ (Neighbor) に経路広告するネットワークの種類 (Address Family) を設定しています。

この例では、IPv4 ユニキャストに対して、経路広告を有効にし、かつ経路広告するネットワークのネクストホップを自分自身とするように設定しています。

以上、詳しい解説はしていないので、ほんの入り口程度の内容ですが、最低限の設定としては以上です。


## 動作確認

上記までは、VyOS A に投入する設定でしたが、VyOS B にも IP アドレスや AS 番号の部分を変えて、設定すると、VyOS 間で BGP をお喋りし始めるはずです。

まず、VyOS A から VyOS B とのお喋り状況を確認してみます。

```text: フォーマット
show ip bgp neighbors <address>
```

```text: 出力例
$ show ip bgp neighbors 10.0.0.2
BGP neighbor is 10.0.0.2, remote AS 65002, local AS 65001, external link
Hostname: VyOSA
  BGP version 4, remote router ID 10.0.0.2, local router ID 10.0.0.1
  BGP state = Established, up for 05w5d14h
  Last read 00:00:01, Last write 00:00:01
  Hold time is 180, keepalive interval is 60 seconds
  Configured conditional advertisements interval is 60 seconds

  ...(略)...

  Message statistics:
    Inq depth is 0
    Outq depth is 0
                         Sent       Rcvd
    Opens:                  1          1
    Notifications:          0          0
    Updates:               12         15
    Keepalives:         58494      58494
    Route Refresh:          0          0
    Capability:             0          0
    Total:              58507      58510
  Minimum time between advertisement runs is 0 seconds

 For address family: IPv4 Unicast
  Update group 1, subgroup 1
  Packet Queue length 0
  NEXT_HOP is always this router
  Community attribute sent to this neighbor(all)
  11 accepted prefixes

  ...(略)...
```

Neighbor の Router ID や AS 番号や、いくつの Update メッセージを送ったか/受け取ったか、いくつのネットワーク情報 (Prefix) を受け取ったかなどを確認することができます。

また、BPG として受け取ったルート情報を確認してみます。

```text: フォーマット
show ip bgp
```

```text: 出力例
$ show ip bgp
BGP table version is 69, local router ID is 10.0.0.1, vrf id 0
Default local pref 100, local AS 65001
Status codes:  s suppressed, d damped, h history, * 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
*  10.0.0.0/24      10.0.0.3                 0             0 65003 ?
*                   10.0.0.2                 0             0 65002 ?
*>                  0.0.0.0                  0         32768 ?
*> 172.19.21.0/24   10.0.0.2                               0 65002 ?
*                   10.0.0.3                 0             0 65003 65002 ?
*> 172.19.22.0/24   10.0.0.2                               0 65002 ?
*                   10.0.0.3                 0             0 65003 65002 ?

  ...(略)...
```

手元の環境が、VyOS A, B 以外に、他の VyOS も居るため、別の VyOS (VyOS C) からの経路も混じっていますが、`10.0.0.0/24` と VyOS B にぶら下がる `172.19.21.0/24` や `172.19.22.0/24` が受け取れていることが分かります。

この結果、実際のルーティングにどんな経路が反映されているかを確認してみます。

```text: フォーマット
show ip route
```

```text: 出力例
$ show ip route
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, F - PBR,
       f - OpenFabric,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

S>* 0.0.0.0/0 [1/0] via 10.0.0.254, eth0, weight 1, 11w3d22h
C>* 10.0.0.0/24 is directly connected, eth0, 11w3d22h
B>* 172.19.21.0/24 [20/0] via 10.0.0.2, eth0, weight 1, 16:38:53
B>* 172.19.22.0/24 [20/0] via 10.0.0.2, eth0, weight 1, 16:38:53

  ...(略)...
```

これを見ると `10.0.0.0/24` は直接繋がっていること (先頭の C のマーク) が分かりますが、VyOS B にぶら下がっている `172.19.21.0/24` や `172.19.22.0/24` へは、VyOS B (`10.0.0.2`) がネクストホップになっており、かつ BGP を経由して学習したこと (先頭の B のマーク) が分かります。

これによって、例えば、VyOS B の背後の VM `172.19.21.11` とかが居れば、そこに対して、VyOS A から ping が飛ぶようになっていると思います。