Cisco IOS / IOS-XE でのBGP-4の設定と確認手順をまとめる。eBGP・iBGPのピア確立から経路広報、属性による経路制御、フィルタリングまでを一通り扱う。
前提/環境
以下の環境で確認した。
R1# show version | include Version
Cisco IOS XE Software, Version 17.03.04a
Cisco IOS Software [Amsterdam], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 17.3.4a, RELEASE SOFTWARE (fc4)
検証構成は次のとおり。R1とR2の間がeBGP、R2とR3の間がiBGPとなる。
198.51.100.0/24 192.0.2.0/24
| |
[ R1 ] [ R2 ] [ R3 ]
AS 65001 AS 65002 AS 65002
Lo0 192.168.255.1 Lo0 192.168.255.2 Lo0 192.168.255.3
| | | |
+--- 203.0.113.0/30 -+ +--- 10.0.23.0/24 ----+
(eBGP) (iBGP)
AS番号はプライベートAS(64512〜65534)を使用。R1は198.51.100.0/24を、R3は192.0.2.0/24をそれぞれBGPに広報する。
BGPの基本動作
eBGPとiBGP
BGPはTCP 179番でピアを張るパスベクタ型のプロトコル。異なるAS間のピアをeBGP、同一AS内のピアをiBGPと呼び、動作が次のように異なる。
eBGP iBGP
AS番号 異なる 同じ
既定のTTL 1(直接接続前提) 255
AD値 20 200
ネクストホップ 自分に書き換わる 受け取った値のまま
再広報 iBGP/eBGP両方へ可 他のiBGPピアへは不可
最後の「iBGPで学習した経路は他のiBGPピアに再広報しない」がBGPのスプリットホライズンで、AS内でiBGPフルメッシュまたはルートリフレクタが必要になる理由。
ピアのステート遷移
ピアは Idle → Connect → Active → OpenSent → OpenConfirm → Established の順に遷移する。Establishedになって初めて経路(UPDATE)が交換される。
Idle 起動直後。TCPセッションを開始する前
Connect TCPの3ウェイハンドシェイク待ち
Active TCP接続に失敗し、再試行している状態
OpenSent OPENメッセージを送信し、相手のOPEN待ち
OpenConfirm OPENを受理し、KEEPALIVE待ち
Established 確立。UPDATEを交換できる
ActiveとIdleを行き来している場合はTCP 179番が通っていないか、AS番号・ルータIDの設定ミスを疑う。
eBGPの設定
eBGPピアを張る手順は次の3ステップ。
- BGPプロセスを自AS番号で起動し、ルータIDを固定する
- neighbor コマンドで対向のIPアドレスと相手のAS番号を指定する
- network コマンドで自分が広報する経路を登録する
R1側の設定。
R1(config)# router bgp 65001
R1(config-router)# bgp router-id 192.168.255.1
R1(config-router)# bgp log-neighbor-changes
R1(config-router)# neighbor 203.0.113.2 remote-as 65002
R1(config-router)# neighbor 203.0.113.2 description to-R2-eBGP
R1(config-router)# network 198.51.100.0 mask 255.255.255.0
R2側の設定。eBGPとiBGPの両方を持つ。
R2(config)# router bgp 65002
R2(config-router)# bgp router-id 192.168.255.2
R2(config-router)# bgp log-neighbor-changes
R2(config-router)# neighbor 203.0.113.1 remote-as 65001
R2(config-router)# neighbor 192.168.255.3 remote-as 65002
R2(config-router)# neighbor 192.168.255.3 update-source Loopback0
R2(config-router)# neighbor 192.168.255.3 next-hop-self
ピアが確立するとログが出る。bgp log-neighbor-changes を入れておくと切り分けが早い。
R1#
*Aug 26 10:02:11.115: %BGP-5-ADJCHANGE: neighbor 203.0.113.2 Up
network コマンドの挙動
network はOSPFのように「インタフェースを有効化する」コマンドではなく、ルーティングテーブルに存在する経路をBGPテーブルに登録するコマンド。マスクまで完全一致する経路がルーティングテーブルに無いと広報されない。
R1(config-router)# network 198.51.100.0 mask 255.255.255.0
mask を省略するとクラスフルマスク(この例では /8)として解釈され、意図した経路が出ていかない。省略しないこと。スタティックルートやconnectedで該当プレフィックスを持たせておく必要がある。
MD5認証
ISPとのeBGPピアでは認証を求められることが多い。両側で同じ文字列を設定する。
R1(config-router)# neighbor 203.0.113.2 password <任意のパスワード>
iBGPの設定
iBGPは直接接続である必要がないため、冗長化のためループバック宛にピアを張るのが一般的。その場合、送信元アドレスをループバックに固定する。
R3(config)# router bgp 65002
R3(config-router)# bgp router-id 192.168.255.3
R3(config-router)# neighbor 192.168.255.2 remote-as 65002
R3(config-router)# neighbor 192.168.255.2 update-source Loopback0
R3(config-router)# network 192.0.2.0 mask 255.255.255.0
update-source を入れないと、パケットの送信元が出力インタフェースのアドレス(10.0.23.3)になり、対向のneighbor設定(192.168.255.3)と一致せずピアが上がらない。またループバック同士に到達性を持たせるIGP(OSPF等)かスタティックが別途必要になる。
next-hop-self が必要な理由
eBGPで受けた経路をiBGPピアに渡すとき、ネクストホップは書き換えられない。R3から見るとネクストホップが自AS外の203.0.113.1になり、到達性がないため経路が無効になる。
R3# show ip bgp
...
Network Next Hop Metric LocPrf Weight Path
* i 198.51.100.0/24 203.0.113.1 0 100 0 65001 i
*> 192.0.2.0/24 0.0.0.0 0 32768 i
先頭に > (best)が付いていない。R2側で next-hop-self を設定するとネクストホップがR2のループバックに書き換わり、有効になる。
R3# show ip bgp
...
Network Next Hop Metric LocPrf Weight Path
*>i 198.51.100.0/24 192.168.255.2 0 100 0 65001 i
*> 192.0.2.0/24 0.0.0.0 0 32768 i
確認方法
ピアの状態
まず show ip bgp summary を見る。最右列が数値ならEstablished、文字列(Idle/Active等)ならまだ確立していない。
R1# show ip bgp summary
BGP router identifier 192.168.255.1, local AS number 65001
BGP table version is 5, main routing table version 5
2 network entries using 496 bytes of memory
2 path entries using 272 bytes of memory
2/2 BGP path/bestpath attribute entries using 560 bytes of memory
1 BGP AS-PATH entries using 24 bytes of memory
BGP using 1352 total bytes of memory
BGP activity 2/0 prefixes, 2/0 paths, scan interval 60 secs
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
203.0.113.2 4 65002 12 13 5 0 0 00:07:41 1
最右列の 1 は「受信したプレフィックス数」。ここが 0 のまま、あるいは Active のままなら経路交換ができていない。
BGPテーブル
R1# show ip bgp
BGP table version is 5, local router ID is 192.168.255.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
x best-external, a additional-path, c RIB-compressed,
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.0.2.0/24 203.0.113.2 0 0 65002 i
*> 198.51.100.0/24 0.0.0.0 0 32768 i
行頭の記号の意味を押さえておく。* は有効な経路、> はベストパス、i(Next Hopの前)はiBGP経由で学習した経路。行末の i はORIGIN属性がIGP(network コマンド由来)であることを示す。再配布した経路は ? (incomplete)になる。
特定プレフィックスの詳細
属性を確認するときはプレフィックスを指定する。どの属性でベストパスが選ばれたかが分かる。
R1# show ip bgp 192.0.2.0
BGP routing table entry for 192.0.2.0/24, version 5
Paths: (1 available, best #1, table default)
Not advertised to any peer
Refresh Epoch 1
65002
203.0.113.2 from 203.0.113.2 (192.168.255.2)
Origin IGP, metric 0, localpref 100, valid, external, best
rx pathid: 0, tx pathid: 0x0
ルーティングテーブルへの反映
R1# show ip route bgp
...
Gateway of last resort is not set
192.0.2.0/24 is subnetted, 1 subnets
B 192.0.2.0 [20/0] via 203.0.113.2, 00:10:14
AD値が 20 なのでeBGP由来。iBGP由来なら 200 になる。
ピアごとの送受信経路
フィルタが意図どおり効いているかは、ピア単位で確認する。
R1# show ip bgp neighbors 203.0.113.2 routes
R1# show ip bgp neighbors 203.0.113.2 advertised-routes
R1# show ip bgp neighbors 203.0.113.2 received-routes
received-routes はフィルタ適用前の経路を見るコマンドで、後述の soft-reconfiguration inbound が有効でないと表示できない。
経路属性と経路選択
ベストパス選択順序
同じプレフィックスを複数経路で受けた場合、上から順に比較して決着した時点で確定する。
- WEIGHT が大きい(Cisco独自、ローカルのみ)
- LOCAL_PREF が大きい
- 自機がローカル生成した経路(network / redistribute / aggregate)
- AS_PATH が短い
- ORIGIN が IGP(i) < EGP(e) < incomplete(?)の順で優先
- MED が小さい(既定では同一AS由来の経路同士のみ比較)
- eBGP経由 が iBGP経由 より優先
- ネクストホップまでのIGPメトリックが小さい
- eBGPではセッションが最も古い経路
- ルータIDが小さい
- ネイバーアドレスが小さい
WEIGHT
Cisco独自の属性で、設定した機器の中だけで有効。他のルータには伝わらない。既定値は0、自機生成の経路は32768。1台のルータでアウトバウンドの経路を寄せたいだけならこれが最も手軽。
R1(config-router)# neighbor 203.0.113.2 weight 100
LOCAL_PREF
AS内のすべてのiBGPピアに伝播する属性。既定100で、値が大きい方が優先される。AS全体でどの出口を使うかを揃えたい場合はこれを使う。route-mapで受信時に付ける。
R1(config)# ip prefix-list PL-CUSTOMER seq 5 permit 192.0.2.0/24
R1(config)# route-map SET-LOCALPREF permit 10
R1(config-route-map)# match ip address prefix-list PL-CUSTOMER
R1(config-route-map)# set local-preference 200
R1(config-route-map)# exit
R1(config)# route-map SET-LOCALPREF permit 20
R1(config-route-map)# exit
R1(config)# router bgp 65001
R1(config-router)# neighbor 203.0.113.2 route-map SET-LOCALPREF in
末尾の空の permit 20 が重要。route-mapは暗黙のdenyで終わるため、これが無いと192.0.2.0/24以外の経路がすべて落ちる。
適用後、ソフトリセットして反映を確認する。
R1# clear ip bgp 203.0.113.2 soft in
R1# show ip bgp 192.0.2.0
BGP routing table entry for 192.0.2.0/24, version 6
Paths: (1 available, best #1, table default)
Not advertised to any peer
Refresh Epoch 2
65002
203.0.113.2 from 203.0.113.2 (192.168.255.2)
Origin IGP, metric 0, localpref 200, valid, external, best
rx pathid: 0, tx pathid: 0x0
AS_PATH プリペンド
自AS番号を重ねて広報し、経路を意図的に長く見せる。相手AS側の設定を変えられない場合に、インバウンドのトラフィックを別経路に寄せる手段として使う。
R2(config)# route-map PREPEND-OUT permit 10
R2(config-route-map)# set as-path prepend 65002 65002
R2(config-route-map)# exit
R2(config)# router bgp 65002
R2(config-router)# neighbor 203.0.113.1 route-map PREPEND-OUT out
R1側で見るとAS_PATHが伸びている。
R1# show ip bgp
...
Network Next Hop Metric LocPrf Weight Path
*> 192.0.2.0/24 203.0.113.2 0 0 65002 65002 65002 i
プリペンドは3回程度までが目安。極端に長くすると、AS_PATHの長さでフィルタしている上流で破棄される場合がある。
MED
隣接ASに対して「こちらの入口を使ってほしい」と伝える属性。値が小さい方が優先される。アウトバウンドのroute-mapで set metric として設定する。
R2(config)# route-map SET-MED permit 10
R2(config-route-map)# set metric 50
R2(config-route-map)# exit
R2(config)# router bgp 65002
R2(config-router)# neighbor 203.0.113.1 route-map SET-MED out
MEDは隣接ASより先には伝播しない。また既定では同じASから来た経路同士でしか比較されないため、複数ASから受けた経路を横断で比較したい場合は次を入れる(挙動が変わるので影響範囲を確認してから)。
R1(config-router)# bgp always-compare-med
R1(config-router)# bgp deterministic-med
経路フィルタ
プレフィックスリスト
受け取る経路・広報する経路を絞る基本形。ISP接続では最低限インバウンドに入れておく。
R1(config)# ip prefix-list PL-IN seq 5 permit 192.0.2.0/24
R1(config)# ip prefix-list PL-IN seq 10 deny 0.0.0.0/0 le 32
R1(config)# router bgp 65001
R1(config-router)# neighbor 203.0.113.2 prefix-list PL-IN in
le / ge はプレフィックス長の範囲指定。0.0.0.0/0 le 32 は「すべての経路」を意味する。
AS_PATHフィルタ
特定のASを経由した経路だけを受ける。正規表現で書く。
R1(config)# ip as-path access-list 10 permit ^65002$
R1(config)# router bgp 65001
R1(config-router)# neighbor 203.0.113.2 filter-list 10 in
^65002$ は「隣接AS 65002が生成した経路のみ」。^$ は自AS生成の経路、.* はすべてを表す。
受信最大数の制限
対向の設定ミスでフルルートが流れ込むのを防ぐ。閾値の80%で警告ログ、上限超過でピアを落とす。
R1(config-router)# neighbor 203.0.113.2 maximum-prefix 100 80
ハマりどころ
clear ip bgp * を打たない
ハードリセットはセッションを切断し、経路が全断する。ポリシー変更の反映はソフトリセットで足りる。
R1# clear ip bgp 203.0.113.2 soft in
R1# clear ip bgp 203.0.113.2 soft out
ソフトリセットのインバウンドはルートリフレッシュ機能(現行IOSは既定で有効)を使う。対向が非対応の場合のみ、受信経路を保持するために次の設定が要る。メモリを消費するので必要なピアだけに入れる。
R1(config-router)# neighbor 203.0.113.2 soft-reconfiguration inbound
ステートがActiveから進まない
TCP 179番が到達していないケースが大半。次の順に確認する。
- ping で対向のピアアドレスに到達できるか(ループバックピアなら送信元指定で)
- ACLやゾーンポリシーで179番が落ちていないか
- 両側の remote-as とピアアドレスの組み合わせが一致しているか
- ルータIDが重複していないか
R1# ping 192.168.255.3 source Loopback0
R1# show tcp brief
TCB Local Address Foreign Address (state)
7FB2C1A8 192.168.255.1.179 192.168.255.3.20143 ESTAB
eBGPをループバックで張るとき
eBGPは既定TTLが1のため、ループバック同士でピアを張ると届かない。ホップ数を明示するか、ttl-securityを使う。
R1(config-router)# neighbor 192.168.255.2 ebgp-multihop 2
R1(config-router)# neighbor 192.168.255.2 update-source Loopback0
経路がBGPテーブルにあるのにルーティングテーブルに乗らない
ネクストホップに到達性がないケースがほとんど。show ip bgp でベストパスの > が付いているかを見て、付いていなければネクストホップのアドレスに対して show ip route を打つ。iBGPなら next-hop-self の入れ忘れを疑う。
もう一つはRIB-failureで、行頭に r が付く。同じプレフィックスをよりAD値の低いプロトコル(スタティック等)で既に持っている場合に起きる。
R1# show ip bgp rib-failure
Network Next Hop RIB-failure RIB-NH Matches
192.0.2.0/24 203.0.113.2 Higher admin distance n/a
iBGPで経路が伝わらない
iBGPで学習した経路は他のiBGPピアに再広報されない。AS内に3台以上のBGPルータがあるならフルメッシュにするか、ルートリフレクタを構成する。
R2(config-router)# neighbor 192.168.255.3 route-reflector-client
フルメッシュに必要なピア数は n(n-1)/2 で増えるため、規模が大きくなるならルートリフレクタを前提に設計する。