JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

BGP:網路之間的路徑向量路由

在一個自治系統內部,路由器會就最短路徑達成共識;但在數萬個自治系統之間,沒有人對任何事達成共識——所以網際網路靠一個奇特、像在傳八卦的通訊協定把它們黏在一起,這個協定宣告的是整條路徑,而不是距離。我們來看看 BGP 究竟是怎麼運作的。

為什麼你已經學過的協定到了邊界就停下來

在路由那一階,你認識了路由器在「一個網路內部」就路徑達成共識的兩種方式:鏈路狀態洪泛(每台路由器都學到整張地圖,再算一次最短路徑)以及距離向量(每台路由器把自己到各目的地的最佳距離告訴鄰居)。兩者都屬於內部閘道協定——IGP,例如 OSPFRIP——而且都共享一個假設:所有路由器都由同一個組織運作、彼此完全信任,而且想要真正最短的那條路徑。

這個假設一到自治系統(AS)的邊緣就碎了。如前兩篇所示,整個網際網路大約由七萬個各自獨立運作的網路組成,靠轉送與對等協議在交換中心縫合起來。Comcast 不信任 Vodafone 的路由器,看不到 Vodafone 的內部地圖,更絕對不想免費替 Vodafone 載運流量。在 AS 之間,路由不再是關於距離,而是關於金錢、合約與信任。

路徑向量:宣告整條路線,而不是距離

邊界閘道協定(BGP)是把整個跨網域網際網路撐在一起的那一個協定,而它屬於第三種路由方式,叫做路徑向量。回想單純距離向量的麻煩:一台路由器只會跟鄰居說「我能以成本 4 抵達 10.0.0.0/8」,鄰居根本不知道這個 4 是怎麼來的。當鏈路斷掉時,一條舊路線的虛假希望可能永遠彈來彈去——就是數到無限的問題。路徑向量的修法是:宣告一條路線會經過的「整串 AS 清單」。

所以一則 BGP 宣告說的不是一個光禿禿的數字,而是:「要抵達前綴 203.0.113.0/24,請走這條 AS 路徑:AS65010、接著 AS65002、再接著 AS65001。」AS 路徑是 BGP 的核心。它是這則宣告已經穿越過的每一個網路所留下的麵包屑足跡,帶著兩項超能力。第一,迴圈偵測變得很簡單:如果一台路由器在路徑中看到自己的 AS 編號,就把這條路線丟掉——迴圈永遠形不成,沒有數到無限的問題。第二,這條路徑是制定政策的原料,而政策正是下一篇的全部重點。

AS65001 owns 203.0.113.0/24 and announces it outward:

  AS65001 --> AS65002 : prefix 203.0.113.0/24, AS-path = [65001]
  AS65002 --> AS65010 : prefix 203.0.113.0/24, AS-path = [65002 65001]
  AS65010 --> AS65020 : prefix 203.0.113.0/24, AS-path = [65010 65002 65001]

Each AS PREPENDS its own number before passing the route along.
If AS65002 ever saw 65002 already in a path, it would reject it (loop).
前綴由它的擁有者宣告;每個 AS 把自己接在最前面,所以 AS 路徑往左生長,記錄下整趟旅程。

注意 BGP 宣告的是什麼:不是主機、不是 IP 位址,而是前綴——以 CIDR 表示法寫成的位址區塊,例如 203.0.113.0/24。一個 AS 宣告「這些前綴可以透過我抵達」,而優良的網路營運者會把許多小前綴聚合成少數幾個大前綴,以免全球路由表爆炸。BGP 之所以用前綴溝通,是因為網際網路有數十億台裝置,但值得拿來「傳八卦」的位址區塊只有數十萬個。

一個 BGP 裡的兩種 BGP:eBGP 把路線載進來,iBGP 把它散播出去

這裡有個讓每個新手都絆倒的細節。BGP 以兩種模式運作,在線路上看起來一模一樣,卻解決相反的問題——這就是 eBGP/iBGP 之分。外部 BGP(eBGP)跑在「不同」AS 的邊界路由器之間;它就是那種跨越邊界、學習鄰居 AS 能抵達哪些前綴的八卦傳遞。內部 BGP(iBGP)跑在「同一個」AS 內部的路由器之間,唯一的工作是把 eBGP 學到的東西分享出去,讓 AS 裡的每台路由器都知道有哪些外部目的地。

為什麼不乾脆讓 IGP 來載這些資訊?因為一個 AS 可能會聽到數十萬個外部前綴,你絕不會想把這一切全倒進 OSPF——OSPF 是為了少數幾條內部鏈路而調校的。所以分工很乾淨:IGP 知道怎麼在實體上抵達 AS 內部的每台路由器(內部地圖),而 iBGP 知道有哪些外部前綴存在、每一個又是從哪台邊界路由器進來的。一個要送往遠方前綴的封包,由 iBGP 交給正確的出口邊界路由器,再由 IGP 算出實際抵達那裡的內部跳數。

一條路線如何被學到、被選中、被安裝

BGP 路由器不洪泛、也不廣播。兩台路由器開啟一條普通的 TCP 連線(BGP 跑在 TCP port 179 上,倚靠它的可靠性,讓 BGP 本身永遠不必重傳)並成為對等夥伴。它們一開始會把各自完整的最佳路線集合互相倒給對方,之後就只送增量更新——「出現了這個新前綴」「那個前綴被撤回了」——沒事的時候保持安靜。以下是一條路線從對等夥伴傳來後的完整一生:

  1. 接收。一個對等夥伴送來一則 UPDATE:一個前綴(例如 198.51.100.0/24)、它的 AS 路徑,以及一捆下一篇要拆解的屬性——區域偏好、AS 路徑長度、MED 等等。
  2. 套用匯入政策。路由器讓這條路線通過篩選器:這條路徑我到底允不允許使用?要不要降級它?來自客戶的路線會被加分,而一條我本來就不該聽到的路線在這裡就被丟掉。
  3. 比較並決定。路由器現在手上可能握有來自不同對等夥伴、通往同一前綴的好幾條路線。它執行 BGP 決策流程——先比最高的區域偏好,再比最短的 AS 路徑,接著是一連串平手判定,最後以最低的 MED 收尾——並只把恰好一條冠軍封為最佳路線。
  4. 安裝。這條唯一的最佳路線被寫進路由器的轉送表,於是未來通往該前綴的封包,會經由最長前綴比對被配對,並送往正確的方向。
  5. (有選擇地)再宣告。路由器把這條冠軍路線告訴它的其他對等夥伴——但只告訴匯出政策允許的那些,並在送出時把自己的 AS 編號接在路徑最前面。

這個迴圈裡有兩件事值得畫線。BGP 對每個對等夥伴只宣告它那條「唯一的最佳路線」,而不是它知道的每個選項——所以全球視野是由每個 AS「選定的意見」拼出來的,而不是原始真相。而再宣告會被政策篩選,這正是一個 AS 拒絕變成「替自己賺不到錢的流量當免費轉送管道」的方法。我們會用下一整篇來講第 3 步的順序為什麼是這樣排的。

無預設路由區,以及 BGP 為什麼脆弱

你家的路由器過著簡單的日子:它只知道少數幾個本地位址,其餘一律推向你 ISP 那邊的一條預設路由。網際網路核心的大型路由器沒辦法這樣偷懶。它們待在無預設路由區裡——對地球上每一個前綴都握有一條 BGP 路線,因為沒有任何「上游」可以把不知道的東西推上去。如今這張全球路由表承載著遠超過九十萬條 IPv4 前綴,而一台核心路由器必須把它們全部儲存並搜尋。所謂身處網際網路的正中央,字面上的意思就是這個。

這一切威力都立在一個令人不安的事實上:傳統 BGP 相信別人告訴它的話。它沒有任何內建機制能證明一個 AS 真的擁有它所宣告的前綴。這份信任是三種著名故障模式的根源。一條時好時壞的鏈路可能讓一條路線反覆出現又消失——路由擺動——而每一次翻轉都會以更新的形式向外擴散,所以營運者會「抑制」那些持續不穩定的路線,以阻止這種震盪蔓延出去。

更嚴重的是 前綴劫持:某個 AS 宣告一個它並不擁有的前綴,通常還是個更具體(更長)的前綴,而由於最長前綴比對永遠偏好更具體的那條路線,原本要送往該區塊的流量就悄悄流向了錯誤的網路。它的親戚「路由洩漏」則發生在一個 AS 把本該保密的路線再宣告出去時——例如把一個供應商的路線傳給另一個供應商,意外把自己當成免費轉送提供出去。兩者都源自缺少政策或缺少認證,也都真的把現實中的服務打掛過。