5Gのコアネットワークをパブリッククラウド上に構築

# free5GCとは
オープンソースのモバイル5Gのコアネットワーク実装プロジェクト。主なコントリビュータは台湾の國立交通大學。

https://www.free5gc.org/



# 環境
Alibaba Cloud/ECSとAWS/EC2のUbuntu 18.04へインストールしてみた。 仕様を確認するとハードウエアは下記が必要らしいので、AlibabaCloudの**ecs.t5-lc1m2.large**とAWSの**t2.medium**を採用。 インストール手順は同じ。ストレージは160GBとあるけどインストールするだけならAlibabaCloudデフォルトの40GBあれば余裕でAWSデフォルト8GBでも行ける。
Ubuntu20.04でも行けるかもしれないが、18.04はaptで指定のカーネルバージョンに変えられるので18.04のほうが楽。

```
- Hardware
    - CPU: Intel i5 processor
    - RAM: 4GB
    - Hard drive: 160G
    - NIC card: 1Gbps ethernet card

- Hardware recommended
    - CPU: Intel i7 processor
    - RAM: 8GB
    - Hard drive: 160G
    - NIC card: 10Gbps ethernet card
```

# インストール
## 必要なパッケージインストール
apt upgradeするとkernelバージョンが上がりすぎてしまうのでここでは省略。apt upgradeを実行した場合は後述の指定カーネルで起動するように適宜grubの設定を。

```
# apt -y update
# apt -y install mongodb wget git gcc cmake autoconf libtool pkg-config libmnl-dev libyaml-dev
```

## カーネル変更
UPFが使用するGTPモジュールをビルドするため、カーネルは**5.0.0-23-generic**指定

```
# apt -y install linux-image-5.0.0-23-generic  linux-headers-5.0.0-23-generic
# reboot

# uname -r
5.0.0-23-generic
```

## GTPモジュールビルド

```
# git clone https://github.com/PrinzOwO/gtp5g.git
# cd gtp5g
# make
# make install
```

## ネットワーク設定
フォワーディングとマスカレードをオンに

```
# sysctl -w net.ipv4.ip_forward=1
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
```

## GOインストール
指定バージョンのGOをインストール

```
# cd
# wget https://dl.google.com/go/go1.12.9.linux-amd64.tar.gz
# tar -C /usr/local -zxvf go1.12.9.linux-amd64.tar.gz
# mkdir -p ~/go/{bin,pkg,src}
# echo 'export GOPATH=$HOME/go' >> ~/.bashrc
# echo 'export GOROOT=/usr/local/go' >> ~/.bashrc
# echo 'export PATH=$PATH:$GOPATH/bin:$GOROOT/bin' >> ~/.bashrc
# echo 'export GO111MODULE=off' >> ~/.bashrc
# source ~/.bashrc
# go get -u github.com/sirupsen/logrus
```


## free5GCビルド

```
# cd $GOPATH/src
# git clone https://github.com/free5gc/free5gc.git
# cd free5gc
# git submodule update --init
# cd $GOPATH/src/free5gc
# ./install_env.sh
# ./build.sh
```

# テスト
## NF Register
あるノードが立ち上がると自分が提供する機能をNRF(Network Exposure Function)へ登録にいくのでその確認。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132165/d5e5e111-066c-f484-078f-6555d7ceb20a.png)

ターミナルを２つ立ち上げ、一方でNRFを事前に起動

```
# cd $GOPATH/src/free5gc/bin
# ./nrf
```
もう一方でamf起動

```
# cd $GOPATH/src/free5gc/bin
# ./amf
```

NRF側のコンソールに下記メッセージが現れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132165/129adcdf-df43-ba8e-f8ae-593207ab5a36.png)

/nnrf-nfm/v1/nf-instances/1de0a621-dbbf-49e4-9b35-0ffe414942adというURLへPUT、つまり1de0a621-dbbf-49e4-9b35-0ffe414942adというIDのAMFインスタンスをRegisterしたということなんだろう。AMFをCtl+cで停止するとDELETEした後にAMFプロセスが停止される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132165/22134423-cabd-bd76-585d-74356c47ae4a.png)


## テストツール
test.shが準備されていて色々できるが知識不足で何が起きているのかログを読み切れない。要勉強

```
# cd $GOPATH/src/free5gc/
# ./test.sh
Usage: ./test.sh [ TestRegistration | TestServiceRequest | TestXnHandover | TestN2Handover | TestDeregistration | TestPDUSessionReleaseRequest | TestPaging | TestNon3GPP ]
```

Non 3GPPアクセスが実装されているように見えるので、5G基地局や端末の無線部分のシミュレータがなくても色々できそう。

# Web UI
Subscriber（つまりSIM）を登録したりできるWeb UIあり。下記、サーバを起動する方法。port 5000で立ち上がる

```
# cd $GOPATH/src/free5gc/webconsole
# go run server.go
```

http://[インスタンスのEIP]:5000/
user: admin
pass: free5gc
でアクセス。多くのことはできない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132165/61d11dbf-09aa-2f2d-724a-4c6c4a0ca8de.png)

# 備考
## EC2での起動カーネルの変更

```
# awk -F\' '/submenu|menuentry / {if($1=="menuentry "){print m++ "    : " $2}else \
if($1=="submenu "){print m "    : " $2}else \
{print " " m ">" s++ " : " $2}}' /boot/grub/grub.cfg

0    : Ubuntu
1    : Advanced options for Ubuntu
 1>0 : Ubuntu, with Linux 5.0.0-23-generic
 1>1 : Ubuntu, with Linux 5.0.0-23-generic (recovery mode)
 1>2 : Ubuntu, with Linux 4.15.0-1065-aws
 1>3 : Ubuntu, with Linux 4.15.0-1065-aws (recovery mode)
```

/etc/defaults/grubのGRUB_DEFAULを編集。ここでは**Ubuntu, with Linux 5.0.0-23-generic**なので**"1>0"**を選択

```
# cat /etc/default/grub
・・・省略・・・
# GRUB_DEFAULT=0
GRUB_DEFAULT="1>2"
・・・省略・・・
```



```
# update-grub
```
参考
https://linuxbucket.com/reverting-to-a-previous-linux-kernel-version/