本文目標:
free5GC 是全世界第一套開源的 5G 核心網路專案,free5GC 遵照 3GPP R15 規格書進行功能開發,目前 free5GC 的貢獻者主要來自交大的師生以及世界各地的 contributor。
free5GC 官方提供兩種安裝方式:
如果想將 free5GC 安裝至你的主機或是虛擬機,可以參考官方文件以及影片教學:
除了安裝至本地的方式以外,讀者也可以使用官方維護的 free5gc-compose 安裝 free5GC,使用 container 的方式安裝可以避免本地開發環境被破壞,設定上也較一般的方法容易。
在 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 位址是由 Internet Assigned Numbers Authority(IANA)分配各個國家與單位,在台灣是由 TWNIC 進行 IP 的管理。
一般來說,IP 可以分成三大類:
範圍從 0.0.0.0 到 127.255.255.255,第一個位元組由 IANA 分配,後面的三個位元組可以自行管理。
假設某單位分配到 Class A IP 為 56.x.x.x,那麼它們一共有 256 x 256 x 256 數量的 IP 可以使用。
範圍從 128.0.0.0 到 191.255.255.255,前兩個位元組由 IANA 分配,後面的兩個位元組可以自行管理。
以交通大學為例,它的 IP 為 140.113.X.,這代表交大一共有 256 x 256 個 IP 能夠使用。
範圍從 192.0.0.0 到 223.255.255.255,前三個位元組由 IANA 分配,最後一個位元組可以自行管理。
前面提到的 Class A|B|C 的可使用數量是理想值,實際情況還要考慮私有 IP(也就是可以用於內部網路的 IP),RFC 1597 所定義的私人網路範圍:
考量到 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)。
前面有提到:
那麼當私人網路的主機需要接入到網際網路該怎麼做呢?假設有 2 組子網路遮罩為 255.255.255.0 的子網路,在沒有 NAT 的情況下,對外的 router 需要保留 500 個外部 I,才能確保所有主機都可以連線至網際網路。
為了解決 IP 數量有限的問題,網路位址轉換(NAT)被提出,功能是當 IP 封包通過防火牆或是 router 時,可以將來源或是目標 IP 改寫(外部網路與私人網路的轉換):
上圖取自 wikipedia。
如此一來,多台內部網路的主機就可以共用一或多個外部網路 IP 囉!
作者補充:
- SNAT 適用於讓內網主機存取外部網路服務的場景,當外部網路服務收到經過 SNAT 處理的封包,它會將 response 送往 NAT Server,這時 NAT Server 會使用該訊息的 sequence number 以及先前 SNAT 轉換紀錄進行比對,在 pre-routing 的階段將 response 的 destination IP 從 NAT Server IP 修改成發出請求的 Client IP。
- 當來自外部網路的請求送至 NAT Server,它會以 destination IP 與 port number 判斷該請求屬於內網的哪一台主機(這個步驟會在 post-routing 處理)並將 destination IP 修改成目標主機的 IP。等到目標主機收到經過 DNAT 處理的請求並準備回應時,因為 source IP 沒有修改的關係(仍時外部網路客戶端的位址),所以能夠直接進行回應。
在 Linux 作業系統上,我們可以使用以下命令去觀察系統的 kernel routing table:
route -n
查詢結果如下:
參考上圖:
如果要新增一個路由表,可以使用 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
要將封包從當前主機送往不同網域下的主機時,我們需要依靠 Router 的幫忙,Router 最主要的用途就是封包轉發。
一般來說,要取得一台 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
Linux kernel 提供了網路封包的過濾機制(netfilter),可以利用 MAC、IP、TCP、UDP 等 L2 至 L4 的資訊進行過濾。
而 iptables 就是一個利用封包過濾機制開發出的工具,它可以幫助我們設定 Linux 主機上的網路資料該如何接收、傳出或是轉送:
上圖取自 https://medium.com/@ebuschini/iptables-and-docker-95e2496f0b45
參考上圖,iptables 有 5 個 chain 和 4 個 table,它們分別是:
而我們使用到的是 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
都是相當複雜的網路工具,實在很難用短短的一篇文章涵蓋這麼多內容!
如果有興趣可以參考鳥哥的教學網站: