OSPFするだけ編はこちら
mwan3でのフェイルオーバー編はこちら
本編
BFDとはなんぞや
- ルーター間でBFDパケットを相互に送受信する
- 途絶えたら障害とみなして各ルーティングプロトコルに通知する
- 各ルーティングプロトコルは経路を再計算し、ルーティングを修正する
これらの一連の流れを爆速でやってくれる仕組み的なやつです。
OSPFだけでもHELLOパケット/DEADインターバルによる死活監視が行われ、動的に再計算されますが、BFDを有効化するとそれより更に高速に障害検知・再ルーティングが行われるようになります。
OSPFに限らずBGPでも使えます。
これを使えばmwan3なしでも自動で高速フェイルオーバー出来るフルトンネルVPNが構築できるんじゃね?
ということで実装してみました。
経路情報は以前のOSPFするだけ編で設定して広報しています。
コンフィグ内容(出口側)
log syslog all;
router id 10.0.0.1;
protocol device {
scan time 10;
}
protocol direct {
ipv4;
}
protocol kernel {
ipv4 {
import all;
export all;
};
scan time 20;
persist;
learn;
}
protocol bfd {
}
protocol ospf v2 OSPF_WG {
tick 10;
rfc1583compat yes;
ipv4 {
import all;
export filter {
if ( source = RTS_DEVICE && net ~ [ 10.0.0.0/8+, 172.16.0.0/12+, 192.168.0.0/16+ ]) then accept;
if net = 0.0.0.0/0 then accept;
reject;
};
};
area 0 {
interface "wg0" {
type ptp;
hello 1;
dead 5;
retransmit 5;
priority 0;
cost 10;
bfd yes;
};
};
}
- 変更点
-
protocol bfdを追加(空コンフィグでOK) -
if net = 0.0.0.0/0 then accept;でデフォルトルートを広報して利用されるように変更 - protocol ospfのinterfaceに
bfd yes;を追加しbfdを使用するよう明示的に指定
-
コンフィグ内容(クライアント側)
log syslog all;
router id 10.0.0.2;
protocol device {
scan time 10;
}
protocol direct {
ipv4;
}
protocol kernel {
ipv4 {
import all;
export all;
};
scan time 20;
persist;
learn;
metric 0;
}
protocol bfd {
}
protocol ospf v2 OSPF_WG {
tick 10;
rfc1583compat yes;
ipv4 {
import all;
export filter {
if ( source = RTS_DEVICE && net ~ [ 10.0.0.0/8+, 172.16.0.0/12+, 192.168.0.0/16+ ]) then accept;
reject;
};
};
area 0 {
interface "wg0" {
type ptp;
hello 1;
dead 5;
retransmit 5;
priority 0;
cost 10;
bfd yes;
};
};
}
- 変更点
-
protocol kernelにmetric 0;を追加し、最優先で使用されるように指定 -
protocol bfdを追加(空コンフィグでOK) - protocol ospfのinterfaceに
bfd yes;を追加しbfdを使用するよう明示的に指定
-
また、これとは別に障害時に使用するインターフェイスのメトリックを下げておく。(今回は10にした)
実際に動かしてみた
コンフィグを更新させるためにbirdを再起動する
root@OpenWrt:~# bservice bird restart
root@OpenWrt:~# birdc show protocol
BIRD 3.0.1 ready.
Name Proto Table State Since Info
kernel1 Kernel master4 up 16:03:40.024
bfd1 BFD --- up 16:03:40.033
OSPF_WG OSPF master4 up 16:03:40.033 Running
device1 Device --- up 16:03:40.024
direct1 Direct --- up 16:03:40.024
こんな感じにbfdが増えていればOK
クライアント側のOpenWrtでルートが反映されているか確認する
root@OpenWrt:~# ip route
default via 10.0.0.1 dev wg0 proto bird onlink
default dev map-wan proto static scope link metric 10
10.0.0.0/24 via 10.0.0.1 dev wg0 proto bird onlink
10.0.0.2 dev wg0 proto bird scope link
xx.xx.xx.xx dev map-wan proto bird scope link
xx.xx.xx.xx dev map-wan proto static scope link metric 10
192.168.0.1 dev wg0 proto static scope link
192.168.1.0/27 via 10.0.0.1 dev wg0 proto bird onlink
192.168.1.32/27 via 10.0.0.1 dev wg0 proto bird onlink
192.168.1.64/26 via 10.0.0.1 dev wg0 proto bird onlink
192.168.1.128/27 via 10.0.0.1 dev wg0 proto bird onlink
192.168.1.160/27 via 10.0.0.1 dev wg0 proto bird onlink
192.168.2.0/24 dev br-lan proto bird scope link
WireGuardの接続を切断したり、インターフェイスを停止してフェイルオーバーが行われるか確認して問題がなければ完成。
https://test-ipv6.com や https://ifconfig.me なんかにつなぎに行ってリロードしてIPv4が切り替わっていればOK。
このようなPowerShellスクリプトをクライアントネットワークに所属するWindowsマシンで実行し、IPアドレスが切り替わることを確認した。
while ($true -eq $true) { (Invoke-WebRequest https://ipv4.seeip.org/).Content ; sleep 1 ; }
ゲートウェイのWireGuardインターフェイスを停止してほぼすぐにルートがフェイルオーバーし、インターネットへ直接出る経路に切り替わった。
その後、WireGuardインターフェイスを再起動後数秒でルートがフェイルバックし、フルトンネルされることが確認できた。
感想
今まで必要に駆られなかったので動的ルーティングをあまり触ってこなかったのですが、最近触り始めてあまりにも便利すぎてもう全拠点において静的ルートを切るのを辞めてガッツリ移行しました。
