SoftLayerのVyOS/VyattaでGRE接続 -> OSPFでNW間を接続

#1. はじめに
[SoftLayerのVyOS/VyattaでGRE接続](http://qiita.com/testnin2/items/c02b1fe63a5df1253286)の続きです。
前回は、[Static IPで接続してみました](http://qiita.com/testnin2/items/8d44ea8926ca45c1cd81)が、これではあまり面白くない（とはいっても、2ノードならばこれで十分でしょうが）、OSPFで構成してみます。

構成図を再掲します。
![vyos_gre.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/c2443cfc-b6db-0ca6-eab1-eca94e7ad56b.jpeg)

#2. OSPFについて

- OSPFを前回構成したGRE上でマルチキャストで実行します。とはいえ、そもそも途中経路のルーターが利用者で管理できない時点で、論理的に隣同士のVyOSでルーティングせざるを得ませんが・・・。
- static routes, OSPF, BGPは、それぞれ独自にテーブル管理されており、これらの独自テーブルから最終的にIPルーティングテーブルが決まります。つまり、以下のような感じです。
    - static routes table --> IP routing table
    - OSPF table --> IP routing table
    - BGP table --> IP routing table
- プロトコルが別々なので、static routingの情報はOSPF上には流れません。static routingで設定した経路をOSPFに取り込む場合には、再配布(redistribute)という操作を行う必要があります。こういうルーティングプロトコル系の設定は、VyOSでは`set protocol ...`という箇所にあります。
- 他に覚えて置くと良いテーブルはconnected table（ネットワークインターフェースを持つために直接接続済みの経路）です。OSPFやBGPで取り込むためには、こちらも再配布が必要です。

この点を考慮した上で、経路交換の方法は幾つかありそうですので、いくつか構成例を載せながらその特徴を記載したいと思います。設定自体は（思ったより）簡単です。

#3. OSPF構成例1:ネットワーク指定（成功例）

- OSPFが動くためには、最低１つはOSPFの経路交換対象のネットワークを選択する必要があります。OSPFのパケットが流れるGRE上のネットワークは必須なので、当然192.168.0.0/30を選択します。
- もちろん、172.16.0.0/24,や172.16.1.0/24も動かしたいので、これらもOSPF経路交換対象にします。
- ただし、こうすると、172.16.0.1/24,や172.16.1.1/24のインターフェースからOSPF Helloを定期的に送って隣接ルータを探そうとします。今回の場合には、GRE側にしか隣接ルーターはいないので、こういう探索は不要です。そのため、GRE用のインターフェース(tun0)以外では探索を行わないように構成します。

```txt:OSPFの設定
vyos@vyostok1# set protocols ospf area 0 network 192.168.0.0/30
vyos@vyostok1# set protocols ospf area 0 network 172.16.0.0/24
vyos@vyostok1# set protocols ospf passive-interface default
vyos@vyostok1# set protocols ospf passive-interface-exclude tun0
vyos@vyostok1# commit

vyos@vyoshkg1# set protocols ospf area 0 network 192.168.0.0/30
vyos@vyoshkg1# set protocols ospf area 0 network 172.16.1.0/24
vyos@vyoshkg1# set protocols ospf passive-interface default
vyos@vyoshkg1# set protocols ospf passive-interface-exclude tun0
vyos@vyoshkg1# commit
```

```txt:tun0はOSPFが有効になっている。eth0もOSPFは有効になっているが、Passive_Interfaceになっている。また、Hello-Intervalの送信間隔が10秒、Dead-Intervalの間隔が40秒になっていることが分かる。DR(Designed_Router：代表ルーター)は192.168.0.1側であり、BDR(Backup_Desgined_Router：バックアップ代表ルーター）は192.168.0.2側で構成されている。
vyos@vyostok1:~$ show ip ospf interface
eth0 is up
  ifindex 2, MTU 1500 bytes, BW 0 Kbit <UP,BROADCAST,RUNNING,MULTICAST>
  Internet Address 172.16.0.1/24, Broadcast 172.16.0.255, Area 0.0.0.0
  MTU mismatch detection:enabled
  Router ID 10.132.75.79, Network Type BROADCAST, Cost: 10
  Transmit Delay is 1 sec, State DR, Priority 1
  Designated Router (ID) 10.132.75.79, Interface Address 172.16.0.1
  No backup designated router on this network
  Multicast group memberships: <None>
  Timer intervals configured, Hello 10s, Dead 40s, Wait 40s, Retransmit 5
    No Hellos (Passive interface)
  Neighbor Count is 0, Adjacent neighbor count is 0
eth1 is up
  ifindex 3, MTU 1500 bytes, BW 0 Kbit <UP,BROADCAST,RUNNING,MULTICAST>
  OSPF not enabled on this interface
gre0 is down
  ifindex 4, MTU 1476 bytes, BW 0 Kbit <NOARP>
  OSPF not enabled on this interface
gretap0 is down
  ifindex 5, MTU 1476 bytes, BW 0 Kbit <BROADCAST,MULTICAST>
  OSPF not enabled on this interface
lo is up
  ifindex 1, MTU 65536 bytes, BW 0 Kbit <UP,LOOPBACK,RUNNING>
  OSPF not enabled on this interface
tun0 is up
  ifindex 6, MTU 1476 bytes, BW 0 Kbit <UP,POINTOPOINT,RUNNING,NOARP,ALLMULTI,MULTICAST>
  Internet Address 192.168.0.1/30, Broadcast 192.168.0.3, Area 0.0.0.0
  MTU mismatch detection:enabled
  Router ID 10.132.75.79, Network Type BROADCAST, Cost: 10
  Transmit Delay is 1 sec, State DR, Priority 1
  Designated Router (ID) 10.132.75.79, Interface Address 192.168.0.1
  Backup Designated Router (ID) 10.111.147.74, Interface Address 192.168.0.2
  Saved Network-LSA sequence number 0x80000163
  Multicast group memberships: OSPFAllRouters OSPFDesignatedRouters
  Timer intervals configured, Hello 10s, Dead 40s, Wait 40s, Retransmit 5
    Hello due in 0.421s
  Neighbor Count is 1, Adjacent neighbor count is 1
```
```txt:neighborとして認識しているルーター。デフォルトではDeadTimeは40秒から開始してカウントダウンを開始するが、10秒置きにHelloパケットが流れて正常確認が取れると再度40秒に戻る。
vyos@vyostok1:~$ show ip ospf neighbor

    Neighbor ID Pri State           Dead Time Address         Interface            RXmtL RqstL DBsmL
10.111.147.74     1 Full/Backup       37.033s 192.168.0.2     tun0:192.168.0.1         0     0     0
```
```txt:OSPF自身が所有するネットワークとして、OSPFルーティングテーブル上に3つ存在する
vyos@vyostok1:~$ show ip ospf route
============ OSPF network routing table ============
N    172.16.0.0/24         [10] area: 0.0.0.0
                           directly attached to eth0
N    172.16.1.0/24         [20] area: 0.0.0.0
                           via 192.168.0.2, tun0
N    192.168.0.0/30        [10] area: 0.0.0.0
                           directly attached to tun0

============ OSPF router routing table =============

============ OSPF external routing table ===========
```
```txt:IPルーティングテーブルにおける最終結果。選択されたルートは">"で表されている。OSPFからは3つのルートが提示されたが、採用されたのは"172.16.1.0/24"への経路のみ
vyos@vyostok1:~$ show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
       I - ISIS, B - BGP, > - selected route, * - FIB route

S>* 0.0.0.0/0 [1/0] via 161.202.xx.xx, eth1
S>* 10.0.0.0/8 [1/0] via 10.132.75.65, eth0
C>* 10.132.75.64/26 is directly connected, eth0
C>* 127.0.0.0/8 is directly connected, lo
C>* 161.202.xx.xx/27 is directly connected, eth1
O   172.16.0.0/24 [110/10] is directly connected, eth0, 11:59:09
C>* 172.16.0.0/24 is directly connected, eth0
O>* 172.16.1.0/24 [110/20] via 192.168.0.2, tun0, 11:57:49
O   192.168.0.0/30 [110/10] is directly connected, tun0, 17:29:26
C>* 192.168.0.0/30 is directly connected, tun0

```


また、**デフォルトで10秒置きにマルチキャストでOSPF Helloが飛び交っている**ことがtcpdumpの結果からわかります。

```
vbash-4.1# sudo tcpdump -i tun0 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
08:04:43.730875 IP 192.168.0.1 > 224.0.0.5: OSPFv2, Hello, length 48
08:04:44.616956 IP 192.168.0.2 > 224.0.0.5: OSPFv2, Hello, length 48
08:04:53.731962 IP 192.168.0.1 > 224.0.0.5: OSPFv2, Hello, length 48
08:04:54.617068 IP 192.168.0.2 > 224.0.0.5: OSPFv2, Hello, length 48
08:05:03.733050 IP 192.168.0.1 > 224.0.0.5: OSPFv2, Hello, length 48
08:05:04.617194 IP 192.168.0.2 > 224.0.0.5: OSPFv2, Hello, length 48
08:05:13.734103 IP 192.168.0.1 > 224.0.0.5: OSPFv2, Hello, length 48
08:05:14.617339 IP 192.168.0.2 > 224.0.0.5: OSPFv2, Hello, length 48
08:05:23.735157 IP 192.168.0.1 > 224.0.0.5: OSPFv2, Hello, length 48
08:05:24.621086 IP 192.168.0.2 > 224.0.0.5: OSPFv2, Hello, length 48
08:05:33.736178 IP 192.168.0.1 > 224.0.0.5: OSPFv2, Hello, length 48
08:05:34.621230 IP 192.168.0.2 > 224.0.0.5: OSPFv2, Hello, length 48
```

#4. OSPF構成例2:再配布（失敗例）

もう１つ思いついたやり方は、OSPFの経路交換対象をnetwork 192.168.0.0/30にし、それ以外のネットワークはconnected routeからOSPFに再配送することです。（static routeからの再配送をしても、static routeには直接接続されたネットワークの経路は含まれていないため172.16.0.0/24や172.16.1.0/24は配布できません）


```txt:OSPFの設定
vyos@vyostok1# set protocols ospf area 0 network 192.168.0.0/30
vyos@vyostok1# set protocols ospf redistribute connected
vyos@vyostok1# commit

vyos@vyoshkg1# set protocols ospf area 0 network 192.168.0.0/30
vyos@vyoshkg1# set protocols ospf redistribute connected
vyos@vyoshkg1# commit
```

結論からいうと、このままではうまくいきません。OSPFが接続と切断を交互に繰り返します。なぜなら、単純にconnectedで経路を再配布すると、10.111.147.64にアクセスするために192.168.0.2経由でアクセスしようとしてしまうからです。GREトンネル自体は10.111.147.64を使って接続しようとしているのに、そのために192.168.0.2を経由しないといけないという自己矛盾を抱えてしまいます。再配布するにしても、vyostok1-vyoshkg1間の10.x.x.xの経路はroute-mapなどを用いてフィルタリングしないといけなさそうです。

```txt:以下の状態が交互に繰り返される
vyos@vyostok1:~$ show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
       I - ISIS, B - BGP, > - selected route, * - FIB route

S>* 0.0.0.0/0 [1/0] via 161.202.86.1, eth1
S>* 10.0.0.0/8 [1/0] via 10.132.75.65, eth0
O>* 10.111.147.64/26 [110/20] via 192.168.0.2, tun0, 00:00:34
C>* 10.132.75.64/26 is directly connected, eth0
O>* 119.81.xx.xx/29 [110/20] via 192.168.0.2, tun0, 00:00:34
C>* 127.0.0.0/8 is directly connected, lo
C>* 161.202.xx.xx/27 is directly connected, eth1
C>* 172.16.0.0/24 is directly connected, eth0
O>* 172.16.1.0/24 [110/20] via 192.168.0.2, tun0, 00:00:34
O   192.168.0.0/30 [110/10] is directly connected, tun0, 18:25:25
C>* 192.168.0.0/30 is directly connected, tun0

vyos@vyostok1:~$ show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
       I - ISIS, B - BGP, > - selected route, * - FIB route

S>* 0.0.0.0/0 [1/0] via 161.202.86.1, eth1
S>* 10.0.0.0/8 [1/0] via 10.132.75.65, eth0
C>* 10.132.75.64/26 is directly connected, eth0
C>* 127.0.0.0/8 is directly connected, lo
C>* 161.202.xx.xx/27 is directly connected, eth1
C>* 172.16.0.0/24 is directly connected, eth0
O   192.168.0.0/30 [110/10] is directly connected, tun0, 18:25:46
C>* 192.168.0.0/30 is directly connected, tun0
```

#5. OSPF構成例3:再配布+経路フィルタリング（成功例）
上記ではGREに接続するIPが再配布されることが問題だったので、今度はconnected routeからの再配送時に10.0.0.0〜10.255.255.255をフィルタリングしてみました（もちろん、vyostok1では10.132.75.64/26のみを、vyostok2では10.111.147.64/26のみをフィルタリングしてもいいと思います。）。ちょっと面倒ですね。
prefix-listにおけるアドレスの指定方法は独特です。`le 32`を書いていなかったために最初は上手くいかずに悩みました。`rule 100 action permit`とかにも気づかずにやはり最初は上手く行かなかったり。。。この辺りは、Cisco機器のガイドや[「ルートフィルタリング（ ip prefix-list ）の設定」](http://www.infraexpert.com/study/routecontrol07.html)や[「ルートマップ（ route-map ）とは」](http://www.infraexpert.com/study/routecontrol09.html)のサイト様が参考になります（というか、いつもこのサイトで勉強させていただいています）。


```txt:OSPFの設定
vyos@vyostok1# set protocols ospf area 0 network 192.168.0.0/30
vyos@vyostok1# set policy prefix-list PRIVATENW rule 10 action permit
vyos@vyostok1# set policy prefix-list PRIVATENW rule 10 prefix 10.0.0.0/8
vyos@vyostok1# set policy prefix-list PRIVATENW rule 10 le 32
vyos@vyostok1# set policy route-map FILTER-PRIVATENW rule 10 action deny
vyos@vyostok1# set policy route-map FILTER-PRIVATENW rule 10 match ip address prefix-list PRIVATENW
vyos@vyostok1# set policy route-map FILTER-PRIVATENW rule 100 action permit
vyos@vyostok1# set protocols ospf redistribute connected route-map FILTER-PRIVATENW
vyos@vyostok1# commit

vyos@vyoshkg1# set protocols ospf area 0 network 192.168.0.0/30
vyos@vyoshkg1# set policy prefix-list PRIVATENW rule 10 action permit
vyos@vyoshkg1# set policy prefix-list PRIVATENW rule 10 prefix 10.0.0.0/8
vyos@vyoshkg1# set policy prefix-list PRIVATENW rule 10 le 32
vyos@vyoshkg1# set policy route-map FILTER-PRIVATENW rule 10 action deny
vyos@vyoshkg1# set policy route-map FILTER-PRIVATENW rule 10 match ip address prefix-list PRIVATENW
vyos@vyoshkg1# set policy route-map FILTER-PRIVATENW rule 100 action permit
vyos@vyoshkg1# set protocols ospf redistribute connected route-map FILTER-PRIVATENW
vyos@vyoshkg1# commit
```

```txt:192.168.0.0/30しかOSPFの対象NWに指定していなかったため、OSPFはtun0でのみ稼動している
vyos@vyostok1:~$ show ip ospf interface
eth0 is up
  ifindex 2, MTU 1500 bytes, BW 0 Kbit <UP,BROADCAST,RUNNING,MULTICAST>
  OSPF not enabled on this interface
eth1 is up
  ifindex 3, MTU 1500 bytes, BW 0 Kbit <UP,BROADCAST,RUNNING,MULTICAST>
  OSPF not enabled on this interface
gre0 is down
  ifindex 4, MTU 1476 bytes, BW 0 Kbit <NOARP>
  OSPF not enabled on this interface
gretap0 is down
  ifindex 5, MTU 1476 bytes, BW 0 Kbit <BROADCAST,MULTICAST>
  OSPF not enabled on this interface
lo is up
  ifindex 1, MTU 65536 bytes, BW 0 Kbit <UP,LOOPBACK,RUNNING>
  OSPF not enabled on this interface
tun0 is up
  ifindex 6, MTU 1476 bytes, BW 0 Kbit <UP,POINTOPOINT,RUNNING,NOARP,ALLMULTI,MULTICAST>
  Internet Address 192.168.0.1/30, Broadcast 192.168.0.3, Area 0.0.0.0
  MTU mismatch detection:enabled
  Router ID 10.132.75.79, Network Type BROADCAST, Cost: 10
  Transmit Delay is 1 sec, State Backup, Priority 1
  Designated Router (ID) 119.81.163.35, Interface Address 192.168.0.2
  Backup Designated Router (ID) 10.132.75.79, Interface Address 192.168.0.1
  Saved Network-LSA sequence number 0x80000168
  Multicast group memberships: OSPFAllRouters OSPFDesignatedRouters
  Timer intervals configured, Hello 10s, Dead 40s, Wait 40s, Retransmit 5
    Hello due in 2.376s
  Neighbor Count is 1, Adjacent neighbor count is 1

```
```txt:例1と特に変わりなし
vyos@vyostok1:~$ show ip ospf neighbor

    Neighbor ID Pri State           Dead Time Address         Interface            RXmtL RqstL DBsmL
119.81.163.35     1 Full/DR           35.670s 192.168.0.2     tun0:192.168.0.1         0     0     0
```
```txt:connectedから再配送された経路情報が載っている
vyos@vyostok1:~$ show ip ospf route
============ OSPF network routing table ============
N    192.168.0.0/30        [10] area: 0.0.0.0
                           directly attached to tun0

============ OSPF router routing table =============
R    119.81.xx.xx         [10] area: 0.0.0.0, ASBR
                           via 192.168.0.2, tun0

============ OSPF external routing table ===========
N E2 119.81.xx.xx/29      [10/20] tag: 0
                           via 192.168.0.2, tun0
N E2 172.16.1.0/24         [10/20] tag: 0
                           via 192.168.0.2, tun0

```
```txt:10.x.x.xに対してはOSPFで経路交換しなくなったため、GREトンネル（192.168.0.2）を通らない。対抗のVyOSが持つPublicIPや172.16.xx.xxに対してはGREトンネルを通る。
vyos@vyostok1:~$ show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
       I - ISIS, B - BGP, > - selected route, * - FIB route

S>* 0.0.0.0/0 [1/0] via 161.202.86.1, eth1
S>* 10.0.0.0/8 [1/0] via 10.132.75.65, eth0
C>* 10.132.75.64/26 is directly connected, eth0
O>* 119.81.xx.xx/29 [110/20] via 192.168.0.2, tun0, 00:07:00
C>* 127.0.0.0/8 is directly connected, lo
C>* 161.202.xx.xx/27 is directly connected, eth1
C>* 172.16.0.0/24 is directly connected, eth0
O>* 172.16.1.0/24 [110/20] via 192.168.0.2, tun0, 00:07:00
O   192.168.0.0/30 [110/10] is directly connected, tun0, 01:16:16
C>* 192.168.0.0/30 is directly connected, tun0
```