BGP Flowspec のバリデーション
BGP ルーターには,Flowspec という機能があります.2009年にRFC5575 として標準化されたもので,ざっくり言えば「遠くのルーターでパケットフィルターを発動させる」機能.
最近 注目されているこのFlowspec のうち,とくにバリデーションについて調べました.
2015-05-28 追記
@shtsuchi さんに指摘をもらい,IOS-XRv の実装が分かりましたので 追記しました.Flowspec ちゃんと動きます.コメントありがとうございました!
2023-01-31 追記
@a16tochjp さんに JUNOS 実装についてコメントをもらい,RFC9117 について追記しました.ありがとうございました!
ところで,使われてるの?
当初脚光を浴びましたが 大規模にデプロイする事業者がなく,その後しばらく下火でした.ここ数年でコンテンツプロバイダー中心にアーリーアダプターが使いはじめ,少しずつ注目されてきたのが現状です.
https://www.slideshare.net/Arbor_Networks/aol-flowspec-2015
BGP Flowspec とは
JANOG35 のセッション が詳しいです.
簡単に言えば
をBGP に乗せて伝搬させます.
- 通常のBGP で言えば「10.0.0.0/8」が入っていたところに「dst prefix=172.16.0.0/16, src prefix=any, proto=1」のような情報が
- BGP community のところに「rate-limit させる」のような情報が
入っているイメージです.*1
show route
すれば「ああ,素直に出力してるんだな」と分かる程度にそのまま表示されます.
バリデーション?
Flowspec は パケット操作方法をeBGP にも乗せられる強力な機能なので,標準にも厳しくバリデーション方法が指定されています.各ルーターでは,Flowspec 経路それぞれをバリデーションし,valid であればそこに記述されているパケットフィルターを発動させます.
A flow specification NLRI must be validated such that it is considered feasible if and only if:
a) The originator of the flow specification matches the originator of the best-match unicast route for the destination prefix embedded in the flow specification.
b) There are no more specific unicast routes, when compared with the flow destination prefix, that have been received from a different neighboring AS than the best-match unicast route, which has been determined in step a).
By originator of a BGP route, we mean either the BGP originator path attribute, as used by route reflection, or the transport address of the BGP peer, if this path attribute is not present.
けっこう重要そうな項目なのに,これだけだと意味がわかりませんね.メーカーサイトにもわかりやすいドキュメントがなかったので「いくつかの実装を試して確かめました」というのが今回の趣旨です.
試したのはJuniper vSRX (12.1X47-D15.4),Cisco IOS-XRv (5.2.2).ともにFlowspec をFIB にインストールする部分が実装されていないようで,今回はルーティングだけの確認です.
Flowspec のオリジネーターとDestination Prefix
a) Flowspec のオリジネーターは,Flowspec 中のdestination prefix に対するベストマッチ経路のものと一致する必要がある
意味がわからない その1.
とあります.
BGP originator パスアトリビュートには,ORIGINATOR_ID のことですが,ルートリフレクターがクライアントのrouter ID を格納します.トランスポートアドレスは,ピアを張るIPアドレスそのものを指します.ですのでFlowspec ルーターは,RR 構成であれば経路のrouter ID を,そうでなければneighbor IP アドレスを使ってオリジネーターを識別していることになります.
なるほど.iBGP だけの世界なら単純そう.ところがiBGP とeBGP を混ぜて考えると少しわかりにくいかもしれません.
トランスポートアドレスが一致する,とは?
iBGP とeBGP がある構成を考えます.
上の構成では どこにも経路フィルターを設定していません.RTR1 から10.0.0.0/8 の経路を広告し,RTR3 まで伝えます.
この構成でRTR2 にstatic なFlowspec (dst=10.0.0.0/8) を設定したとすると,RTR3 にも伝搬しますが,そこでは該当のFlowspec 経路はvalid になります.通常の経路はRTR1 でオリジネートし,Flowspec はRTR2 でオリジネートしたにも関わらず,です.
これは経路の向きを逆にして,RTR1 上で考えたとしても同じです.
このような動作になるのは,Flowspec ルーターがトランスポートアドレスによってオリジネーターを識別しているからです.ようするに「オリジネーターが同じ」とは,「同じBGP セッションから受信した」と解釈して構いません.*2
ベストマッチ経路とは?
該当のprefix を含有する最小の経路のことです.
たとえばBGP テーブル上に10.0.0.0/8 と10.0.0.0/16 がある場合,dst=10.0.0.0/24 なFlowspec 経路に対するベストマッチ経路は10.0.0.0/16 です.
また,ベストマッチ経路が存在しない場合はFlowspec 経路はinvalid です.
逆に言うとBGP テーブル上に10.0.0.0/8 がある場合は,dst=10.0.0.0/8~/32 までのFlowspec 経路がベストマッチ経路を持ち,valid になる可能性があります.
Destination Prefix が指定されていなかった場合は?
「dst 条件がなかったらどうなんの?」と思った方はするどいですね.
- Juniper vSRX の場合
- dst=0.0.0.0/0 相当です.この場合のベストマッチ経路はデフォルトルート(0.0.0.0/0) です.なので,dst 条件のないFlowspec 経路をvalid にするには,デフォルトルートが必要になります.
- Cisco IOS-XRv の場合
- オリジネーターバリデーションしません.なので,dst 条件のないFlowspec 経路をvalid にするために,デフォルトルートは必要ありません.
ここまでのまとめ
a) Flowspec のオリジネーターは,Flowspec 中のdestination prefix に対するベストマッチ経路のものと一致する必要がある
というのは,言いかえると
Flowspec 経路と,そのdestination prefix を含む最小の経路は,同じBGP セッションから受信する必要がある
2015-05-28 追記
Cisco IOS-XRv は「iBGP からFlowspec 経路を受信した場合に限り,上のオリジネーターバリデーションをスキップする」という実装になっています.詳しくは後述しますが,Juniper vSRX と動作が違うので注意です.
More Specific な経路があってはいけない,とは?
b) 異なるAS から受信する,more specific な経路がないこと
意味がわからない その2.
こちらも経路フィルターがない構成で,RTR1 とRTR3 から経路を注入します.すると,RTR2 のBGP テーブルに10.0.0.0/8 と10.0.0.0/24 が乗ります.
この状態ではRTR2 上でdst=10.0.0.0/8 なFlowspec 経路はinvalid になり,Flowspec テーブルには乗りません.more specific な/24 の経路があるためです.
「割り当てられた/8 から/24 を他者に割り振る」ような状況も考慮すると,「/8 単位での制御は危険だからやめとくべき」という意図だと思われますが,ちょっと窮屈ですね.
また,今回のテストではなぜか「異なるAS かどうか」は評価されないように見えました.10.0.0.0/24 をiBGP から受信しようが,eBGP から受信しようが,static な経路だろうが,dst=10.0.0.0/8 なFlowspec 経路はinvalid になります.
RFC によると「異なるAS からmore specific 経路が広告された場合のみinvalid」になりそうですが,そのような動作はしません.*3
Destination Prefix が指定されていなかった場合は?
- Juniper vSRX の場合
- dst=0.0.0.0/0 相当なので,デフォルトルート以外の経路が存在しない場合に限り 該当のFlowspec 経路はvalid になります.通常そんなことはありえないので,destination prefix が指定されていないFlowspec は常にinvalid です.
- Cisco IOS-XRv の場合
- more specific バリデーションしません.destination prefix が指定されていないFlowspec もvalid になる可能性があります.
Flowspec をstatic に設定することができる
ここまでで,Flowspec のバリデーションは
- Flowspec 経路と,そのdestination prefix を含む最小の経路は,同じBGP セッションから受信している
- BGP テーブル上に,destination prefix よりmore specific な経路がない
ことを確認するものだ,と理解できます.
この動作に不都合を感じる場合は,Flowspec をstatic に設定することで,設定したルーター上に限りバリデーションをスキップすることができます.
たとえばJUNOS でdst prefix を指定せずFlowspec を有効にしたい場合,該当ルーターすべてにstatic 設定することで実現できます.ただ,「そこまでするならパケットフィルターを書いて回ったほうがいいんでは」と感じます.
ほかにstatic 設定はFlowspec をオリジネートするためにも使われますが,通常はこっちがメインだと思います.
Neighbor やピアグループ単位でバリデーションを無効にできる (2015-05-28 追記)
AS内だけでFlowspec を使う場合など,厳しいバリデーションが邪魔になることがあります.その場合はNeighbor やピアグループ単位でバリデーションをスキップすることができます.
Juniper vSRX:
protocols { bgp { group ibgp { family inet { flow { no-validate skip-validation; } } } } } policy-options { policy-statement skip-validation { then accept; # フィルター条件をいろいろ書ける } }
router bgp 64600 neighbor 192.168.1.20 address-family ipv4 flowspec validation disable
Juniper vSRX とCisco IOS-XRv のちがい (2015-05-28 追記)
destination prefix 指定のないFlowspec の扱いなどに違いはありますが,一番大きな差は
@codeout メールしまーす。簡単にいうと、RFC5575の部分、draft-ietf-idr-bgp-flowspec-oidでiBGPはリラックスさせる。eBGPだとknobで無効化しなきゃいけないって感じ
— Shishio Tsuchiya (@shtsuchi) 2015年5月26日
です.Cisco IOS-XRv はdraft-ietf-idr-bgp-flowspec-oid-02 が実装されており,オリジネーターバリデーションが一部変更されています.
Step (a) of the validation procedure specified in RFC 5575, section 6 is redefined as follows:
a) One of the following conditions MUST hold true: o The originator of the flow specification matches the originator of the best-match unicast route for the destination prefix embedded in the flow specification. o The AS_PATH and AS4_PATH attribute of the flow specification are empty. o The AS_PATH and AS4_PATH attribute of the flow specification does not contain AS_SET and AS_SEQUENCE segments.
簡単に言えば「iBGP からFlowspec 経路を受信した場合に限り,上のオリジネーターバリデーションをスキップする」です.オリジネーターがベストマッチ経路と一致しない場合や,ベストマッチ経路が存在しない場合でもvalid になる可能性があります.
RFC9117 (2023-01-31 追記)
現在👆のI-Dは RFC9117 になっています.
未確認ですが,多くの実装で iBGP から受信したFlowspec 経路に関するバリデーションをスキップすると思われます。@a16tochjp さんのコメントによると「JUNOSもそうなっている」とのことです.
その他
- JUNOS の場合,特定のPFE やVRF だけにインストールすることはできないようです.インターフェイスを指定して設定するパケットフィルターとは考え方が変わる点に注意
- Flowspec 経路にも BGP community をつけることができます.いつものようにBGP community を見る経路フィルターを作れば,Flowspec 経路を選択的にvalid にすることができます
- Juniper とCisco で実装が違うので注意
どう使うか?
今回のIOS-XRv のように期待通り動かないことや,CloudFlare でのトラブル のような例もあります.議論の余地はありますが,現状だと まだ「コミュニティに知見が足りないため検証するしかないが,コストに対して得られるメリットが小さい」場合が多そうです.
一方で「用途を限ればすごく便利で,コスト問題も解決できるかも」と感じています.
たとえば,次のような使い方はよさそう.
DDoS 対策など,小さいdst prefix を守るために使う
- dst prefix が広い場合,more specific バリデーションで落とされる可能性が高い
- more specific 経路が無ければ大きいdst prefix でも動くが,いちいち確認するのが手間
exabgp のようなAPI 豊富なソフトウェアルーターを使い,Flowspec を注入する
- 自動化のため
AS ボーダーでフィルターする目的で,ソフトウェアルーターは1段階だけ下流のルーターとピアする
- 小さいdst prefix を守りたい場合,その経路はおそらく下流からくる
- トランスポートアドレスバリデーションにより,AS ボーダーでのみFlowspec が動くと期待できる
特定のルーターでのみ発動させたい場合は,BGP community で制御
強力なので,ハマれば便利そうですが…どうでしょうかね. 「こういう使い方できそう」「こうやってる」などなど,ぜひご意見ください!