QuaggaでBGP Route Serverを作ってみた

#概要
BGP Route Serverを構築する機会があったので、手順をまとめておきます。

#BGP Route Serverとは
BGPを使って事業者が所有するルータ同士が相互接続する際に、Internet eXhange(IX)のサービスを利用します。その際、主に２通りの接続方法があります。
- Bilateral Peering
- Multilateral Peering

BGP Route Serverとは後者のMultilateral Peeringで利用されるBGPルータの機能のことです。ちなみにDNS Root Serverとは一切関係ありませんのでご注意ください。

## Bilateral Peering と Multilateral Peering の仕組み
Bilateral Peeringでは同じIXサービスを利用している事業者同士が、1対1の交渉の上で、お互いのルータにBGP設定を投入することで相互接続を実現します。

一方でMultilateral Peeringでは、事業者が所有するルータとIXが用意しているRoute Serverとの間でBGP接続をすることで、Route ServerとBGP接続している他の事業者と自動的にBGP経路の交換をすることができます。Route Serverに各事業者の経路情報が集まってくるイメージです。

Multilateral Peeringでは１対１の事業者同士の交渉や個別のルータ設定作業をする必要が無いため多数の事業者と相互接続したい場合は非常に効率的ではありますが、その一方で「相互接続する事業者を自ら選定できない」「トラフィックコントロールがやりづらい」といったデメリットもあります。
日本ではBilateral Peeringが採用される場合が多いようです。

## BGP Route Server詳細情報
Route ServerやMultilateral Peeringの詳細を知り対方は、JANOG29で発表された下記資料をご参照ください。
[JANOG29: IXで見えるユーザ動向とマルチラテラルピアリングの可能性](http://www.janog.gr.jp/meeting/janog29/program/bgpmulti.html)

# 環境構築
Route Serverを作るにあたり、今回は[Quagga](http://www.nongnu.org/quagga/)で試してみます。
Quagga以外にも、例えばCiscoルータにも[Route Server機能を有効にするコマンド](http://www.cisco.com/c/en/us/td/docs/ios/ios_xe/iproute_bgp/configuration/guide/2_xe/irg_xe_book/irg_route_server_xe.html#wp1063180)があります。調べてはいませんが、VyOSやBIRDといったソフトウェアルータでも実現できるかもしれません。

前回の記事([VagrantでQuggaを複数台作ってBGP](http://qiita.com/taijijiji/items/4cdb62317896f5509101))で作成した手順と同様に３台のQuaggaを構築して、Route Server + Route Server Clientを構築していきます。

![quagga_network3.png](https://qiita-image-store.s3.amazonaws.com/0/45596/841f2681-664d-170b-eaf4-b4aaceb3d0e7.png)

Vagrantfileは下記のように編集して利用しています。

```:vagrantfile
Vagrant.configure(2) do |config|
      config.vm.box = "centos70"

      config.vm.define :routeserver do | routeserver |
          routeserver.vm.hostname = 'routeserver'
          routeserver.vm.network "private_network", ip: "192.168.33.30"
          routeserver.vm.synced_folder "./quagga/quagga_routeserver", "/etc/quagga",
            create: true, owner: "root", group: "root"
      end
      config.vm.define :client1 do | client1 |
          client1.vm.hostname = 'client1'
          client1.vm.network "private_network", ip: "192.168.33.31"
          client1.vm.synced_folder "./quagga/quagga_client1", "/etc/quagga",
            create: true, owner: "root", group: "root"
      end
      config.vm.define :client2 do | client2 |
          client2.vm.hostname = 'client2'
          client2.vm.network "private_network", ip: "192.168.33.32"
          client2.vm.synced_folder "./quagga/quagga_client2", "/etc/quagga",
            create: true, owner: "root", group: "root"
      end
end

```

この後、Vagrant up 、Quaggaのインストール、設定などの手順が必要ですが、流れについてはこちらのブログを参照してください。

[VagrantでQuggaを複数台作ってBGP](http://qiita.com/taijijiji/items/4cdb62317896f5509101)



# QuaggaでRoute Server化させる
QuaggaをRouter Serverとして動作させるのは簡単です。
通常のBGP設定に加えてBGPネイバーに対してこの設定を入れるだけでRoute Server機能を有効化できます。

```
neighbor A.B.C.D route-server-client
```

##Route Server機能の設定前の状態確認
まずは、Route Server機能が無効の状態（=通常のeBGPの状態）でのclient1 / client2 の状態を確認してみます。

```
[Quagga: client1]
client1# sh ip bgp summary
BGP router identifier 10.10.10.2, local AS number 65001
RIB entries 5, using 560 bytes of memory
Peers 1, using 4560 bytes of memory

Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down
 State/PfxRcd
192.168.33.30   4 65000     137     136        0    0    0 00:11:17
        2
Total number of neighbors 1
```

```
[Quagga: client1]
client1# sh ip bgp
BGP table version is 0, local router ID is 10.10.10.2
Status codes: s suppressed, d damped, h history, * valid, > best, i
 - internal,
              r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 192.168.100.0    192.168.33.30            0             0 65000
i
*> 192.168.101.0    0.0.0.0                  0         32768 i
*> 192.168.102.0    192.168.33.30                          0 65000
65002 i
```

```
[Quagga: client2]
client2# sh ip bgp summary
BGP router identifier 10.10.10.3, local AS number 65002
RIB entries 5, using 560 bytes of memory
Peers 1, using 4560 bytes of memory

Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down
 State/PfxRcd
192.168.33.30   4 65000      53      89        0    0    0 00:12:39
        2
Total number of neighbors 1

```
```
[Quagga: client2]
client2# sho ip bgp
BGP table version is 0, local router ID is 10.10.10.3
Status codes: s suppressed, d damped, h history, * valid, > best, i
 - internal,
              r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 192.168.100.0    192.168.33.30            0             0 65000
i
*> 192.168.101.0    192.168.33.30                          0 65000
65001 i
*> 192.168.102.0    0.0.0.0                  0         32768 i

Total number of prefixes 3
```

ここでは、Quaggaルータであるrouteserverから受信している経路が全てAS65000のAS-PATHが追加されて受信されていることが確認できます。これは通常のeBGPでの仕様通りの挙動です。


##Route Server機能の設定後の状態確認
次に下記のように設定することで、client1 / client2 に対する
Route Server機能を有効にします。

```
[Quagga: routeserver]
(一部省略)
router bgp 65000
 bgp router-id 10.10.10.1
 network 192.168.100.0/24
 neighbor 192.168.33.31 remote-as 65001
 neighbor 192.168.33.31 next-hop-self
 neighbor 192.168.33.31 route-server-client
 neighbor 192.168.33.32 remote-as 65002
 neighbor 192.168.33.32 next-hop-self
 neighbor 192.168.33.32 route-server-client
```

設定後、clinet1 / client2 の状態確認をします。

```
[Quagga: client1]
client1# sh ip bgp summary
BGP router identifier 10.10.10.2, local AS number 65001
RIB entries 3, using 336 bytes of memory
Peers 1, using 4560 bytes of memory

Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down
 State/PfxRcd
192.168.33.30   4 65000     146     147        0    0    0 00:00:27
        1

Total number of neighbors 1
```
```
[Quagga: client1]
client1# sh ip bgp
BGP table version is 0, local router ID is 10.10.10.2
Status codes: s suppressed, d damped, h history, * valid, > best, i
 - internal,
              r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 192.168.100.0    192.168.33.30            0             0 i
*> 192.168.101.0    0.0.0.0                  0         32768 i
*> 192.168.102.0    192.168.33.32            0             0 65002
i

Total number of prefixes 3
```

```
[Quagga: client2]
client2# sh ip bgp summary
BGP router identifier 10.10.10.3, local AS number 65002
RIB entries 5, using 560 bytes of memory
Peers 1, using 4560 bytes of memory

Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down
 State/PfxRcd
192.168.33.30   4 65000      74     108        0    0    0 00:01:50
        2

Total number of neighbors 1
```

```
[Quagga: client2]
client2# sh ip bgp
BGP table version is 0, local router ID is 10.10.10.3
Status codes: s suppressed, d damped, h history, * valid, > best, i
 - internal,
              r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 192.168.100.0    192.168.33.30            0             0 i
*> 192.168.101.0    192.168.33.31            0             0 65001
i
*> 192.168.102.0    0.0.0.0                  0         32768 i
```

上記の結果を見ると、Route Serverルータであるrouteserverからの受信経路にAS65000のAS-PATHが追加されなかったことが読み取れます。

これはRoute Server Clientからみると、BGPネイバー状態は変わらないものの、Route ServerそのもののAS番号(ここではAS65000)を付加せずに受信していることがわかります。

言い換えると、Route Server Clientであるルータclient1、client2は直接BGPピアを確立することなく、お互いの経路を交換した状態と同様の効果を得られたと考えることができます。

# Bilateral PeeringとMultilateral Peeringの挙動の違い
今回は経路フィルタを使わない単純な例を用いて、Route Serverを有効にした場合と無効にした場合との状態の違いを説明しましたが、実際のBGP接続では経路フィルタによる経路制御が行われます。

Bilateral Peeringの場合、BGPネイバー先に対して、通常は自AS内の経路情報しか送信しません。つまり今回で述べたRoute Server機能有効化前(通常のeBGP接続)に受信していた「65000 65002 i」といったようなAS-PATHが付いた経路は、そもそも基本的にはAS65000ルータ(routeserver)からAS65001ルータ(client1)に経路広告されることはありません。そこでAS65001(client1)がAS65002(client2)の経路情報を入手したい場合は、AS65002の事業者と交渉した上で、AS65001(client1)とAS65002ルータ(client2)との間でBGPピア接続し、直接経路交換をする必要があります。

その一方でMultilateral Peeringの方式では、RouteServer(routeserver)とAS65001ルータ(client1)がBGPピア接続するだけでAS65002の経路情報を得ることができ、さらにはその他のASが保有する経路情報も、個別のBGP接続なしで受け取ることができます。これがMutilateral Peeringの大きなメリットです。

#(おまけ) QuaggaとCiscoルータの挙動の違い
Quaggaとは異なりCiscoルータの場合、BGP接続しているASとは異なるAS-PATHが追加された経路情報は受信しない、という仕組みが動作します。
今回の例で説明すると、AS65000ルータ(routeserver)からAS65001ルータ(client1)に対して「65002 i」という経路を受信した場合、異常な状態であると判定され、ルータで経路受信することができなくなる、という仕組みです。

このようにRoute Serverを有効にする場合にこの仕組みが無効にするために、Route Server Client側ルータに[BGP Enforce the First Autonomous System Path](
http://www.cisco.com/c/en/us/td/docs/ios/12_0s/feature/guide/s_befasp.html)という設定を入れる必要があります。

QuaggaはCiscoライクといえ、このような点で挙動が異なる部分もあることから設定時には注意が必要です。

#最後に
このように1,2行の設定でQuaggaをRoute Serverにすることができました。Route Serverを自前で用意する必要が出た場合は、Quaggaを使うと比較的手軽に環境を準備することが可能です。