圖解 IP Address:從定址原理到路由機制
前言
每一次瀏覽器發出請求、每一次手機打開 App、每一次視訊通話的封包在網路上流動,背後都依賴著一套精密的定址系統,這套系統必須在全球數十億台設備中,精確地找到正確的目的地。這套系統的核心就是 IP Address(網際網路協定位址)。
IP 位址有兩個版本:IPv4 是 1970 年代設計、 至今仍是網路骨幹的版本;IPv6 則是 1990 年代為了應對 IPv4 耗盡而設計的繼任者,讓每台冰箱、每個門鈴感測器都能擁有自己的全球唯一位址。這篇筆記會涵蓋位址的結構、全球分配體系、私有網路與公網如何共存、封包如何在路由器之間找到目的地。
IP Address:網路世界的定址基礎
IP Address 可以看作分配給每一台參與網路通訊的設備的數字標籤,路由器依據這個標籤來決定封包應該往哪個方向轉發。在我之前寫的 OSI 七層模型筆記 中有提到,IP 位址工作在 L3(Network Layer),負責跨網路的邏輯定址。與 L2 的 MAC 位址不同的是,MAC 位址是硬體層面的實體位址,只在同一個網段內有意義;IP 位址是邏輯位址,不限於同一個網段,負責在不同網路之間識別裝置並路由封包。
IP 位址有兩個版本。IPv4 是 32 位元的位址,以四個十進位數字表示(例如 192.168.1.1),總共約 4.3 億個可能的位址——這個數字在 1980 年代設計者的眼中已經遠超需求,但最終在智慧型手機和 IoT 時代被證明遠遠不夠。IPv6 是 128 位元的位址,以十六進位分組表示(例如 2001:db8::1),可容納約 3.4×10³⁸ 個位址,徹底解決了耗盡問題。這篇筆記的重心在 IPv4,理解 IPv4 的設計與演進是掌握現代網路定址體系的基礎;IPv6 的格式與共存機制會在後面獨立說明。
IPv4 的地址格式與歷史演進
32 位元的地址結構
一個 IPv4 位址是一個 32 位元的二進位數字。為了讓人類便於閱讀,它被拆成四個 8-bit 的群組(稱為 Octet),每個 Octet 轉換成十進位,用 . 隔開,這種表示法稱為點分十進位(dotted-decimal notation)。每個 Octet 的範圍是 0~255(2⁸ = 256 種值),因此一個 IPv4 位址看起來像 192.168.1.100。
32 個 bits 總共能表達 2³² ≈ 43 億個唯一地址。1970 年代 IPv4 被設計出來時,全世界只有少數幾百台電腦連接在 ARPANET 上,43 億這個數字看起來綽綽有餘。沒有人預見到幾十年後每個人都會隨身攜帶多部智慧型手機、平板,家裡每個電器都可能連網,雲端服務商同時管理數百萬台虛擬機器。
地址的組成:Network Portion 與 Host Portion
一個 IP 位址在概念上分為兩個部分:Network Portion(網路部分) 與 Host Portion(主機部分)。可以把它想像成電話號碼的結構:區碼(area code)識別的是「哪個地區」,局號加分機識別的是「哪個特定用戶」。IP 位址中的網路部分決定「這台設備屬於哪個網路」,主機部分決定「該網路中的哪台設備」。
這個階層式設計是路由效率的關鍵。路由器不需要知道全世界每一台設備的精確位置,只需根據封包目標 IP 的「網路前綴」決定下一跳方向,再由目標網路內的本地裝置負責最後一段精細投遞,就像快遞公司先按郵遞區號分揀到對應城市,再由當地配送員按門牌號碼投遞。
不過這個設計成立的前提是:32 個 bits 中,哪些 bits 屬於網路部分、哪些屬於主機部分,必須有一個清楚定義的邊界。而第一個系統性回答這個問題的方案,就是 Classful Addressing。
早期的分配方式:Classful Addressing
早期(1981 年,RFC 791)的 IPv4 採用 Classful Addressing 的思路解決這個問題:根據 IP 位址的最高幾個位元(leading bits) 來決定它屬於哪個「類別(Class)」,每個 Class 有固定的網路/主機部分邊界。
-
Class A 的最高位元固定為
0,因此第一個 Octet 的位元模式從00000001(1)到01111110(126)。以10.0.0.1為例:它的第一個 Octet 是00001010,最高位元是0,所以是 Class A。Class A 的網路邊界在第 8 個 bit,即前 8 bits 是網路部分,後 24 bits 是主機部分,Subnet Mask 為255.0.0.0(/8)。整個10.x.x.x空間就是一個 Class A 網路,最多容納 16,777,214 台主機。全球只有 128 個 Class A 區塊,它們最初分配給大型機構和早期網際網路的核心單位。 -
Class B 最高兩位元固定為
10,第一 Octet 範圍 128~191。以172.16.0.1為例:第一個 Octet10101100,前兩位元是10,確認為 Class B。網路邊界在第 16 個 bit,Subnet Mask255.255.0.0(/16),每個 Class B 網路最多容納 65,534 台主機,全球 16,384 個 Class B 區塊,適合中型組織。 -
Class C 最高三位元固定為
110,第一 Octet 範圍 192~223。以192.168.1.1為例:第一個 Octet11000000,前三位元是110,確認為 Class C。網路邊界在第 24 個 bit,Subnet Mask255.255.255.0(/24),每個 Class C 網路只有 254 個可用主機位址,但全球有超過 200 萬個 Class C 區塊可分配,適合小型網路。 -
Class D(前四位元
1110,第一 Octet 224~239)保留給 Multicast 用途:一次將封包發送給一組設備,不分配給一般主機。 -
Class E(前四位元
1111,240~255)保留給實驗性研究使用,從未正式投入生產。值得注意的是,127.0.0.0/8雖然落在 Class A 的數值範圍內,但整個區塊完整保留給 Loopback(這也是表格中 Class A 範圍從 1 開始、不含 127 的原因,之後的特殊地址章節會詳細說明)。
Subnet Mask:明確劃定網路邊界
看到上面那張表中每個 Class 都有一個對應的 Default Subnet Mask,這個 Subnet Mask 正是用來明確指出 IP 位址中哪些 bits 屬於網路部分的工具。Subnet Mask 是一個 32 位元的數字,結構非常固定:前段為連續的 1(對應網路部分),後段為連續的 0(對應主機部分),中間不能穿插。
要從 IP 位址中提取網路位址,只需要將 IP 與 Subnet Mask 做 AND 運算。以 192.168.1.100 搭配 255.255.255.0 為例:
IP: 11000000.10101000.00000001.01100100 (192.168.1.100)
Mask: 11111111.11111111.11111111.00000000 (255.255.255.0)
AND: 11000000.10101000.00000001.00000000 (192.168.1.0) ← 網路位址
結果 192.168.1.0 就是這台設備所在的 Network Address(網路位址)。同一個 /24 網路內所有設備做 AND 運算,結果都會是 192.168.1.0,這正是路由器用來判斷「這台設備是否和我在同一個網路」的方法。
Subnet Mask 與 CIDR 前綴表示法其實代表完全相同的資訊:255.255.255.0 就是 /24(24 個 1 位元),255.255.0.0 就是 /16,255.0.0.0 就是 /8。CIDR 前綴表示法更簡潔,也順帶引出了下一個問題:如果可以自由指定前綴長度,而不侷限在 /8、/16、/24,整個地址分配的效率會不會大幅改善?
CIDR:彈性的現代分配方案
Classful Addressing 的致命缺陷
Classful Addressing 的問題在於粒度太粗,因為它只提供三種實際可用的尺寸:/8(約 1,677 萬個主機)、/16(約 6.5 萬個主機)、/24(254 個主機)。這三個固定尺寸在現實需求面前顯得極度僵化。
假設某個中型公司需要容納 1,000 台設備。Class C 的 /24 只有 254 個可用 IP,完全不夠;那就只能申請 Class B 的 /16,得到 65,534 個可用 IP。但公司只需要 1,000 個,剩餘的 64,534 個地址白白浪費——浪費率高達 98.5%。更嚴重的是,全球只有 16,384 個 Class B 區塊。1990 年代初,需要 300 到幾千個 IP 的公司統統往 Class B 擠,這些區塊被迅速耗盡。整個 Classful 體系正在以驚人的速度燒掉 IPv4 有限的地址空間。解決方案在 1993 年以 RFC 1519 的形式出現,這就是 CIDR。
前綴表示法與任意位元分割
CIDR(Classless Inter-Domain Routing)移除了 Class 的概念,允許網路/主機的分割點落在 32 個 bits 中的任意位置。表示方式是 IP/前綴長度,例如 192.168.1.0/24、10.0.0.0/22、172.16.0.0/12。
回到剛才的 1,000 台主機問題:用 CIDR 申請一個 /22 區塊——主機部分有 32-22 = 10 個 bits,可容納 2¹⁰ = 1,024 個地址,扣除保留的 2 個(Network Address 和 Broadcast Address),剩 1,022 個可用 IP。幾乎完美對應需求,浪費幾乎可以忽略不計。這種任意前綴長度的彈性,就是 CIDR 的核心創新:分割點可以落在 bit 22、bit 18、bit 27,完全根據實際需求裁切。
Network Address 與 Broadcast Address
在任何一個 CIDR 區塊中,有兩個特殊地址永遠保留,無法分配給實際設備。Network Address(網路位址) 是主機部分 bits 全為 0 的地址,代表「這個網路本身」,是網路的識別符。Broadcast Address(廣播位址) 是主機部分 bits 全為 1 的地址,發送到這個地址的封包會被轉送給網路內所有設備。
以 192.168.1.0/24 為例:主機部分有 8 個 bits,共 256 個地址(2⁸)。192.168.1.0 是 Network Address(保留),192.168.1.255 是 Broadcast Address(保留),實際可分配給設備的是 192.168.1.1 到 192.168.1.254,共 254 個。
可用主機數 = 2^(32-N) - 2
例如 /24 = 2⁸ - 2 = 254,/22 = 2¹⁰ - 2 = 1,022,/30 = 2² - 2 = 2(常用於點對點連線)。
常用 CIDR 區塊速查表
CIDR 的各個前綴長度對應不同的 Subnet Mask 和可用主機數量,以下是開發和維運中最常見的幾個區塊:
/32 是一個特殊情況,主機部分有 0 個 bits,代表「精確的單一主機位址」。在路由規則或防火牆規則中,/32 用來精確匹配一個特定 IP,不多不少。而 /0(未列在表中)則是完全相反的另一個極端,前綴長度為 0 代表「匹配所有 IP」,這就是路由表中的預設路由(Default Route),也就是「如果沒有更具體的路由條目,就走這條路」的意思,路由機制章節會再深入說明。
以 VPC 子網路劃分為例
CIDR 在雲端基礎設施設計中是每天都在用的工具。以 AWS VPC 為例,假設建立了一個 10.0.0.0/16 的 VPC:/16 前綴意味著前 16 個 bits(即前兩個 Octet:10.0)是這個 VPC 的固定網路識別符,剩下的 16 bits(後兩個 Octet)是可供 VPC 內部自由分配的空間,總共 2¹⁶ = 65,536 個 IP,涵蓋範圍 10.0.0.0 到 10.0.255.255。
接著可以用 /24 把這個空間切成多個子網路:10.0.1.0/24 代表以 24 bits 作為網路識別:前三個 Octet 10.0.1 指定了這個特定子網路在 VPC 內的身份,只有最後一個 Octet(8 bits)留給子網路內的個別主機,也就是 10.0.1.1 到 10.0.1.254。
可以把 /16 的 VPC 想像成一個「社區」,每個 /24 子網路就是社區裡的一條「街道」。10.0.1.0/24(Web 伺服器)、10.0.2.0/24(資料庫)、10.0.3.0/24( 內部服務)是三條在同一個社區(10.0.x.x)內的不同街道,各自有獨立的路由規則(Route Table)、安全群組(Security Group)和網路 ACL,實現精細的存取控制邊界。
公有 IP 與私有 IP
前面我們知道 IPv4 只有 43 億個地址,而且 Classful Addressing 浪費了大量的空間。但即使 CIDR 提高了效率,43 億個地址終究是有限的,那全球的 IP 地址是如何分配和管理的呢?
全球地址分配體系:IANA → RIR → ISP
IPv4 位址空間的全球分配有一套嚴格的層級體系。最頂端是 IANA(Internet Assigned Numbers Authority),負責管理整個 IP 位址空間的頂層分配,保留特殊用途地址,並將大塊地址空間分配給五個大區的 RIR(Regional Internet Registry,區域網際網路登記機構):ARIN 負責北美、RIPE NCC 負責歐洲和中東、APNIC 負責亞太地區(台灣屬於 APNIC 的管轄範圍)、LACNIC 負責拉丁美洲、AFRINIC 負責非洲。RIR 再將地址段分配給各國的 ISP,由 ISP 最終分配給企業和個人用戶。
ISP(Internet Service Provider,網際網路服務供應商)是提供你網路連線服務的公司。台灣常見的 ISP 包括中華電信、台灣大哥大、遠傳電信。當家裡申請網路時,實際上就是向這些 ISP 購買連線服務,並從他們那裡取得一個公有 IP 地址(或動態地從他們的 IP 池中分配一個)。
私有地址:保留給內網的專屬空間
有一個問題讓我第一次思考到時覺得很有趣:如果全球的公有 IP 地址有限,而且都被分配給了各個 ISP 和機構,那家裡的筆電、手機這些設備是怎麼取得 IP 的?難道公有 IP 足夠多到可以讓每一台家用設備都有一個專屬的公有位址?
答案是否定的。大多數設備並沒有自己的公有 IP。RFC 1918 定義了三個永久保留為「私有用途」的 IP 範圍,這些地址永遠不會在公網上路由,可以在任何私有網路中自由重複使用:
10.0.0.0/8(約 1,677 萬個地址)172.16.0.0/12(約 104 萬個地址)192.168.0.0/16(約 6.5 萬個地址)
這些私有範圍在 IP 空間分配時就被切割保留,不進入 IANA 的公有分配池。因為私有地址永遠不在公網路由,兩個完全不同的家庭都可以使用 192.168.1.x,毫無衝突, 這些私有 IP 只需要在各自的網路內唯一即可,就像兩棟不同大樓都可以有「3 樓 301 室」,彼此互不干擾。這也解答了前言裡的問題。
公有 IP 絕對不會落在私有地址範圍內。如果從 ISP 那裡拿到的 IP 是 10.x.x.x 或 192.168.x.x,那一定是搞錯了。ISP 只分配真正的公有 IP,私有地址由各自的路由器管理。
靜態 IP 與動態 IP
ISP 在分配公有 IP 時有兩種模式。動態 IP(Dynamic IP) 是最常見的家庭用戶方案:ISP 維護一個 IP 位址池,每次連線(或定期輪換)時從池中取一個可用的 IP 分配,不同時段可能拿到不同的地址。同一個 IP 地址這個月可能是你的,下個月可能分配給了鄰居。這讓 ISP 能用比客戶數量少得多的 IP 同時服務所有用戶。靜態 IP(Static IP) 則是固定分配,每次連線都是同一個 IP,通常需要額外的費用,是架設對外服務的必要條件——想讓外部用戶總是能找到你的伺服器,就必須有一個固定不變的地址。
那如果對外提供服務的裝置拿到的是動態的公有 IP 會發生什麼事呢?假設在家 裡架了一台 Home Server,今天的公有 IP 是 203.x.x.x,但路由器重連之後 IP 變成了 210.x.x.x,所有原本指向舊 IP 的連線全部失效。這時的解法是 DDNS(Dynamic DNS):每次 IP 變更時,路由器上的客戶端程式自動更新一個域名(例如 myhome.ddns.net)的 DNS 記錄,讓用戶永遠透過域名連接,而不是直接用 IP。
需要澄清的是,靜態/動態的概念在公有 IP 和私有 IP 這兩個層面都存在,但語境不同。對於公有 IP,靜態vs動態是指 ISP 是否給你固定的 IP。對於家庭網路內的私有 IP,設備可以動態地向路由器的 DHCP 服務申請(每次開機可能拿到不同的內網 IP),也可以靜態設定(手動指定一個固定的私有 IP)。舉例來說,家裡的 Home Server 除了需要固定的公有 IP(或 DDNS),同樣應該設定固定的私有 IP(例如 192.168.1.100),否則路由器的 Port Forwarding 規則(「把外部連進來的 80 port 轉發給 192.168.1.100:80」)在 Home Server 重啟後拿到不同的內網 IP 時就會失效。
那內網裝置是如何自動取得私有 IP 的呢?這就是 DHCP 的工作。
DHCP:IP 地址的自動配發機制
DHCP(Dynamic Host Configuration Protocol) 是設備加入網路時自動取得 IP 配置的機制。在有 DHCP 服務的情況下,設備不需要手動設定任何網路參數,一切由協定自動完成。
整個過程遵循 DORA 四步驟:設備一進入網路,就向 255.255.255.255(有限廣播)發送 Discover 廣播(此時它的來源地址填 0.0.0.0,因為還沒有 IP)。網路上的 DHCP Server 收到後,回應一個 Offer,包含它準備提供的 IP 位址和租約期限。設備確認後廣播一個 Request(「我選擇這個 Offer」),DHCP Server 最後發出 Acknowledge 正式確認配發。整個過程通常在幾百毫秒內完成。
DHCP 配發的不只是 IP 位址,而是一整套網路配置:IP 地址 + Subnet Mask(告訴設備自己在哪個子網路)、Default Gateway(預設閘道)(路由器的 IP,讓設備知道送往外部的封包要交給誰)、DNS Server IP(讓設備能做域名解析)。在大多數家庭網路中,路由器同時扮演 DHCP Server(負責分發私有 IP 給內網設備)和 NAT Gateway(負責將私有 IP 轉換為公有 IP 以連接網際網路)兩個角色。
DHCP 是一個值得單獨深入探討的協定,這裡只介紹它與 IP 地址分配的關聯。之後會有一篇單獨的 DHCP 筆記涵蓋完整的協定細節。
NAT:讓私有地址連上網際網路
現在我們知道內網裝置拿到的是私有 IP,而私有 IP 不在公網上路由。但我的筆電明明就是透過 Wi-Fi 在瀏覽網頁,這中間是怎麼發生的?答案是 NAT(Network Address Translation)。
NAT 運行在路由器上,核心機制是維護一張連線追蹤表(Connection Tracking Table)。當筆電(192.168.1.2:54321)向 Google 發出請求時,路由器攔截封包,把來源地址從私有 IP:Port 替換成自己的公有 IP:Port(例如 203.x.x.x:40001),此步驟稱為 SNAT(Source NAT),同時在追蹤表中記錄 192.168.1.2:54321 ↔ 203.x.x.x:40001 的對應關係。封包送出後,Google 只看到公有 IP,回應封包送回 203.x.x.x:40001,路由器查詢追蹤表,反向映射回 192.168.1.2:54321,再轉送給筆電。
至於從外部主動發起連線到內部設備,例如在家架 Web Server,需要額外設定 DNAT / Port Forwarding:告訴路由器「凡是連入公有 IP 的 80 port,都轉送給內部的 192.168.1.100:80」。若沒有這條規則,外部發起的連線在路由器的追蹤表裡找不到對應條目,路由器不知道要交給哪台內部設備,只能拒絕或丟棄封包。這也是家用路由器天然扮演「防火牆」角色的原因——NAT 的有狀態追蹤機制讓未經主動請求的入站連線無法穿透。在雲端環境中,EC2 Instance 只有 VPC 內的私有 IP,對外服務由 Load Balancer 或 NAT Gateway 代理,正是同樣的架構模式。
NAT 雖然延緩了 IPv4 耗盡的危機,但它破壞了網際網路原本「端對端透明(end-to-end transparency)」的設計哲學,這個哲學要求兩端直接通訊,中間路由器只轉送封包而不修改內容。NAT 的存在讓 FTP、VoIP、P2P 等協定的實作複雜化(因為這些協定有時在封包 payload 裡攜帶 IP 地址,NAT 必須深入應用層才能正確替換)。此外,連線追蹤表是有狀態的資料結構,在高流量場景下可能成為瓶頸。