概要
Linuxで、二つのセグメントに対してデフォルトゲートウェイを設定したいというパターンがあるとする。
この時、写真の例で192.168.160.1(ゲートウェイ1)をデフォルトゲートウェイに設定していた場合、192.168.161.0/24で付与していたアドレス宛に対しては疎通できない。
疎通できない理由は簡単に説明すると以下の通り。
VRFやスタティックルートを使わないときの経路の解説
*送信元IPは適当に、10.0.1.20とする。そいつのゲートウェイは10.0.1.1とする。
この時、
10.0.1.20(送信元PC:X)
↓
10.0.1.1(送信元PCが指定するゲートウェイ)
↓
192.168.161.1/24(161.0/24セグにつながるルーター)
↓
192.168.161.x(宛先PC:Y)
という経路になる。
この時の宛先PCのルーティングテーブルは以下の通りになる。
default via 192.168.160.1 dev eth0 ← NIC1側
192.168.160.0/24 dev eth0 proto kernel scope link src 192.168.160.x
192.168.161.0/24 dev eth1 proto kernel scope link src 192.168.161.x
この場合Replyを宛先PCが返そうとしたとき、10.0.1.20(送信元PC:X)はどの経路にも存在しないため、デフォルトルートの経路を使用しようとする。
すると、送信元IPアドレスが192.168.160.xを利用する事になり、行きの時に使用したNIC(IP)とは別のものを使用する事になる。
送信元IP:192.168.160.x
宛先IP:10.0.1.20
出口:eth0(10.0.1.10/10.0.1.1経由)
すると、送信元PC:Xが指定するゲートウェイ(10.0.1.1)の方では以下のように判断される。
192.168.160.x → 10.0.1.20 というパケットが入ってきたが、
入ってきたインターフェースと返送先ネットワークが整合しない(非対称経路)
そうなると、
- 送信元IPアドレスが想定外のものである。
- 逆方向の経路を知らない
という形で10.0.1.1が判断し、パケットを落としてしまい、通信ができなくなる。
解決策
これを解決するためには、サーバ側の経路の非対称性を解消する必要がある。
- Staticrouteの設定
- ポリシーベースルーティングの設定
- VRFによる複数ゲートウェイの設定
といった方法が主であるが、今回はVRFの設定方法を記載する。
Linuxにて、VRFの設定方法。
環境
実行元:AlmaLinux9.4
VRFの作成
バニラのLinux環境は既に出来上がっているものとし、2つのNICがあるとする。各セグメントのゲートウェイは第4オクテットが1であるものとする。
NICの一つには普通にIPやゲートウェイを付ける。
sudo nmcli con add \
type 802-3-ethernet \
ifname eth0 \
con-name eth0 \
autoconnect yes \
ipv4.method manual \
ipv4.address "192.168.160.x/24" \
ipv4.gateway 192.168.160.1 \
以下のコマンドでvrfコネクションを作成する。
- ifnameとconnameは同一の名前にする。
- table [数字]の部分にはtableidが入るため、数字を設定する。
- この場合tableidが1000になる。
sudo nmcli connection add type vrf ifname vrf0 con-name vrf0 table 1000 ipv4.method disabled ipv6.method disabled
eth1(NIC)のコネクションを作成し、作ったvrf0をマスターにする。
- IPアドレスやゲートウェイの設定をここでする。
- またこの設定により、ルーティング情報は、vrf0 デバイスに関連付けられているルーティングテーブル 1000 に自動的に割り当てられます。
sudo nmcli connection add type ethernet con-name eth1 ifname eth1 master vrf0 ipv4.method manual ipv4.address 192.168.161.x/24 ipv4.gateway 192.168.161.1
どのプロセスが利用するか指定
下記の参考サイトではnginxが利用する場合はVRFを使用する、というようなかたちをとっている。
全てのプロセスでも利用できるようにするには以下のようにsysctl.confを変更しカーネルに修正する。
sudo vi /etc/sysctl.conf
net.ipv4.tcp_l3mdev_accept=1
net.ipv4.udp_l3mdev_accept=1
上記の内容をカーネルに反映させる。
sudo sysctl -p
動作確認
以下のコマンドで、vrf0 に関連付けられている機器の IP 設定を表示します。
ip -br addr show vrf vrf0
VRF名と、tableidの紐づけを確認する。
ip vrf show
通常のルーティングテーブルを確認するにはip route showでできる。ここではVRFの情報は出てこない。
ip route show tableidで、vrfにて設定した内容を確認できる。
ip route show table 1000
VRF使用時のtracerouteを確認するには以下の通り。
sudo ip vrf exec vrf名 traceroute 宛先IP
また、VRFを使用したIPアドレスに対して、ルーティングを使用した経路でもアクセスができる事を確認してみる事。
参考
