ネットワーク

Cisco IOS BGP 設定と経路制御のまとめ

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ステップ。

  1. BGPプロセスを自AS番号で起動し、ルータIDを固定する
  2. neighbor コマンドで対向のIPアドレスと相手のAS番号を指定する
  3. 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 が有効でないと表示できない。

経路属性と経路選択

ベストパス選択順序

同じプレフィックスを複数経路で受けた場合、上から順に比較して決着した時点で確定する。

  1. WEIGHT が大きい(Cisco独自、ローカルのみ)
  2. LOCAL_PREF が大きい
  3. 自機がローカル生成した経路(network / redistribute / aggregate)
  4. AS_PATH が短い
  5. ORIGIN が IGP(i) < EGP(e) < incomplete(?)の順で優先
  6. MED が小さい(既定では同一AS由来の経路同士のみ比較)
  7. eBGP経由 が iBGP経由 より優先
  8. ネクストホップまでのIGPメトリックが小さい
  9. eBGPではセッションが最も古い経路
  10. ルータIDが小さい
  11. ネイバーアドレスが小さい

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番が到達していないケースが大半。次の順に確認する。

  1. ping で対向のピアアドレスに到達できるか(ループバックピアなら送信元指定で)
  2. ACLやゾーンポリシーで179番が落ちていないか
  3. 両側の remote-as とピアアドレスの組み合わせが一致しているか
  4. ルータ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 で増えるため、規模が大きくなるならルートリフレクタを前提に設計する。

-ネットワーク