IBM Cloud: 複数インターフェースを持つVSIのeth0以外となぜ通信できないのか？（ポリシーベース・ルーティングによる解決）

#1. はじめに

[IBM Cloud: 複数インターフェースを持つVSIのeth0以外となぜ通信できないのか？](https://qiita.com/testnin2/items/b896ac54089a9bb22a0b)の解決案2である、ポリシーベースルーティングでの構成例の紹介です。
この場合、Server-Bのeth1から受信したパケットはeth1を通って送信することになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/75c937b0-3c84-a87c-66d9-6e80c948d42e.png)




#2. 設定のキモ

Server-A(172.16.0.4)からServer-B(172.16.5.4)への応答は、もちろん

    Source IPが172.16.5.4
    Destination IPが172.16.0.4

であるべきです。この時、Server-Bから送信されるパケットのSource IPが172.16.5.4であるにも関わらず、経路情報を優先してeth0が使われていたために非対称ルーティングが発生していたのでした。よって、

- Source IPが172.16.5.0/24の時はeth1を使う
- Source IPが172.16.6.0/24の時はeth2を使う
- Source IPが172.16.7.0/24の時はeth3を使う

というルールを強制できれば非対称ルーティングは発生しません。

#3. ポリシールーティングの設定

##3-1. eth1に対するポリシーベースルーティング

今回は一時的な検証のために、Linuxでの設定例は非永続化構成としています。

```txt:デフォルトの経路テーブル構成
[root@server-b ~]# ip rule show
0:	from all lookup local
32766:	from all lookup main
32767:	from all lookup default

[root@server-b ~]# ip route show table main
default via 172.16.4.1 dev eth0
169.254.0.0/16 dev eth0 scope link metric 1002
172.16.4.0/24 dev eth0 proto kernel scope link src 172.16.4.2
172.16.5.0/24 dev eth1 proto kernel scope link src 172.16.5.4
172.16.6.0/24 dev eth2 proto kernel scope link src 172.16.6.4
172.16.7.0/24 dev eth3 proto kernel scope link src 172.16.7.4
```

以下で、ポリシーベースルーティングの設定と確認を行います。

```txt:table1000を初期化
[root@server-b ~]# ip route flush table 1000
```
```txt:table1000にデフォルトゲートウェイとsubnet情報を設定
[root@server-b ~]# ip route add table 1000 to default via 172.16.5.1 dev eth1
[root@server-b ~]# ip route add table 1000 to 172.16.5.0/24 dev eth1
```
```txt:どのsubnetからのパケットはtable1000を使うかを指定（優先度は100）
[root@server-b ~]# ip rule add from 172.16.5.0/24 table 1000 priority 100
```
```txt:設定の確認
[root@server-b ~]# ip rule show
0:	from all lookup local
100:	from 172.16.5.0/24 lookup 1000
32766:	from all lookup main
32767:	from all lookup default

[root@server-b ~]# ip route show table 1000
default via 172.16.5.1 dev eth1
172.16.5.0/24 dev eth1 scope link
```

同様にeth2, eth3に対してもポリシーベースルーティングを設定します。

##3-2. テスト

```txt:Server-Bのeth1に対してpingに成功
[root@server-a ~]# ping -c 3 172.16.5.4
PING 172.16.5.4 (172.16.5.4) 56(84) bytes of data.
64 bytes from 172.16.5.4: icmp_seq=1 ttl=64 time=0.328 ms
64 bytes from 172.16.5.4: icmp_seq=2 ttl=64 time=0.479 ms
64 bytes from 172.16.5.4: icmp_seq=3 ttl=64 time=0.382 ms

--- 172.16.5.4 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.328/0.396/0.479/0.064 ms
```

```txt:Server-Bにて、eth1で受信し、eth1で返信（送信）している。
[root@server-b ~]# tcpdump -i eth1 icmp -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
07:59:17.595554 IP 172.16.0.4 > 172.16.5.4: ICMP echo request, id 15007, seq 1, length 64
07:59:17.595585 IP 172.16.5.4 > 172.16.0.4: ICMP echo reply, id 15007, seq 1, length 64
07:59:18.595938 IP 172.16.0.4 > 172.16.5.4: ICMP echo request, id 15007, seq 2, length 64
07:59:18.595969 IP 172.16.5.4 > 172.16.0.4: ICMP echo reply, id 15007, seq 2, length 64
07:59:19.595811 IP 172.16.0.4 > 172.16.5.4: ICMP echo request, id 15007, seq 3, length 64
07:59:19.595840 IP 172.16.5.4 > 172.16.0.4: ICMP echo reply, id 15007, seq 3, length 64
```