0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OpenWrt + WireGuard + Bird + OSPF + BFDでフルトンネル&高速フェイルオーバーVPNを構築する

Last updated at Posted at 2025-12-06

OSPFするだけ編はこちら

mwan3でのフェイルオーバー編はこちら

本編

BFDとはなんぞや

  1. ルーター間でBFDパケットを相互に送受信する
  2. 途絶えたら障害とみなして各ルーティングプロトコルに通知する
  3. 各ルーティングプロトコルは経路を再計算し、ルーティングを修正する

これらの一連の流れを爆速でやってくれる仕組み的なやつです。
OSPFだけでもHELLOパケット/DEADインターバルによる死活監視が行われ、動的に再計算されますが、BFDを有効化するとそれより更に高速に障害検知・再ルーティングが行われるようになります。
OSPFに限らずBGPでも使えます。

これを使えばmwan3なしでも自動で高速フェイルオーバー出来るフルトンネルVPNが構築できるんじゃね?

ということで実装してみました。
経路情報は以前のOSPFするだけ編で設定して広報しています。

コンフィグ内容(出口側)

/etc/bird.conf
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を使用するよう明示的に指定

コンフィグ内容(クライアント側)

/etc/bird.conf
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 kernelmetric 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.comhttps://ifconfig.me なんかにつなぎに行ってリロードしてIPv4が切り替わっていればOK。

このようなPowerShellスクリプトをクライアントネットワークに所属するWindowsマシンで実行し、IPアドレスが切り替わることを確認した。

while ($true -eq $true) { (Invoke-WebRequest https://ipv4.seeip.org/).Content ; sleep 1 ; }

image.png

ゲートウェイのWireGuardインターフェイスを停止してほぼすぐにルートがフェイルオーバーし、インターネットへ直接出る経路に切り替わった。
その後、WireGuardインターフェイスを再起動後数秒でルートがフェイルバックし、フルトンネルされることが確認できた。

感想

今まで必要に駆られなかったので動的ルーティングをあまり触ってこなかったのですが、最近触り始めてあまりにも便利すぎてもう全拠点において静的ルートを切るのを辞めてガッツリ移行しました。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?