安裝 free5GC 也能學習網路概念! - ianchen0119/Introduce-to-5GC GitHub Wiki

在 free5GC 的官方教學中有一個很重要的部分:

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
sudo systemctl stop ufw

透過上面所列出的命令將運行核心網路的機器變成一台 Linux router,這樣核心網路才有能力轉送來自 UE 的 uplink data。 對於沒有網路概念的人來說可能會難以理解上面這些設定的目的,為此,筆者特別整理了一篇文章簡單的介紹網路概念。

進入正題

複習:IP 與 netmask

IP 位址是由 Internet Assigned Numbers Authority(IANA)分配各個國家與單位,在台灣是由 TWNIC 進行 IP 的管理。 一般來說,IP 可以分成三大類:

Class A(255.0.0.0)

範圍從 0.0.0.0 到 127.255.255.255,第一個位元組由 IANA 分配,後面的三個位元組可以自行管理。 假設某單位分配到 Class A IP 為 56.x.x.x,那麼它們一共有 256 x 256 x 256 數量的 IP 可以使用。

Class B(255.255.0.0)

範圍從 128.0.0.0 到 191.255.255.255,前兩個位元組由 IANA 分配,後面的兩個位元組可以自行管理。 以交通大學為例,它的 IP 為 140.113.X.,這代表交大一共有 256 x 256 個 IP 能夠使用。

Class C(255.255.255.0)

範圍從 192.0.0.0 到 223.255.255.255,前三個位元組由 IANA 分配,最後一個位元組可以自行管理。

私有網路

前面提到的 Class A|B|C 的可使用數量是理想值,實際情況還要考慮私有 IP(也就是可以用於內部網路的 IP),RFC 1597 所定義的私人網路範圍:

  • Class A(10.X.X.X)
  • Class B(172.16.0.0 - 172.31.255.255)
  • Class C(192.168.0.0 - 192.168.255.255)

Classless Inter-Domain Routing (CIDR)

考量到 IPv4 的數量有限,Class C 對於大部分使用者來說仍是過多,因此無類別域間路由 CIDR 的概念被提出了。 以 10.10.1.32/27 為例:

00001010.00001010.00000001.00100000

如果要驗證一個 IP 是否屬於這個網路下,我們可以將 IP 也轉為二進制,並且檢查兩者的前 27 的位元是否相同。 換句話說,10.10.1.32/27 這個網路範圍內一個共有 2^5 - 2 個 IP 可供分配,需要扣除 2 的原因是要預留網路位址(5 個位元皆為 0)與廣播位址(5 個位元皆為 1)。

NAT (Network Address Translation)

前面有提到:

  • IPv4 的數量有限
  • 部分 IP 為私人網路專用

那麼當私人網路的主機需要接入到網際網路該怎麼做呢?假設有 2 組子網路遮罩為 255.255.255.0 的子網路,在沒有 NAT 的情況下,對外的 router 需要保留 500 個外部 I,才能確保所有主機都可以連線至網際網路。 為了解決 IP 數量有限的問題,網路位址轉換(NAT)被提出,功能是當 IP 封包通過防火牆或是 router 時,可以將來源或是目標 IP 改寫(外部網路與私人網路的轉換):

image

上圖取自 wikipedia

  • SNAT:當封包從內網主機送往 Router,帶有 NAT 功能的 Router 會將當前為內網 IP 的 Source IP 修改成內部持有的外部 IP。
  • DNAT:當封包從外部網路送回 Router,Router 會根據先前的紀錄將目前為外網 IP 的 Destination IP 轉換為內網 IP。

如此一來,多台內部網路的主機就可以共用一或多個外部網路 IP 囉!

觀察路由表

在 Linux 作業系統上,我們可以使用以下命令去觀察系統的 kernel routing table:

route -n

查詢結果如下:

image

參考上圖:

  • 第一條為預設路由,所有要送往外部網路的封包都會經由外部的 Gateway(10.10.0.1 的主機)送出。
  • 第二條路由表示在該區域網路下,送往其他封包的主機會從 local 送出。
  • 第三條路由表示 Gateway 主機的路由,其優先權(metric)較第二條路由更高。

如果要新增一個路由表,可以使用 route add

sudo route add -net 0.0.0.0 gw 192.168.0.33 netmask 128.0.0.0 dev ens01

相對的,如果要移除建立好的路由表,可以使用 route del

sudo route del -net 0.0.0.0 gw 192.168.0.33 netmask 128.0.0.0 dev ens01

Linux kernel 的封包轉送

要將封包從當前主機送往不同網域下的主機時,我們需要依靠 Router 的幫忙,Router 最主要的用途就是封包轉發。 一般來說,要取得一台 Router 可以透過兩種方式:

  1. 直接購買網路硬體公司生產的 Router,並且設定它的路由表
  2. 利用軟體功能實作 Router 機制

Linux kernel 就內建了封包轉送的能力,要開啟該功能需要在開機時下達以下命令:

sudo sysctl -w net.ipv4.ip_forward=1

此外,也可以修改 /etc/sysctl.conf 讓系統每次啟動時都套用這項設定:

$ sudo vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
$ sudo sysctl -p

iptables

Linux kernel 提供了網路封包的過濾機制(netfilter),可以利用 MAC、IP、TCP、UDP 等 L2 至 L4 的資訊進行過濾。 而 iptables 就是一個利用封包過濾機制開發出的工具,它可以幫助我們設定 Linux 主機上的網路資料該如何接收、傳出或是轉送:

image

上圖取自 https://medium.com/@ebuschini/iptables-and-docker-95e2496f0b45

參考上圖,iptables 有 5 個 chain 和 4 個 table,它們分別是:

  • Chain: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING
  • Table: filter, nat, mangle, raw
    • 優先級:raw > mangle > nat > filter

而我們使用到的是 nat 的功能,以本篇文章最初提到的指令:

sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE

來看,它其實就是新增了一個 SNAT(MASQUERADE)規則,使 UE 送來的封包可以透過核心網路進行轉送(參考上圖 POSTROUTING 的部分),轉送的過程中會修改 UE 的 Source IP。 而 sudo systemctl stop ufw 則是關閉防火牆以避免轉送的過程中受到干擾。

作者的話:對 iptables 有興趣的話推薦看看這篇文章,它對每一個 Chain 和 Table 的使用說明還蠻清楚的~

總結

本篇文章大致解釋了為何每次在啟動 free5GC 時都需要下達那些命令,實際上,route 以及 iptables 都是相當複雜的網路工具,實在很難用短短的一篇文章涵蓋這麼多內容! 如果有興趣可以參考鳥哥的教學網站:

References