はじめに
GoBGP、apt-get
してドキュメントどおりに設定書いて終わりだからとくにハマることないよなあ、と思いながらやってみたら、思ってたよりハマったのでメモを残します。試した環境はUbuntu 20.04LTSです。
インストール
sudo apt-get install -y frr gobgpd
あとでちゃんと確認してみたら、バージョンは
- gobgpd: 2.12.0-1
- frr: 7.2.1-1
でした。
FRRを入れるのには理由があります。GoBGPは経路交換してくれますが、それをカーネルのFIBに反映してくれません。FIBへの反映にzebraを用いる場合、QuaggaあるいはFRRoutingが必要とのことでした。
参考: FIB manipulation
FRRの設定
とくに必要ありません。何もしなくてもzebra
は動いていると思います。動いてなければsudo systemctl start frr.service
で。
GoBGPの設定
最低限の設定を/etc/gobgpd.conf
に記述し、残りはgobgp
コマンドつまりCLIで設定していきます。下記が/etc/gobgpd.conf
の中身になります。
[global.config]
as = 1000
router-id = "10.10.10.1"
[zebra]
[zebra.config]
enabled = true
url = "unix:/var/run/frr/zserv.api"
redistribute-route-type-list = ["connect"]
software-name = "frr7.2"
version = 6
[global.config]
がないとgobgpd
は動いてくれません。AS番号、router-idは適宜変更を。
この設定のポイントは[zebra]
以降です。これを書いておくことで、GoBGPは経路交換して得た経路をカーネルに流し込む(FIBに反映する)ようになります。書いておかないとカーネルには経路が流し込まれません。
redistiribute-route-type-list
はお好みで。重要なのは最後の2行。ドキュメントをしっかり読むと書いてあるのですが、少なくとも今回試している環境では、version
だけでは動きません。プロセスは動作していて、設定もできているのに、経路が反映されません。version
とsoftware-name
両方指定する必要があります。
ドキュメントに記載されている例をコピペして、中身を読まないでいるとハマる(そして、ソースコーを眺めて条件に気づく)というオチでしたorz
FRRと連携するための変更
/etc/systemd/system/multi-user.target.wants/gobgpd.service
を編集します。
-
DynamicUser=yes
行の削除 - 削除した箇所に
User=frr
行の追加
/var/run/frr/zserv.api
はプロセス間通信のためのソケットファイルなのですが、アクセス権限を見るとユーザfrr
でしかアクセスできないようになっています。
$ ls -l /var/run/frr/zserv.api
srwx------ 1 frr frr 0 Feb 17 23:39 /var/run/frr/zserv.api
GoBGPがFRRと連携するには、zserv.api
ファイルのアクセス権限を変更するか、gobgpd
を許可されているユーザで動作させる必要があるのですが、ここでは後者を選択したということになります。
本当はどうやるのが正解なのかよくわからないままです。
GoBGPの起動
システムごと再起動するもよし、sudo systemctl start gobgpd.service
するもよし。
起動直後の状態
172.21.0.2/24
と192.168.0.2/24
の2本足ルータの想定です。
$ ip route
default via 192.168.122.1 dev ens3 proto dhcp src 192.168.122.7 metric 100
172.21.0.0/24 dev ens5 proto kernel scope link src 172.21.0.2
192.168.0.0/24 dev ens4 proto kernel scope link src 192.168.0.2
192.168.122.0/24 dev ens3 proto kernel scope link src 192.168.122.7
192.168.122.1 dev ens3 proto dhcp scope link src 192.168.122.7 metric 100
なお、上記例での192.168.122.7/24
はマネジメント用の足です。
CLIでの設定
neighbor(BGPをおしゃべりするお隣さん)の情報と、広報する経路の追加をやってみます。
$ sudo gobgp neighbor add 172.21.0.1 as 2000
$ sudo gobgp global rib add 192.168.0.0/24
なお、context deadline exceeded
と言われる場合、gobgpd
は動いていません。/etc/gobgpd.conf
の記述ミスがないかなどチェックしましょう。
コマンドを実行すると、GoBGP側は下記のようになりました。
$ gobgp global
AS: 1000
Router-ID: 10.10.10.1
Listening Port: 179, Addresses: 0.0.0.0, ::
$ gobgp neighbor
Peer AS Up/Down State |#Received Accepted
172.21.0.1 2000 00:00:45 Establ | 4 1
$ gobgp global rib
Network Next Hop AS_PATH Age Attrs
*> 10.0.0.0/24 172.21.0.1 2000 00:00:47 [{Origin: i} {Med: 0}]
*> 172.21.0.0/24 0.0.0.0 00:05:11 [{Origin: i} {Med: 0}]
*> 192.168.0.0/24 0.0.0.0 00:00:49 [{Origin: i} {Med: 0}]
*> 192.168.122.0/24 0.0.0.0 00:05:11 [{Origin: i} {Med: 0}]
$ ip route
default via 192.168.122.1 dev ens3 proto dhcp src 192.168.122.7 metric 100
10.0.0.0/24 via 172.21.0.1 dev ens5 proto bgp metric 20
172.21.0.0/24 dev ens5 proto kernel scope link src 172.21.0.2
192.168.0.0/24 dev ens4 proto kernel scope link src 192.168.0.2
192.168.122.0/24 dev ens3 proto kernel scope link src 192.168.122.7
192.168.122.1 dev ens3 proto dhcp scope link src 192.168.122.7 metric 100
10.0.0.0/24
が増えているのがわかるかと思います。AS番号2000のお隣さん(172.21.0.1
)が広報している経路です。無事経路情報を受け取ってカーネルのFIBに反映させることができました。
おわりに
ドキュメントをよく読みましょう。