SoftLayerのVyOS/VyattaでGRE接続

#1. はじめに
GRE(Generic Routing Encapsulation)をBluemix Infrastructure(旧SoftLayer）で使ってみたという記事です。GREは、IP持込みソリューションなどによく利用する基本の通信方法なので、独立した記事にしたいと思います。
ちなみにVyOSは、[ここ](http://qiita.com/testnin2/items/24413ee4df9fa5185fec)のものを利用しています。

#2. GREの注意点

- GREトンネリングでは、オリジナルパケットに「GREヘッダ(4 Byte)」と「IPヘッダ(20 Byte)」を付加することでカプセル化を行い、あたかも両端の機器が直結しているかのように扱うことができます。
    - **GREによるオーバーヘッドは24 Byte**です。よって、MTUサイズが1500のネットワークでは、GREにすることで1500-24=1476に抑える必要があります。なお、SoftLayerのPrivate NWはJumbo Frameが利用可能なので物理サーバーであればMTUサイズは9000まで大きくすることができます。仮想サーバーはハイパーバイザー層で制御されているため、依然として1500までです。今回は仮想サーバーを使っているので、1500を上限に考えています。
    - IPトンネル内でのカプセル化のために、TCP/UDPにあるポート番号がありません。よって、通常は**NAT越えができません**。
    - **暗号化はされません**。データの安全性を保ちたい場合は GRE over IPSec VPNを利用しましょう。
    - **GREトンネリング上では、マルチキャスト通信を流すことができます**。OSPFなどのプロトコルではマルチキャスト通信が必要なので重宝します。

#3. なぜGREが必要なのか

例えば以下のSoftLayer上の構成図を見てみましょう。

![vyos_gre.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/c2443cfc-b6db-0ca6-eab1-eca94e7ad56b.jpeg)

本記事でやりたいことは、vyostok1とvyoshkg1が、あたかも直結通信しているかのようにGREを構成することです。

- 本来は物理的には色々なルーターを通って通信するのですが、その中継ルーターは自分が管理していないので経路情報を教えることはできません。よって、赤色の172.16.0.0/24から黄色の172.16.1.0/24に通信しようと思っても、BCR/MBR/DAR/BBRなどのルーターはその経路情報を持っていないので通信できません。
- GRE（緑色）で仮想的にルーター間をあたかも直結しているかのような仕組みを作れば、vyostok1配下にいるサーバーとvyoshkg1配下にいるサーバーが好きなIPを割り当てられていても、経路途中であるvyostok1もvyoshkg1のどちらのルーターも自分で管理できるため、その間の経路情報の管理が可能になります。

#4. 事前準備。172.16.0.0/24および172.16.1.0/24のアドレス付与
VyOSはそれぞれのネットワークに足を出していますので、それぞれに172.16.0.1/24および172.16.1.1/24のIPアドレスを割り振ります。
本項はGREを張る上では特に必要ありませんが、今後の準備のためにということで、事前に実施しておきます。

```txt:アドレスの設定
#vyostok1
vyos@vyostok1# set interfaces ethernet eth0 address 172.16.0.1/24
vyos@vyostok1# commit

vyoshkg
vyos@vyoshkg1# set interfaces ethernet eth0 address 172.16.1.1/24
vyos@vyoshkg1# commit
vyos@vyoshkg1# exit
```


```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
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

vyos@vyoshkg1:~$ 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 119.81.163.33, eth1
S>* 10.0.0.0/8 [1/0] via 10.111.147.65, eth0
C>* 10.111.147.64/26 is directly connected, eth0
C>* 119.81.xx.xx/29 is directly connected, eth1
C>* 127.0.0.0/8 is directly connected, lo
C>* 172.16.1.0/24 is directly connected, eth0
```

vyostok1は172.16.0.0/24に、vyoshkg1は172.16.1.0/24にルーティング上は直結していることが確認できます。

#5. GREを設定してみる。

```txt:vyostok1
vyos@vyostok1# set interfaces tunnel tun0 address '192.168.0.1/30'
vyos@vyostok1# set interfaces tunnel tun0 description 'GRE_TOK_TO_HKG'
vyos@vyostok1# set interfaces tunnel tun0 encapsulation 'gre'
vyos@vyostok1# set interfaces tunnel tun0 multicast enable
vyos@vyostok1# set interfaces tunnel tun0 local-ip '10.132.75.79'
vyos@vyostok1# set interfaces tunnel tun0 remote-ip '10.111.147.74'
vyos@vyostok1# commit
vyos@vyostok1# save
``` 

```txt:vyoshkg1
vyos@vyoshkg1# set interfaces tunnel tun0 address '192.168.0.2/30'
vyos@vyoshkg1# set interfaces tunnel tun0 description 'GRE_HKG_TO_TOK'
vyos@vyoshkg1# set interfaces tunnel tun0 encapsulation 'gre'
vyos@vyoshkg1# set interfaces tunnel tun0 multicast enable
vyos@vyoshkg1# set interfaces tunnel tun0 local-ip '10.111.147.74'
vyos@vyoshkg1# set interfaces tunnel tun0 remote-ip '10.132.75.79'
vyos@vyoshkg1# commit
vyos@vyoshkg1# save
```

GREだけなら簡単ですね。

#6. GREの動作確認

```txt:
#トンネル情報の確認と経路情報
vyos@vyostok1:~$ show interfaces tunnel
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface        IP Address                        S/L  Description
---------        ----------                        ---  -----------
tun0             192.168.0.1/30                    u/u  GRE_TOK_TO_HKG

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.0/27 is directly connected, eth1
C>* 192.168.0.0/30 is directly connected, tun0

```

以下で、GREで利用されている実IPが確認できます。また、MTUサイズが1476に縮小されていることが分かります。

```
vyos@vyostok1:~$ show interfaces tunnel detail
tun0@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1476 qdisc noqueue state UNKNOWN group default
    link/gre 10.132.75.79 peer 10.111.147.74
    inet 192.168.0.1/30 brd 192.168.0.3 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::5efe:a84:4b4f/64 scope link
       valid_lft forever preferred_lft forever
    Description: GRE_TOK_TO_HKG

    RX:  bytes    packets     errors    dropped    overrun      mcast
           756          9          0          0          0          0
    TX:  bytes    packets     errors    dropped    carrier collisions
           792          9          0          0          0          0
```

pingでは、8（ICMPヘッダ）＋20（IPヘッダ）の計28bit消費されるので、1476-28=1448までならパケットは通せます。

```
vyos@vyostok1:~$ sudo ping 192.168.0.2 -s 1448 -M do
PING 192.168.0.2 (192.168.0.2) 1448(1476) bytes of data.
1456 bytes from 192.168.0.2: icmp_req=1 ttl=64 time=47.9 ms
1456 bytes from 192.168.0.2: icmp_req=2 ttl=64 time=47.5 ms
1456 bytes from 192.168.0.2: icmp_req=3 ttl=64 time=47.4 ms
1456 bytes from 192.168.0.2: icmp_req=4 ttl=64 time=47.3 ms
^C
--- 192.168.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 47.353/47.569/47.905/0.298 ms

vyos@vyostok1:~$ sudo ping 192.168.0.2 -s 1449 -M do
PING 192.168.0.2 (192.168.0.2) 1449(1477) bytes of data.
ping: local error: Message too long, mtu=1476
ping: local error: Message too long, mtu=1476
ping: local error: Message too long, mtu=1476
ping: local error: Message too long, mtu=1476
^C
--- 192.168.0.2 ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3004ms

```

#7. 最後に
まだこれだけではルーティング情報を設定していないので、ルーターであるVyOS同士は直接接続できるようになりましたが、172.16.0.0/24と172.16.1.0/24はまだ接続できません。もちろん、Static IPを設定すればよいのですが、それでは芸がないので、勉強を兼ねてDynamic Routingを設定しましょう。次回はこのGREトンネルを使ってダイナミックルーティング（OSPFやBGP）の設定をしてみたいと思います。