跳转至

Advanced Start

对应于官方文档的 Build free5GC from scratch

实验配置

  • 宿主机: Ubuntu24.04LTS
  • 试验平台: 使用 VMware Workstation 创设三台虚拟机, Ubuntu 20.04 Server
    • ubuntu: ubuntu@ubuntu
      • 备用
    • free5gc: free5gc@free5gc
      • free5gc 移动网络仿真器
    • ueransim: ueransim@ueransim
      • ueransim 模拟器框架

网络配置:

  • ubuntu:
    • ens34: 动态IP,没自己绑定, 172.16.122.129
    • 已翻墙: ~/.config/mihomo 下运行 ./clash-linux
    • ping www.baidu.com/1.1.1.1/8.8.8.8都可以
    • 已配置SSH,跟github互联
  • free5gc:
    • ens34: 静态IP,自己设定, 172.16.122.131
    • 已翻墙: ~/.config/mihomo 下运行 `./clash-linux
    • ping www.baidu.com/1.1.1.1/8.8.8.8都可以
    • 已配置SSH,跟github互联
  • ueransim:
    • ens34: 静态IP,自己设定, 172.16.122.133
    • 已翻墙: ~/.config/mihomo 下运行 `./clash-linux
    • ping www.baidu.com/1.1.1.1/8.8.8.8都可以
    • 已配置SSH,跟github互联

连接方式: 在宿主机新开3个CLI窗口

实验流程

参考的是: CSDN 传送门

Tip

笔者已经很多年没看CSDN这种小破站了,但是这篇写的确实还不错

笔者的主体实验流程根据上述CSDN文档,但也存在一些问题,因此重新梳理一下:

配置实验机器

  1. 如何配置机器:

    1. 系统下载与安装: 传送门
    2. Server端 的 “科学上网”: 传送门
    3. 与github的SSH互联: 无须多言
  2. 网络配置:

    1. 按照上面“实验配置”中的网络参数:
      1. free5gc: host-only interface = ens34, 静态IP, 自行设定
      2. ueransim: host-only interface = ens34, 静态IP, 自行设定
    2. 确保:
      1. free5gc 和 ueransim 能够被宿主机终端以SSH访问, 测试:
      2. free5gc 和 ueransim 之间可以互相ping通
        Bash
        1
        2
        3
        4
        # 在 [email protected]
        ping 172.16.122.133
        # 在 [email protected]
        ping 172.16.122.131
        

过程解析与汇总

Danger

这一部分是笔者的“踩坑帖”,类似于cheat sheet

还包含了常见问题的处理方式

(1) 如何改变一台设备的主机名

Bash
1
2
sudo vim /etc/hostname
sudo vim /etc/hosts

(2) 如何改变端口的IP

人为设定成静态IP

Bash
1
2
cd /etc/netplan
sudo vim 00-installer-config.yaml

改变内容, 举个例子:

Bash
1
2
3
4
5
6
7
8
9
# This is the network config written by 'subiquity'
network:
    ethernets:
        ens32:
          dhcp4: true
        ens33:
          dhcp4: no # prev: true
          addresses: [172.16.122.131/24] # prev: nothing this line
    version: 2

让配置生效:

Bash
1
2
sudo netplan try
sudo netplan apply

随后检查:

Bash
1
2
ifconfig # check interfaces
route -n # check routing and gateway

(3) 确定 kernel 版本:

Bash
1
uname -r

(4) go 的常见报错处理:

网络资源获取失败

package golang.org/x/sys/unix: unrecognized import path "golang.org/x/sys/unix" (https fetch: Get https://golang.org/x/sys/unix?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)

通常是由于网络连接问题导致无法访问 golang.org 的资源。这种情况在某些网络环境中较为常见,尤其是在无法直接访问 Google 服务的地区

解决方式 1:

Bash
1
2
3
4
5
6
7
8
mkdir -p $GOPATH/src/golang.org/x
cd $GOPATH/src/golang.org/x
git clone [email protected]:golang/sync.git
git clone [email protected]:golang/crypto.git
git clone [email protected]:golang/sys.git

# downloads
go get -u github.com/sirupsen/logrus
Why 1 works

这种方法绕过了 Go 在网络上自动下载依赖包的机制,而是通过 Git 直接克隆仓库到本地的 $GOPATH/src 目录中。这样做可以避免网络连接问题和 DNS 解析问题

为什么需要放在 $GOPATH/src/golang.org/x 目录中:

Go 的包管理机制依赖于 包的导入路径与文件系统路径之间的对应 。例如,包 golang.org/x/sys 的源代码应该位于 $GOPATH/src/golang.org/x/sys 目录中

通过将克隆的仓库放在正确的目录结构中,Go 可以正确地找到并使用这些包

解决方式 2:

Bash
1
2
3
4
5
export GO111MODULE=on
export GOPROXY=https://goproxy.cn

# downloads
go get -u github.com/sirupsen/logrus
Why 2 works
  1. 设置 GO111MODULE=on,确保 Go 使用 Go Modules 来管理依赖包。这是从 Go 1.11 开始引入的包管理系统,旨在更好地管理项目依赖
  2. 设置 GOPROXY=https://goproxy.cn 指定了一个代理服务器 (go的国内CDN) 来下载依赖包, 国内可访问; 可以绕过可能存在的网络限制或 DNS 解析问题,确保依赖包可以被成功下载

free5gc主机网络设置

Bash
1
2
3
4
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o [DATA_NETWORK_INTERFACE] -j MASQUERADE
sudo iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1400
sudo systemctl stop ufw
  1. 上述配置每次关机后都会自动失去效果, 因此每当free5gc开机一次,就要单独运行上述指令
  2. [DATA_NETWORK_INTERFACE] 指的是可访问外部网络的接口, 在我这里指的是 ens33

(5) ping 的接口

Bash
1
2
3
4
5
6
# default interface
ping baidu.com
# specific interface
ping -I uersimtun0 baidu.com
# setting default interface
sudo ip r add default dev uesimtun0 # 系统将所有未指定特定路由的网络流量发送到 uesimtun0 设备

使用方式

本地终端SSH连接

  1. free5gc 开机并登陆
    1. 宿主机终端SSH连接上: ssh [email protected]
  2. ueransim 开机并登陆
    1. 宿主机终端SSH连接上: ssh [email protected]

free5gc的启动项

Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 系统允许将接收到的数据包转发到其他网络接口
sudo sysctl -w net.ipv4.ip_forward=1
# 常用于共享 Internet 连接或在Private Net中提供访问Public Net的能力
sudo iptables -t nat -A POSTROUTING -o [DATA_NETWORK_INTERFACE] -j MASQUERADE
# MSS max=1400, 解决因 MTU 限制导致的网络连接问题,确保数据包在通过网络时不会被分片
sudo iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1400
# 关闭防火墙
sudo systemctl stop ufw
# 系统将允许所有数据包在网络接口之间转发, 不进行任何过滤或阻拦
sudo iptables -I FORWARD 1 -j ACCEPT
Danger
  1. 上述配置每次关机后都会自动失去效果, 因此每当free5gc开机一次,就要单独运行上述指令
  2. [DATA_NETWORK_INTERFACE] 指的是可访问外部网络的接口, 在我这里指的是 ens33

free5gc的用前测试

(1) 检测配置信息是否被原文件覆盖: 如有覆盖,改成自己设备信息

详见 CSDN 中的 free5gc 网络参数配置

Bash
1
2
3
cat ~/free5gc/config/amfcfg.yaml
cat ~/free5gc/config/smfcfg.yaml
cat ~/free5gc/NFs/upf/build/config/upfcfg.yaml

(2) 执行单元测试:

Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
cd ~/free5gc
# test for each function
./test.sh TestRegistration
./test.sh TestGUTIRegistration
./test.sh TestServiceRequest
./test.sh TestXnHandover
./test.sh TestDeregistration
./test.sh TestPDUSessionReleaseRequest
./test.sh TestPaging
./test.sh TestN2Handover
./test.sh TestNon3GPP
./test.sh TestReSynchronisation
./test_ulcl.sh -om 3 TestRegistration

(3) 两个设备相互ping:

Bash
1
2
3
4
# 在 [email protected]
ping 172.16.122.133
# 在 [email protected]
ping 172.16.122.131

后续实验

依据 free5gc & UERANSIM 的集成测试

完结撒花🎉