BGP

**邊界閘道器協定**（英語：Border Gateway Protocol，縮寫：BGP）是網際網路上一個核心的去中心化自治路由協定。它通過維護 IP 路由表或「字首」表來實現自治系統（AS）之間的可達性，屬於向量路由協定。BGP 不使用傳統的內部網路關協定（IGP）的指標，而使用基於路徑、網路策略或規則集來決定路由。因此，它更適合被稱為向量性協定，而不是路由協定。

大多數 ISP 必須使用 BGP 來與其他 ISP 建立路由連接（尤其是當它們採取內送流量備援容錯機制連接時）。因此，即使大多數網際網路使用者不直接使用它，但是與 7 號信令系統 —— 即通過 PSTN 的跨供應商核心回應設定協定相比，BGP 仍然是網際網路最重要的協定之一。特大型的私有 IP 網路也可以使用 BGP。例如，當需要將若干個大型的 OSPF（開放最短路徑優先）網路進行合併，而 OSPF 本身又無法提供這種可延伸性時。使用 BGP 的另一個原因是其能為內送流量備援容錯機制的單個或多個 ISP（RFC 1998）網路提供更好的冗餘。

## 歷史

BGP 是為了取代外部閘道器協定（EGP）協定而建立的，其允許執行一個完全分散的路由系統，從 ARPANET 模型的核心路由系統過渡到包括 NSFNET 骨幹網及其相關區域網路的分散系統。這使得網際網路成為一個真正的分權制度。自 1994 年以來，第四版的 BGP 在網際網路上使用，所有以前的版本現在都已過時且不可用。第 4 版中主要的增強功能是通過支援無類別域間路由和路由聚合來減少路由表的大小。第 4 版（BGP-4）是在早期的 RFC 1771 第 4 版的基礎上編纂，通過 20 多個草案修改，最終在 2006 年 1 月通過，形成 RFC 4271。RFC 4271 版本糾正了一些錯誤，澄清模糊之處，帶來了更接近工業級應用標準的 RFC 行業慣例。

IPv6 BGP 在 1995 年被 RFC 1883 定義，在 1998 年的 RFC 2283 中有所改進。它使得 BGP-4 能夠支援諸如 IPv4、IPv6 等一系列的位址類型，也被稱為多協定 BGP（Multiprotocol BGP，MP-BGP）。

## BGP 執行

BGP 的鄰居關係（或稱通信對端 / 對等實體，peer）是通過人工組態實現的，對等實體之間通過 TCP 埠 179 建立對談交換資料。BGP 路由器會周期地傳送 19 位元組的保持存活（keep-alive）訊息來維護連接（預設周期為 60 秒）。在各種路由協定中，只有 BGP 使用 TCP 作為傳輸層協定。

同一個 AS 自治系統中的兩個或多個對等實體之間執行的 BGP 被稱為 iBGP（Internal/Interior BGP）。歸屬不同的 AS 的對等實體之間執行的 BGP 稱為 eBGP（External/Exterior BGP）。在 AS 邊界上與其他 AS 交換資訊的路由器被稱作邊界路由器（border/edge router），邊界路由器之間互為 eBGP 對端。在 Cisco IOS 中，iBGP 通告的路由距離為 200，優先級比 eBGP 和任何內部網路關協定（IGP）通告的路由都低。其他的路由器實現中，優先級順序也是 eBGP 高於 IGP，而 IGP 又高於 iBGP。

iBGP 和 eBGP 的區別主要在於轉發路由資訊的行為。例如，從 eBGP peer 獲得的路由資訊會分發給所有 iBGP peer 和 eBGP peer，但從 iBGP peer 獲得的路由資訊僅會分發給所有 eBGP peer。所有的 iBGP peer 之間需要全互聯。

BGP 也可以執行於 VPN 之上，使得位置上相隔較遠的站點也能安全地交換路由資訊。

### 協定擴充協商

在 peer 的握手過程中，通過 OPEN 訊息來協商所支援的協定擴充，例如多協定擴充（多協定 BGP）、各種故障恢復模式等。

## BGP 路由聯通性和路由學習

同一 AS 內如果有多個路由器參與 BGP 路由，則它們之間必須組態成全連通的網狀網格結構：任意兩個路由器之間都必須組態成對等實體。這樣做會帶來擴充方面的問題，因為所需要的（TCP）連接數是（BGP）路由器數量的平方。為緩減這個問題，BGP 支援兩種選項：route reflectors （RFC 4456）和 confederations（RFC 5065）。下面討論了在全連通的 IBGP 網格中的基本更新處理（UPDATE）。

### 基本更新過程

NLRI（Network Layer Reachability Information 網路層可達資訊）。

一個 BGP 路由器可以從多個鄰居接收 NLRI 更新資訊，並且將（自己擁有的）NLRI 資訊通告給自己的鄰居們（與收到 NLRI 更新訊息的鄰居可以不一致）。BGP 維護自己的主路由表，稱為 Loc-RIB（本地路由資訊庫），注意與路由器的主路由表的區別。針對每一個鄰居，當前 BGP 的行程（可以理解成本地 BGP 實體）維護一個 Adj-RIB-In（鄰接路由資訊庫，入站），記錄從該鄰居收到的 NLRI 訊息；還要維護一個 Adj-RIB-Out（出站），記錄從本地 BGP 實體傳送給該鄰居的 NLRI 資訊。

在上一段中提到的 Loc-RIB, Adj-RIB-In 和 Adj-RIB-Out 的具體實現（這些 RIB 的物理儲存和結構）都由不同的廠商在實現 BGP 時自行決定。雖然本地路由器上往往通過管理指令查詢這些 RIB，但 BGP 路由器並不關心其他 BGP 路由器是如何實現這些 RIB 的。具體實現方法可以不同，大家往往把兩個 Adj-RIBs 和 loc-RIB 存在同一個資料結構中，依靠每個 RIB 表項後附加的額外資訊來區分。BGP 行程可以從附加資訊中得知很多資訊，例如哪些表項是屬於為某個特定鄰居準備的 Adj-RIBs，Loc-RIB 表項是否有資格被遞交給本地路由器的路由表管理行程，逐鄰接路由選擇行程收到的 Loc-RIB 是否符合策略。

如果 Loc-RIB 表項有資格被提交給本地路由器的路由表管理行程，BGP 會把自認為最佳的多條路由遞交給主路由表行程。所遞交的 BGP 路由是否被選用，則是完全由上述行程的具體實現決定的。例如，如果從路由器的本地埠獲知某一字首與本路由器直接相連，則通常會選擇直接轉發的路由。只要直連的埠還在正常工作，去向該目的字首的 BGP 路由就不會被真正納入路由表（主路由表）。如果直連埠無法正常工作，並且不存在優先級較高的路由，則 Loc-RIB 路由表項就會被載入主路由表。之前有一個常見的誤解，認為 BGP 傳送各種策略。實際上 BGP 只傳送資訊，基於這些資訊，BGP 行程可以做決策。有些資訊顯然是用於決策的，例如 communities 和 multi-exit discriminators （MED）。

### 路由選擇

在選擇合適的 NLRI 加入 loc-RIB 時，BGP 標準規定了很多決策準則。評價 NLRI 的第一個準則就是判斷它的下一跳屬性必須是可達（reachable 或 resolvable）。下一跳可達還可以做如下解釋：在本路由器的主路由表中，有一條活動可用的路由，指向下一跳位址所在的字首。換句話說，必須有一條活動可用的路由去向下一跳。

其次，針對每個鄰居，本地 BGP 行程可以採用不同的標準和廠商自訂的原則決定哪些路由可以加入該鄰居對應的 Adj-RIB-in。鄰居可以把去向某個目的地的多條路由發給你，but the first level of preference is at the neighbor level。對於某個目的地，只有一條路由會被加入所謂的 Adj-RIB-In（註：在本地，針對每個鄰居都有一個 Adj-RIB-In）。如果鄰居復原了任何路由，該 BGP 行程還要負責從 Adj-RIB-In 中刪除對應的條目（如果有）。

如果某個 Adj-RIB-In 發生變化，原生的主 BGP 行程將判斷對應的鄰居通告的新路由是否比 Loc-RIB 中現有路由更好。如是，將進行替換。如果某個路由被鄰居復原，而且沒有別的路由指向相應的目的地，則需要從 Loc-RIB 中刪除相應的路由表項，並且 BGP 不再將該表項遞交給主路由表管理器。如果 OSPF 或其他非 BGP 協定也沒能為本路由器找到一條指向該目的地的路由，則相應的路由表項將從主路由表中刪除。

### 逐鄰居選擇

如果某條路由資訊（NLRI）來自一個本域內的對等實體（IBGP），BGP 標準規定的第一條準則就是檢查 LOCAL\_PREFERENCE（以下簡稱 LOCAL\_PREF）屬性。如果來自鄰居（同一 AS 域）的多條 IBGP 路由指向同一目的字首，則選擇具有最高 LOCAL\_PREF 的那條路由。如果恰巧有多條路由都具有相同的最高 LOCAL\_PREF，則執行下一條準則。標準中規定 LOCAL\_PREF 為第一準則，一旦確定了下一跳（NEXT\_HOP）可達，Cisco 和其他幾個廠商首先考慮了本地路由器定義的 WEIGHT 值（該屬性僅在本地路由器有效，不會通過 BGP 擴散），即選擇具有最大 WEIGHT 的路由。

可以通過本地組態或控制軟體能夠操縱 LOCAL\_PREF、WEIGHT 以及其他的準則。標準中並未定義這樣的操縱，但在實際產品中廣泛存在。例如，BGP 選擇行程（selection process）並不直接使用 COMMUNITY 屬性（見下面）。但 BGP 鄰居行程（neighbor process）可以根據手動組態的規則來設定 LOCAL\_PREF 或別的 factor 的屬性值。例如，當 COMMUNITY 屬性值滿足某種模式匹配準則（或者說具有某種模式）時，BGP 鄰居行程就可以修改 LOCAL\_PREF 的值。如果某條路由是從相鄰 AS 的某個對等實體（BGP）獲知的，per-neighbor BGP process 會根據原生的策略規則計算該路由的 LOCAL\_PREF，並且與來自同一鄰居的其他路由的 LOCAL\_PREF 比較大小。

如果不考慮廠商自己對規則的修改，在 BGP 協定中，per-neighbor level 上依次執行下面的準則，直至選出唯一的一條路由：

1. 選擇具有最短 AS\_PATH 的路徑。AS\_PATH 是由到達通告中的目的地所必須經過的 AS 號組成。例如：AS1-AS2-AS3 比 AS4-AS5-AS6-AS7 短。
2. （如果多條路由具有相同的 AS\_PATH 長度）選擇具有最小 ORIGIN 值的路由。
3. （如果多條路由具有相同的 ORIGIN）選擇具有最小 MED 值的路由。

## BGP 組態錯誤事件

BGP 組態對於網際網路流量路由至關重要，組態錯誤，經過 BGP 的自動擴散，會導致網際網路流量紊亂甚至中斷。

* AS 7007 事件
* 2018 年 11 月 14 日，尼日尼亞網際網路服務商 MainOne 由於組態錯誤，將直連 Google 的網路路由泄漏到中國電信的網路，然後通過中國電信的 BGP 傳播到其他 ISP 中，導致一部分北美連接 Google 服務的流量通過迂迴的 AS 路徑傳輸。MainOne 其後承認出現錯誤。
* 2019 年 6 月 6 日，甲骨文的一名安全分析師發現瑞士資料中心代管商 Safe Host 的 AS 泄露了 7 萬個路由記錄到中國電信的網路，並通過中國電信的 BGP 傳播，導致部分歐洲的網際網路流量繞進了中國電信的網路，這個組態錯誤至少延續了 2 個小時。
* 2019 年 6 月 25 日，美國網際網路運營商 Verizon 將其客戶 Allegheny Technologies 泄漏的來自 DQE Communications BGP 最佳化器的路由傳播到其他 ISP 中，導致北美部分地區的流量通過 DQE Communications 傳輸，導致網路癱瘓。
* 2021 年 Facebook 當機事件：2021 年 10 月 4 日，由於組態錯誤，Facebook 的 DNS 權威伺服器位址通過 BGP 復原，導致使用者和 Facebook 的其他服務的伺服器無法根據 DNS 獲得相應的伺服器位址，導致 Facebook 的網路服務中斷了 6~7 小時。

## 參考文獻

## 外部連結

* LinkRank University of California, Los Angeles 製作的 BGP 路由圖形化工具
* BGP Routing Resources （頁面存檔備份，存於網際網路檔案館）（包含一個專門的章節在 BGP & ISP Core Security （頁面存檔備份，存於網際網路檔案館））
* BGP 表統計 （頁面存檔備份，存於網際網路檔案館）