導入背景とBIRDを選ぶ理由
本格的なHomeLab(5つのVLAN、2拠点に分散した6台のVPSノード、自宅の3台のベアメタルマシン)を構築し始めたとき、スタティックルートはすぐに管理の悪夢と化してしまいました。サブネットを追加したり、マシンを移動したりするたびに、すべてのノードで手動でルートを更新しなければならなかったのです。これでは続きません。
FRRoutingは以前使ったことがあり(このブログにはFRRの専用ガイドもあります)、BIRDの方が適している場面に何度も遭遇しました。BIRDが特に優れているのは以下のケースです:
- ネットワーク内でのBGPルートリフレクターの構築 — テンプレートベースの設定により格段にスッキリした構成が可能
- RAMを食いつぶさない軽量デーモン — 静かなネットワーク上でBIRD2は30MB以下で動作。一部の代替品の200MB以上と比べて圧倒的に少ない
- BIRD独自のフィルター言語を使った細かいルートフィルタリング — プレフィックスリストだけでなく、適切なaccept/reject/modifyロジックを実装可能
- 実際のISPやIXP環境にも通用するルーティングスキルの習得 — BIRDはインターネットエクスチェンジで広く使われている
BIRD(BIRD Internet Routing Daemon)はチェコのドメインレジストリであるCZ.NICが開発し、数十年にわたって本格的な本番ネットワークで稼働してきました。現行のメジャーバージョンBIRD2は、単一プロセスでIPv4とIPv6の両方を処理します。この構成を本番環境で1年以上運用してきましたが、予期しないBGPセッションの切断は一度もありません。
FRRとの最大の違い:BIRDは独自の構文を持つ単一の宣言的な設定ファイルを使います。Ciscoスタイルの「configure terminal」ワークフローは不要です。ファイルを編集してbirdc configureを実行するだけで完了します。設定の差分は綺麗で、バージョン管理も容易です。
インストール
Ubuntu / Debian
BIRD2はUbuntu 20.04以降とDebian 11以降の標準リポジトリに含まれています:
sudo apt update
sudo apt install bird2
インストール後、サービスは自動的に起動します。起動を確認してください:
sudo systemctl status bird
bird --version
# BIRD バージョン 2.0.x
RHEL / Rocky Linux / AlmaLinux
RHELファミリーのシステムでは、EPELからインストールします:
sudo dnf install epel-release
sudo dnf install bird
Rocky 9およびAlmaLinux 9では、EPELパッケージは追加の依存関係なしにクリーンにインストールできます。
メインの設定ファイルは/etc/bird/bird.confにあります。編集する前にバックアップを取っておきましょう:
sudo cp /etc/bird/bird.conf /etc/bird/bird.conf.orig
設定
設定ファイルの構造を理解する
BIRDの設定ファイルは論理的に3つのパーツで構成されています:
- グローバルオプション — ルーターID、ログ出力先、ソケットの場所
- プロトコルブロック — ルーティングプロトコルまたはシステム機能ごとに1つのブロック(kernel、device、static、ospf、bgpなど)
- フィルター定義 — プロトコルブロック内で適用される名前付きルートフィルター
すべての設定に必要な最小限のスケルトンは次のとおりです:
# /etc/bird/bird.conf
log syslog all;
router id 10.0.0.1; # ループバックまたはプライマリIPを使用
# 直接接続されたインターフェースを検出
protocol device { }
# 直接ルートをBIRDのルーティングテーブルにエクスポート
protocol direct {
ipv4;
ipv6;
}
# BIRDのルートをLinuxカーネルに同期
protocol kernel {
ipv4 {
export all;
};
}
kernelプロトコルはBIRDとLinuxカーネルのルーティングテーブルの橋渡し役です。export allがない場合、BIRDは内部でルートを計算しますが、それをインストールしません。これは初めて使う際に最もよくある落とし穴の一つです。
OSPFの設定
OSPFは、すべてのルーターを自分で管理するHomeLabに最適な選択肢です。この設定は、2つのインターフェースをまたいで単一のOSPFエリアを構築します:
protocol ospf v2 homelab_ospf {
area 0.0.0.0 {
interface "eth0" {
type broadcast;
hello 10;
dead 40;
cost 10;
};
interface "eth1" {
type broadcast;
cost 20; # コストが高い = 優先度が低いパス
};
};
ipv4 {
import all;
export where source = RTS_OSPF || source = RTS_STATIC;
};
}
export行はBIRDがOSPFにアドバタイズする内容を制御します。ここではOSPFで学習したルートとスタティックルートを再配信しています。各ノードが共有すべき内容に応じてこのフィルターを調整してください。IPv6の場合は、ospf v2をospf v3に置き換え、ipv4をipv6に変更します。
BGPの設定
ここでBIRDのテンプレートシステムの真価が発揮されます。ネイバーごとにピア設定を重複させる代わりに、テンプレートを一度定義して継承します:
# すべてのiBGPピア用テンプレート — 一度定義して再利用
template bgp ibgp_peers {
local as 65001;
hold time 90;
keepalive time 30;
ipv4 {
next hop self;
import all;
export all;
};
}
# 各ピアはテンプレートを参照するだけ
protocol bgp homelab_router2 from ibgp_peers {
neighbor 10.0.0.2 as 65001;
description "HomeLabルーター2";
}
protocol bgp homelab_router3 from ibgp_peers {
neighbor 10.0.0.3 as 65001;
description "HomeLabルーター3";
}
ルートリフレクター(他のすべてのノードにルートを再配信する中央ノードで、フルメッシュが不要になる)を運用する場合は、テンプレートに2行追加します:
template bgp ibgp_rr_client {
local as 65001;
rr client; # 接続するピアをRRクライアントとして扱う
rr cluster id 1;
next hop self;
ipv4 {
import all;
export all;
};
}
各クライアントはルートリフレクターにのみ接続し、他のすべてのピアとは接続しません。計算してみると:フルメッシュで6台のルーターがあれば15本の独立したBGPセッションが必要です。ルートリフレクターを使えば5本に減ります。大幅な簡素化です。
ルートフィルター
フィルター言語こそがBIRDが他と一線を画す部分です。このフィルターはRFC1918の10.x.x.x空間からのルートのみを受け入れ、それ以外はすべて拒否します:
filter only_homelab_routes {
if net ~ [ 10.0.0.0/8+ ] then accept;
reject;
}
protocol bgp homelab_router2 from ibgp_peers {
neighbor 10.0.0.2 as 65001;
ipv4 {
import filter only_homelab_routes;
export all;
};
}
10.0.0.0/8+という表記は「10.0.0.0/8およびより具体的なプレフィックス」を意味し、個別に列挙することなく10.0.0.0/8配下のすべてのサブネットをカバーします。
設定変更の適用
設定ファイルを編集した後、セッションを切断することなくリロードします:
sudo birdc configure
BIRDは適用前に構文を検証します。エラーがあれば既存の設定が維持されてエラーが報告されるため、タイプミスによってサービスが中断することはありません。
動作確認とモニタリング
birdcインタラクティブシェル
birdcはBIRDのコントロールインターフェース — ルーターのCLIに相当します:
sudo birdc
シェル内の主要コマンド:
bird> show status
bird> show protocols
bird> show protocols all
bird> show route
bird> show route table master4
bird> show ospf topology
bird> show ospf neighbors
bird> show bgp sessions
スクリプトやモニタリングには、インタラクティブシェルに入らずにbirdcに直接コマンドを渡せます:
sudo birdc show protocols
sudo birdc show route count
BGPセッションの状態確認
sudo birdc show protocols
正常なBGPセッションは次のように表示されます:
Name Proto Table State Since Info
homelab_router2 BGP --- up 2026-07-01 Established
Establishedの代わりにActiveやConnectが表示される場合、TCP接続が完了していません。まず確認すべきこと:両端のファイアウォールルールです。BGPはTCPポート179で動作するため、両側でネイバーIPからのインバウンド接続を許可する必要があります。
OSPF隣接関係の確認
sudo birdc show ospf neighbors
Router ID Pri State DTime Interface Router ID
10.0.0.2 1 Full/DR 00:32 eth0 10.0.0.2
Full/DRは隣接関係が完全に確立されていることを意味します。2-WayやExStartから進まない場合は、両端が同じOSPFエリアにあること、hello/deadインターバルが完全に一致していることを確認してください。
カーネルへのルートインストールの確認
BIRDが実際にLinuxのルーティングテーブルにルートを反映していることを確認します:
ip route show
# BIRDで学習したルートが正しいメトリクスで表示される
# 特定のプレフィックスを確認:
ip route show 10.0.2.0/24
リアルタイムログの監視
sudo journalctl -u bird -f
特定のBGPセッションのデバッグには、一時的にプロトコルブロックにdebug allを追加します。注意:アクティブなセッションでは1時間に数百メガバイトのログが生成される可能性があります。忘れる前に削除しましょう:
protocol bgp homelab_router2 from ibgp_peers {
neighbor 10.0.0.2 as 65001;
debug all; # デバッグ後に削除
}
モニタリング用のシンプルなヘルスチェック
BGPセッションのダウンを検知するために、モニタリングスタックにこのワンライナーを組み込んでいます:
sudo birdc show protocols | grep BGP | grep -v Established \
&& echo "警告: BGPセッションがダウンしています" \
|| echo "OK: すべてのBGPセッションが確立されています"
cronジョブやPrometheusのtextfileコレクターに組み込んでおけば、セッションがダウンしてから数分以内にアラートが届きます。
BIRDの設定モデルを理解するには、おそらく週末1回分の時間があれば十分です。一度理解してしまえば、すぐに元が取れます。フィルターポリシーを含む完全なルートリフレクター設定が100行未満に収まります。Cisco IOSで同じ設定をすれば3倍の行数になり、差分も取りにくくなります。6ヶ月後にピアを追加したりフィルターを調整したりする際も、設定ファイルを見ればすぐに思い出せます。一から学び直す必要はありません。

