BGP
大本はBorder Gateway Protocol 4, RFC4271。 ただし近年は純粋なBGP-4ではなく、
BGPの仕組みを通じて追加で様々なメッセージを広報するMP-BGPのほうが一般的に使われている。rfc 4760 概要
純粋なBGP(BGP-4)はASと呼ばれる区画ごとのipv4の経路広報をするためだけの仕組み。
AS間の経路交換をする場合はeBGP,AS内での経路交換をする場合はiBGPと呼ばれそれぞれで微妙に動きが変わる。
大雑把な動きとしては
BGP speakerはtcp:179でlistenで待機。他のBGPからのOPENメッセージを待つ。
他のlisten しているBGP speakerにOPENメッセージをおくりセッション構築開始。
セッションが確立できた場合は互いにBGP RIBにあるUPDATEメッセージを送る。これで経路広報をする。
update message format
UPDATEメッセージで実際の経路情報を交換する。その時にやりとりする情報が下記のような内容
code: format
+-----------------------------------------------------+
| Withdrawn Routes Length (2 octets) |
+-----------------------------------------------------+
| Withdrawn Routes (variable) |
+-----------------------------------------------------+
| Total Path Attribute Length (2 octets) |
+-----------------------------------------------------+
| Path Attributes (variable) |
+-----------------------------------------------------+
| Network Layer Reachability Information (variable) |
+-----------------------------------------------------+
withdrawn routes
削除されるべき経路(ipv4 prefix)
Path Attributes
経路のapth attribute。識別のためにtype codeが確保されている。色々あるが例えばwell-knownな属性の例として次がある。
Origin type: code 1
AS_PATH :type code 2
Nexthop: type code3
LOCAL_PREF: type code 5
BGP Extende Community: type code 16
Network Layer Reachability Information
追加してほしい経路(ipv4 prefix)
bestpath 優先順位付け(cisco)
1 Cisco独自のWEIGHTアトリビュートが最も大きいルートを優先
2 LOCAL_PREFアトリビュートが最も大きいルートを優先
3 ローカルルートが発生元であるルート(networkコマンドで生成したルート)を優先
4 AS_PATHアトリビュートが最も短いルートを優先
5 ORIGINアトリビュートが最も小さいルートを優先( IGP < EGP < Incomplete )
6 MED(MULTI_EXIT_DISC)アトリビュートが最も小さいルートを優先
7 IBGPで学習したルートよりもEBGPで学習したルートを優先
8 ネクストホップに対して最小のIGPメトリックを持つルートを優先
9 EBGPネイバーから受信したルートのうち、最も古いルート(先に受信したルート)を優先
10 ルータIDが最小のBGPピアから受信したルートを優先
11 最小のcluster_listをもつBGP ルートを優先
12 BGPピアのIPアドレスが最小のルートを優先
bestpath 優先順位付けアルゴリズム(junos)
1. next hopが解決できるか確認
2. RPが最も低いrouteを選択。
routing policyで拒否、またはnexthopにアクセスできないrouteh不適格なrouteはRPが-1と判断されて選ばれない
3 LPが最も高いものを選択
4 AIGPが有効ならもっとおAICPの値が低いパスを選択
5. AS-pathが短いものを選択
6. 最も低いORIGNを選択。IGP<EGP<Incomple
7. MEDが小さいものを優先
8. IGPの種類(static,direct,local)の中でもっとも優先度が高いもの
9 IBGP経由で学習したEBGP経路を優先
10 NexthopのIGP経由で解決したときに最も低いメトリックの経路
BGP Well known attribute
BGPには複数のAttributeがあるが、次の3つはwell known mondatory attributeと呼ばれ、BGPで必ずなければならいattribute。
ORIGIN : igp:0 , egp:1 , imcomplete:2 ORIGIN同士の比較の優先度はIGPが一番優先。IGPはAS内で生成された経路は全てIGP。EGPについてはEGPが使われない現在は事実上でることはまずない。imcompleteはIGPの内容をBGPで再配布された経路の場合にORIGINに設定される。
AS_PATH: AS番号リスト、一番右が最初のAS.新規ASは左から追加されていく
NEXT_HOP: ネクストホップアドレス。ibgpでは書き換えず、ebgpでは広報時に自分のIPに書き換えてアドバタイズ
MP-BGP
MP-BGPはBGP-4でipv4しか対応していない問題を解消して、ipv6や他のプロトコルのメッセージも広報できるよう拡張した。
AS_Path Attributeの新しいtype codeとして拡張定義された規格である。具体的には次の二つが拡張された規格。
MP_REACH_NLRI: type code 14
MP_UNREACH_NLRI: type code 15
MP_REACH_NLRIのフォーマットは次の通り。
code: format
+---------------------------------------------------------+
| Address Family Identifier (2 octets) |
+---------------------------------------------------------+
| Subsequent Address Family Identifier (1 octet) |
+---------------------------------------------------------+
| Length of Next Hop Network Address (1 octet) |
+---------------------------------------------------------+
| Network Address of Next Hop (variable) |
+---------------------------------------------------------+
| Reserved (1 octet) |
+---------------------------------------------------------+
| Network Layer Reachability Information (variable) |
+---------------------------------------------------------+
AFI(AddressFamilyIdentifier)とSAFI(SubsequentAddressFarmliyIdentifier)によって
MP_REACH_NLRIを様々なプロトコルのメッセージングの基盤として利用されている。
BGP RIB
Cisco機器はBGPはRouting Information Base(RIB)を独自にもつ。BGP内のRIBに一旦学習した情報を載せて、その中からベストパスを実際のルーターのRoute Tableに乗せるという動作をする。BGP RIBは詳細には次のような構成になっている。
https://gyazo.com/22e37e530d6155316cc8fd88de6fbe16
大きく分けて次の3つで構成される。
1. Adj-RIBs-In
他のBGP ピアから受信したupdateメッセージ(経路)を保持する。ピアごとに存在する。
2. Loc-RIBs
Adj-RIBs-In ごとに適用されている Path Attribute(パス属性)を適用した結果を総合して保持するテーブル。Loc-RIBs から、更にベストパス選択アルゴリズムに従って選出されたベストパスがルーティングテーブルにインストールされる。
3. Adj-RIBs-Out
ピアへ送信する経路(ベストパス)を保持する。ピアごとに存在する。この情報が実際にBGP updateで他のBGP speakerに届く。
JuniperはCiscoでいうBGP RIBはない。
OSPF、BGPもすべて一つのルーティングテーブルで管理される。
CiscoではBGP RIB上でベストとなった経路がBGP peerにBestpathとして広報されるが、Juniperではルーティングテーブル上でベストにならないとベストパスとして広報されない。Ciscoと同様にBGP内でのベストパス(ルーティングテーブル上ではベストパスではない)を広報するにはadvertise-inactiveという設定が必要になる。
Juniperの挙動で厄介なのはルーティングテーブル上のベストパスをBGPで広報するという仕組みの都合、他のOSPF等で学習した経路もベストパスとしてルーティングテーブルにのっていれば、その経路はBGPで広報されてしまう。なのでoutbound policyでmatch protocol bgpという条件を記載しないとospfや他のIGP経路がBGPで広報されてしまうという大事故につながる。
ciscoとマルチベンダーでつかうならadvertise-inactiveは必ず入れておいたほうが良い。
ROUTE REFRESH
BGPにはいくつかメッセージがあるが、その中にROUTE-REFRESH(TYPE5)がある。
ROUTE-REFLESHはAdj-RIB-outの経路を送れというメッセージである。CIsco IOS XRならclear bgp ipv4 unicast soft inでこのメッセージを送信できる。ただしメッセージを受け取るルーターでこの機能(capability)が有効である必要がある。
soft-reconfiguration inboud
前提としてBGPピアは基本的に一度送信したUpdateを再送付する仕組みが無い。そのためすでにあるLoc-RIBにある一部経路のLPを変更するようなフィルタ設定を新規にしても、フィルタを適用する前の元の経路情報がないため現在のLoc-RIBの内容を更新することができない。更新するにはBGP sessionを一度切って再接続して経路情報をまたもらうかROUTE REFRESHメッセージを送信して再度経路情報をうけとり新規フィルターを通すしかない。
sof-reconfiguration inboudは受信した経路情報をキャッシュするためのコンフィグである。このキャッシュにより経路を受けった後で受信経路に新規フィルターを適用したくなった場合に、過去のキャッシュした受信経路情報をとりだし、それに対してフィルターをかけることでsessionを再接続するようなことをしなくて済むようになる。
ちなみにピアがROUTE REFRESHをサポートしていない場合はこの機能を有効化する際に、BGPセッションの断が発生する(キャッシュのために経路情報を再度もらうため)。ROUTE REFRESHをサポートしていればROUTE REFRESHメッセージをおくって経路をもらい、それをキャッシュするので断はおこらない。
BGP add path
BGPはベストパスしか広報しないため、1つのBGP speakerから全く同じ複数の経路しか広告できない。
この広告されたベストパスが消えた時、BGP update(withdrow)が走り最終的には新たな別の経路を学習する。しかし、この学習するまでのコンバージェンス時間は大規模なネットワークになると時間がかかりサービス障害をもたらす。
最初からベストパスとバックアップパスの複数経路を広報したいが、ベストパスしか広報しないという制約によりそれはできない。そのため別途BGPにはadd pathというattributeが作られた。このadd pathを用いることでベストパス以外にもbackup pathとして経路を広報して、障害時にも即座にバックアップ経路に切り替えるようなことができる。
AS運用時に必要となるフィルターについて
full routeもらう時にやるべき雑な要約
BOGON (予約、プライベート)フィルタ、これはACLでも落としてよい。
自身のネットワークからのパケットフィルタ(IP spoofing対策)
外部広報時にプライベートASを取り除く
max path prefixの制限設定
異常に細かいprefexのフィルタ
異常に長いAS-pathの経路をフィルタ
peeringDBで広報が明示されている経路以外をフィルタ
ネットワークデバイスのインターフェースなどアクセスさせたくない部分へのパケットフィルタ
ispとして
peer先からはIRRで公開されているAS path だけ許可。
peer先からはIRRで公開されてprefixだけ許可。
必要ならcommunityを付ける。顧客経路やPeer経路の識別のため。
渡された不必要なcommunityは削除。顧客から変なcomunityつけられて困る場合には。
AS_PATH
AS path segmentの列からなる。次の2種類にわかれる。
AS_SEQUENCE
AS_SET
AS_SEQUENCE
経路情報されてきたASの列(通過順)
AS_SET
アップデートメッセージ内部の経路情報が経由した ASの順序がついてない集合。これは多くの場合、経路情報が集約された場合に 用いる。ASN 10 のプレフィックスAX/24 と ASN 11 のAY/24 を 集約すると、A/16 というプレフィックスになる場合、10と11のAS は順序が付けられない(そこでj分岐するから)。従って、{10,11} の集合に対して A/16の プレフィックスを公告する。
具体的には次のようなAS pathが生成されうる 10 20 30 {400 401} 50 60
これは{{400 401}}でまとめた経路集約が行われれて30に広報されていたということがわかる。
経路監視
Multithreaed Routing Tool(MRT)形式がある。
Quaggaはこの形式でファイルに保存される。MRTはRFC6396
libbagpdumpというツールでMRTバイナリをテキストとして出力可能
ソフトウェアのBGPルーターを置くべき。フルルートでも毎時保存しても1日100M程度らしい。年間でも3Gbyte程度。
経路奉行というTelecom-ISACが運営する経路監視システム
経路奉公
BMP(BGP Monitoring Protocol Mis-Oritination(経路ハイジャック)
BGPの学習速度の問題
一般的にはeBGP,IGPの収束時間を比較した場合に、
eBGPのfull routeの収束時間 > IGP収束時間となる。
これによって例えばBGPルーターの単純な再起動をした場合に、eBGPの収束前にIGPでの経路収束が完了して内部トラフィックを吸い込むが外にパケットを出せないという状態に一時的になる(ブラックホール)。
そのためeBGPの収束するまではIGPでは迂回をかけておくという運用が必要になる。
よくあるのが起動10分程度でtimeoutされるoverload, max-metoricをルーターに設定しておくこと。
これでルーターの再起動直後のブラックホールは発生しない。もっと直接的に外部向けIFに対してdelay updateを仕込むというのもある。IFによってはIGPの収束も影響を受けるので適用するIFに注意。
このブラックホール問題を防ぐためにWait-for-bgpという機能がある。これはOSPFをIGPに利用している場合の機能。
wait-for-bgpが具体的に何をしているかというとBGPが収束するまでOSPFのcostをMAXにしておくことで、transit routerとして利用されないようにする。
設定としてはmax-metrcのオプションとして設定する。
これを使わない場合はon startup 600等の間の時間指定でmax-metricを仕掛けるような運用になる。
ただしこの時間が適切かどうかというのは状況よりけりなのでチューニングが必須となる。
BGP updateを受け取ってRIB->FIBの更新は実は実装依存でどのタイミングでおこるかは機種による。
またBGPのUPDATEをneighborに送る際にneighborにどの順番で送るかはランダム。
MRAI
BGPにはMinimum Route Advertisement IntervalというBGP Update前にランダム時間待ってBGP Updateの内容をバッファリングしてからまとめて広報する仕組みがあるらしい。無駄なBGP Updateの回数を減らすことでBGPによるCPU負荷を下げたり無駄なフラップをなくす効果がある。デメリットとしてコンバージェンス時間が伸びる。参考 やっかいなのかがwithdraw updateと単純なupdate、また経路切り替え時のupdateでMRAIのランダムウェイトが発生するかは実装ごとに仕様が違うらしい。
Ciscoだとadvertise-intervalというBGP UPDATEの最小送信間隔を設定するコマンドがある。
IOSXRではeBGP peerにたいして最小30秒の待ちが発生するがadvertise-intervalでこの間隔を短くできる。0にすると即座にUPDATEする。
BGP betpath selection
BGPのbestpath selectionはprefixごとに基本的に次のようなアルゴリズムできまる。
code:bestpath selction
// prefixAにたいしての全受信経路を取得
// pathsはFILOな構造。一番最後に受け取った経路からpopされ、一番最初に受け取った経路が最後にpop
paths = get_paths(prefixA)
//一番最後に受け取った経路を取り出す。
bestpath = paths.pop()
// pathsの全経路について比較終了するまで
for paths.length > 0
cmppath = paths.pop()
// cmppathのほうが今のbestpathよりも最適だったらbestpathをcmppathに更新。
if cmppath > bestpath
bestpath = cmppath
具体例
特定のprefix Aに複数の経路 P1, P2, P3がある場合次のようなアルゴリズムでベストパスを決定する。なお経路の受信順番はP1,P2,P3とする。つまりP3が一番新しく、P1が一番古い経路である。
prefix Aの中で最後に受信した新しい順に経路を2つ取得する。今回ではP2,P3となる。
選ばれた経路を比較してより最適な経路を選定する。今回だと例えばP3が最適だとする。
現在の最適経路P3と3番目に新しい経路P1を比較する。今回P1が最適だとする。
全ての経路について比較をしたのでP1がprefixAに対してのベストパスとする。
実はこのやり方だとより小さいMEDを入れたのに比較の順番の関係上MEDが大きい経路が実際にはベストパスになるという問題が経路の受信の順番によっては発生する。そのためこのベストパスの決定アルゴリズムは設定で少し挙動を変えることができる。
Lookingglass
telnet://route-views.routeviews.orgでログイン可能
ただし各ASがどんな経路を広報しているかは自由でわからない。
Leaf-Spin構成にBGPをよく使う理由
フラッティングが発生しないから。
リンクステートプロトコルだとSPFがそれなりのコストになりがちだから。
弱点
自発的なノード発見のメカニズムがない。
トラフィックエンジニアリングがない。
Nexthop
NEXT_HOPはアトリビュートは必須属性であり、UPDATE messageの中で設定される。
iBGPの場合はNexthopの場合自身でアナウンスした経路か、そうでないかで挙動がかわる
自分でoriginateするアップデートはnexthopは自身のインターフェースをセットして広報
自分でoriginateしていないアップデートはnexthopは書き換えない。
受け取ったBGPアップデートはnexthopに到達性があれば自身のRIBにいれる。到達性がなければ有効化しない
これの対策としてどこかでnexthop selfをしてNexthopをAS内の到達性のあるもの書き換える。
またはIGPで外部との接続点となるインターフェースIP(Nexthop)への到達性をあたえる。
eBGPの場合はNexthopを自身のインターフェースIPに書き換える。
eBGPの接続構成にはfirst party nexthopとthird party nexthopと呼ばれる状態がある。
third party nexthop
first form
IX接続で発生しやすいケース。
https://gyazo.com/a7f06b7eab403577e73e17d50b32362f
R1とR3でeBGP接続、R1,R2でiBGP接続しているときR2はR3のIP10.10.1.3をNexthopに設定した経路をR1からiBGPで受け取る。
R2は10.10.1.3への到達性があるので、R1から受け取ったR3をNexthopとして経路をRIBにインストールする。
結果としてR2はPeerを外部ASルーターであるR3とeBGP peeringをしていないのにR3をNexthopとした外部へのルーティングを行う。これはR3からするとPeerをはっていないルーターからトラフィックが流れてくるので気持ち悪い状態。IXだと場合によっては弾かれるかも。このような状態を第一のthrid party nexthopとよぶ。R1でNexthop selfをいれることでR1経由の通信になる。
この状態で起きえる事故として、新規ルーターで既接続IXへの接続の足を増やす際にIXへの新規IFをあげた瞬間に
thried party nexthopが発生して新規ルーターでBGP peerを繋いでないにもかかわらず意図せずトラフィックが流入してしまうケースがある。
このような事故を防ぐためにIXでのpublic peerについてはNexthop selfをしておくことで、新規に足を増やしただけでthrid party nexthopしてしまうのを防げる。この状態の場合は新規ルーターでも別途BGP peeerを張ることによってトラフィックが流れるようになる。
second form
first party nexthop
https://gyazo.com/166bc11cf553a3ea881e31a1c1bf1e8e
R1,R2,R3が共通のネットワークでeBGPを張っている状態。ただしフルメッシュではないのがポイント。
この状態でR1を経由でR2,R3の経路交換をするとR2<->R3の間の通信はすべてR1を経由することになる。
この状態でトラフィック最適化するためにR1でeBGPで経路広報するときにNexthopを書き換えない設定をいれることで
R2からR3、またその逆のNexthopがR1ではなくR2,R3のインターフェースIPとなる。
これによりR2<->R3が直接トラフィックを流す。このような状態をfirst party nexthopと呼ぶ。
IXのルートサーバーのようなマルチリテラルピアリングにこのような構成は利用される。
なお、CiscoやJunos等の機種だとこの1st party nexthopを勝手に行う挙動をとる。
arista EOSだとnexthop unchangedという設定をいれないと1st party nexthopはおこらない。
aggreate, atomic_aggragate attribute
bgp as-path attributeにはaggreate, atomic_aggragate attributeがある。
aggreate attributeにはaggreateを行ったルーターのIDとAS番号がセットされる。どこで集約が発生したがわかる。atomic_aggregate attributeはフラグのようなものであり、このフラグがたったルートは経路集約されて生成されたルートだとわかる。
ちなみにaggreate 経路を広報することはあまり歓迎されていないらしい。
as-pathのas-set不要論
まぁまだ提案レベルなので、
BGP設計
ISP向けのBGP設計
古いが現代でも通用する基本設計方針。
show route xxx exact detail activpath
Protocol nexthop
show route xx terse exct activetate
BGP接続時の留意点
対向からどんな経路が来るかはPeeringDBや先方との連絡で把握しておく
少なくとも最大受信経路数についてはフィルタをしておいたほうがよい。
稀にオペミスでとんでもないprefix数をぶち込んでくることがある。
PeeringDB等で吐く経路数がわかって数も少ないならその経路だけ受け取るようにフィルターも書くとベスト。
初回の接続時は一旦経路は受け取らずに捨てると安全。
BGPの接続自体に問題がないかを事前に安全に確認できる。
臨んだ経路がきちんと来ているかの確認も安全にできる。
特にTransit接続の場合は明示的な経路フィルターを書かないの全部のトラフィックが吸われる可能性がでてくるので注意
送受信で全ての経路をフィルターで落とす設定をいれておく。
peerからくる経路のcommunityやMEDなど余分なものが設定されていないかは見て置く
それらのアトリビュートは特に利用しないならリセットしておくとよい。
広報した経路が先方にどう見えているかはlooking glassで確認するとよい。
大きなキャリアならだいたい持っている。
そもそも経路がきちんと見えるか、変なcommunityが内部で付与されていないかを確認できる。
community制御する場合は付与したcommunityがきちんと付与されているかもみる。
制御communityで意図通りに制御されているかはさすがに信じるしかないが
とくに海外の大手キャリアと接続した際に海外向け通信が大回りになることも考えられる。
ある程度重要なサイトが事前にわかるなら、遅延の計測や戻り経路がどうなっているかを見ておくとよい。
ピアを貼った際のトラフィックの吸い込みは注視。設定ミスっていると思わぬトラフィックの吐き、出しがあるので
とはいえここは完全な事前予測は難しいので、先方との調整でこちらに吐かれる見込みを聞いておくとよい。
他のpeer, transitとのトラフィック影響があるので気にしておくこと。
BGP gracefule restart
bgp再起動時にもフォワーディングを維持するための機能
junosだとdefault disable。neighborごとにも設定可能。ciscoは? 設定するとcapablity通知のため既存peer sessionだと再起動するので注意。
bgp が再起動を伴う際に、対向の相手にはbgpのsession flapが発生する。
結果として不要なルーティングアップデートが走る。
bgp flapは一時的なフォワーディングループやブラックホールを作る可能性がある。
この影響を小さくするための機能がbgp gracefule resetart。
要はbgp sesionが切れてもしばらくFibを維持する機能。
bgp flapに強くなるが本当のbgp session障害のときに迂回が遅れる。
ルーター再起動などのI/F downを伴う障害ならおそらく即時 にwithdrowは発生するとは思う。
挙動
bgp established時に gracefule restart capablityを通知。
この時にrestartにかかると思われるrestart timeも通知。
restart timeはhold timeより短くないといけない。
bgp restartの際にはneihgborから受け取った経路はLoc-RIBに残しておく
これら経路は古い経路としてマークしておく。
指定されたrestart timeの間は本来削除対象だった経路はforwarding tableからの消去はせず転送は継続する。
restart timeを超えると従来通り経路は削除
再bgp establish時にrestart flagでrestartをした旨を伝える。
RouteReflector
iBGPは基本的にはfull meshにしないといけない。
splite horizenの機能で自身がibgpで学んだ経路を他のibgp peerに広報しないため
これ自体はrouting loop防止のため
一定数以上のBGP routerがある場合full mesh設定はbgp neighborが大量に必要になる
full meshにしないとibgp routerは自身の経路を全てのibgp routerに広報できない。
大量のpeerはメモリ,CPUリソースを過剰に消費する。
Clientとなるpeerから受け取ったibgp経路を全てのclient peerにもReflectionするのがRouteReflector
全てのclientに反射するので、送った本人にも経路がくる
RouterReflectorをRR,RouteReflector ClientをRCと表記
要はibgpからsplite horizenの機能を無くした状態
RR-RC構成でフルメッシュではなくスター構成のようなbgp peerの構成に変更できる。
edge となるrouter(RC)はRRにibgp peerを張るだけでよい
RRから各edgeの経路が送られてくる
Originator_ID attribute
Originator_idは経路生成元ルータのrouter id
RRによりルートリフレクトされた経路にOriginator_id attributeが付与される
RCはRRから経路を受け取った際に自身のOriginator_IDが設定された経路は受け取らない。
要は自分が送った経路が自分にきたら破棄する挙動
RRは見境なくclientから経路を受け取ると反射するので
clientが送った経路を、そのままそのclientにも反射している
RC自身が送った経路がRRから即座に返ってくる
これができないとループにつながる
Cluster_ID attribute
RRによりルートリフレクトされた経路にCluster_id attributeが付与される
defaultは自身のbgp router-idがcluster_idとなる。
明示的にcluster_idを設定することもできる。
経路のCluster_Listに自身のCluster_IDが存在すればその経路を無視
これもループ防止のため
正直明示的に設定しなくてもなくてもそこまで問題にならない
2台のRRに1台のRCがそれぞれに経路を広報
RR同士でreflceetor-clientとして接続しあうとループになってしまう
この時にcluster_idが同一なら経路を破棄してくれる
上記のミスしない限りは問題にはならない
RR同士を通常のiBGP peerとして接続しあえば問題なし。
split horizenがあるので
ベストパスセレクションに関与しているアトリビュート
RR-RC構成を接続を維持しながらやめたりする際に影響があるので注意
そもそも経路遷移が難しいのでそんなオペレーションはしないほうがよい。