Metonymical Deflection

ゆるく日々のコト・たまにITインフラ

UERANSIM + Open5GS による 5GC SA構築方法

UERANSIM & Open5GSによる5GC SAの構築方法を記載します。
4年前の記事では、OAI L2 nFAPI + Free5GCによる5GC NSAについて記載しました。
現在は、とても簡単かつスムーズに構築ができるようになっています。技術の進歩に感謝です。

UEとgNBはUERANSIMで構築し、5G Coreの各NFはOpen5GSで構築します。
また、最終的な構成では、N4インターフェース(SMFとUPF)間はPcapができるように分離します。*1

1.構成

1-1.環境

全ての端末(仮想マシン)はVMWare上に構築しています。

VMWare   : VMware(R) Workstation 17 Pro 17.5.0 build-22583795

Open5GS用仮想マシン
OS          : Ubuntu 22.04.2
Open5GS     : v2.7.0
MongoDB     : v6.0.0

UERANSIM仮想マシン
OS          : Ubuntu 22.04.2
UERANSIM    : v3.2.6
1-2.全体構成


各インターフェース名を記載すると以下のようになります。

上記は最終構成のため複雑に見えますが、最初は以下の構成にて1Call成功まで構築します。
その後、仮想マシンをクローンして、Open5GSのAMFやSMFを含む5GCとUPFに分離します。

1-3 .全体の流れ ~概要~
  1. 事前準備
  2. Open5GS設定
  3. UERANSIM設定
  4. 簡易動作確認
  5. Open5GSの分離*2
  6. 動作確認
  7. 動作確認:応用編

2.事前準備

UbuntuのNW周りの設定を記載しますが、少し掘り下げます。*3
再掲しますが、現段階では以下の構成で構築していきます。

2-1.u222c111:UERANSIMのNW設定

192.168.11.xは管理用で、インターネット接続が可能な状態になっています。
必要なアプリのインストール完了後、DNSやDefaultGW設定をコメントアウトします。

root@u222c111:~# cat /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      addresses:
      - 192.168.11.111/24
      nameservers:
        addresses:
        - 192.168.11.1
      routes:
      - to: default
        via: 192.168.11.1
    ens35:
      addresses:
      - 192.168.56.111/24
  version: 2

root@u222c111:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.11.1    0.0.0.0         UG    0      0        0 ens33
192.168.11.0    0.0.0.0         255.255.255.0   U     0      0        0 ens33
192.168.56.0    0.0.0.0         255.255.255.0   U     0      0        0 ens35

設定完了後は、Bash上で以下のように設定反映が必要です。
以降は特に記載しませんが、NW周りの設定変更後は忘れずに実施してください。

netplan generate
netplan apply
2-2.u222c112:Open5GSのNW設定

UERANSIMと同様に、192.168.11.xは管理用で、後ほどDNSやDefaultGW設定をコメントアウトします。

root@u222c112:~# cat /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      addresses:
      - 192.168.11.112/24
      nameservers:
        addresses:
        - 192.168.11.1
      routes:
      - to: default
        via: 192.168.11.1
    ens35:
      addresses:
      - 192.168.56.112/24
    ens37:
      addresses:
      - 192.168.33.112/24
  version: 2

root@u222c112:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.11.1    0.0.0.0         UG    0      0        0 ens33
192.168.11.0    0.0.0.0         255.255.255.0   U     0      0        0 ens33
192.168.33.0    0.0.0.0         255.255.255.0   U     0      0        0 ens37
192.168.56.0    0.0.0.0         255.255.255.0   U     0      0        0 ens35
2-3.u222c112:Open5GSのIP転送とFW無効化設定
sed -i -e "s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g" /etc/sysctl.conf
sysctl -p

systemctl stop ufw && \
systemctl disable ufw

reboot

<補足>
Open5GS関連のDoc*4を読むと、UPF上でNAPT(IPマスカレード)設定を行っています。
しかし、ここでは意図的に設定していませんので、その理由を以下に補足します。

理由1 GTP-Uトンネル終端後、カプセル化を解除します。その上、UEのIPに対して、さらにNAPTをかける、という処理を行うことになります。このため、上手くいかないときの切り分けが困難になりそうなので、UPFでNAPTはしないようにしています。*5
理由2 N6(4GでのGi/SGi)において、実環境では各種FWやDPI、CGNなど、UEトラフィックに対して色々チェックしたり、いじりたいポイントでもあるため、UPFでNAPTをかけてしまうのは、もったいないなと個人的には思っています。
2-4.NATルータの戻り経路設定

本来、補足レベルの内容ですが、気付かないとハマるので、念のため。
NATルータ上で、以下のようにUEのIP Prefixに対して、戻り経路を設定しておいてください。

ip route 10.45.0.0 0.0.255.255 192.168.33.112

3.Open5GS設定

u222c112:Open5GSの端末で作業します。

3-1.MongoDBのインストール
apt -y install wget gnupg software-properties-common ca-certificates lsb-release
wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/mongodb-6.gpg
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/6.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-6.0.list

apt update
apt install -y mongodb-org
systemctl start mongod && \
systemctl enable mongod
3-2.Open5GSのインストール
add-apt-repository ppa:open5gs/latest
apt update
apt -y install open5gs

<補足>
add-apt-repository ppa:open5gs/latest の実行時、以下のように確認を求められますが、Enterで進めてください。

root@u222c112:~# add-apt-repository ppa:open5gs/latest
PPA publishes dbgsym, you may need to include 'main/debug' component
Repository: 'deb https://ppa.launchpadcontent.net/open5gs/latest/ubuntu/ jammy main'
Description:
Open5GS is a C-language Open Source implementation of 5G Core and EPC, i.e. the core network of NR/LTE network (Release-17)
More info: https://launchpad.net/~open5gs/+archive/ubuntu/latest
Adding repository.
Press [ENTER] to continue or Ctrl-c to cancel.
3-3.Open5GS Web Consoleのインストール

最初にnodejsをインストールした後、Web ConsoleのインストールスクリプトをDLして実行します。

apt -y install ca-certificates curl gnupg
mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
apt update
apt -y install nodejs

curl -fsSL https://open5gs.org/open5gs/assets/webui/install | sudo -E bash -
3-4.Web Consoleの起動設定

DefaultではループバックアドレスでListenしてしまうため、コンソール端末などからアクセスできないので、以下のように設定します。
追記箇所:青文字

vi /lib/systemd/system/open5gs-webui.service

[Unit]
Description=Open5GS WebUI
Wants=mongodb.service mongod.service

[Service]
Type=simple

WorkingDirectory=/usr/lib/node_modules/open5gs
Environment=NODE_ENV=production
Environment=HOSTNAME=0.0.0.0
Environment=PORT=3000
ExecStart=/usr/bin/node server/index.js
Restart=always
RestartSec=2

[Install]
WantedBy=multi-user.target

設定が完了したら、設定反映とサービス再起動を実施します。

systemctl daemon-reload
systemctl restart open5gs-webui

<補足>
サービスのステータスが以下のようになっていればOKです。

systemctl status open5gs-webui.service

root@u222c112:~# systemctl status open5gs-webui.service
● open5gs-webui.service - Open5GS WebUI
     Loaded: loaded (/lib/systemd/system/open5gs-webui.service; enabled; vendor prese>
     Active: active (running) since Thu 2024-02-01 18:34:23 JST; 3s ago
   Main PID: 8279 (node)
      Tasks: 14 (limit: 4530)
     Memory: 54.9M
        CPU: 442ms
     CGroup: /system.slice/open5gs-webui.service
             └─8279 /usr/bin/node server/index.js

Feb 01 18:34:23 u222c112 systemd[1]: Started Open5GS WebUI.
Feb 01 18:34:24 u222c112 node[8279]: (node:8279) DeprecationWarning: collection.ensur>
Feb 01 18:34:24 u222c112 node[8279]: (Use `node --trace-deprecation ...` to show wher>
Feb 01 18:34:24 u222c112 node[8279]: > Ready on http://0.0.0.0:3000
3-5.加入者情報(Subscriber)の登録

Web Consoleにアクセスして加入者情報を登録します。
0.0.0.0:3000にてListenしていますので、ブラウザを開いてHTTPでアクセスしてください。

今回は例として、http://192.168.11.112:3000/にアクセスしています。
Username:admn
Password:1423

ログイン後、以下の画面が表示されますので、ADD A SUBSCRIBERをクリック。

Subscriber Configuration画面にて、以下のIMSIを入力し、SAVEをクリック。
IMSI:999700000000001
K値やOPcはDefaultのままでOKです。

元の画面に戻ります。
右下の赤い+をクリックし、同様の手順にて、連番のIMSIで2~3登録します。

IMSI:999700000000001、999700000000002、999700000000003を登録しました。

3-6.AMFの設定

ループバックアドレス(127.0.0.5)を実IP(192.168.56.112)に変更します。
127.0.0.5は複数あるため変更箇所を間違えないように気を付けてください。
yaml形式なので把握し易いですが、nagp:配下のサービス待ち受けアドレス127.0.0.5を変更します。
変更箇所:緑文字

vi /etc/open5gs/amf.yaml

  ngap:
    server:
      - address: 192.168.56.112
3-7.UPFの設定

ループバックアドレス(127.0.0.7)を実IP(192.168.56.112)に変更します。
UPFの場合は、gtpu:配下のサービス待ち受けアドレス127.0.0.7を変更します。
変更箇所:緑文字

vi /etc/open5gs/upf.yaml

  gtpu:
    server:
      - address: 192.168.56.112
3-8.未使用サービスの停止

4G関連の使用しないサービスを停止します。*6

for service in open5gs-hssd open5gs-mmed open5gs-pcrfd open5gs-sgwcd open5gs-sgwud; do
  systemctl stop "$service"
  systemctl disable "$service"
done

reboot
3-9.再起動後の確認

前項にて再起動後、以下のコマンドでサービス起動確認をしてください。
hssd, mmed, pcrfd, sgwcd, sgwudがdisabledであればOKです。

systemctl list-unit-files --type=service |grep open5gs

root@u222c112:~# systemctl list-unit-files --type=service |grep open5gs
open5gs-amfd.service                       enabled         enabled
open5gs-ausfd.service                      enabled         enabled
open5gs-bsfd.service                       enabled         enabled
open5gs-hssd.service                       disabled        enabled
open5gs-mmed.service                       disabled        enabled
open5gs-nrfd.service                       enabled         enabled
open5gs-nssfd.service                      enabled         enabled
open5gs-pcfd.service                       enabled         enabled
open5gs-pcrfd.service                      disabled        enabled
open5gs-scpd.service                       enabled         enabled
open5gs-sgwcd.service                      disabled        enabled
open5gs-sgwud.service                      disabled        enabled
open5gs-smfd.service                       enabled         enabled
open5gs-udmd.service                       enabled         enabled
open5gs-udrd.service                       enabled         enabled
open5gs-upfd.service                       enabled         enabled
open5gs-webui.service                      enabled         enabled

加えて、以下のコマンドで待ち受けIPアドレスの確認を行ってください。
以下のようになっていればOKです。

cat /var/log/open5gs/amf.log |grep ngap_server
cat /var/log/open5gs/upf.log |grep gtp_server

root@u222c112:~# cat /var/log/open5gs/amf.log |grep ngap_server
02/01 18:23:43.215: [amf] INFO: ngap_server() [127.0.0.5]:38412 (../src/amf/ngap-sctp.c:61)
02/01 19:14:37.767: [amf] INFO: ngap_server() [192.168.56.112]:38412 (../src/amf/ngap-sctp.c:61)

root@u222c112:~# cat /var/log/open5gs/upf.log |grep gtp_server
02/01 18:23:45.149: [gtp] INFO: gtp_server() [127.0.0.7]:2152 (../lib/gtp/path.c:30)
02/01 19:14:37.864: [gtp] INFO: gtp_server() [192.168.56.112]:2152 (../lib/gtp/path.c:30)

4.UERANSIM設定

u222c111:UERANSIMの端末で作業します。

4-1.必要なアプリのインストール
apt update
apt -y install make g++ libsctp-dev lksctp-tools iproute2
snap install cmake --classic
reboot
4-2.UERANSIMのビルド
cd ~
git clone https://github.com/aligungr/UERANSIM
cd UERANSIM
git checkout 3a96298
make

<出力例>
makeには少し時間を要しますが、以下のような出力であればOKです。

root@u222c111:~/UERANSIM# make
rm -fr logs # Old version log files
mkdir -p build
rm -fr build/*
# cmake -DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - Unix Makefiles" . -B cmake-build-debug
cmake -DCMAKE_BUILD_TYPE=Release -G "CodeBlocks - Unix Makefiles" . -B cmake-build-release
CMake Deprecation Warning:
  Support for "Extra Generators" like

    CodeBlocks

  is deprecated and will be removed from a future version of CMake.  IDEs may
  use the cmake-file-api(7) to view CMake-generated project build trees.


-- The C compiler identification is GNU 11.4.0
-- The CXX compiler identification is GNU 11.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (0.3s)
-- Generating done (0.1s)
-- Build files have been written to: /root/UERANSIM/cmake-build-release
# cmake --build cmake-build-debug --target all
cmake --build cmake-build-release --target all
gmake[1]: Entering directory '/root/UERANSIM/cmake-build-release'
gmake[2]: Entering directory '/root/UERANSIM/cmake-build-release'
gmake[3]: Entering directory '/root/UERANSIM/cmake-build-release'
gmake[3]: Leaving directory '/root/UERANSIM/cmake-build-release'
gmake[3]: Entering directory '/root/UERANSIM/cmake-build-release'
[  0%] Building C object src/asn/asn1c/CMakeFiles/asn-asn1c.dir/ANY.c.o
[  0%] Building C object src/asn/asn1c/CMakeFiles/asn-asn1c.dir/BIT_STRING.c.o
[  0%] Building C object src/asn/asn1c/CMakeFiles/asn-asn1c.dir/BOOLEAN.c.o
[  0%] Building C object src/asn/asn1c/CMakeFiles/asn-asn1c.dir/INTEGER.c.o

=== s n i p ===

[100%] Building CXX object CMakeFiles/nr-cli.dir/src/cli.cpp.o
[100%] Linking CXX executable nr-cli
gmake[3]: Leaving directory '/root/UERANSIM/cmake-build-release'
[100%] Built target nr-cli
gmake[2]: Leaving directory '/root/UERANSIM/cmake-build-release'
gmake[1]: Leaving directory '/root/UERANSIM/cmake-build-release'
cp cmake-build-release/nr-gnb build/
cp cmake-build-release/nr-ue build/
cp cmake-build-release/nr-cli build/
cp cmake-build-release/libdevbnd.so build/
cp tools/nr-binder build/
UERANSIM successfully built.
4-3.gNBの設定

自身のIPと接続先AMFのIPを設定します。
いずれもループバックアドレスになっているため、実際のIPに変更します。
変更箇所:緑文字

vi /root/UERANSIM/config/open5gs-gnb.yaml

linkIp: 192.168.56.111   # gNB's local IP address for Radio Link Simulation (Usually same with local IP)
ngapIp: 192.168.56.111   # gNB's local IP address for N2 Interface (Usually same with local IP)
gtpIp: 192.168.56.111    # gNB's local IP address for N3 Interface (Usually same with local IP)

# List of AMF address information
amfConfigs:
  - address: 192.168.56.112
    port: 38412
4-4.UEの設定

gNB Search ListのIPをループバックアドレスから自身のIPに変更します。
変更箇所:緑文字

vi /root/UERANSIM/config/open5gs-ue.yaml

# List of gNB IP addresses for Radio Link Simulation
gnbSearchList:
  - 192.168.56.111

補足1
IMSIやK値、OPcなどは既に設定済みです。
Open5GS Web Consoleの値と一致しているかを確認してもよいと思います。

open5gs-ue.yamlでの出力例

cat /root/UERANSIM/config/open5gs-ue.yaml

root@u222c111:~/UERANSIM# cat /root/UERANSIM/config/open5gs-ue.yaml
# IMSI number of the UE. IMSI = [MCC|MNC|MSISDN] (In total 15 digits)
supi: 'imsi-999700000000001'
# Mobile Country Code value of HPLMN
mcc: '999'
# Mobile Network Code value of HPLMN (2 or 3 digits)
mnc: '70'
# SUCI Protection Scheme : 0 for Null-scheme, 1 for Profile A and 2 for Profile B
protectionScheme: 0
# Home Network Public Key for protecting with SUCI Profile A
homeNetworkPublicKey: '5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a65
0'
# Home Network Public Key ID for protecting with SUCI Profile A
homeNetworkPublicKeyId: 1
# Routing Indicator
routingIndicator: '0000'

# Permanent subscription key
key: '465B5CE8B199B49FAA5F0A2EE238A6BC'
# Operator code (OP or OPC) of the UE
op: 'E8ED289DEBA952E4283B54E88E6183CA'
# This value specifies the OP type and it can be either 'OP' or 'OPC'
opType: 'OPC'
# Authentication Management Field (AMF) value
amf: '8000'
# IMEI number of the device. It is used if no SUPI is provided
imei: '356938035643803'
# IMEISV number of the device. It is used if no SUPI and IMEI is provided
imeiSv: '4370816125816151'

Open5GS Web Consoleでの出力例

補足2
K値やOPcについて、厳密にはきちんと設定する必要があります。
テスト用の値は、3GPP TS 35.208に記載があるので参照してもよいと思います。
私が確認した 3GPP TS 35.208 V17.0.0 (2022-03) では、4.3 Test Setsに20個のサンプルが記載されていました。



5.簡易動作確認

インストールが完了しましたので、各端末のDNSやDefaultGW設定を変更後、簡易動作確認を実施していきます。

5-1.u222c111:UERANSIMのNW設定

以下のように変更し、設定を反映させます。

root@u222c111:~# cat /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      addresses:
      - 192.168.11.111/24
    ens35:
      addresses:
      - 192.168.56.111/24
  version: 2

続いて、resolv.confを修正します。
変更箇所:緑文字

vi /etc/resolv.conf

nameserver 8.8.8.8

一旦、再起動します。

<route設定>
再起動後、Default Routeが消えていればOKです。

route -n

root@u222c111:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.11.0    0.0.0.0         255.255.255.0   U     0      0        0 ens33
192.168.56.0    0.0.0.0         255.255.255.0   U     0      0        0 ens35

DNS設定>
nameserverが8.8.8.8になっていればOKです。*7

cat /run/systemd/resolve/resolv.conf |grep nameserver

root@u222c111:~# cat /run/systemd/resolve/resolv.conf |grep nameserver
nameserver 8.8.8.8
5-2.u222c112:Open5GSのNW設定

以下のように変更し、設定を反映させます。

root@u222c112:~# cat /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      addresses:
      - 192.168.11.112/24
    ens35:
      addresses:
      - 192.168.56.112/24
    ens37:
      addresses:
      - 192.168.33.112/24
      routes:
      - to: default
        via: 192.168.33.1
  version: 2

一旦、再起動します。

<route設定>
再起動後、Default RouteのNext-Hopが192.168.33.1に変わっていればOKです。

route -n

root@u222c112:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.33.1    0.0.0.0         UG    0      0        0 ens37
10.45.0.0       0.0.0.0         255.255.0.0     U     0      0        0 ogstun
192.168.11.0    0.0.0.0         255.255.255.0   U     0      0        0 ens33
192.168.33.0    0.0.0.0         255.255.255.0   U     0      0        0 ens37
192.168.56.0    0.0.0.0         255.255.255.0   U     0      0        0 ens35
5-3.動作確認前の準備

u222c111:UERANSIMは、ssh接続して、ターミナルを3つ用意してください。
これはUERANSIMのgNBやUEがforegroundで動作するためです。

u222c111:UERANSIM ターミナルA gNB用
u222c111:UERANSIM ターミナルB UE用
u222c111:UERANSIM ターミナルC 通信確認用

u222c112:Open5GSは、ターミナル無しで構いません。
但し、初回UEアタッチ時はログが見れた方が良いと思うので、ターミナルは3つ程度用意しておいた方が良いです。
参照しておいた方が良いログは、以下3つとなります。

  • /var/log/open5gs/amf.log
  • /var/log/open5gs/smf.log
  • /var/log/open5gs/upf.log
u222c112:Open5GS ターミナルD AMF用
u222c112:Open5GS ターミナルE SMF用
u222c112:Open5GS ターミナルF UPF用

以降は、上記ターミナルA~Fが用意されている前提で記載していきます。

5-4.ログ出力設定

各ターミナルで、tail -fを実行しておきます。
ターミナルD:AMF

tail -f /var/log/open5gs/amf.log

ターミナルE:SMF

tail -f /var/log/open5gs/smf.log

ターミナルF:UPF

tail -f /var/log/open5gs/upf.log
5-5.gNB&UEの起動と通信確認

ターミナルAとBでgNBとUEを起動します。
ターミナルA:gNB

cd ~/UERANSIM && \
build/nr-gnb -c config/open5gs-gnb.yaml

ターミナルB:UE

cd ~/UERANSIM && \
build/nr-ue -c config/open5gs-ue.yaml

ターミナルC:通信確認
UEが正常起動したら、Default RouteのNext-Hopをuesimtun0に指定して、NATルータまで疎通確認を行います。

ip route add default dev uesimtun0

ping 192.168.33.1
5-6.起動時のログ出力例

ターミナルD:AMF

root@u222c112:~# tail -f /var/log/open5gs/amf.log 

02/02 07:01:39.750: [amf] INFO: gNB-N2 accepted[192.168.56.111]:43431 in ng-path module (../src/amf/ngap-sctp.c:113)
02/02 07:01:39.750: [amf] INFO: gNB-N2 accepted[192.168.56.111] in master_sm module (../src/amf/amf-sm.c:741)
02/02 07:01:39.754: [amf] INFO: [Added] Number of gNBs is now 1 (../src/amf/context.c:1231)
02/02 07:01:39.754: [amf] INFO: gNB-N2[192.168.56.111] max_num_of_ostreams : 10 (../src/amf/amf-sm.c:780)
02/02 07:01:45.820: [amf] INFO: InitialUEMessage (../src/amf/ngap-handler.c:401)
02/02 07:01:45.820: [amf] INFO: [Added] Number of gNB-UEs is now 1 (../src/amf/context.c:2550)
02/02 07:01:45.820: [amf] INFO:     RAN_UE_NGAP_ID[1] AMF_UE_NGAP_ID[1] TAC[1] CellID[0x10] (../src/amf/ngap-handler.c:562)
02/02 07:01:45.820: [amf] INFO: [suci-0-999-70-0000-0-0-0000000001] Unknown UE by SUCI (../src/amf/context.c:1835)
02/02 07:01:45.820: [amf] INFO: [Added] Number of AMF-UEs is now 1 (../src/amf/context.c:1616)
02/02 07:01:45.820: [gmm] INFO: Registration request (../src/amf/gmm-sm.c:1165)
02/02 07:01:45.820: [gmm] INFO: [suci-0-999-70-0000-0-0-0000000001]    SUCI (../src/amf/gmm-handler.c:166)
02/02 07:01:46.040: [gmm] INFO: [imsi-999700000000001] Registration complete (../src/amf/gmm-sm.c:2146)
02/02 07:01:46.041: [amf] INFO: [imsi-999700000000001] Configuration update command (../src/amf/nas-path.c:612)
02/02 07:01:46.041: [gmm] INFO:     UTC [2024-02-01T22:01:46] Timezone[0]/DST[0] (../src/amf/gmm-build.c:559)
02/02 07:01:46.041: [gmm] INFO:     LOCAL [2024-02-02T07:01:46] Timezone[32400]/DST[0] (../src/amf/gmm-build.c:564)
02/02 07:01:46.041: [amf] INFO: [Added] Number of AMF-Sessions is now 1 (../src/amf/context.c:2571)
02/02 07:01:46.041: [gmm] INFO: UE SUPI[imsi-999700000000001] DNN[internet] S_NSSAI[SST:1 SD:0xffffff] smContextRef [NULL] (../src/amf/gmm-handler.c:1241)
02/02 07:01:46.041: [gmm] INFO: SMF Instance [d6eb5314-c147-41ee-b28f-b5844066cb66] (../src/amf/gmm-handler.c:1280)
02/02 07:01:46.052: [amf] INFO: [imsi-999700000000001:1:11][0:0:NULL] /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify (../src/amf/nsmf-handler.c:837)

ターミナルE:SMF

root@u222c112:~# tail -f /var/log/open5gs/smf.log

02/02 07:01:46.041: [smf] INFO: [Added] Number of SMF-UEs is now 1 (../src/smf/context.c:1019)
02/02 07:01:46.042: [smf] INFO: [Added] Number of SMF-Sessions is now 1 (../src/smf/context.c:3068)
02/02 07:01:46.047: [smf] INFO: UE SUPI[imsi-999700000000001] DNN[internet] IPv4[10.45.0.2] IPv6[] (../src/smf/npcf-handler.c:539)
02/02 07:01:46.048: [gtp] INFO: gtp_connect() [192.168.56.112]:2152 (../lib/gtp/path.c:60)

ターミナルF:UPF

root@u222c112:~# tail -f /var/log/open5gs/upf.log

02/02 07:01:46.047: [upf] INFO: [Added] Number of UPF-Sessions is now 1 (../src/upf/context.c:208)
02/02 07:01:46.047: [gtp] INFO: gtp_connect() [127.0.0.4]:2152 (../lib/gtp/path.c:60)
02/02 07:01:46.047: [upf] INFO: UE F-SEID[UP:0xece CP:0x442] APN[internet] PDN-Type[1] IPv4[10.45.0.2] IPv6 (../src/upf/context.c:485)
02/02 07:01:46.047: [upf] INFO: UE F-SEID[UP:0xece CP:0x442] APN[internet] PDN-Type[1] IPv4[10.45.0.2] IPv6 (../src/upf/context.c:485)
02/02 07:01:46.050: [gtp] INFO: gtp_connect() [192.168.56.111]:2152 (../lib/gtp/path.c:60)

ターミナルA:gNB

root@u222c111:~# cd ~/UERANSIM && \
build/nr-gnb -c config/open5gs-gnb.yaml

UERANSIM v3.2.6
[2024-02-02 07:01:39.741] [sctp] [info] Trying to establish SCTP connection... (192.168.56.112:38412)
[2024-02-02 07:01:39.750] [sctp] [info] SCTP connection established (192.168.56.112:38412)
[2024-02-02 07:01:39.750] [sctp] [debug] SCTP association setup ascId[3]
[2024-02-02 07:01:39.750] [ngap] [debug] Sending NG Setup Request
[2024-02-02 07:01:39.755] [ngap] [debug] NG Setup Response received
[2024-02-02 07:01:39.755] [ngap] [info] NG Setup procedure is successful
[2024-02-02 07:01:45.817] [rrc] [debug] UE[1] new signal detected
[2024-02-02 07:01:45.819] [rrc] [info] RRC Setup for UE[1]
[2024-02-02 07:01:45.819] [ngap] [debug] Initial NAS message received from UE[1]
[2024-02-02 07:01:45.836] [ngap] [debug] Initial Context Setup Request received
[2024-02-02 07:01:46.049] [ngap] [info] PDU session resource(s) setup for UE[1] count[1]

ターミナルB:UE

root@u222c111:~# cd ~/UERANSIM && \
build/nr-ue -c config/open5gs-ue.yaml

UERANSIM v3.2.6
[2024-02-02 07:01:45.817] [nas] [info] UE switches to state [MM-DEREGISTERED/PLMN-SEARCH]
[2024-02-02 07:01:45.817] [rrc] [debug] New signal detected for cell[1], total [1] cells in coverage
[2024-02-02 07:01:45.817] [nas] [info] Selected plmn[999/70]
[2024-02-02 07:01:45.818] [rrc] [info] Selected cell plmn[999/70] tac[1] category[SUITABLE]
[2024-02-02 07:01:45.818] [nas] [info] UE switches to state [MM-DEREGISTERED/PS]
[2024-02-02 07:01:45.818] [nas] [info] UE switches to state [MM-DEREGISTERED/NORMAL-SERVICE]
[2024-02-02 07:01:45.818] [nas] [debug] Initial registration required due to [MM-DEREG-NORMAL-SERVICE]
[2024-02-02 07:01:45.818] [nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-02-02 07:01:45.818] [nas] [debug] Sending Initial Registration
[2024-02-02 07:01:45.818] [nas] [info] UE switches to state [MM-REGISTER-INITIATED]
[2024-02-02 07:01:45.818] [rrc] [debug] Sending RRC Setup Request
[2024-02-02 07:01:45.819] [rrc] [info] RRC connection established
[2024-02-02 07:01:45.819] [rrc] [info] UE switches to state [RRC-CONNECTED]
[2024-02-02 07:01:45.819] [nas] [info] UE switches to state [CM-CONNECTED]
[2024-02-02 07:01:45.826] [nas] [debug] Authentication Request received
[2024-02-02 07:01:45.829] [nas] [debug] Security Mode Command received
[2024-02-02 07:01:45.829] [nas] [debug] Selected integrity[2] ciphering[0]
[2024-02-02 07:01:45.837] [nas] [debug] Registration accept received
[2024-02-02 07:01:45.837] [nas] [info] UE switches to state [MM-REGISTERED/NORMAL-SERVICE]
[2024-02-02 07:01:45.837] [nas] [debug] Sending Registration Complete
[2024-02-02 07:01:45.837] [nas] [info] Initial Registration is successful
[2024-02-02 07:01:45.837] [nas] [debug] Sending PDU Session Establishment Request
[2024-02-02 07:01:45.837] [nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-02-02 07:01:46.040] [nas] [debug] Configuration Update Command received
[2024-02-02 07:01:46.050] [nas] [debug] PDU Session Establishment Accept received
[2024-02-02 07:01:46.050] [nas] [info] PDU Session establishment is successful PSI[1]
[2024-02-02 07:01:46.064] [app] [info] Connection setup for PDU session[1] is successful, TUN interface[uesimtun0, 10.45.0.2] is up.

ターミナルC:通信確認

root@u222c111:~# ip route add default dev uesimtun0

root@u222c111:~# ping 192.168.33.1
PING 192.168.33.1 (192.168.33.1) 56(84) bytes of data.
64 bytes from 192.168.33.1: icmp_seq=1 ttl=254 time=1.54 ms
64 bytes from 192.168.33.1: icmp_seq=2 ttl=254 time=1.69 ms
64 bytes from 192.168.33.1: icmp_seq=3 ttl=254 time=1.50 ms
64 bytes from 192.168.33.1: icmp_seq=4 ttl=254 time=1.60 ms
^C
--- 192.168.33.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3006ms
rtt min/avg/max/mdev = 1.496/1.582/1.693/0.073 ms

<補足>
ここまで正常確認ができれば全てOKです。
インターネット向け通信については、NATルータ上でNAPT(IPマスカレード)設定を行った後、UEからcurl www.google.comなどにアクセスしてみてください。
NATルータの192.168.33.1に疎通OKなので、ひとまず5G Core内の動作が正常であることを担保できています。

6.Open5GSの分離

u222c112:Open5GSについて、UPFとそれ以外*8に分離した後、以下の構成に変更します。

u222c112 UPF用 以降、u222c112:UPFと記載
u222c113 AMF, SMF用 以降、u222c113:AMFと記載


具体的には、u222c112をクローンしてu222c113を作成します。
Subnetが変わるため、端末のIPを変更します。
低レイヤでは仮想NICの接続先LANセグメントや仮想SWを変更するなどの作業も発生します。
この点については、各環境に合わせて変更してください。*9

加えて、各端末間でRoutingを行うためVyosを導入します。*10
各インターフェースにGWとなるIPを設定するだけで、特にRouting周りの設定は不要です。*11
<Vyos設定例>

vyos@vyos14c114# run show configuration commands
set interfaces ethernet eth0 address '192.168.11.114/24'
set interfaces ethernet eth0 hw-id '00:0c:29:c6:ea:14'
set interfaces ethernet eth1 address '192.168.56.1/24'
set interfaces ethernet eth1 hw-id '00:0c:29:c6:ea:1e'
set interfaces ethernet eth2 address '192.168.57.1/24'
set interfaces ethernet eth2 hw-id '00:0c:29:c6:ea:28'
set interfaces ethernet eth3 address '192.168.58.1/24'
set interfaces ethernet eth3 hw-id '00:0c:29:c6:ea:32'

vyos@vyos14c114# run sho ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
       f - OpenFabric,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

C>* 192.168.11.0/24 is directly connected, eth0, 00:43:13
C>* 192.168.56.0/24 is directly connected, eth1, 00:40:52
C>* 192.168.57.0/24 is directly connected, eth2, 00:40:52
C>* 192.168.58.0/24 is directly connected, eth3, 00:40:52
6-1.u222c112:UPFの設定
6-1-1.u222c112:UPFのNW設定

NW周りの設定を変更します。

root@u222c112:~# cat /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      addresses:
      - 192.168.11.112/24
    ens35:
      addresses:
      - 192.168.58.112/24
      routes:
      - to: 192.168.56.0/22
        via: 192.168.58.1
    ens37:
      addresses:
      - 192.168.33.112/24
      routes:
      - to: default
        via: 192.168.33.1
  version: 2

設定変更&反映後、以下のようになっていればOKです。

root@u222c112:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.33.1    0.0.0.0         UG    0      0        0 ens37
192.168.11.0    0.0.0.0         255.255.255.0   U     0      0        0 ens33
192.168.33.0    0.0.0.0         255.255.255.0   U     0      0        0 ens37
192.168.56.0    192.168.58.1    255.255.252.0   UG    0      0        0 ens35
192.168.58.0    0.0.0.0         255.255.255.0   U     0      0        0 ens35
6-1-2.u222c112:UPFのサービス設定

UPF上で不要なサービスを停止&無効化します。

for service in open5gs-amfd open5gs-ausfd open5gs-bsfd open5gs-nrfd open5gs-nssfd open5gs-pcfd open5gs-scpd open5gs-smfd open5gs-udmd open5gs-udrd open5gs-webui; do
  systemctl stop "$service"
  systemctl disable "$service"
done
6-1-3.u222c112:UPFのyaml設定

gtpu serverの待ち受けアドレスに加えて、pfcp serverの待ち受けアドレスも変更します。
変更箇所:緑文字

vi /etc/open5gs/upf.yaml

upf:
  pfcp:
    server:
      - address: 192.168.58.112
    client:
#      smf:     #  UPF PFCP Client try to associate SMF PFCP Server
#        - address: 127.0.0.4
  gtpu:
    server:
      - address: 192.168.58.112

設定が完了したら、一旦再起動をしておきます。

6-2.u222c113:AMFの設定変更
6-2-1.u222c113:AMFのNW設定

NW周りの設定を変更します。

root@u222c113:~# cat /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      addresses:
      - 192.168.11.113/24
    ens35:
      addresses:
      - 192.168.57.113/24
      routes:
      - to: 192.168.56.0/22
        via: 192.168.57.1
  version: 2

設定変更&反映後、以下のようになっていればOKです。

root@u222c113:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.11.0    0.0.0.0         255.255.255.0   U     0      0        0 ens33
192.168.56.0    192.168.57.1    255.255.252.0   UG    0      0        0 ens35
192.168.57.0    0.0.0.0         255.255.255.0   U     0      0        0 ens35
6-2-2.u222c113:AMFのサービス設定

UPFサービスを停止&無効化します。

systemctl stop open5gs-upfd.service && \
systemctl disable open5gs-upfd.service
6-2-3.u222c113:AMFのamf.yaml設定

ngap serverの待ち受けアドレスを変更します。
変更箇所:緑文字

vi /etc/open5gs/amf.yaml

  ngap:
    server:
      - address: 192.168.57.113
6-2-4.u222c113:AMFのsmf.yaml設定

UPFを分離したため、smf.yamlの設定変更が必要になります。
pfcp serverの待ち受けアドレスと、pfcp clientの接続先アドレス(=UPFのアドレス)を変更します。
変更箇所:緑文字

vi /etc/open5gs/smf.yaml

  pfcp:
    server:
      - address: 192.168.57.113
    client:
      upf:
        - address: 192.168.58.112
6-3.u222c111:UERANSIMの設定変更
6-3-1.u222c111:UERANSIMのNW設定

NW周りの設定を変更します。

root@u222c111:~# cat /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      addresses:
      - 192.168.11.111/24
    ens35:
      addresses:
      - 192.168.56.111/24
      routes:
      - to: 192.168.56.0/22
        via: 192.168.56.1
  version: 2

設定変更&反映後、以下のようになっていればOKです。*12

root@u222c111:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.11.0    0.0.0.0         255.255.255.0   U     0      0        0 ens33
192.168.56.0    0.0.0.0         255.255.255.0   U     0      0        0 ens35
192.168.56.0    192.168.56.1    255.255.252.0   UG    0      0        0 ens35
6-3-2.u222c111:UERANSIMのyaml設定

AMFへの接続先アドレスを変更します。
変更箇所:緑文字

vi /root/UERANSIM/config/open5gs-gnb.yaml

# List of AMF address information
amfConfigs:
  - address: 192.168.57.113
    port: 38412

7.動作確認

5.簡易動作確認と同様にターミナルA~Fが用意されている前提で記載していきます。

u222c111:UERANSIM ターミナルA gNB用
u222c111:UERANSIM ターミナルB UE用
u222c111:UERANSIM ターミナルC 通信確認用
u222c113:AMF ターミナルD AMF用
u222c113:AMF ターミナルE SMF用
u222c112:UPF ターミナルF UPF用

各インターフェース名が入った構成図を再掲しておきます。

7-1.ログ出力設定

コマンドは、5.簡易動作確認と全く同じですが再掲しておきます。

各ターミナルで、tail -fを実行しておきます。
ターミナルD:AMF

tail -f /var/log/open5gs/amf.log

ターミナルE:SMF

tail -f /var/log/open5gs/smf.log

ターミナルF:UPF

tail -f /var/log/open5gs/upf.log
7-2.gNB&UEの起動と通信確認

ターミナルAとBでgNBとUEを起動します。
ターミナルA:gNB

cd ~/UERANSIM && \
build/nr-gnb -c config/open5gs-gnb.yaml

ターミナルB:UE

cd ~/UERANSIM && \
build/nr-ue -c config/open5gs-ue.yaml

ターミナルC:通信確認
UEが正常起動したら、Default RouteのNext-Hopをuesimtun0に指定して、NATルータまで疎通確認を行います。

ip route add default dev uesimtun0

ping 192.168.33.1

次項では、各ターミナルにおける正常時の出力例を記載していきます。

7-3.起動時のログ出力例

ターミナルD:AMF

root@u222c113:~# tail -f /var/log/open5gs/amf.log 

02/02 12:38:34.152: [amf] INFO: gNB-N2 accepted[192.168.56.111]:50398 in ng-path module (../src/amf/ngap-sctp.c:113)
02/02 12:38:34.152: [amf] INFO: gNB-N2 accepted[192.168.56.111] in master_sm module (../src/amf/amf-sm.c:741)
02/02 12:38:34.156: [amf] INFO: [Added] Number of gNBs is now 1 (../src/amf/context.c:1231)
02/02 12:38:34.157: [amf] INFO: gNB-N2[192.168.56.111] max_num_of_ostreams : 10 (../src/amf/amf-sm.c:780)
02/02 12:38:41.607: [amf] INFO: InitialUEMessage (../src/amf/ngap-handler.c:401)
02/02 12:38:41.607: [amf] INFO: [Added] Number of gNB-UEs is now 1 (../src/amf/context.c:2550)
02/02 12:38:41.607: [amf] INFO:     RAN_UE_NGAP_ID[1] AMF_UE_NGAP_ID[1] TAC[1] CellID[0x10] (../src/amf/ngap-handler.c:562)
02/02 12:38:41.607: [amf] INFO: [suci-0-999-70-0000-0-0-0000000001] Unknown UE by SUCI (../src/amf/context.c:1835)
02/02 12:38:41.608: [amf] INFO: [Added] Number of AMF-UEs is now 1 (../src/amf/context.c:1616)
02/02 12:38:41.608: [gmm] INFO: Registration request (../src/amf/gmm-sm.c:1165)
02/02 12:38:41.608: [gmm] INFO: [suci-0-999-70-0000-0-0-0000000001]    SUCI (../src/amf/gmm-handler.c:166)
02/02 12:38:41.619: [sbi] INFO: [UDM] (SCP-discover) NF registered [1ac074c8-c17c-41ee-b2d4-338cf5ac6abc:1] (../lib/sbi/path.c:211)
02/02 12:38:41.621: [sbi] WARNING: [UDM] (SCP-discover) NF has already been added [1ac074c8-c17c-41ee-b2d4-338cf5ac6abc:2] (../lib/sbi/path.c:216)
02/02 12:38:41.829: [gmm] INFO: [imsi-999700000000001] Registration complete (../src/amf/gmm-sm.c:2146)
02/02 12:38:41.829: [amf] INFO: [imsi-999700000000001] Configuration update command (../src/amf/nas-path.c:612)
02/02 12:38:41.830: [gmm] INFO:     UTC [2024-02-02T03:38:41] Timezone[0]/DST[0] (../src/amf/gmm-build.c:559)
02/02 12:38:41.830: [gmm] INFO:     LOCAL [2024-02-02T12:38:41] Timezone[32400]/DST[0] (../src/amf/gmm-build.c:564)
02/02 12:38:41.830: [amf] INFO: [Added] Number of AMF-Sessions is now 1 (../src/amf/context.c:2571)
02/02 12:38:41.830: [gmm] INFO: UE SUPI[imsi-999700000000001] DNN[internet] S_NSSAI[SST:1 SD:0xffffff] smContextRef [NULL] (../src/amf/gmm-handler.c:1241)
02/02 12:38:41.830: [gmm] INFO: SMF Instance [1ad5297c-c17c-41ee-a541-7dc64ea9161c] (../src/amf/gmm-handler.c:1280)
02/02 12:38:41.843: [amf] INFO: [imsi-999700000000001:1:11][0:0:NULL] /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify (../src/amf/nsmf-handler.c:837)

ターミナルE:SMF

root@u222c113:~# tail -f /var/log/open5gs/smf.log

02/02 12:38:41.831: [smf] INFO: [Added] Number of SMF-UEs is now 1 (../src/smf/context.c:1019)
02/02 12:38:41.831: [smf] INFO: [Added] Number of SMF-Sessions is now 1 (../src/smf/context.c:3068)
02/02 12:38:41.834: [sbi] INFO: [UDM] (SCP-discover) NF registered [1ac074c8-c17c-41ee-b2d4-338cf5ac6abc:1] (../lib/sbi/path.c:211)
02/02 12:38:41.837: [smf] INFO: UE SUPI[imsi-999700000000001] DNN[internet] IPv4[10.45.0.2] IPv6[] (../src/smf/npcf-handler.c:539)
02/02 12:38:41.838: [gtp] INFO: gtp_connect() [192.168.58.112]:2152 (../lib/gtp/path.c:60)
02/02 12:38:41.843: [sbi] WARNING: [UDM] (SCP-discover) NF has already been added [1ac074c8-c17c-41ee-b2d4-338cf5ac6abc:2] (../lib/sbi/path.c:216)

ターミナルF:UPF

root@u222c112:~# tail -f /var/log/open5gs/upf.log

02/02 12:38:41.837: [upf] INFO: [Added] Number of UPF-Sessions is now 1 (../src/upf/context.c:208)
02/02 12:38:41.837: [gtp] INFO: gtp_connect() [127.0.0.4]:2152 (../lib/gtp/path.c:60)
02/02 12:38:41.837: [upf] INFO: UE F-SEID[UP:0x937 CP:0x83c] APN[internet] PDN-Type[1] IPv4[10.45.0.2] IPv6 (../src/upf/context.c:485)
02/02 12:38:41.837: [upf] INFO: UE F-SEID[UP:0x937 CP:0x83c] APN[internet] PDN-Type[1] IPv4[10.45.0.2] IPv6 (../src/upf/context.c:485)
02/02 12:38:41.840: [gtp] INFO: gtp_connect() [192.168.56.111]:2152 (../lib/gtp/path.c:60)

ターミナルA:gNB

root@u222c111:~# cd ~/UERANSIM && \
build/nr-gnb -c config/open5gs-gnb.yaml

UERANSIM v3.2.6
[2024-02-02 12:38:34.129] [sctp] [info] Trying to establish SCTP connection... (192.168.57.113:38412)
[2024-02-02 12:38:34.152] [sctp] [info] SCTP connection established (192.168.57.113:38412)
[2024-02-02 12:38:34.152] [sctp] [debug] SCTP association setup ascId[3]
[2024-02-02 12:38:34.152] [ngap] [debug] Sending NG Setup Request
[2024-02-02 12:38:34.157] [ngap] [debug] NG Setup Response received
[2024-02-02 12:38:34.158] [ngap] [info] NG Setup procedure is successful
[2024-02-02 12:38:41.605] [rrc] [debug] UE[1] new signal detected
[2024-02-02 12:38:41.606] [rrc] [info] RRC Setup for UE[1]
[2024-02-02 12:38:41.606] [ngap] [debug] Initial NAS message received from UE[1]
[2024-02-02 12:38:41.625] [ngap] [debug] Initial Context Setup Request received
[2024-02-02 12:38:41.839] [ngap] [info] PDU session resource(s) setup for UE[1] count[1]

ターミナルB:UE

root@u222c111:~# cd ~/UERANSIM && \
build/nr-ue -c config/open5gs-ue.yaml

UERANSIM v3.2.6
[2024-02-02 12:38:41.605] [nas] [info] UE switches to state [MM-DEREGISTERED/PLMN-SEARCH]
[2024-02-02 12:38:41.605] [rrc] [debug] New signal detected for cell[1], total [1] cells in coverage
[2024-02-02 12:38:41.605] [nas] [info] Selected plmn[999/70]
[2024-02-02 12:38:41.605] [rrc] [info] Selected cell plmn[999/70] tac[1] category[SUITABLE]
[2024-02-02 12:38:41.605] [nas] [info] UE switches to state [MM-DEREGISTERED/PS]
[2024-02-02 12:38:41.605] [nas] [info] UE switches to state [MM-DEREGISTERED/NORMAL-SERVICE]
[2024-02-02 12:38:41.605] [nas] [debug] Initial registration required due to [MM-DEREG-NORMAL-SERVICE]
[2024-02-02 12:38:41.605] [nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-02-02 12:38:41.606] [nas] [debug] Sending Initial Registration
[2024-02-02 12:38:41.606] [nas] [info] UE switches to state [MM-REGISTER-INITIATED]
[2024-02-02 12:38:41.606] [rrc] [debug] Sending RRC Setup Request
[2024-02-02 12:38:41.606] [rrc] [info] RRC connection established
[2024-02-02 12:38:41.606] [rrc] [info] UE switches to state [RRC-CONNECTED]
[2024-02-02 12:38:41.606] [nas] [info] UE switches to state [CM-CONNECTED]
[2024-02-02 12:38:41.613] [nas] [debug] Authentication Request received
[2024-02-02 12:38:41.617] [nas] [debug] Security Mode Command received
[2024-02-02 12:38:41.617] [nas] [debug] Selected integrity[2] ciphering[0]
[2024-02-02 12:38:41.626] [nas] [debug] Registration accept received
[2024-02-02 12:38:41.626] [nas] [info] UE switches to state [MM-REGISTERED/NORMAL-SERVICE]
[2024-02-02 12:38:41.626] [nas] [debug] Sending Registration Complete
[2024-02-02 12:38:41.626] [nas] [info] Initial Registration is successful
[2024-02-02 12:38:41.626] [nas] [debug] Sending PDU Session Establishment Request
[2024-02-02 12:38:41.626] [nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-02-02 12:38:41.830] [nas] [debug] Configuration Update Command received
[2024-02-02 12:38:41.840] [nas] [debug] PDU Session Establishment Accept received
[2024-02-02 12:38:41.840] [nas] [info] PDU Session establishment is successful PSI[1]
[2024-02-02 12:38:41.845] [app] [info] Connection setup for PDU session[1] is successful, TUN interface[uesimtun0, 10.45.0.2] is up.

ターミナルC:通信確認

root@u222c111:~# ip route add default dev uesimtun0

root@u222c111:~# ping 192.168.33.1
PING 192.168.33.1 (192.168.33.1) 56(84) bytes of data.
64 bytes from 192.168.33.1: icmp_seq=1 ttl=254 time=1.66 ms
64 bytes from 192.168.33.1: icmp_seq=2 ttl=254 time=1.63 ms
64 bytes from 192.168.33.1: icmp_seq=3 ttl=254 time=1.66 ms
^C
--- 192.168.33.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 1.626/1.647/1.659/0.015 ms

<補足>
5.簡易動作確認の最後にも記載しましたが、インターネット向け通信については、NATルータ上で設定を行ってください。
ここまでの正常動作確認ができたら、Vyosを導入した構成変更後においても、5G Core内の動作が正常であることを担保できています。
UEアタッチまでのシーケンスをPcapしたファイルはこちらにアップしました。

8.動作確認:応用編

応用編として、UEを3台に増やす方法について記載します。
UE起動時のコマンドに"-n 3"を追加します。
すると、open5gs-ue.yamlに設定したIMSI:999700000000001から999700000000003まで連番にてUEを起動してくれるようになります。
なお、3-5.加入者情報(Subscriber)の登録にて、既にSubscriberが登録済みのため、UEを3台に増やすことができるようになっています。
さらに、UEを増やしたい場合には、Open5GS Web Console上で、事前にSubscriberの追加登録を行ってください。

8-1.UEの起動と通信確認

追記箇所:青文字
ターミナルB:UE

cd ~/UERANSIM && \
build/nr-ue -c config/open5gs-ue.yaml -n 3

ターミナルC:通信確認

ip route add default dev uesimtun0

<インターフェース指定によるPingcurlコマンド>
ping -I uesimtun0 192.168.33.1
ping -I uesimtun1 192.168.33.1
ping -I uesimtun2 192.168.33.1
curl --interface uesimtun0 www.google.com
curl --interface uesimtun1 www.google.com
curl --interface uesimtun2 www.google.com

<補足>
この状態でifconfigを実施すると、uesimtun0~2までTunインターフェースが生成されています。

ターミナルC:ifconfig出力例

uesimtun0: flags=369  mtu 1400
        inet 10.45.0.2  netmask 255.255.255.255  destination 10.45.0.2
        inet6 fe80::fde3:ddca:d856:1830  prefixlen 64  scopeid 0x20
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 36  bytes 23196 (23.1 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 49  bytes 3086 (3.0 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

uesimtun1: flags=369  mtu 1400
        inet 10.45.0.3  netmask 255.255.255.255  destination 10.45.0.3
        inet6 fe80::e37c:d6c3:702f:c37e  prefixlen 64  scopeid 0x20
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 2  bytes 168 (168.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13  bytes 808 (808.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

uesimtun2: flags=369  mtu 1400
        inet 10.45.0.4  netmask 255.255.255.255  destination 10.45.0.4
        inet6 fe80::bf1f:4cc2:2d60:7279  prefixlen 64  scopeid 0x20
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 2  bytes 168 (168.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13  bytes 808 (808.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
8-2.UE複数起動時のgNBとUEのログ出力例

ターミナルA:gNB

root@u222c111:~# cd ~/UERANSIM && \
build/nr-gnb -c config/open5gs-gnb.yaml

UERANSIM v3.2.6
[2024-02-02 19:16:13.090] [sctp] [info] Trying to establish SCTP connection... (192.168.57.113:38412)
[2024-02-02 19:16:13.100] [sctp] [info] SCTP connection established (192.168.57.113:38412)
[2024-02-02 19:16:13.101] [sctp] [debug] SCTP association setup ascId[3]
[2024-02-02 19:16:13.101] [ngap] [debug] Sending NG Setup Request
[2024-02-02 19:16:13.110] [ngap] [debug] NG Setup Response received
[2024-02-02 19:16:13.110] [ngap] [info] NG Setup procedure is successful
[2024-02-02 19:16:42.062] [rrc] [debug] UE[1] new signal detected
[2024-02-02 19:16:42.063] [rrc] [debug] UE[2] new signal detected
[2024-02-02 19:16:42.063] [rrc] [debug] UE[3] new signal detected
[2024-02-02 19:16:42.068] [rrc] [info] RRC Setup for UE[1]
[2024-02-02 19:16:42.068] [rrc] [info] RRC Setup for UE[2]
[2024-02-02 19:16:42.068] [ngap] [debug] Initial NAS message received from UE[1]
[2024-02-02 19:16:42.069] [ngap] [debug] Initial NAS message received from UE[2]
[2024-02-02 19:16:42.070] [rrc] [info] RRC Setup for UE[3]
[2024-02-02 19:16:42.070] [ngap] [debug] Initial NAS message received from UE[3]
[2024-02-02 19:16:42.097] [ngap] [debug] Initial Context Setup Request received
[2024-02-02 19:16:42.098] [ngap] [debug] Initial Context Setup Request received
[2024-02-02 19:16:42.102] [ngap] [debug] Initial Context Setup Request received
[2024-02-02 19:16:42.117] [ngap] [info] PDU session resource(s) setup for UE[1] count[1]
[2024-02-02 19:16:42.118] [ngap] [info] PDU session resource(s) setup for UE[2] count[1]
[2024-02-02 19:16:42.119] [ngap] [info] PDU session resource(s) setup for UE[3] count[1]

ターミナルB:UE

root@u222c111:~# cd ~/UERANSIM && \
build/nr-ue -c config/open5gs-ue.yaml -n 3

UERANSIM v3.2.6
[2024-02-02 19:16:42.062] [999700000000002|nas] [info] UE switches to state [MM-DEREGISTERED/PLMN-SEARCH]
[2024-02-02 19:16:42.062] [999700000000001|nas] [info] UE switches to state [MM-DEREGISTERED/PLMN-SEARCH]
[2024-02-02 19:16:42.062] [999700000000003|nas] [info] UE switches to state [MM-DEREGISTERED/PLMN-SEARCH]
[2024-02-02 19:16:42.063] [999700000000002|rrc] [debug] New signal detected for cell[1], total [1] cells in coverage
[2024-02-02 19:16:42.063] [999700000000002|nas] [info] Selected plmn[999/70]
[2024-02-02 19:16:42.063] [999700000000001|rrc] [debug] New signal detected for cell[1], total [1] cells in coverage
[2024-02-02 19:16:42.063] [999700000000002|rrc] [info] Selected cell plmn[999/70] tac[1] category[SUITABLE]
[2024-02-02 19:16:42.064] [999700000000002|nas] [info] UE switches to state [MM-DEREGISTERED/PS]
[2024-02-02 19:16:42.064] [999700000000002|nas] [info] UE switches to state [MM-DEREGISTERED/NORMAL-SERVICE]
[2024-02-02 19:16:42.064] [999700000000002|nas] [debug] Initial registration required due to [MM-DEREG-NORMAL-SERVICE]
[2024-02-02 19:16:42.064] [999700000000001|nas] [info] Selected plmn[999/70]
[2024-02-02 19:16:42.064] [999700000000001|rrc] [info] Selected cell plmn[999/70] tac[1] category[SUITABLE]
[2024-02-02 19:16:42.064] [999700000000001|nas] [info] UE switches to state [MM-DEREGISTERED/PS]
[2024-02-02 19:16:42.064] [999700000000001|nas] [info] UE switches to state [MM-DEREGISTERED/NORMAL-SERVICE]
[2024-02-02 19:16:42.064] [999700000000001|nas] [debug] Initial registration required due to [MM-DEREG-NORMAL-SERVICE]
[2024-02-02 19:16:42.064] [999700000000002|nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-02-02 19:16:42.064] [999700000000002|nas] [debug] Sending Initial Registration
[2024-02-02 19:16:42.065] [999700000000002|nas] [info] UE switches to state [MM-REGISTER-INITIATED]
[2024-02-02 19:16:42.068] [999700000000002|rrc] [debug] Sending RRC Setup Request
[2024-02-02 19:16:42.068] [999700000000001|nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-02-02 19:16:42.068] [999700000000001|nas] [debug] Sending Initial Registration
[2024-02-02 19:16:42.068] [999700000000001|rrc] [debug] Sending RRC Setup Request
[2024-02-02 19:16:42.068] [999700000000001|nas] [info] UE switches to state [MM-REGISTER-INITIATED]
[2024-02-02 19:16:42.068] [999700000000002|rrc] [info] RRC connection established
[2024-02-02 19:16:42.068] [999700000000002|rrc] [info] UE switches to state [RRC-CONNECTED]
[2024-02-02 19:16:42.068] [999700000000002|nas] [info] UE switches to state [CM-CONNECTED]
[2024-02-02 19:16:42.069] [999700000000003|rrc] [debug] New signal detected for cell[1], total [1] cells in coverage
[2024-02-02 19:16:42.069] [999700000000001|rrc] [info] RRC connection established
[2024-02-02 19:16:42.069] [999700000000001|rrc] [info] UE switches to state [RRC-CONNECTED]
[2024-02-02 19:16:42.069] [999700000000001|nas] [info] UE switches to state [CM-CONNECTED]
[2024-02-02 19:16:42.069] [999700000000003|nas] [info] Selected plmn[999/70]
[2024-02-02 19:16:42.069] [999700000000003|rrc] [info] Selected cell plmn[999/70] tac[1] category[SUITABLE]
[2024-02-02 19:16:42.069] [999700000000003|nas] [info] UE switches to state [MM-DEREGISTERED/PS]
[2024-02-02 19:16:42.069] [999700000000003|nas] [info] UE switches to state [MM-DEREGISTERED/NORMAL-SERVICE]
[2024-02-02 19:16:42.069] [999700000000003|nas] [debug] Initial registration required due to [MM-DEREG-NORMAL-SERVICE]
[2024-02-02 19:16:42.069] [999700000000003|nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-02-02 19:16:42.069] [999700000000003|nas] [debug] Sending Initial Registration
[2024-02-02 19:16:42.069] [999700000000003|nas] [info] UE switches to state [MM-REGISTER-INITIATED]
[2024-02-02 19:16:42.069] [999700000000003|rrc] [debug] Sending RRC Setup Request
[2024-02-02 19:16:42.070] [999700000000003|rrc] [info] RRC connection established
[2024-02-02 19:16:42.070] [999700000000003|rrc] [info] UE switches to state [RRC-CONNECTED]
[2024-02-02 19:16:42.070] [999700000000003|nas] [info] UE switches to state [CM-CONNECTED]
[2024-02-02 19:16:42.076] [999700000000002|nas] [debug] Authentication Request received
[2024-02-02 19:16:42.080] [999700000000001|nas] [debug] Authentication Request received
[2024-02-02 19:16:42.080] [999700000000003|nas] [debug] Authentication Request received
[2024-02-02 19:16:42.082] [999700000000002|nas] [debug] Security Mode Command received
[2024-02-02 19:16:42.082] [999700000000002|nas] [debug] Selected integrity[2] ciphering[0]
[2024-02-02 19:16:42.084] [999700000000001|nas] [debug] Security Mode Command received
[2024-02-02 19:16:42.084] [999700000000001|nas] [debug] Selected integrity[2] ciphering[0]
[2024-02-02 19:16:42.086] [999700000000003|nas] [debug] Security Mode Command received
[2024-02-02 19:16:42.086] [999700000000003|nas] [debug] Selected integrity[2] ciphering[0]
[2024-02-02 19:16:42.098] [999700000000002|nas] [debug] Registration accept received
[2024-02-02 19:16:42.098] [999700000000002|nas] [info] UE switches to state [MM-REGISTERED/NORMAL-SERVICE]
[2024-02-02 19:16:42.098] [999700000000002|nas] [debug] Sending Registration Complete
[2024-02-02 19:16:42.098] [999700000000002|nas] [info] Initial Registration is successful
[2024-02-02 19:16:42.098] [999700000000002|nas] [debug] Sending PDU Session Establishment Request
[2024-02-02 19:16:42.098] [999700000000002|nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-02-02 19:16:42.098] [999700000000001|nas] [debug] Registration accept received
[2024-02-02 19:16:42.098] [999700000000001|nas] [info] UE switches to state [MM-REGISTERED/NORMAL-SERVICE]
[2024-02-02 19:16:42.098] [999700000000001|nas] [debug] Sending Registration Complete
[2024-02-02 19:16:42.098] [999700000000001|nas] [info] Initial Registration is successful
[2024-02-02 19:16:42.098] [999700000000001|nas] [debug] Sending PDU Session Establishment Request
[2024-02-02 19:16:42.098] [999700000000001|nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-02-02 19:16:42.103] [999700000000003|nas] [debug] Registration accept received
[2024-02-02 19:16:42.103] [999700000000003|nas] [info] UE switches to state [MM-REGISTERED/NORMAL-SERVICE]
[2024-02-02 19:16:42.103] [999700000000003|nas] [debug] Sending Registration Complete
[2024-02-02 19:16:42.103] [999700000000003|nas] [info] Initial Registration is successful
[2024-02-02 19:16:42.103] [999700000000003|nas] [debug] Sending PDU Session Establishment Request
[2024-02-02 19:16:42.103] [999700000000003|nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-02-02 19:16:42.103] [999700000000002|nas] [debug] Configuration Update Command received
[2024-02-02 19:16:42.103] [999700000000001|nas] [debug] Configuration Update Command received
[2024-02-02 19:16:42.104] [999700000000003|nas] [debug] Configuration Update Command received
[2024-02-02 19:16:42.118] [999700000000002|nas] [debug] PDU Session Establishment Accept received
[2024-02-02 19:16:42.118] [999700000000002|nas] [info] PDU Session establishment is successful PSI[1]
[2024-02-02 19:16:42.120] [999700000000003|nas] [debug] PDU Session Establishment Accept received
[2024-02-02 19:16:42.120] [999700000000003|nas] [info] PDU Session establishment is successful PSI[1]
[2024-02-02 19:16:42.121] [999700000000001|nas] [debug] PDU Session Establishment Accept received
[2024-02-02 19:16:42.121] [999700000000001|nas] [info] PDU Session establishment is successful PSI[1]
[2024-02-02 19:16:42.127] [999700000000002|app] [info] Connection setup for PDU session[1] is successful, TUN interface[uesimtun0, 10.45.0.2] is up.
[2024-02-02 19:16:42.135] [999700000000001|app] [info] Connection setup for PDU session[1] is successful, TUN interface[uesimtun1, 10.45.0.3] is up.
[2024-02-02 19:16:42.141] [999700000000003|app] [info] Connection setup for PDU session[1] is successful, TUN interface[uesimtun2, 10.45.0.4] is up.

以上です。

9.最後に

以下のサイトを参考にさせて頂きました。
Open5GS | Open5GS is a C-language implementation of 5G Core and EPC, i.e. the core network of NR/LTE network (Release-17)
GitHub - s5uishida/open5gs_5gc_ueransim_sample_config: Open5GS 5GC & UERANSIM UE / RAN Sample Configuration

何よりも「aptコマンドで5G Coreがインストールできちゃうんだ!」ということが、驚きと感動で震えました。
Open5GSの開発者やコントリビュータの方々に、ただひたすら感謝しています。

4年前は、ビルドが必須だったり、ビルドするとターミナル画面が文字化けして、画面を閉じないと先に進めなかったりしていました。
さらに、仮想マシンではPingは通るけどRTTが不安定だったりしました。
このため、Low Latency Kernelで動作させるべく、物理マシンを用意して、Linux Kernelのビルドからやっていました。

今後もこの分野はさらに発展していくと思うので、5Gの動向にアンテナを張りつつ、技術をより深化させ精進していきたいと思います。

*1:分離といっても、仮想マシンをクローンするだけです。

*2:UPFとそれ以外のNFに分離します。

*3:パケット転送をするなどNW周りの設定がポイントになるためです

*4:公式のQuickstartや関連ブログなど

*5:NAPT無しで全ての動作確認が成功した後、最後にNAPTかければよくないですか?と思っています。NAPTをかけることが目的ではないので。

*6:4G関連サービスは、Open5GSのインストール時に自動起動設定が行われています。

*7:DNSサーバアドレス設定については、/etc/resolv.confを直接変更しても意味がないなど諸説あるのですが、実体は/run/systemd/resolve/resolv.confの値が、設定した値8.8.8.8になっていればOKです。ただし、/run/systemd/resolve/resolv.confを直接変更するのはダメなようです。

*8:主にAMF, SMFですが、その他の5GCore NF(例えば、NRFとかPCFなど)も含まれます。

*9:仮想環境における低レイヤ周りの技術は極めて極めて重要なのですが、VMWare WorkstationやESXi、VBox、KVMなど環境によって異なるため詳細は割愛します。掘り下げると数本分のブログ内容に発展するためです。

*10:Routingを行うためにプラスして、N2, N3, N4間通信をPcapするためでもあります。

*11:10.45.0.xのUE IPは、GTP-Uトンネル内のInnerIPのため、Vyos上ではRouting対象になりません。

*12:192.168.56.0のPrefixが2つ存在していますが、ロンゲストマッチが効くので問題ありません。

Tcpreplay利用方法

Tcpreplayのセットアップ利用方法について記載します。
また、実用面を考慮し、構成を明示した上で具体的な設定例についても記載します。

1.環境

1-1.VMWare
筐体                             : 自作PC(Win10pro)
VMWare              : VMware(R) Workstation 17 Pro 17.5.0 build-22583795
OS                               : Ubuntu 22.04, Vyos14
Tcpreplay                        : v4.4.4
1-2.全体構成

TcpreplayはUbuntu22.04上にインストールします。
DUT(Device Under Test)はVyosを使用していますが、各種RouterやFWなどでも構成可能です。

1-3 .全体の流れ ~概要~
  1. インストールとビルド
  2. 利用方法その1:単純なPcapファイルの送信
  3. 利用方法その2:Routerを経由したPcapファイルの送受信

2.インストールとビルド

2-1.事前準備

ビルドが必要になるので事前に必要なアプリケーションをaptでインストールしておきます。

apt update && \
apt -y install build-essential libpcap-dev
2-2.Tcpreplayのインストール

/root/tmp/配下で作業を行っていきます。*1

2-2-1.TcpreplayのDL

以下のコマンドにてtarファイルをDLします。

mkdir /root/tmp
cd /root/tmp/
wget https://github.com/appneta/tcpreplay/releases/download/v4.4.4/tcpreplay-4.4.4.tar.gz
tar zxvf tcpreplay-4.4.4.tar.gz
2-2-2.Tcpreplayのビルド

Cのソースからビルドします。

cd /root/tmp/tcpreplay-4.4.4/
./configure
make
make install

./configureの出力例

root@u222c96:~/tmp/tcpreplay-4.4.4# ./configure
checking whether to enable maintainer-specific portions of Makefiles... yes
checking if malloc debugging is wanted... no
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu

### snip ###

config.status: creating src/common/Makefile
config.status: creating src/defines.h
config.status: creating test/Makefile
config.status: creating test/config
config.status: creating scripts/Makefile
config.status: creating src/config.h
config.status: executing depfiles commands
config.status: executing libtool commands

##########################################################################
             TCPREPLAY Suite Configuration Results (4.4.4)
##########################################################################
libpcap:                    /usr (1.10.1)
PF_RING libpcap             no
libdnet:                    no
autogen:                     (unknown - man pages will not be built)
Use libopts tearoff:        yes
64bit counter support:      yes
tcpdump binary path:        /usr/bin/tcpdump
fragroute support:          no
tcpbridge support:          yes
tcpliveplay support:        yes

Supported Packet Injection Methods (*):
Linux TX_RING:              no
Linux PF_PACKET:            yes
BSD BPF:                    no
libdnet:                    no
pcap_inject:                yes
pcap_sendpacket:            yes **
pcap_netmap                 no
Linux/BSD netmap:           no
Tuntap device support:      yes

* In order of preference; see configure --help to override
** Required for tcpbridge

makeの出力例

root@u222c96:~/tmp/tcpreplay-4.4.4# make
Making all in scripts
make[1]: Entering directory '/root/tmp/tcpreplay-4.4.4/scripts'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/root/tmp/tcpreplay-4.4.4/scripts'
Making all in lib
make[1]: Entering directory '/root/tmp/tcpreplay-4.4.4/lib'
  CC       strlcat.o
  CC       strlcpy.o
  AR       libstrl.a

### snip ###

  CCLD     tcpbridge
  CC       tcpliveplay-tcpliveplay_opts.o
  CC       tcpliveplay-tcpliveplay.o
  CCLD     tcpliveplay
make[3]: Leaving directory '/root/tmp/tcpreplay-4.4.4/src'
make[2]: Leaving directory '/root/tmp/tcpreplay-4.4.4/src'
make[1]: Leaving directory '/root/tmp/tcpreplay-4.4.4/src'
make[1]: Entering directory '/root/tmp/tcpreplay-4.4.4'
make[1]: Nothing to be done for 'all-am'.
make[1]: Leaving directory '/root/tmp/tcpreplay-4.4.4'

make installの出力例

root@u222c96:~/tmp/tcpreplay-4.4.4# make install
Making install in scripts
make[1]: Entering directory '/root/tmp/tcpreplay-4.4.4/scripts'
make[2]: Entering directory '/root/tmp/tcpreplay-4.4.4/scripts'
make[2]: Nothing to be done for 'install-exec-am'.
make[2]: Nothing to be done for 'install-data-am'.
make[2]: Leaving directory '/root/tmp/tcpreplay-4.4.4/scripts'
make[1]: Leaving directory '/root/tmp/tcpreplay-4.4.4/scripts'
Making install in lib
make[1]: Entering directory '/root/tmp/tcpreplay-4.4.4/lib'

### snip ###

libtool: install: /usr/bin/install -c tcprewrite /usr/local/bin/tcprewrite
libtool: install: /usr/bin/install -c tcpreplay-edit /usr/local/bin/tcpreplay-edit
libtool: install: /usr/bin/install -c tcpcapinfo /usr/local/bin/tcpcapinfo
libtool: install: /usr/bin/install -c tcpbridge /usr/local/bin/tcpbridge
libtool: install: /usr/bin/install -c tcpliveplay /usr/local/bin/tcpliveplay
 /usr/bin/mkdir -p '/usr/local/share/man/man1'
 /usr/bin/install -c -m 644 tcpreplay.1 tcpprep.1 tcprewrite.1 tcpreplay-edit.1 tcpcapinfo.1 tcpbridge.1 tcpliveplay.1 '/usr/local/share/man/man1'
make[4]: Leaving directory '/root/tmp/tcpreplay-4.4.4/src'
make[3]: Leaving directory '/root/tmp/tcpreplay-4.4.4/src'
make[2]: Leaving directory '/root/tmp/tcpreplay-4.4.4/src'
make[1]: Leaving directory '/root/tmp/tcpreplay-4.4.4/src'
make[1]: Entering directory '/root/tmp/tcpreplay-4.4.4'
make[2]: Entering directory '/root/tmp/tcpreplay-4.4.4'
make[2]: Nothing to be done for 'install-exec-am'.
make[2]: Nothing to be done for 'install-data-am'.
make[2]: Leaving directory '/root/tmp/tcpreplay-4.4.4'
make[1]: Leaving directory '/root/tmp/tcpreplay-4.4.4'
2-2-3.インストール後の確認

インストール完了後、tcpの後にTabキーを入力し、補完候補を表示させた結果、
以下のように表示されていればOKです。(tcpdump以外が表示されればOKです)

root@u222c96:~# tcp + Tabキー
tcpbridge       tcpdump         tcpprep         tcpreplay-edit
tcpcapinfo      tcpliveplay     tcpreplay       tcprewrite

補足
インストール後、make testコマンドにて動作確認することも可能ですが、
確認方法は最後のAppendixに記載します。

3.利用方法その1:単純なPcapファイルの送信

test.pcapファイルを利用して、Pcapファイルのリプレイを行います。

3-1.事前準備

以下のサイトから、サンプルPcapファイル test.pcap をDLしておきます。
ページの一番下に test.pcap のリンクがあります。
https://tcpreplay.appneta.com/wiki/captures.html

DL後、以下のPathに保存しておいてください。

/root/tmp/test.pcap
3-2.構成

以下の構成では、Ubuntuのens34からVyosのeth1へ、test.pcapに含まれる全パケットを送信します。

Ubuntuのens35とVyosのeth2は利用しません。
また、パケットに含まれるSrc/Dst-MAC, Src/Dst-IPには何も変更を加えません。*2

3-3.コマンドの実行

以下のPathにcdした後、

cd /root/tmp

以下のコマンドを実行してください。

tcpreplay \
-i ens34 \
test.pcap

出力例

root@u222c96:~/tmp# tcpreplay \
-i ens34 \
test.pcap
Actual: 141 packets (62704 bytes) sent in 2.78 seconds
Rated: 22539.0 Bps, 0.180 Mbps, 50.68 pps
Flows: 37 flows, 13.29 fps, 140 unique flow packets, 1 unique non-flow packets
Statistics for network device: ens34
        Successful packets:        141
        Failed packets:            0
        Truncated packets:         0
        Retried packets (ENOBUFS): 0
        Retried packets (EAGAIN):  0
3-4.Vyos側でのPcap

3-3.コマンドの実行の前に、Vyos側でPcapを実行しておくと、Ubuntuから送信されたパケットを確認することができます。
Vyos側で以下のコマンドによりPcapを実施してください。
Ctrl+cでPcapを停止できます。

monitor traffic interface eth1 save test.pcap

出力例

vyos@vyos14c163:~$ monitor traffic interface eth1 save test.pcap
tcpdump: listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
^C141 packets captured
141 packets received by filter
0 packets dropped by kernel

保存したPcapファイルは自身のPCにDLして、Wiresharkなどで閲覧可能です。

3-5.ユースケース

Vyosのeth1に記載の通り、受信側はTapポートなどで全パケットを受信します。
受信側において、トラフィックの中身をInspectするような機器(FWやセキュリティセンサ機器など)の場合に活用することができます。
別のユースケースとして、負荷試験などを想定し、一方的にUDPトラフィックを送り付けるような場合も活用できると思います。
Tcpreplayの出力例には、以下のように各種Rate(Bps, Mbps, pps)やfpsなどが表示されます。

Rated: 22539.0 Bps, 0.180 Mbps, 50.68 pps
Flows: 37 flows, 13.29 fps, 140 unique flow packets, 1 unique non-flow packets

4.利用方法その2:Routerを経由したPcapファイルの送受信

前項では、test.pcapをそのままリプレイするだけでした。
本項では、test.pcapに含まれるSrc/Dst-MAC, Src/Dst-IPを、今回の構成用に変更します。
これにより、DUTであるVyosにてパケット転送処理を発生させ、パケットを通過させることができます。
なお、test.pcap を再利用しますので事前準備は不要です。

4-1.構成

以下のように、パケットの送受信ができるようにします。
 行き:Ubuntu ens34 ー> Vyos eth1 ー>Switching&Routing処理 ー> Vyos eth2 ー>Ubuntu ens35
 戻り:Ubuntu ens35 ー> Vyos eth2 ー>Switching&Routing処理 ー> Vyos eth1 ー>Ubuntu ens34

以降は、
 Ubuntu ens34 と Vyos eth1 をClient Side
 Ubuntu ens35 と Vyos eth2 をServer Side
として説明していきます。

4-2.Vyos側でのPcap

Tcpreplayコマンドの実行前に、Vyos側でPcapを仕掛けておきます。
Vyosでは、ClientSideとServerSideのそれぞれでPcapを実施しますので、sshセッションを2つ張っておいてください。
これにより、ClientSideとServerSideにて、Src/Dst-MACの確認が可能です。

ClientSideのsshコンソール上

monitor traffic interface eth1 save test21.pcap

ServerSideのsshコンソール上

monitor traffic interface eth2 save test22.pcap
4-3.コマンドの実行

以下のコマンドを実行してください。

tcpprep \
--auto=client \
--pcap=test.pcap \
--cachefile=test.cache

tcprewrite \
--enet-dmac=00:0c:29:56:33:4d,00:0c:29:56:33:57 \
--enet-smac=00:0c:29:3c:00:67,00:0c:29:3c:00:71 \
--endpoints=192.168.34.96:192.168.35.96 \
--cachefile=test.cache \
--infile=test.pcap \
--outfile=test2.pcap \
--skipbroadcast

tcpprep \
--auto=client \
--pcap=test2.pcap \
--cachefile=test2.cache

tcpreplay \
--cachefile=test2.cache \
--intf1=ens34 \
--intf2=ens35 \
test2.pcap

<出力例>
tcpprepやtcprewriteはコマンドが正常に終了した場合、何も出力されません。

root@u222c96:~/tmp# tcpreplay \
--cachefile=test2.cache \
--intf1=ens34 \
--intf2=ens35 \
test2.pcap
Actual: 141 packets (62704 bytes) sent in 2.78 seconds
Rated: 22537.7 Bps, 0.180 Mbps, 50.67 pps
Flows: 37 flows, 13.29 fps, 140 unique flow packets, 1 unique non-flow packets
Statistics for network device: ens34
        Successful packets:        74
        Failed packets:            0
        Truncated packets:         0
        Retried packets (ENOBUFS): 0
        Retried packets (EAGAIN):  0
        Flows total:               20
        Flows unique:              0
        Flows expired:             0
        Flow packets:              74
        Non-flow packets:          0
        Invalid flow packets:      0
Statistics for network device: ens35
        Successful packets:        67
        Failed packets:            0
        Truncated packets:         0
        Retried packets (ENOBUFS): 0
        Retried packets (EAGAIN):  0
        Flows total:               17
        Flows unique:              0
        Flows expired:             0
        Flow packets:              66
        Non-flow packets:          1
        Invalid flow packets:      0

WiresharkのScreeShot>
以下のスクショはClientSideのPcapとなります。

4-4.各コマンドの詳細
4-4-1.tcpprepコマンド

tcpprepコマンドにて、キャッシュファイルを生成します。
tcpprepコマンドのポイントは、NICが2つある場合、どのNICからどのパケットを送信するか決定することにあります。

1回目
tcpprep \
--auto=client \
--pcap=test.pcap \
--cachefile=test.cache

2回目
tcpprep \
--auto=client \
--pcap=test2.pcap \
--cachefile=test2.cache

2回目のtcpprepについて
tcprewriteコマンドにて、Src/Dst-MAC と Src/Dst-IPを変更した新たなtest2.pcapファイルが生成されます。
このため、test2.pcapに対して、新たにキャッシュファイルを生成しています。

tcpprepコマンドの詳細については以下のサイトを参照ください。
英語サイト
https://tcpreplay.appneta.com/wiki/tcpprep
日本語サイト(非公式)
https://otsuka752.github.io/wiki/tcpprep.html

4-4-2.tcprewriteコマンド

tcprewriteコマンドにて、実際の環境に合わせたSrc/Dst-MAC と Src/Dst-IPに変更します。

tcprewrite \
--enet-dmac=00:0c:29:56:33:4d,00:0c:29:56:33:57 \
--enet-smac=00:0c:29:3c:00:67,00:0c:29:3c:00:71 \
--endpoints=192.168.34.96:192.168.35.96 \
--cachefile=test.cache \
--infile=test.pcap \
--outfile=test2.pcap \
--skipbroadcast

アドレス部分が難解なので構成図と見比べてみてください。

tcprewrite \
--enet-dmac=Vyos eth1-MAC,Vyos eth2-MAC \
--enet-smac=Ubuntu ens34-MAC,Ubuntu ens35-MAC \
--endpoints=Ubuntu ens34-IP:Ubuntu ens35-IP \
--cachefile=test.cache \
--infile=test.pcap \
--outfile=test2.pcap \
--skipbroadcast


その他の部分について
test.pcapとtest.cacheをInputとして、Src/Dst-MAC と Src/Dst-IPを変更したtest2.pcapを新たに生成しています。
--skipbroadcastはオプションですが、BUMトラフィックに対して、MAC アドレスの書き換えをしないようにしています。

4-4-3.tcpreplayコマンド

--intf1がClientSide--intf2がServerSideと明示的に指定することにより、Router経由のトラフィック送受信を実現しています。

tcpreplay \
--cachefile=test2.cache \
--intf1=ens34 \
--intf2=ens35 \
test2.pcap
4-5.ユースケース

今回のケースでは、
 Ubuntu ens34 と Vyos eth1 をClient Side
 Ubuntu ens35 と Vyos eth2 をServer Side
として、定義しています。
これにより、DUT(Vyos)でパケット転送処理を発生させ、実際にトラフィックを通過させることができます。
加えて、ClientとServer間でトラフィック送受信を模倣することが可能です。

これらを踏まえたユースケースとしては、トラブル発生時の再現性確認には極めて有用と考えられます。
自社製機器と他社製機器間でのトラブル時において、他社製機器をすぐに準備できないケースなどではその有用性が上がると思います。
また、FWやセキュリティセンサ機器などでアラート発生確認を実施する場合にも活用できます。
特にステートフルな処理を行っている機器に対しては有用ではないかと考えられます。
加えて、負荷試験の用途においても活用できると思います。*3

但し、遅延やジッターの考慮が必要なケースにおいては、慎重に検証を進めることが重要だと考えられます。
今回のケースであれば、test2.pcapとtest21.pcapの時間を比較してみてください。
 test2.pcapは、Tcpreplayを実行する際に使用したPcapファイルです。
 test21.pcapは、Tcpreplayコマンドにより発生させた実トラフィックのPcapファイルです。
ms(ミリセカンド)レベルではほぼ同時刻ですが、μs(マイクロセカンド)レベルでは差異が発生しています。
また、DUT(Vyos)において高負荷が発生するようなケースでは、転送遅延が加算されることも考慮する必要があると思います。

Appendix.インストール後の確認:make testについて

2-2-3.インストール後の確認において、より詳細な確認を行うため、make testコマンドを利用することが可能です。
やり方は、ビルドしたPathにて、make testコマンドを実行するだけです。

cd /root/tmp/tcpreplay-4.4.4/
make test

但し、Defaultでは、インターフェース名がeth0に固定されているため、いくつかのテスト項目でエラーが発生します。
<出力例>

### snip ###

[tcpreplay] Basic test: make[1]: *** [Makefile:819: replay_basic] Error 255
[tcpreplay] Cache test: make[1]: *** [Makefile:825: replay_cache] Error 255
[tcpreplay] Packets/sec test: make[1]: *** [Makefile:1100: replay_pps] Error 255
[tcpreplay] Mbps test: make[1]: *** [Makefile:1106: replay_rate] Error 255
[tcpreplay] Topspeed test: make[1]: *** [Makefile:1124: replay_top] Error 255
[tcpreplay] Config file/VLAN add test: make[1]: *** [Makefile:1142: replay_config] Error 255
[tcpreplay] Multiplier test: make[1]: *** [Makefile:1112: replay_multi] Error 255
[tcpreplay] Packets/sec Multiplier test: make[1]: *** [Makefile:1118: replay_pps_multi] Error 255
[tcpreplay] Precache test: make[1]: *** [Makefile:1130: replay_precache] Error 255
[tcpreplay] Statistics test: make[1]: *** [Makefile:837: replay_stats] Error 255
[tcpreplay] Dual file test: make[1]: *** [Makefile:1148: replay_dualfile] Error 255
[tcpreplay] Maximum sleep test: make[1]: *** [Makefile:1154: replay_maxsleep] Error 255

### snip ###

make[1]: Target 'test' not remade because of errors.
make[1]: Leaving directory '/root/tmp/tcpreplay-4.4.4/test'
make: *** [Makefile:904: test] Error 2

これを回避するため、以下のコマンドにて事前にインターフェース名を変更しておきます。

sed -i -e "/intf1/s/eth0/ens34/g" /root/tmp/tcpreplay-4.4.4/test/config
sed -i -e "/intf2/s/eth0/ens35/g" /root/tmp/tcpreplay-4.4.4/test/config

sed -i -e "/nic1/s/eth0/ens34/g" /root/tmp/tcpreplay-4.4.4/test/Makefile
sed -i -e "/nic2/s/eth0/ens35/g" /root/tmp/tcpreplay-4.4.4/test/Makefile

改めて、make testコマンドを実行します。

cd /root/tmp/tcpreplay-4.4.4/
make test

<出力例>

root@u222c96:~/tmp/tcpreplay-4.4.4# make test
echo Making test in ./test
Making test in ./test
cd ./test && make test
make[1]: Entering directory '/root/tmp/tcpreplay-4.4.4/test'
NOTICE: Tests must be run as root
Sending traffic on 'ens34' and 'ens35'
[tcpprep] Auto/Router mode test:                OK
[tcpprep] Auto/Bridge mode test:                OK
[tcpprep] Auto/Client mode test:                OK
[tcpprep] Auto/Server mode test:                OK
[tcpprep] Auto/First mode test:                 OK
[tcpprep] CIDR mode test:                       OK
[tcpprep] Regex mode test:                      OK
[tcpprep] Port mode test:                       OK
[tcpprep] MAC mode test:                        OK
[tcpprep] Comment mode test:                    OK
[tcpprep] Print info mode test:                 OK
[tcpprep] Print comment mode test:              OK
[tcpprep] Config mode test:                     OK
[tcpprep] MAC reverse mode test:                OK
[tcpprep] CIDR reverse mode test:               OK
[tcpprep] Regex reverse mode test:              OK
[tcpprep] exclude packets test:                 OK
[tcpprep] include packets test:                 OK
[tcpprep] include source test:                  OK
[tcpprep] include destination test:             OK
[tcpreplay] Basic test:                         OK
[tcpreplay] Cache test:                         OK
[tcpreplay] Packets/sec test:                   OK
[tcpreplay] Mbps test:                          OK
[tcpreplay] Topspeed test:                      OK
[tcpreplay] Config file/VLAN add test:          OK
[tcpreplay] Multiplier test:                    OK
[tcpreplay] Packets/sec Multiplier test:        OK
[tcpreplay] Precache test:                      OK
[tcpreplay] Statistics test:                    OK
[tcpreplay] Dual file test:                     OK
[tcpreplay] Maximum sleep test:                 OK
[tcprewrite] Portmap test:                      OK
[tcprewrite] Portmap range test:                OK
[tcprewrite] Endpoint test:                     OK
[tcprewrite] Pseudo NAT test:                   OK
[tcprewrite] Truncate test:                     OK
[tcprewrite] Pad test:                          OK
[tcprewrite] Seed IP test:                      OK
[tcprewrite] Src/Dst MAC test:                  OK
[tcprewrite] Layer2 test:                       OK
[tcprewrite] Config/VLAN Add test:              OK
[tcprewrite] Skip bcast test:                   OK
[tcprewrite] DLT User test:                     OK
[tcprewrite] DLT Cisco HDLC test:               OK
[tcprewrite] VLAN 802.1ad test:                 OK
[tcprewrite] VLAN Delete test:                  OK
[tcprewrite] Remove EFCS:                       OK
[tcprewrite] Force TTL:                         OK
[tcprewrite] Increase TTL:                      OK
[tcprewrite] Reduce TTL:                        OK
[tcprewrite] TOS test:                          OK
[tcprewrite] MTU Truncate test:                 OK
[tcprewrite] Substitute Src/Dst MAC test:       OK
[tcprewrite] Seeded MAC test:                   OK
[tcprewrite] Seeded Keep MAC test:              OK
[tcprewrite] L7 fuzzing test:                   OK
[tcprewrite] TCP sequence test:                 OK
[tcprewrite] Fix checksum test:                 OK
[tcprewrite] Fix length and pad test:           OK
[tcprewrite] Fix length and truncate test:      OK
[tcprewrite] Fix length and delete test:        OK
make[1]: Leaving directory '/root/tmp/tcpreplay-4.4.4/test'

以上です。

5.最後に

以下のサイトを参考にさせて頂きました。
Tcpreplay - Pcap editing and replaying utilities
Tcpreplay - pcap ファイルの書き換えと再送信ユーティリティ

TcpreplayはPcapファイルのリプレイをすることにより、様々なユースケースにおいて応用できることがわかりました。
今回は取り上げませんでしたが、netmapをビルドして組み込むことにより、ワイヤレートに近い性能が出せるようなので、負荷試験においても活用できると思います。
負荷試験ツールに関しては、過去にこのブログでCisco Trexやdperfを取り上げましたが、Tcpreplayもラインナップに加えられそうです。
CentOS7 Cisco TRex利用方法 その1 - Metonymical Deflection
CentOS7 Cisco TRex利用方法 その2 - Metonymical Deflection
CentOS baidu dperf 設定方法 - Metonymical Deflection

私の個人的な考えですが、この手のツールは優劣を比較してもあまり意味がなく、あくまでも適材適所だと思っています。
また、これらのツールは、いざという時にゴリゴリ使える人として活躍できるよう、常日頃から遊び感覚*4練習しておくことが重要だと考えています。

*1:極力、絶対Pathで記載するようにします。

*2:変更を加えるパターンは、4.利用方法その2に記載します。

*3:公式サイトを読む限りでは、これが最も力を入れているユースケースのようです

*4:遊び半分ではなく、遊び感覚という点が極めて重要です。

wso2 identity serverによるSAML Idpの設定方法

wso2 identity server(以下、wso2)を使用したSAML Idpの設定方法を記載していきます。
ここでは動作確認用としてWordpressSAML SPとします。
wso2の認証バックエンドには、Windows2019のADを使用します。

前回記事(Keycloak)のwso2版と考えてください。*1

1.構成

1-1.環境

全ての端末(仮想マシン)はVMWare上に構築しています。

VMWare : VMware(R) Workstation 15 Pro 15.5.1 build-15018445 

wso2用仮想マシン
OS : Ubuntu 22.04.2
Java : openjdk-11
Keycloak : 6.1.0
OpenSSL : 3.0.2

Wordpress仮想マシン
bitnami-wordpress-5.9.0
OVAからデプロイ

Active Directory仮想マシン
OS : Windows Server 2019

ClientPC用仮想マシン
OS : Windows10
1-2.全体の流れ
  • ドメイン登録
  • AD構築
  • 証明書発行
  • wso2インストール
  • wso2各種設定
  • Wordpress インストール&各種設定
  • 動作確認
1-3.全体構成

fig.1

IPアドレスドメイン名は自身の環境に置き換えてください。
私の環境ではヘアピンNATができないためBBルータが2台あります。
BBルータAの方で、TCP9443でポートフォワードの設定をしています。*2

2.ドメイン登録

自身で独自ドメインを取得するか、以下のサイトなどで無料のドメイン登録を行ってください。
ddns.kuku.lu
ここでは上記サイトで、idp.f5.siのドメインを登録したものとして進めます。
登録したドメインを使用して、AレコードにGlobalIP-AのIPアドレスを設定しておいてください。

補足
wso2のHostname設定に、IPアドレスを設定していると、HTTPリダイレクトの際にうまく動作しなかったり、といったことを確認したため、ドメイン登録の項を記載しました。
仮に、閉じられた環境内で構築する場合であっても、別途DNSサーバを構築して、名前解決可能な環境にしておくことが必要だと考えています。*3

3.AD構築

以下のサイトなどを参考にADの構築を行ってください。
www.rem-system.com
上記サイトは、スクショ入りのStep by Stepで詳細に記載されており、特に躓くことなくADを構築できます。

ADはKeycloakの認証バックエンドとして利用しますので、AD上に任意のユーザを2-3つくらい作成しておいてください。
ここでは例として、user001@example.comといったユーザを作成したものとして進めます。*4
補足
AD上でユーザを作成する際、以下のように作成されていることを前提として進めます。

4.証明書発行

ここからは、wso2用仮想マシンでの作業となります。

4-1.openssl.cnfの設定

/etc/ssl/openssl.cnfファイルを編集します。
青文字箇所が変更した部分となります。

vi /etc/ssl/openssl.cnf
==== snip ====
[ CA_default ]

dir             = /etc/ssl/demoCA      # Where everything is kept  ./demoCAから絶対Pathに変更
certs           = $dir/certs            # Where the issued certs are kept

==== snip ====
[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = JP
countryName_min                 = 2
countryName_max                 = 2

stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = Tokyo

localityName                    = Locality Name (eg, city)
localityName_default            = Chiyoda-ku

0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = f5.si

# we can do this but it is not needed normally :-)
#1.organizationName             = Second Organization Name (eg, company)
#1.organizationName_default     = World Wide Web Pty Ltd

organizationalUnitName          = Organizational Unit Name (eg, section)
#organizationalUnitName_default =

commonName                      = Common Name (e.g. server FQDN or YOUR name)
commonName_max                  = 64
==== snip ====
4-2.CAの構築

/usr/lib/ssl/misc/CA.plを使用して、CAを構築していきます。

cd /etc/ssl
/usr/lib/ssl/misc/CA.pl -newca

<出力例>

root@u222c96:/etc/ssl# /usr/lib/ssl/misc/CA.pl -newca
CA certificate filename (or enter to create) <ー空Enter

Making CA certificate ...
openssl req  -new -keyout ./demoCA/private/cakey.pem -out ./demoCA/careq.pem
..+......+....+..+.......+.....+.......+.....+....+.....+.+......+........+....+...+.................+.+..+...+....+...+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+...+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+.+.....+...+.+..+...+......+.........+....+...................................+..........+......+..+.......+............+......+.................+.......+...+......+.....+.....................+......+.......+.....+......+....+..+...+............+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
..+.+..............+.+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+.+...+.....+.+.....+....+..+.........+..........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+.....+......+...+....+......+..+.........+...+.+......+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Enter PEM pass phrase: <ーパスフレーズを入力
Verifying - Enter PEM pass phrase: <ーパスフレーズを入力
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [JP]: <ー空Enter
State or Province Name (full name) [Tokyo]: <ー空Enter
Locality Name (eg, city) [Chiyoda-ku]: <ー空Enter
Organization Name (eg, company) [f5.si]: <ー空Enter
Organizational Unit Name (eg, section) : <ー空Enter
Common Name (e.g. server FQDN or YOUR name) :CA.f5.si <ーCAのCommon Nameを手入力。任意の名前でOK
Email Address : <ー空Enter

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password : <ー空Enter
An optional company name []: <ー空Enter
==> 0
openssl ca  -create_serial -out ./demoCA/cacert.pem -days 1095 -batch -keyfile ./demoCA/private/cakey.pem -selfsign -extensions v3_ca -infiles ./demoCA/careq.pem
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem: <ー最初に入力した(cakeyの)パスフレーズを再度入力
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            6e:fa:be:0b:64:8b:ea:4c:c2:ee:c2:7b:62:b3:64:5f:52:40:59:2b
        Validity
            Not Before: Nov 23 00:12:36 2023 GMT
            Not After : Nov 22 00:12:36 2026 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = f5.si
            commonName                = CA.f5.si
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                3B:BE:09:A3:AF:51:5A:6A:D5:3F:DD:C1:D2:60:4A:88:E9:F8:79:BF
            X509v3 Authority Key Identifier:
                3B:BE:09:A3:AF:51:5A:6A:D5:3F:DD:C1:D2:60:4A:88:E9:F8:79:BF
            X509v3 Basic Constraints: critical
                CA:TRUE
Certificate is to be certified until Nov 22 00:12:36 2026 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated
==> 0
CA certificate is in ./demoCA/cacert.pem

これにより、/etc/ssl配下に、demoCAというディレクトリが作成されます。
/etc/ssl/demoCA配下に、CAのルート証明書が格納されています。
/etc/ssl/demoCA/private配下に、CAのキーファイルが格納されています。

4-3.Idpで利用する証明書を発行

/etc/ssl/demoCA配下でIdpの証明書を発行します。
初めに、SAN(Subject Altanative Name)設定ファイルを作成します。

cat > /etc/ssl/demoCA/subjectnames.txt <<EOF
subjectAltName = DNS:idp.f5.si
EOF
cd /etc/ssl/demoCA
openssl genrsa -out idp.key 2048
openssl req -utf8 -new -key idp.key -out idp.csr
openssl ca -in idp.csr -out idp.pem -extfile subjectnames.txt

<出力例>

root@u222c96:/etc/ssl/demoCA# cd /etc/ssl/demoCA
root@u222c96:/etc/ssl/demoCA# openssl genrsa -out idp.key 2048
root@u222c96:/etc/ssl/demoCA# openssl req -utf8 -new -key idp.key -out idp.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [JP]: <ー空Enter
State or Province Name (full name) [Tokyo]: <ー空Enter
Locality Name (eg, city) [Chiyoda-ku]: <ー空Enter
Organization Name (eg, company) [f5.si]: <ー空Enter
Organizational Unit Name (eg, section) : <ー空Enter
Common Name (e.g. server FQDN or YOUR name) :idp.f5.si <ーidp.f5.siと入力
Email Address :

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password : <ー空Enter
An optional company name []: <ー空Enter

root@u222c96:/etc/ssl/demoCA# openssl ca -in idp.csr -out idp.pem -extfile subjectnames.txt
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for /etc/ssl/demoCA/private/cakey.pem: <ーcakeyのパスフレーズを再度入力
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            6e:fa:be:0b:64:8b:ea:4c:c2:ee:c2:7b:62:b3:64:5f:52:40:59:2c
        Validity
            Not Before: Nov 23 06:24:02 2023 GMT
            Not After : Nov 22 06:24:02 2024 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = f5.si
            commonName                = idp.f5.si
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:idp.f5.si
Certificate is to be certified until Nov 22 06:24:02 2024 GMT (365 days)
Sign the certificate? [y/n]:y <ーyを入力しEnter


1 out of 1 certificate requests certified, commit? [y/n]y <ーyを入力しEnter
Write out database with 1 new entries
Data Base Updated
4-4.発行した証明書の確認

以下ファイルのうち、cacert.pem, idp.pem, idp.keyは後ほど使用しますので、ClientPC内などに保存しておきます。

root@u222c96:/etc/ssl/demoCA# ls
cacert.pem  crl        idp.key    index.txt.attr      newcerts  serial.old
careq.pem   crlnumber  idp.pem    index.txt.attr.old  private   subjectnames.txt
certs       idp.csr    index.txt  index.txt.old       serial

5.wso2インストール

5-1.OpenJDK11インストール

OpenJDK11をインストールします。
unzipは後ほど使用するため一緒にインストールしてしまいます。

apt update && \
apt -y install openjdk-11-jdk unzip

インストール完了後、以下のコマンドでPathを通します。

cat > /etc/profile.d/java.sh <<'EOF'
export JAVA_HOME=$(dirname $(dirname $(readlink $(readlink $(which java)))))
export PATH=$PATH:$JAVA_HOME/bin
EOF

source /etc/profile.d/java.sh

java --version

<出力例>
以下のように出力されればOKです。

root@u222c96:~# java --version
openjdk 11.0.21 2023-10-17
OpenJDK Runtime Environment (build 11.0.21+9-post-Ubuntu-0ubuntu122.04)
OpenJDK 64-Bit Server VM (build 11.0.21+9-post-Ubuntu-0ubuntu122.04, mixed mode, sharing)
5-2.wso2のDL

以下のサイトからDLしてください。ファイル名はwso2is-6.1.0.zipとなります。*5
wso2.com

DLが完了したら、wso2is-6.1.0.zipを/root/tmp/配下にコピーしておいてください。
コピー後、以下のコマンドで解凍します。

cd /root/tmp
unzip wso2is-6.1.0.zip

以降は、/root/tmp/wso2is-6.1.0/配下で作業をしていきます。

5-3.JKS(Java Key Store)ファイルの準備
5-3-1.証明書のコピー

4-4.で発行した証明書を/root/tmp/wso2is-6.1.0/repository/resources/security/配下にコピーします。

cp /etc/ssl/demoCA/cacert.pem /root/tmp/wso2is-6.1.0/repository/resources/security/
cp /etc/ssl/demoCA/idp.pem /root/tmp/wso2is-6.1.0/repository/resources/security/
cp /etc/ssl/demoCA/idp.key /root/tmp/wso2is-6.1.0/repository/resources/security/
5-3-2.証明書をpfx形式に変換

cacert.pem, idp.pem, idp.keyの3つの証明書を一旦pfx形式に変換します。

cd /root/tmp/wso2is-6.1.0/repository/resources/security

openssl pkcs12 -export \
-in idp.pem \
-inkey idp.key \
-name "idp.f5.si" \
-certfile cacert.pem \
-out idp-f5-si.pfx

<出力例>
以下のように出力されればOKです。

root@u222c96:~/tmp/wso2is-6.1.0/repository/resources/security# openssl pkcs12 -export \
-in idp.pem \
-inkey idp.key \
-name "idp.f5.si" \
-certfile cacert.pem \
-out idp-f5-si.pfx
Enter Export Password: <-パスフレーズを入力
Verifying - Enter Export Password:  <-パスフレーズを入力
5-3-3.pfx形式をjks形式に変換

続いて、idp-f5-si.pfxをjks形式に変換します。

keytool -importkeystore \
-srckeystore idp-f5-si.pfx \
-srcstoretype pkcs12 \
-destkeystore idp-f5-si.jks \
-deststoretype JKS

<出力例>
以下のように出力されればOKです。

root@u222c96:~/tmp/wso2is-6.1.0/repository/resources/security# keytool -importkeystore \
-srckeystore idp-f5-si.pfx \
-srcstoretype pkcs12 \
-destkeystore idp-f5-si.jks \
-deststoretype JKS
Importing keystore idp-f5-si.pfx to idp-f5-si.jks...
Enter destination keystore password: <-パスフレーズを入力
Re-enter new password: <-パスフレーズを入力
Enter source keystore password: <-パスフレーズを入力
Entry for alias idp.f5.si successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

補足1
以降、以下のようなWarningメッセージが表示されますが無視してください。

The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using~

補足2
wso2の仕様上、JKSのKeystore passwordとPrivate Key passwordを統一する必要があるため、各種パスワードやパスフレーズは「Password!」などに統一しておいた方が良いです。*6

5-3-4.証明書をTruststoreにインポート準備

一旦、idp-f5-si.jksから証明書をPEM形式で取り出します。

keytool -export \
-alias "idp.f5.si" \
-keystore idp-f5-si.jks \
-file idp-f5-si.pem

<出力例>
以下のように出力されればOKです。

root@u222c96:~/tmp/wso2is-6.1.0/repository/resources/security# keytool -export \
-alias "idp.f5.si" \
-keystore idp-f5-si.jks \
-file idp-f5-si.pem
Enter keystore password: <-パスフレーズを入力
Certificate stored in file 
5-3-5.証明書をTruststoreにインポート

取り出した証明書をclient-truststore.jksにインポートします。*7

keytool -import \
-alias idp.f5.si \
-file idp-f5-si.pem \
-keystore client-truststore.jks \
-storepass wso2carbon

<出力例>
以下のように出力されればOKです。

root@u222c96:~/tmp/wso2is-6.1.0/repository/resources/security# keytool -import \
-alias idp.f5.si \
-file idp-f5-si.pem \
-keystore client-truststore.jks \
-storepass wso2carbon
Owner: CN=idp.f5.si, O=f5.si, ST=Tokyo, C=JP
Issuer: CN=CA.f5.si, O=f5.si, ST=Tokyo, C=JP

--- snip ---

Trust this certificate? [no]:  yes <- yesと入力しEnter
Certificate was added to keystore
5-4.wso2の初期設定

deployment.tomlファイルを編集していきます。

vi /root/tmp/wso2is-6.1.0/repository/conf/deployment.toml

[server]
hostname = "idp.f5.si" <-localhostから変更
node_ip = "192.168.33.96" <-127.0.0.1から変更

--- snip ---
最終行に以下を追記

[keystore.tls]
file_name = "idp-f5-si.jks"
type = "JKS"
password = "Password!"
alias = "idp.f5.si"
key_password = "Password!"
5-5.wso2の起動

/root/tmp/wso2is-6.1.0/bin配下にあるshスクリプトを実行します。

cd /root/tmp/wso2is-6.1.0/bin

./wso2server.sh

<出力例>
以下のように出力されればOKです。

root@u222c96:~/tmp/wso2is-6.1.0/bin# ./wso2server.sh
JAVA_HOME environment variable is set to /usr/lib/jvm/java-11-openjdk-amd64
CARBON_HOME environment variable is set to /root/tmp/wso2is-6.1.0
Using Java memory options: -Xms256m -Xmx1024m
[2023-12-03 09:51:53,243]   INFO {org.ops4j.pax.logging.spi.support.EventAdminConfigurationNotifier} - Sending Event Admin notification (configuration successful) to org/ops4j/pax/logging/Configuration
[2023-12-03 09:51:53,416]   INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} - Starting WSO2 Carbon...
[2023-12-03 09:51:53,417]   INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} - Operating System : Linux 5.15.0-72-generic, amd64
[2023-12-03 09:51:53,418]   INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} - Java Home        : /usr/lib/jvm/java-11-openjdk-amd64
[2023-12-03 09:51:53,418]   INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} - Java Version     : 11.0.21
[2023-12-03 09:51:53,418]   INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} - Java VM          : OpenJDK 64-Bit Server VM 11.0.21+9-post-Ubuntu-0ubuntu122.04,Ubuntu
[2023-12-03 09:51:53,419]   INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} - Carbon Home      : /root/tmp/wso2is-6.1.0
[2023-12-03 09:51:53,419]   INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} - Java Temp Dir    : /root/tmp/wso2is-6.1.0/tmp
[2023-12-03 09:51:53,419]   INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} - User             : root, en-US, Asia/Tokyo
[2023-12-03 09:51:53,624]   INFO {org.wso2.carbon.event.output.adapter.kafka.internal.ds.KafkaEventAdapterServiceDS} - Successfully deployed the Kafka output event adaptor service
[2023-12-03 09:51:53,841]   INFO {org.wso2.carbon.identity.hash.provider.pbkdf2.internal.PBKDF2HashServiceComponent} - PBKDF2 bundle activated successfully.

--- snip ---

[2023-12-03 09:52:12,408]   INFO {openjpa.Runtime} - Starting OpenJPA 2.2.0-wso2v1
[2023-12-03 09:52:12,465]   INFO {openjpa.jdbc.JDBC} - Using dictionary class "org.apache.openjpa.jdbc.sql.H2Dictionary".
[2023-12-03 09:52:12,712]   INFO {org.wso2.carbon.core.transports.http.HttpTransportListener} - HTTP port        : 9763
[2023-12-03 09:52:12,713]   INFO {org.wso2.carbon.core.transports.http.HttpsTransportListener} - HTTPS port       : 9443
[2023-12-03 09:52:12,799]   WARN {org.apache.tomcat.util.net.SSLUtilBase} - The trusted certificate with alias [secomscrootca1] and DN [OU=Security Communication RootCA1, O=SECOM Trust.net, C=JP] is not valid due to [NotAfter: Sat Sep 30 13:20:49 JST 2023]. Certificates signed by this trusted certificate WILL be accepted
[2023-12-03 09:52:12,809]   INFO {org.apache.tomcat.util.net.NioEndpoint.certificate} - Connector [https-jsse-nio-9443], TLS virtual host [_default_], certificate type [UNDEFINED] configured from [/root/tmp/wso2is-6.1.0/repository/resources/security/idp-f5-si.jks] using alias [idp.f5.si] and with trust store [/root/tmp/wso2is-6.1.0/repository/resources/security/client-truststore.jks]
[2023-12-03 09:52:12,838]   INFO {org.wso2.carbon.bpel.core.ode.integration.BPELSchedulerInitializer} - Starting BPS Scheduler
[2023-12-03 09:52:12,849]   INFO {openjpa.Runtime} - Starting OpenJPA 2.2.0-wso2v1
[2023-12-03 09:52:12,850]   INFO {openjpa.jdbc.JDBC} - Using dictionary class "org.apache.openjpa.jdbc.sql.H2Dictionary" (H2 2.1.210 (2022-01-17) ,H2 JDBC Driver 2.1.210 (2022-01-17)).
[2023-12-03 09:52:12,893]   INFO {org.wso2.carbon.core.internal.StartupFinalizerServiceComponent} - Server           :  WSO2 Identity Server-6.1.0
[2023-12-03 09:52:12,895]   INFO {org.wso2.carbon.core.internal.StartupFinalizerServiceComponent} - WSO2 Carbon started in 23 sec
[2023-12-03 09:52:13,197]   INFO {org.apache.jasper.servlet.TldScanner} - At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
[2023-12-03 09:52:13,216]   INFO {org.wso2.carbon.ui.internal.CarbonUIServiceComponent} - Mgt Console URL  : https://idp.f5.si:9443/carbon/
[2023-12-03 09:52:13,250]   INFO {org.wso2.identity.apps.common.internal.AppsCommonServiceComponent} - My Account URL : https://idp.f5.si:9443/myaccount
[2023-12-03 09:52:13,251]   INFO {org.wso2.identity.apps.common.internal.AppsCommonServiceComponent} - Console URL : https://idp.f5.si:9443/console
[2023-12-03 09:52:13,252] []  INFO {org.wso2.identity.apps.common.internal.AppsCommonServiceComponent} - Identity apps common service component activated successfully.

wso2は、Ctrl+cで停止させることができます。

5-6.wso2管理コンソールログイン

ClientPCなどから管理コンソールにログインします。
https://idp.f5.si:9443/carbon/にアクセス
Username: admin
Password: admin

以降は、ClientPC側から、https://idp.f5.si:9443/carbon/にアクセスしながら設定を進めて行きます。
当然、Internetに晒されているため、SrcIPをGlobalIP-Bだけに絞るなど、BBルータA上で各種セキュリティ設定を行っておいてください。*8

https://idp.f5.si:9443/carbon/にアクセスした際、ブラウザ上に証明書の警告が表示されますので、/etc/ssl/demoCA/cacert.pemをクライアントPCの信頼されたルート証明機関にインストールしておいてください。

6.wso2の各種設定

設定を行う前にKeycloakとの設定項目名を比較してみます。

wso2の項目名 Keycloakの項目名 備考
Tenant Realm 管理ドメインを作成します。
User Stores User federation ADやLDAPとの連携設定を行います。
Claims Mappers Attributeのマッピングを行います。
Service Provider Clients SAML SPの設定を行います。*9

実装の違いにより項目の詳細は異なっていますが、やろうとしていることは同じです。
どの項目で何ができるかを把握していれば充分だと思います。

6-1.テナントの作成

wso2上にテナントを作成します。*10

6-1-1.新規テナントの作成

Configure>Mutitenancy>Add New Tenantをクリック
必要項目を記載します。

項目 設定値 備考
Domain example.com ADのDomain名と一致させてください
Select Usage Plan For Tenant Demo 他に選択できないためこのままでOKです
First Name super 任意の名前でOKです
Last Name user 任意の姓でOKです
Admin username admin wso2のexample.comテナントにログインする際、admin@example.comとなります
Admin Password Password! 任意のパスワードでOKです
Email admin@example.com 任意のEmailでOKです

以下のように設定してください。そして、Saveをクリック。

テナント作成後、
Configure>Mutitenancy>View Tenantsをクリックすると、テナントの詳細が確認できます。
このテナント上で各種設定を行っていきます。
右上のSign-outをクリックして、一旦サインアウトします。

6-1-2.新規テナントへのログイン

テナントへログインする際は、前項で作成したアカウントでログインしてください。
Username:admin@example.com *11
Password:Password!
以降はこのテナントで作業しますので、上記クレデンシャルを入力してwso2にログインしてください。

6-6.ADとの連携設定

最初にGUIで設定後、CLIで追加設定を行います。*12

6-6-1.GUIでの設定

Main>Identity>User Stores>Addをクリック
必要項目を記載します。

項目 設定値 備考
User Store Manager Class org.wso2.carbon.user.core.ldap.UniqueIDActiveDirectoryUserStoreManager
Domain Name example.com ADのDomain名と一致させます
Connection URL ldap://192.168.240.91:389 ポート番号まで入れてください
Connection Name CN=Administrator,CN=Users,DC=example,DC=com
Connection Password 上記アカウントのパスワード
User Search Base CN=Users,DC=example,DC=com

<Optional>

項目 設定値 備考
Group Search Base CN=Users,DC=example,DC=com

<Advanced>

項目 設定値 備考
Default Realm Name EXAMPLE.COM ほぼ使う事はありませんがKrbのレルム名です

以下のように設定してください。そして、Addをクリック。

6-6-2.CLIでの追加設定

設定ファイルを直接編集するため、一旦wso2をCtrl+cで停止させます。
作成したテナントのUser Stores設定ファイルは以下のPathに存在します。*13
/root/tmp/wso2is-6.1.0/repository/tenants/1/userstores/example_com.xml
このファイルに直接編集&追記していきます。
赤文字が修正、青文字は行を追記します。

vi /root/tmp/wso2is-6.1.0/repository/tenants/1/userstores/example_com.xml

<Property name="UserNameSearchFilter">(&amp; (objectClass=user)(|(userPrincipalName=?)(sAMAccountName=?)))</Property>
<Property name="UserNameJavaRegEx">[a-zA-Z0-9@._-|//]{3,30}$</Property>
<Property name="UserNameJavaScriptRegEx">[a-zA-Z0-9._-|//]{3,30}$</Property>
<Property name="UserNameWithEmailJavaScriptRegEx">[a-zA-Z0-9@._-|//]{3,30}$</Property>

補足
以下3項目は"6-6-1.GUIでの設定"でも設定可能です。*14

CLI上での設定名 GUI上での設定名 備考
UserNameSearchFilter User Search Filter 赤文字を入力。CLI上での"amp;"はエスケープなので、GUI上では入力不要です。
UserNameJavaRegEx Username RegEx (Java) 赤文字を入力。本項目は<Optional>の中ほどにあります。
UserNameJavaScriptRegEx Username RegEx (Javascript) 赤文字を入力。本項目は<Optional>の中ほどにあります。

以下の項目だけはCLIでの設定が必要となります。

UserNameWithEmailJavaScriptRegEx
6-6-3.wso2の起動

修正が完了したら、再度wso2を起動します。

cd /root/tmp/wso2is-6.1.0/bin

./wso2server.sh

wso2起動後に再度テナントにログインすると、以下のようなメッセージが表示されれば、ADとディレクトリ情報の同期が取れています。*15

[2023-12-03 16:06:46,651] [7569af63-31c8-45db-ade5-1ca3100a299f]  WARN {org.wso2.carbon.user.core.ldap.UniqueIDActiveDirectoryUserStoreManager} - Connection to the Active Directory is not secure. Password involved operations such as update credentials and adduser operations will fail
[2023-12-03 16:06:46,661] [7569af63-31c8-45db-ade5-1ca3100a299f]  INFO {org.wso2.carbon.user.core.ldap.UniqueIDReadWriteLDAPUserStoreManager} - LDAP connection created successfully in read-write mode
6-7.Claimsの設定

続いて、属性マッピングの設定を行っていきます。

6-7-1.upnの追加

Main>Identity>Claims>Add>Add Local Claimをクリック
必要項目を記載します。

項目 設定値 備考
Claim URI http://wso2.org/claims/upn
Display Name userPrincipalName
Description userPrincipalName
Mapped Attribute userPrincipalName PRIMARYの右側の空欄に入力します
Supported by Default チェックを入れる

以下のように設定してください。そして、Addをクリック。

6-7-2.usernameの変更

Main>Identity>Claims>List>http://wso2.org/claimsをクリック
スクロールダウンして、Usernameの右横のEditをクリック
Mapped Attributeのuidー>cnに変更。
以下のように設定してください。そして、Updateをクリック。

6-8.Service Providerの設定

SPの設定となりますが、ここではIdpのMetadataを出力するところまでの手順に留めます。

6-8-1.Service Providerの追加

Main>Identity>Service Providers>Addをクリック
Service Provider NameにWordPressと入力。
以下のように設定してください。そして、Registerをクリック

6-8-2.Service Providerの基本設定

必要項目を記載します。

項目 設定値 備考
SaaS Application チェックを入れる

<Claim Configuration>

項目 設定値 備考
Subject Claim URI http://wso2.org/claims/upn プルダウンメニューより選択。一番下の方にあります。
Service Provider Claim Dialect http://wso2.org/claimsを選択してAddをクリック Addをクリックすると、すぐ下に表示されます。

以下のように設定してください。そして、Updateをクリック

6-8-3.Idp Metadaの出力

一旦元の画面に戻るので、Editをクリック

Inbound Authentication Configuration>SAML2 Web SSO Configurationをクリックして、Configureをクリック

一番下までスクロールダウンして、Download IDP Metadataボタンをクリック。
後ほど、Wordpressにインポートしますので、idp.xmlとして保存しておきます。
一旦、Cancelをクリック。


7.Wordpressインストール&各種設定

7-3-2.までは、Keycloakの時と同じ手順となります。

7-1.Wordpressインストール

以下のサイトからWordpressOVAファイルをDLします。
bitnami.com
OVAファイルをVMWare上にデプロイしてください。

7-2.Wordpress初期設定

構成図に基づき、ssh接続やIPアドレス設定を記載しています。
Defaultでは、DHCP設定にてIPアドレスを自動取得しますが、自動取得が特に気にならない方は、7-2-3までスキップしてください。*16

7-2-1.OSコンソールへのログインとssh設定

以下のクレデンシャルでログインしてください。

ユーザ名:bitnami
パスワード:bitnami

sshのパスワード接続を許可したいので、PasswordAuthenticationのコメントアウトを外します。

sudo vi /etc/ssh/sshd_config

PasswordAuthentication yes

その後、以下のコマンドでsshサーバを起動します。

sudo rm -f /etc/ssh/sshd_not_to_be_run
sudo systemctl enable ssh
sudo systemctl start ssh
7-2-2.IPアドレス設定

ssh接続後、IPアドレスを変更します。*17

sudo vi /etc/systemd/network/25-wired.network

[Match]
Name=ens*

[Network]
Address=192.168.11.94/24
Gateway=192.168.11.1
DNS=192.168.11.1

設定が完了したら、一旦再起動します。

7-2-3.Wordpressコンソールへのログイン

再起動後、VMWareのコンソール上に以下のような画面が表示されます。

ClientPCから以下のURLにアクセスしてください。
補足:パスワードはWordpressをデプロイするたびに自動生成されるため都度変更されます。

http://192.168.11.94/admin/
ユーザ名:user
パスワード:vfwUWFiS25BR

以下のような画面で上記クレデンシャルを入力しログインします。

ログインすると以下の画面が表示されます。
Please update nowをクリックして、最新Verにアップデートしておきます。

初回ログイン時は、WordpressのローカルDBを使用しました。
ここから、WordpressSAML SPとして設定することにより、wso2 IdpによるSAML認証ができるように設定をしていきます。

7-3.WordpressSAML SP設定
7-3-1.SAML Plug-inのインストール

Plugins>Add New Pluginをクリック

画面右上Keywordの右側にsamlと入力すると検索候補が表示されます。
SAML Single Sign On - SSO LoginのInstall Nowをクリックします。*18

インストールが完了すると以下の表示に切り替わるので、Activateをクリック

以下の画面が表示されるので、Configure Your IDP Nowをクリック*19

7-3-2.SAML Idp(wso2) Metadataのインポート

画面中央のUpload IDP Metadataタブをクリックします。
Identity Provider Nameには、任意の名前を入力(ここでは例として、wso2と入力)
ファイル選択をクリックし、6-8-3.Idp Metadaの出力で保存したidp.xmlを選択
そして、Uploadをクリック

idp.xmlファイルのアップロードが成功すると、以下の画面が表示。
画面を下スクロールしてSaveをクリック

7-3-3.SAML SP(Wordpress) Metadataのエクスポート

画面上部のService Provider Metadataタブをクリックし、Downloadをクリック
任意のファイル名(ここでは例として、sp.xml)でClientPCに保存

7-3-4.wso2 SP Metadataのインポート

ここからはwso2のexample.comテナントにログインして作業を進めます。
Main>Identity>Service Providers>Listをクリック
WordPressの右横のEditをクリック

Inbound Authentication Configuration>SAML2 Web SSO Configurationをクリックして、Configureをクリック

Metadata File Configurationをクリック
ファイルを選択をクリックして、Wordpressからエクスポートしたsp.xmlを選択
Uploadをクリック

以下の画面に戻るので、SAML2 Web SSO ConfigurationのEditをクリック

以下2つの項目にチェック
Enable Attribute Profile
Include Attributes in the Response Always
画面を一番下までスクロールダウンして、Updateをクリック

元の画面に戻り、SAML2 Web SSO ConfigurationのAttribute Consuming Service Indexの項目に任意の数字が表示されます。

以上で設定は完了です。
ここからは動作確認をしていきます。




8.動作確認

動作確認前に、ここでもう一度構成を確認しておきましょう。

  1. ClientPCー>WordPress SPにアクセスし、SAML認証を選択
  2. ClientPCー>wso2 Idpにリダイレクトされ、クレデンシャルを入力
  3. ClientPCー>WordPress SPにリダイレクトされ、ログイン完了後の画面が表示

fig.1

ClientPCから以下URLにアクセス
http://192.168.11.94/admin/
Login with wso2をクリック

wso2の方にリダイレクトされるので、クレデンシャルを入力して、Continueをクリック

以下の警告画面が表示されますが、そのまま送信するをクリック*20

ログイン完了後、以下の画面が表示されます。

以上です。

*1:同じ挙動を別アプリで動作させてみることは極めて重要です。なぜなら、障害時の切り分けに活用できるからです。加えて、規格で定義されているパラメータと、アプリ独自実装のパラメータが明確に把握できるからです。その上で、規格のドキュメントを読むと、より理解が深まります。

*2:wso2のデフォルト待ち受けポートはTCP9443となります。KeycloakのときはTCP8443でしたので、wso2とKeycloakを並行運用可能です。

*3:もう少し掘り下げて検証すれば、Hostname=IPアドレスでも、うまく動作する可能性はあります。しかし、IPアドレスのままでKeycloakを動作させることが目的ではないため、私は素直にドメイン登録をしました。

*4:このユーザ名は一番最後の動作確認時に利用します。

*5:DLする際にメアドの登録が必要となります。メアド登録に抵抗がある方は、ソースからビルドすることも可能です。ビルドする場合はMaven3.xが必要となります。私がビルドした際、完了までに約30分程度要しました。こちらのgithubからソースをDLすることが可能です。https://github.com/wso2/product-is/tree/v6.1.0

*6:セキュリティ上はよろしくないですが、初めてトライするときは、統一しておいた方が混乱せずに済むと思います。2回目以降は、どこが統一されていないとダメで、どこが異なっていても良いかなどを確認しながら進めてください。

*7:client-truststore.jksは、wso2にDefaultで存在するJKSファイルです。ここには信頼された証明書が格納されています。各種Docを読む限り、この手順となっているのですが、私個人的には、cacert.pemをインポートすれば良いのでは?と思っています。時間のあるときに検証してみようと思います。

*8:本来であれば、リバプロやWAFの導入といった作業をした方が良いです。

*9:本記事ではSAML Idpの設定方法を記載しているため、「SAML SPの設定を行います」、と記載しました。しかし、wso2もKeycloakもCAS(Central Authentication Service)なので、SAMLだけなく、OAuthなど他の認証方式でも本項目を利用します。このため、本来はSAML SPに限定されないという点に留意してください。

*10:初期設定ではadminテナントが存在していますが、名前の通りadminなので、これとは別にIdpとして利用するためのテナントを別途作成します。

*11:@example.comの部分でログインするテナントを識別しています。

*12:これは、UPN(userPrincipalName)とSAM(sAMAccountName より厳密にはcnとなります)の両方でログイン可能とするための設定となります。

*13:/root/tmp/wso2is-6.1.0/repository/tenants/までは決まっています。1/は1番目に作成したテナントを意味しています。userstores/も決まっています。example_com.xmlは、テナント作成時に指定したドメイン名により決まります。例:example.comであれば、example_com.xmlとなります。

*14:はてな記法の関係上、テーブル内で、|(パイプ)とか;(セミコロン)のエスケープができなかったため、CLI上での設定として記載しました。どなたか良い方法があれば教えてください。

*15:Warningメッセージはldapsで通信していないため表示されていますので今回の構成であれば無視してOKです。

*16:Wordpressの最新Ver6.4.1の場合、この方法でIPアドレス設定ができませんでした。Wordpressのマニュアルを読む限り、VMWare上の設定が必要とのことで、VMWare関連ドキュメントへのリンクが大量に掲載されたページしか表示されなかったため、Ver5.9.0を使用しています。ここは頑張りどころではないため古いVer5.9.0でスルーしましたが、WordpressはDebian11で動作しているため、Debian11のネットワーク設定を少しいじればサクッと設定できるかもしれません。

*17:DefaultではDHCP設定となっているため固定IP設定とします。Internetに出られれば良いので、DHCP設定のままでも構いません。

*18:似たような候補でLogin using WordPress Users(WP asSAML IDP)が表示されますが無視してください。

*19:画面に表示されているwso2をクリックすると、wso2の設定マニュアルが表示されます。

*20:ClientPCからWordpressにクレデンシャルが平文で送信されます。一般的に、SAML IdpとSP間で直接通信することはなく、必ずClientPCを経由して通信します。今回の構成では、SAML SPであるWordpressSSL化されていなくても、ClientPCとWordpress間はローカルNW内の通信となり、クレデンシャルがInternetに晒されることはないので特に問題ありません。

KeycloakによるSAML Idpの設定方法

Keycloakを使用したSAML Idpの設定方法を記載していきます。
ここでは動作確認用としてWordpressSAML SPとします。
Keycloakの認証バックエンドには、Windows2019のADを使用します。

1.構成

1-1.環境

全ての端末(仮想マシン)はVMWare上に構築しています。

VMWare : VMware(R) Workstation 15 Pro 15.5.1 build-15018445 

Keycloak用仮想マシン
OS : Ubuntu 22.04.2
Java : openjdk-17
Keycloak : 22.0.5
OpenSSL : 3.0.2

Wordpress仮想マシン
bitnami-wordpress-5.9.0
OVAからデプロイ

Active Directory仮想マシン
OS : Windows Server 2019

ClientPC用仮想マシン
OS : Windows10
1-2.全体の流れ
  • ドメイン登録
  • AD構築
  • 証明書発行
  • Keycloakインストール
  • Keycloak 各種設定
  • Wordpress インストール&各種設定
  • 動作確認
1-3.全体構成

fig.1

IPアドレスドメイン名は自身の環境に置き換えてください。
私の環境ではヘアピンNATができないためBBルータが2台あります。
BBルータAの方で、TCP8443でポートフォワードの設定をしています。*1

2.ドメイン登録

自身で独自ドメインを取得するか、以下のサイトなどで無料のドメイン登録を行ってください。
ddns.kuku.lu
ここでは上記サイトで、idp.f5.siのドメインを登録したものとして進めます。
登録したドメインを使用して、AレコードにGlobalIP-AのIPアドレスを設定しておいてください。

補足
KeycloakのHostname設定に、IPアドレスを設定していると、HTTPリダイレクトの際にうまく動作しなかったり、といったことを確認したため、ドメイン登録の項を記載しました。
仮に、閉じられた環境内で構築する場合であっても、別途DNSサーバを構築して、名前解決可能な環境にしておくことが必要だと考えています。*2

3.AD構築

以下のサイトなどを参考にADの構築を行ってください。
www.rem-system.com
上記サイトは、スクショ入りのStep by Stepで詳細に記載されており、特に躓くことなくADを構築できます。

ADはKeycloakの認証バックエンドとして利用しますので、AD上に任意のユーザを2-3つくらい作成しておいてください。
ここでは例として、user001@example.comといったユーザを作成したものとして進めます。*3
補足
AD上でユーザを作成する際、以下のように作成されていることを前提として進めます。

4.証明書発行

ここからは、Keycloak用仮想マシンでの作業となります。

4-1.openssl.cnfの設定

/etc/ssl/openssl.cnfファイルを編集します。
青文字箇所が変更した部分となります。

vi /etc/ssl/openssl.cnf
==== snip ====
[ CA_default ]

dir             = /etc/ssl/demoCA      # Where everything is kept  ./demoCAから絶対Pathに変更
certs           = $dir/certs            # Where the issued certs are kept

==== snip ====
[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = JP
countryName_min                 = 2
countryName_max                 = 2

stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = Tokyo

localityName                    = Locality Name (eg, city)
localityName_default            = Chiyoda-ku

0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = f5.si

# we can do this but it is not needed normally :-)
#1.organizationName             = Second Organization Name (eg, company)
#1.organizationName_default     = World Wide Web Pty Ltd

organizationalUnitName          = Organizational Unit Name (eg, section)
#organizationalUnitName_default =

commonName                      = Common Name (e.g. server FQDN or YOUR name)
commonName_max                  = 64
==== snip ====
4-2.CAの構築

/usr/lib/ssl/misc/CA.plを使用して、CAを構築していきます。

cd /etc/ssl
/usr/lib/ssl/misc/CA.pl -newca

<出力例>

root@u222c96:/etc/ssl# /usr/lib/ssl/misc/CA.pl -newca
CA certificate filename (or enter to create) <ー空Enter

Making CA certificate ...
openssl req  -new -keyout ./demoCA/private/cakey.pem -out ./demoCA/careq.pem
..+......+....+..+.......+.....+.......+.....+....+.....+.+......+........+....+...+.................+.+..+...+....+...+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+...+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+.+.....+...+.+..+...+......+.........+....+...................................+..........+......+..+.......+............+......+.................+.......+...+......+.....+.....................+......+.......+.....+......+....+..+...+............+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
..+.+..............+.+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+.+...+.....+.+.....+....+..+.........+..........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+.....+......+...+....+......+..+.........+...+.+......+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Enter PEM pass phrase: <ーパスフレーズを入力
Verifying - Enter PEM pass phrase: <ーパスフレーズを入力
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [JP]: <ー空Enter
State or Province Name (full name) [Tokyo]: <ー空Enter
Locality Name (eg, city) [Chiyoda-ku]: <ー空Enter
Organization Name (eg, company) [f5.si]: <ー空Enter
Organizational Unit Name (eg, section) : <ー空Enter
Common Name (e.g. server FQDN or YOUR name) :CA.f5.si <ーCAのCommon Nameを手入力。任意の名前でOK
Email Address : <ー空Enter

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password : <ー空Enter
An optional company name []: <ー空Enter
==> 0
openssl ca  -create_serial -out ./demoCA/cacert.pem -days 1095 -batch -keyfile ./demoCA/private/cakey.pem -selfsign -extensions v3_ca -infiles ./demoCA/careq.pem
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem: <ー最初に入力した(cakeyの)パスフレーズを再度入力
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            6e:fa:be:0b:64:8b:ea:4c:c2:ee:c2:7b:62:b3:64:5f:52:40:59:2b
        Validity
            Not Before: Nov 23 00:12:36 2023 GMT
            Not After : Nov 22 00:12:36 2026 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = f5.si
            commonName                = CA.f5.si
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                3B:BE:09:A3:AF:51:5A:6A:D5:3F:DD:C1:D2:60:4A:88:E9:F8:79:BF
            X509v3 Authority Key Identifier:
                3B:BE:09:A3:AF:51:5A:6A:D5:3F:DD:C1:D2:60:4A:88:E9:F8:79:BF
            X509v3 Basic Constraints: critical
                CA:TRUE
Certificate is to be certified until Nov 22 00:12:36 2026 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated
==> 0
CA certificate is in ./demoCA/cacert.pem

これにより、/etc/ssl配下に、demoCAというディレクトリが作成されます。
/etc/ssl/demoCA配下に、CAのルート証明書が格納されています。
/etc/ssl/demoCA/private配下に、CAのキーファイルが格納されています。

4-3.Idpで利用する証明書を発行

/etc/ssl/demoCA配下でIdpの証明書を発行します。
初めに、SAN(Subject Altanative Name)設定ファイルを作成します。

cat > /etc/ssl/demoCA/subjectnames.txt <<EOF
subjectAltName = DNS:idp.f5.si
EOF
cd /etc/ssl/demoCA
openssl genrsa -out idp.key 2048
openssl req -utf8 -new -key idp.key -out idp.csr
openssl ca -in idp.csr -out idp.pem -extfile subjectnames.txt

<出力例>

root@u222c96:/etc/ssl/demoCA# cd /etc/ssl/demoCA
root@u222c96:/etc/ssl/demoCA# openssl genrsa -out idp.key 2048
root@u222c96:/etc/ssl/demoCA# openssl req -utf8 -new -key idp.key -out idp.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [JP]: <ー空Enter
State or Province Name (full name) [Tokyo]: <ー空Enter
Locality Name (eg, city) [Chiyoda-ku]: <ー空Enter
Organization Name (eg, company) [f5.si]: <ー空Enter
Organizational Unit Name (eg, section) : <ー空Enter
Common Name (e.g. server FQDN or YOUR name) :idp.f5.si <ーidp.f5.siと入力
Email Address :

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password : <ー空Enter
An optional company name []: <ー空Enter

root@u222c96:/etc/ssl/demoCA# openssl ca -in idp.csr -out idp.pem -extfile subjectnames.txt
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for /etc/ssl/demoCA/private/cakey.pem: <ーcakeyのパスフレーズを再度入力
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            6e:fa:be:0b:64:8b:ea:4c:c2:ee:c2:7b:62:b3:64:5f:52:40:59:2c
        Validity
            Not Before: Nov 23 06:24:02 2023 GMT
            Not After : Nov 22 06:24:02 2024 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = f5.si
            commonName                = idp.f5.si
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:idp.f5.si
Certificate is to be certified until Nov 22 06:24:02 2024 GMT (365 days)
Sign the certificate? [y/n]:y <ーyを入力しEnter


1 out of 1 certificate requests certified, commit? [y/n]y <ーyを入力しEnter
Write out database with 1 new entries
Data Base Updated
4-4.発行した証明書の確認

以下ファイルのうち、cacert.pem, idp.pem, idp.keyは後ほど使用しますので、ClientPC内などに保存しておきます。

root@u222c96:/etc/ssl/demoCA# ls
cacert.pem  crl        idp.key    index.txt.attr      newcerts  serial.old
careq.pem   crlnumber  idp.pem    index.txt.attr.old  private   subjectnames.txt
certs       idp.csr    index.txt  index.txt.old       serial

5.Keycloakインストール

5-1.OpenJDK17インストール
apt update && \
apt -y install openjdk-17-jdk
5-2.KeycloakソースDL
mkdir /root/tmp && \
cd /root/tmp && \
wget https://github.com/keycloak/keycloak/releases/download/22.0.5/keycloak-22.0.5.tar.gz && \
tar zxvf keycloak-22.0.5.tar.gz
5-3.Keycloak初期起動

ローカルホスト名に任意のホスト名を追記します。
これを実施しないと、Keycloak起動時にエラーで起動できない場合があるためです。
idp.f5.siのようにFQDNで記載しないでください。

vi /etc/hosts

127.0.0.1 localhost idp <ー ローカルホスト名にidpを追記

続いて、管理者アカウントの設定を行います。
ここでは例として、ユーザ名:admin、パスワード:Password!とします。
環境変数に設定後、echoコマンドで確認します。

KEYCLOAK_ADMIN=admin && \
export KEYCLOAK_ADMIN && \
KEYCLOAK_ADMIN_PASSWORD=Password! && \
export KEYCLOAK_ADMIN_PASSWORD

echo $KEYCLOAK_ADMIN
echo $KEYCLOAK_ADMIN_PASSWORD

<出力例>
以下のように出力されればOKです。

root@u222c93:~/tmp# echo $KEYCLOAK_ADMIN
admin
root@u222c93:~/tmp# echo $KEYCLOAK_ADMIN_PASSWORD
Password!

それでは、Keycloakを起動します。

cd /root/tmp/keycloak-22.0.5/bin/
./kc.sh start-dev

<出力例>

root@u222c93:~/tmp/keycloak-22.0.5/bin# ./kc.sh start-dev
Updating the configuration and installing your custom providers, if any. Please wait.
2023-11-23 16:14:12,828 INFO  [io.quarkus.deployment.QuarkusAugmentor] (main) Quarkus augmentation completed in 5769ms
2023-11-23 16:14:14,012 INFO  [org.keycloak.quarkus.runtime.hostname.DefaultHostnameProvider] (main) Hostname settings: Base URL: , Hostname: , Strict HTTPS: false, Path: , Strict BackChannel: false, Admin URL: , Admin: , Port: -1, Proxied: false
2023-11-23 16:14:14,961 WARN  [io.quarkus.agroal.runtime.DataSources] (main) Datasource  enables XA but transaction recovery is not enabled. Please enable transaction recovery by setting quarkus.transaction-manager.enable-recovery=true, otherwise data may be lost if the application is terminated abruptly
2023-11-23 16:14:15,348 WARN  [org.infinispan.PERSISTENCE] (keycloak-cache-init) ISPN000554: jboss-marshalling is deprecated and planned for removal
2023-11-23 16:14:15,421 WARN  [org.infinispan.CONFIG] (keycloak-cache-init) ISPN000569: Unable to persist Infinispan internal caches as no global state enabled
2023-11-23 16:14:15,499 INFO  [org.infinispan.CONTAINER] (keycloak-cache-init) ISPN000556: Starting user marshaller 'org.infinispan.jboss.marshalling.core.JBossUserMarshaller'
2023-11-23 16:14:16,050 INFO  [org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory] (main) Node name: node_127375, Site name: null
2023-11-23 16:14:16,055 INFO  [org.keycloak.broker.provider.AbstractIdentityProviderMapper] (main) Registering class org.keycloak.broker.provider.mappersync.ConfigSyncEventListener
2023-11-23 16:14:18,460 INFO  [org.keycloak.quarkus.runtime.storage.legacy.liquibase.QuarkusJpaUpdaterProvider] (main) Initializing database schema. Using changelog META-INF/jpa-changelog-master.xml

UPDATE SUMMARY
Run:                        115
Previously run:               0
Filtered out:                 0
-------------------------------
Total change sets:          115

2023-11-23 16:14:21,812 INFO  [org.keycloak.services] (main) KC-SERVICES0050: Initializing master realm
2023-11-23 16:14:23,400 INFO  [io.quarkus] (main) Keycloak 22.0.5 on JVM (powered by Quarkus 3.2.7.Final) started in 10.483s. Listening on: http://0.0.0.0:8080
2023-11-23 16:14:23,401 INFO  [io.quarkus] (main) Profile dev activated.
2023-11-23 16:14:23,401 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-h2, jdbc-mariadb, jdbc-mssql, jdbc-mysql, jdbc-oracle, jdbc-postgresql, keycloak, logging-gelf, micrometer, narayana-jta, reactive-routes, resteasy, resteasy-jackson, smallrye-context-propagation, smallrye-health, vertx]
2023-11-23 16:14:23,521 INFO  [org.keycloak.services] (main) KC-SERVICES0009: Added user 'admin' to realm 'master'
2023-11-23 16:14:23,522 WARN  [org.keycloak.quarkus.runtime.KeycloakMain] (main) Running the server in development mode. DO NOT use this configuration in production.

<補足1>
Ctrl+c でKeycloakを停止することが可能です。

<補足2>
もし、起動時にエラーが出力される場合は、以下3つのいずれかをそれぞれ試してください。

./kc.sh start-dev --db-pool-initial-size=100
./kc.sh start-dev --db-pool-max-size=100
./kc.sh start-dev --db-pool-min-size=100

私が試した結果、基本的には最初に記載した/etc/hostsファイルのローカルホストに任意のホスト名(FQDNはNG)を記載するだけで問題なく起動するはずです。

5-4.Keycloak管理コンソールログイン

管理コンソールにログインします。
ここではログインテストとして、ローカルのNWセグメント(192.168.240.0/24 or 192.168.33.0/24)から、http://192.168.240.93:8080/ もしくはhttp://192.168.33.93:8080/にログインしてください。

http://192.168.240.93:8080/にアクセス
Administration Consoleをクリック

ユーザ名とパスワードを入力して、Sign Inをクリック

Keycloakのメイン画面が表示されます。

ここではログインテストとして、http://192.168.240.93:8080/にアクセスしましたが、実際はClientPCがInternet経由でIdpにアクセスします。(fig.1参照)
このため、この後の項では、登録したドメイン名でのアクセスやSSL化するための設定を実施していきます。
fig.1

6.Keycloak各種設定

既に起動してあるKeycloakは、Ctrl+cで一旦停止しておいてください。

6-1.証明書ファイルのコピー

idp.pem, idp.keyをコピーしておきます。

cp /etc/ssl/demoCA/idp.pem /root/tmp/keycloak-22.0.5/conf/
cp /etc/ssl/demoCA/idp.key /root/tmp/keycloak-22.0.5/conf/
6-2.keycloak.conf設定

SSL化設定やKeycloakのホスト名設定を実施します。

vi /root/tmp/keycloak-22.0.5/conf/keycloak.conf

=====snip=====
# The file path to a server certificate or certificate chain in PEM format.
#https-certificate-file=${kc.home.dir}conf/server.crt.pem
https-certificate-file=/root/tmp/keycloak-22.0.5/conf/idp.pem

# The file path to a private key in PEM format.
#https-certificate-key-file=${kc.home.dir}conf/server.key.pem
https-certificate-key-file=/root/tmp/keycloak-22.0.5/conf/idp.key

=====snip=====

# Hostname for the Keycloak server.
#hostname=myhostname
hostname=idp.f5.si
6-3.keycloak起動

それでは、改めてKeycloakを起動します。*4

cd /root/tmp/keycloak-22.0.5/bin/
./kc.sh start-dev

<出力例>
初回起動と大きく異なる点は、https://0.0.0.0:8443が追加された点です。

root@u222c93:~/tmp/keycloak-22.0.5/bin# ./kc.sh start-dev
2023-11-23 16:56:54,173 INFO  [org.keycloak.quarkus.runtime.hostname.DefaultHostnameProvider] (main) Hostname settings: Base URL: , Hostname: idp.f5.si, Strict HTTPS: false, Path: , Strict BackChannel: false, Admin URL: , Admin: , Port: -1, Proxied: false
2023-11-23 16:56:55,317 WARN  [io.quarkus.agroal.runtime.DataSources] (main) Datasource  enables XA but transaction recovery is not enabled. Please enable transaction recovery by setting quarkus.transaction-manager.enable-recovery=true, otherwise data may be lost if the application is terminated abruptly
2023-11-23 16:56:55,654 WARN  [org.infinispan.PERSISTENCE] (keycloak-cache-init) ISPN000554: jboss-marshalling is deprecated and planned for removal
2023-11-23 16:56:55,705 WARN  [org.infinispan.CONFIG] (keycloak-cache-init) ISPN000569: Unable to persist Infinispan internal caches as no global state enabled
2023-11-23 16:56:55,749 INFO  [org.infinispan.CONTAINER] (keycloak-cache-init) ISPN000556: Starting user marshaller 'org.infinispan.jboss.marshalling.core.JBossUserMarshaller'
2023-11-23 16:56:56,584 INFO  [org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory] (main) Node name: node_752132, Site name: null
2023-11-23 16:56:56,589 INFO  [org.keycloak.broker.provider.AbstractIdentityProviderMapper] (main) Registering class org.keycloak.broker.provider.mappersync.ConfigSyncEventListener
2023-11-23 16:56:57,637 INFO  [io.quarkus] (main) Keycloak 22.0.5 on JVM (powered by Quarkus 3.2.7.Final) started in 4.471s. Listening on: http://0.0.0.0:8080 and https://0.0.0.0:8443
2023-11-23 16:56:57,637 INFO  [io.quarkus] (main) Profile dev activated.
2023-11-23 16:56:57,637 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-h2, jdbc-mariadb, jdbc-mssql, jdbc-mysql, jdbc-oracle, jdbc-postgresql, keycloak, logging-gelf, micrometer, narayana-jta, reactive-routes, resteasy, resteasy-jackson, smallrye-context-propagation, smallrye-health, vertx]
2023-11-23 16:56:57,641 WARN  [org.keycloak.quarkus.runtime.KeycloakMain] (main) Running the server in development mode. DO NOT use this configuration in production.
6-4.Keycloak管理コンソールログイン

改めて管理コンソールにログインします。
https://idp.f5.si:8443/にアクセス

以降は、ClientPC側から、https://idp.f5.si:8443/にアクセスしながら設定を進めて行きます。
当然、Internetに晒されているため、SrcIPをGlobalIP-Bだけに絞るなど、BBルータA上で各種セキュリティ設定を行っておいてください。*5

https://idp.f5.si:8443/にアクセスした際、ブラウザ上に証明書の警告が表示されますので、/etc/ssl/demoCA/cacert.pemをクライアントPCの信頼されたルート証明機関にインストールしておいてください。

6-5.レルムの作成

KeycloaK上にレルムを作成します。*6

masterのプルダウンメニューから、Create Realmをクリック

Realm nameに任意の名前を入力して、Createをクリック*7
ここでは例として、KC_Idpとします。

KC_Idpレルムが作成されました。このレルム上で各種設定を行っていきます。

6-6.ADとの連携設定

サイドメニューの一番下にあるUser federationをクリック

User federation画面にて、Add Ldap providersをクリック

設定が必要な項目のみピックアップします。

項目 設定値 備考
UI display name ADDC 任意の名前でOKです。
Connection URL ldap://192.168.240.92
BindDN CN=Administrator,CN=Users,DC=example,DC=com DC=example,DC=comの部分は自身の環境に合わせて変更
BindCredentials Administratorのパスワードを入力
Edit mode READ_Only
UsersDN CN=Users,DC=example,DC=com BindDNと同様に自身の環境に合わせて変更
Import users Off 一旦Offにしておきます。
Sync Registrations Off READ_Onlyの場合は使用しないため無効にします
User LDAP filter (&(objectClass=person)(userPrincipalName=*))

以下のように設定してSaveをクリック

Periodic full syncの項目が消えていますが、DefaultのOffから変更していません。

登録が完了すると以下の画面が表示されます。
続けて、Mappers設定を行うため、ADDCをクリック

6-7.Mappers設定

ADDCから取得した各種のLDAP属性をKeycloakで利用可能な属性にマッピングします。

初期状態は以下のようになっています。
ここでは、group, sAMAccountNameを追加し、usernameを編集していきます。

都度、Add mapperをクリックして、Mapper typeを選択すると、必要な設定項目が表示されます。

6-7-1.Group Mappers設定

設定が必要な項目のみピックアップします。

項目 設定値 備考
Name group
Mapper type group-ldap-mapper プルダウンメニューから選択すると設定項目が表示
LDAP Groups DN CN=Users,DC=example,DC=com 自身の環境に合わせて変更
Preserve Group Inheritance Off Directory同期時にエラーとなるためOff
Ignore Missing Groups Off 注意:もしDirectory同期時にエラーとなる場合はOn

以下のように設定してSaveをクリック

6-7-2.sAMAccountName Mappers設定

設定が必要な項目のみピックアップします。

項目 設定値 備考
Name sAMAccountName
Mapper type user-attribute-ldap-mapper プルダウンメニューから選択すると設定項目が表示
User Model Attribute sAMAccountName
LDAP Attribute cn
Always Read Value From LDAP Off 作成時はこの項目自体が存在しないため無視してください

以下のように設定してSaveをクリック

6-7-3.username Mappers設定

既存のusernameをクリックして編集します。
設定が必要な項目のみピックアップします。

項目 設定値 備考
Name username グレーアウトのため変更不要
Mapper type user-attribute-ldap-mapper グレーアウトのため変更不要
User Model Attribute username 変更不要
LDAP Attribute userPrincipalName cnからuserPrincipalName
Always Read Value From LDAP Off 作成時はこの項目自体が存在しないため無視してください

以下のように設定してSaveをクリック

6-7-4.ユーザのインポート

前項でMapperが以下のように設定されていればOKです。

ユーザをインポートするため、一旦Settingsタブに切り替えます。
Synchronization settingsまでスクロールダウンして、Import usersをOnに変更しSaveします。

再び、Mappersタブに切り替えて、Actionプルダウンメニューから、Sync all usersをクリックします。
すると、以下のメッセージが表示されインポートが完了します。

補足1
ここでは8usersになっていますが、作成したユーザ数によって変化します。
補足2
インポートしたユーザはサイドメニューのUsersから参照できます。
何も表示されない場合がありますが、検索フォームにuserなどと入力して検索すると表示されます。*8

6-8.Idp証明書のインポートと設定

4-4.発行した証明書の確認でClientPCに保存したidp.pemとidp.keyをKeycloakにインポートしていきます。

6-8-1.既存の自己署名証明書の削除

Realm settings>Keysタブ>Providersタブをクリック
rsa-generatedの右側にある「・・・」をクリックすると、Deleteが表示されますのでクリックします。

以下の画面が表示されるので、さらにDeleteをクリック

rsa-generatedが削除されました。

6-8-2.idp.pemの編集

OpenSSLで発行したidp.pemには、余分な行が含まれているため、インポート時にエラーとなります。
このため、ClientPCに保存しているidp.pemをテキストエディタなどで開き、-----BEGIN CERTIFICATE-----より、上の行を削除します。
以下の例では、赤文字部分を削除して、青文字部分だけ残します。

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            3c:f3:fd:5b:4b:0d:4c:3f:3c:70:8f:64:74:0b:67:65:56:b3:fa:65
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, O=f5.si, CN=CA.f5.si
        Validity
            Not Before: Nov 23 07:03:39 2023 GMT
            Not After : Nov 22 07:03:39 2024 GMT
        Subject: C=JP, ST=Tokyo, O=f5.si, CN=idp.f5.si
        Subject Public Key Info:
=====snip=====
        65:5e:9f:df:e0:ea:52:05:52:61:8e:96:55:ea:32:12:3f:a7:
        e9:89:9c:d6:72:93:41:83:af:37:03:04:10:ed:45:bf:b5:2a:
        b9:76:57:e2:2b:5b:fa:35:de:31:9a:68:c7:e1:48:c4:6f:13:
        b5:6a:9c:39:c7:18:ac:23:92:1a:96:4b:67:09:84:8a:f0:a7:
        aa:25:67:4c:69:ee:d0:91:51:1e:87:15:47:6f:5a:a4:76:bf:
        5d:43:03:dc:a3:7d:ff:61:1d:e7:49:4f:19:dd:10:46:6e:4a:
        32:c8:c6:ba:95:e2:39:21:65:11:22:b7:ed:73:66:3b:b6:f8:
        c0:50:04:39:ce:ae:7c:cc:c1:62:a9:9e:33:bf:4e:88:38:4b:
        6a:aa:7c:8f:18:98:53:09:81:d7:c1:67:19:50:70:16:4c:34:
        c1:70:b4:7f:06:d3:2f:96:0b:fa:3b:b2:3d:ef:ac:37:05:d9:
        bf:7b:de:f4
-----BEGIN CERTIFICATE-----
MIIDZzCCAk+gAwIBAgIUPPP9W0sNTD88cI9kdAtnZVaz+mUwDQYJKoZIhvcNAQEL
BQAwQDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMQ4wDAYDVQQKDAVmNS5z
aTERMA8GA1UEAwwIQ0EuZjUuc2kwHhcNMjMxMTIzMDcwMzM5WhcNMjQxMTIyMDcw
=====snip=====
BBDtRb+1Krl2V+IrW/o13jGaaMfhSMRvE7VqnDnHGKwjkhqWS2cJhIrwp6olZ0xp
7tCRUR6HFUdvWqR2v11DA9yjff9hHedJTxndEEZuSjLIxrqV4jkhZREit+1zZju2
MBQBDnOrnzMwWKpnjO/Tog4S2qqfI8YmFMJgdfBZxlQcBZMNMFwtH8G0y+WC/o7
sj3vrDcF2b973vQ=
-----END CERTIFICATE-----
6-8-3.idp.pemとidp.keyのインポート

Realm settings>Keysタブ>Providersタブ>Add providerをクリック
以下の画面で、rsaをクリック

以下の画面で、idp.pemとidp.keyをインポートします。
Nameには、任意の名前(ここでは、idp.f5.si)を入力します。
Private RSA KeyのBrowse...をクリックして、idp.keyを選択します。
X509 CertificateのBrowse...をクリックして、idp.pemを選択します。

最後にSaveをクリックすると、以下のように登録されます。

idp.f5.siの左のアイコン(・・・が6つあるアイコン)をドラッグすると優先順位を上げられるため、一番上に移動させておきます。

6-9.Idpのmetadataのエクスポート

Realm settings>Generalタブをクリック
SAML 2.0 Identity Provider Metadataをクリック

ブラウザ上に新しいタブが作成され、以下の画面が表示されます。

このmetadetaをテキストエディタなどにコピペして、任意のファイル名(idp.xmlなど)で保存しておきます。
idp.xmlは、後ほどSAML SPであるWordpress側にインポートして利用します。

7.Wordpressインストール&各種設定

7-1.Wordpressインストール

以下のサイトからWordpressOVAファイルをDLします。
bitnami.com
OVAファイルをVMWare上にデプロイしてください。

7-2.Wordpress初期設定

構成図に基づき、ssh接続やIPアドレス設定を記載しています。
Defaultでは、DHCP設定にてIPアドレスを自動取得しますが、自動取得が特に気にならない方は、7-2-3までスキップしてください。*9

7-2-1.OSコンソールへのログインとssh設定

以下のクレデンシャルでログインしてください。

ユーザ名:bitnami
パスワード:bitnami

sshのパスワード接続を許可したいので、PasswordAuthenticationのコメントアウトを外します。

sudo vi /etc/ssh/sshd_config

PasswordAuthentication yes

その後、以下のコマンドでsshサーバを起動します。

sudo rm -f /etc/ssh/sshd_not_to_be_run
sudo systemctl enable ssh
sudo systemctl start ssh
7-2-2.IPアドレス設定

ssh接続後、IPアドレスを変更します。*10

sudo vi /etc/systemd/network/25-wired.network

[Match]
Name=ens*

[Network]
Address=192.168.11.94/24
Gateway=192.168.11.1
DNS=192.168.11.1

設定が完了したら、一旦再起動します。

7-2-3.Wordpressコンソールへのログイン

再起動後、VMWareのコンソール上に以下のような画面が表示されます。

ClientPCから以下のURLにアクセスしてください。
補足:パスワードはWordpressをデプロイするたびに自動生成されるため都度変更されます。

http://192.168.11.94/admin/
ユーザ名:user
パスワード:vfwUWFiS25BR

以下のような画面で上記クレデンシャルを入力しログインします。

ログインすると以下の画面が表示されます。
Please update nowをクリックして、最新Verにアップデートしておきます。

初回ログイン時は、WordpressのローカルDBを使用しました。
ここから、WordpressSAML SPとして設定することにより、Keycloak IdpによるSAML認証ができるように設定をしていきます。

7-3.WordpressSAML SP設定
7-3-1.SAML Plug-inのインストール

Plugins>Add New Pluginをクリック

画面右上Keywordの右側にsamlと入力すると検索候補が表示されます。
SAML Single Sign On - SSO LoginのInstall Nowをクリックします。*11

インストールが完了すると以下の表示に切り替わるので、Activateをクリック

以下の画面が表示されるので、Configure Your IDP Nowをクリック*12

7-3-2.SAML Idp(Keycloak) Metadataのインポート

画面中央のUpload IDP Metadataタブをクリックします。
Identity Provider Nameには、任意の名前を入力(ここでは例として、KC_Idpと入力)
ファイル選択をクリックし、6-9.Idpのmetadataのエクスポートで保存したidp.xmlを選択
そして、Uploadをクリック

idp.xmlファイルのアップロードが成功すると、以下の画面が表示。
画面を下スクロールしてSaveをクリック

7-3-3.SAML SP(Wordpress) Metadataのエクスポート

画面上部のService Provider Metadataタブをクリックし、Downloadをクリック
任意のファイル名(ここでは例として、sp.xml)でClientPCに保存

7-3-4.Keycloak SP Metadataのインポート

ここからはKeycloakの管理コンソール画面に切り替えます。
サイドメニューより、Clients>Clients listタブ>Import clientをクリック

画面右上のBrowse...をクリックし、前項でエクスポートしたsp.xmlを選択
Nameには、任意の名前を入力(ここでは例として、wordpressと入力)

最後にSaveをクリックすると、以下の画面が表示されます。

7-3-5.Keycloak Mapper設定

前項画面からの続きで、Client scopesタブをクリック*13
続いて、http://192.168.11.94/wp-content/~をクリック

以下の画面で、Add predefined mapperをクリック

以下の画面で、X500~を全てチェックし、Addをクリック

登録が完了すると、以下の画面が表示されます。

以上で設定は完了です。
ここからは動作確認をしていきます。

8.動作確認

動作確認前に、ここでもう一度構成を確認しておきましょう。

  1. ClientPCー>WordPress SPにアクセスし、SAML認証を選択
  2. ClientPCー>Keycloak Idpにリダイレクトされ、クレデンシャルを入力
  3. ClientPCー>WordPress SPにリダイレクトされ、ログイン完了後の画面が表示

fig.1

ClientPCから以下URLにアクセス
http://192.168.11.94/admin/
Login with KC_Idpをクリック

Keycloakの方にリダイレクトされるので、クレデンシャルを入力して、Sign Inをクリック

以下の警告画面が表示されますが、そのまま送信するをクリック*14

ログイン完了後、以下の画面が表示されます。

以上です。

9.最後に

以下のサイトを参考にさせて頂きました。
Guides - Keycloak
Keycloak22.0.1のセットアップ #Java - Qiita
https://qiita.com/s-takino/items/ee3be5bcf6f318bc5d40

次回以降のKeycloak関連記事では、以下のようなトピックを取り上げられたらいいなと考えています。

  • Nginxによるリバースプロキシ
  • PostgresSQLの利用
  • LetsEncryptによる証明書発行

*1:Keycloakのデフォルト待ち受けポートはTCP8443となります

*2:もう少し掘り下げて検証すれば、Hostname=IPアドレスでも、うまく動作する可能性はあります。しかし、IPアドレスのままでKeycloakを動作させることが目的ではないため、私は素直にドメイン登録をしました。

*3:このユーザ名は一番最後の動作確認時に利用します。

*4:初回は環境変数でユーザ名とパスワードを設定しましたが、2回目以降の起動では設定不要です。

*5:本来であれば、リバプロやWAFの導入といった作業をした方が良いです。また、keycloak.conf上で、hostname-urlやhostname-admin-urlといった設定も可能なのですが今回は割愛しています。

*6:レルムとはKeycloak上の管理ドメインです。初期設定ではmasterレルムが存在していますが、名前の通りmasterなので、これとは別にIdpとして利用するためのレルムを別途作成します。

*7:名前は任意で構いませんが、URI上にこの名前が登場するためスペースを入れたりすることは控えてください。

*8:なぜ表示されないかは謎です。。またユーザが重複して表示される場合もありますがSAML認証には影響しないため気にしないでください。

*9:Wordpressの最新Ver6.4.1の場合、この方法でIPアドレス設定ができませんでした。Wordpressのマニュアルを読む限り、VMWare上の設定が必要とのことで、VMWare関連ドキュメントへのリンクが大量に掲載されたページしか表示されなかったため、Ver5.9.0を使用しています。ここは頑張りどころではないため古いVer5.9.0でスルーしましたが、WordpressはDebian11で動作しているため、Debian11のネットワーク設定を少しいじればサクッと設定できるかもしれません。

*10:DefaultではDHCP設定となっているため固定IP設定とします。Internetに出られれば良いので、DHCP設定のままでも構いません。

*11:似たような候補でLogin using WordPress Users(WP asSAML IDP)が表示されますが無視してください。

*12:画面に表示されているKeycloakをクリックすると、Keycloakの設定マニュアルが表示されます。

*13:サイドメニューにも"Client scopes"がありますが、これはクリックしないでください。もしクリックしてしまった場合、Clients>Clients listタブ>http://192.168.11.94/wp-content/~>Client scopesタブをクリックします。

*14:ClientPCからWordpressにクレデンシャルが平文で送信されます。一般的に、SAML IdpとSP間で直接通信することはなく、必ずClientPCを経由して通信します。今回の構成では、SAML SPであるWordpressSSL化されていなくても、ClientPCとWordpress間はローカルNW内の通信となり、クレデンシャルがInternetに晒されることはないので特に問題ありません。

CentOS8 小ネタ集その7:nmcli コマンドよるVRF設定

CentOS8にてnmcli コマンドよるVRF設定方法を記載します。

CentOS7ではKernel Versionの関係で設定できません。

1.NICバイスの確認

以下の状態からens32にVRF table10を設定していきます。

[root@c85g192 ~]# nmcli dev
DEVICE      TYPE      STATE                   CONNECTION
ens33       ethernet  connected               ens33
virbr0      bridge    connected (externally)  virbr0
ens32       ethernet  disconnected            --
lo          loopback  unmanaged               --
virbr0-nic  tun       unmanaged               --

2.VRFの作成

先にVRFのRouteテーブルを作成します。
ここでは、table 10 とします。

nmcli connection add type vrf autoconnect yes ifname vrf10 con-name vrf10 table 10
nmcli connection modify vrf10 ipv4.method disabled ipv6.method disabled
nmcli connection up vrf10

<出力例>

[root@c85g192 ~]# nmcli connection add type vrf autoconnect yes ifname vrf10 con-name vrf10 table 10
Connection 'vrf10' (501751b7-df6d-4d18-95d6-cb87459d6052) successfully added.
[root@c85g192 ~]# nmcli connection modify vrf10 ipv4.method disabled ipv6.method disabled
[root@c85g192 ~]# nmcli connection up vrf10
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/5)
[root@c85g192 ~]# nmcli con show
NAME    UUID                                  TYPE      DEVICE
ens33   1de6e2fb-e8ee-4c3d-852b-5f84d480a201  ethernet  ens33
virbr0  7c2ded50-2e7c-49e4-ba46-2081f823c50f  bridge    virbr0
vrf10   501751b7-df6d-4d18-95d6-cb87459d6052  vrf       vrf10

3.ens32(物理NICバイス)の設定

シンタックスは、ブリッジに物理デバイスをアタッチする設定に近いです。
masterにvrf10を指定している点がポイントとなります。
その他、今回作成したVRF table 10のRouteテーブルは、VRF無しのDefaultのRouteテーブルと分離されていますので、IPアドレスに加え、Gatewayアドレスも設定してしまいます。

nmcli connection add type ethernet autoconnect yes ifname ens32 con-name ens32 master vrf10
nmcli connection modify ens32 ipv4.method manual ipv4.address 192.168.30.192/24
nmcli connection modify ens32 ipv4.gateway 192.168.30.254
nmcli connection up ens32

<出力例>

[root@c85g192 ~]# nmcli connection add type ethernet autoconnect yes ifname ens32 con-name ens32 master vrf10
nmcli connection modify ens32 ipv4.gateway 192.168.30.254
nmcli connection up ens32
Connection 'ens32' (fa7f298b-266f-4131-8d70-39c4bf542e36) successfully added.
[root@c85g192 ~]# nmcli connection modify ens32 ipv4.method manual ipv4.address 192.168.30.192/24
[root@c85g192 ~]# nmcli connection modify ens32 ipv4.gateway 192.168.30.254
[root@c85g192 ~]# nmcli connection up ens32
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/7)
[root@c85g192 ~]# nmcli con show
NAME    UUID                                  TYPE      DEVICE
ens33   1de6e2fb-e8ee-4c3d-852b-5f84d480a201  ethernet  ens33
ens32   fa7f298b-266f-4131-8d70-39c4bf542e36  ethernet  ens32
virbr0  7c2ded50-2e7c-49e4-ba46-2081f823c50f  bridge    virbr0
vrf10   501751b7-df6d-4d18-95d6-cb87459d6052  vrf       vrf10

4.設定確認

ip -br addr show vrf vrf10
ip vrf show
ip route show table 10
ip vrf exec vrf10 ping 192.168.30.254

<出力例>

[root@c85g192 ~]# ip -br addr show vrf vrf10
ens32            UP             192.168.30.192/24 fe80::8cf6:2ee3:5eb0:8817/64

[root@c85g192 ~]# ip vrf show
Name              Table
-----------------------
vrf10               10

[root@c85g192 ~]# ip route show table 10
default via 192.168.30.254 dev ens32 proto static metric 101
broadcast 192.168.30.0 dev ens32 proto kernel scope link src 192.168.30.192
192.168.30.0/24 dev ens32 proto kernel scope link src 192.168.30.192 metric 101
local 192.168.30.192 dev ens32 proto kernel scope host src 192.168.30.192
broadcast 192.168.30.255 dev ens32 proto kernel scope link src 192.168.30.192

[root@c85g192 ~]# ip vrf exec vrf10 ping 192.168.30.254
PING 192.168.30.254 (192.168.30.254) 56(84) bytes of data.
64 bytes from 192.168.30.254: icmp_seq=1 ttl=64 time=1.41 ms
64 bytes from 192.168.30.254: icmp_seq=2 ttl=64 time=1.87 ms
64 bytes from 192.168.30.254: icmp_seq=3 ttl=64 time=1.89 ms
^C
--- 192.168.30.254 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2006ms
rtt min/avg/max/mdev = 1.409/1.721/1.888/0.223 ms

以上です。

5.最後に

小ネタ集なので、今回はここまでの内容とします。

しかし、実用的な使い方として、VRF上では管理用IPやsshd、chronydサービスを動作させながらも、VRF無しのDefaultのRouteテーブル上では、サービス用IPによるHTTPサービスなどを起動させておく、といった使い方も想定されます。

このため、次回はVRF上でのsshdやchronydの起動方法を記載していきたいと思います。

あれから20年

ちょうど20年前の今日、私は夢を諦めました。

今日は節目の日として、10年前の記事を振り返りながら、少し個人的なことを書きたいと思います。
あれから10年 - Metonymical Deflection


10年前は、こんな自分↓を想像していました。
(一人称が「オレ」となっている点は若気の至りだと思ってご容赦ください。。)

オレの10年後は、技術系の教育者という側面も兼ね備えたヒトに
成っているのではないか?と想像している。

この10年(2012-2022年)の間、大学に進学したり仕事で教育業務に従事させて頂くことはありました。
しかし、今は現役でITエンジニアの仕事をさせて頂いており、日々強烈な刺激を受けられる環境に、とても感謝しています。


過去を振り返った時、どのくらい前から「今の自分」が想像できていたのかを思い返してみました。

20年前 2002年 夢を諦め挫折を受け入れた直後で、今の自分は1ミリも想像できていませんでした。
10年前 2012年 大学進学を控え、没頭できる研究テーマを見つけて修士や博士課程に進みたいと考えていたため、今の自分は全く想像できていませんでした。ちなみに、3年半後、院試に落ちてしまったので、再び挫折を受け入れることになりました。
5年前 2017年 ひたすら仕事に没頭していたため、今の自分はほとんど想像できていませんでした。
3年前 2019年 漠然とですが、今の自分のイメージが思い浮かびつつあったような気がします。

ある選択をした時点で、その選択の正誤は誰にも判断できないのではないかと思います。
たとえ、不本意な選択を受け入れるしかなくても、その選択の結果は、その後のアクションで決まってくる、と実体験を通して感じたからです。
なので、大切なことは、その選択が正しかったと思えるようになるまで、アクションを起こし続けることではないかと考えています。


また、こんなこと↓を書いていました。

けれど、夢を諦めてから、10年間がむしゃらに走り続けてきた結果、
とても遠回りをしてしまったけれど、今の道を選択した。

この10年(2012-2022年)の間、最初は「がむしゃら」でしたが、
次第に色々なことを考えながら走れるようになってきた気がします。
加えて、これまで以上に人に感謝することを学べたと考えています。
なので、この点は10年前よりも少しだけ成長できたのかなと実感しています。


一方で、こんなこと↓も書いていました。

ただ、確実に言えることがあるとするならば、
10年後のオレも今と同じように
「自分のやりたいことに挑戦し続けている」
のではないのかなぁ、と思ってる。

この点は今も変わっておらず、「自分のやりたいこと」には、とても強い拘りがあることを自覚しています。
この「やりたいこと」の軸がブレ始めると急ブレーキが掛かり、軌道修正できるようになってきました。
これは挫折を経験して備わった保護装置なのかなと考えています。


加えて、こんなこと↓を書いていました。

当然、そんな自分が少しづつ「違う」とか
「異なっている」ということは認識しているつもり。

でも「何が?」って思う。

オレはオレだから。

肩ひじ張ったような言い回しですが、10年前の私は、所詮この程度だったなと、しみじみ思います。
一方、多様性が受容される世界を垣間見て、今は同じことが楽に思えるようになりました。
自分が「違う」とか「異なっている」などと気負う必要はなく、私は私です、と。


過去を振り返り、10年後の自分を想像することは、ほぼ不可能なことがわかりました。
しかし、希望だけで言えば、10年前と変わらず技術系の教育者をイメージしています。
特にここ数年、若手の教育は改めて大切だと感じています。

というのも、10年前、私が教育させて頂いた若手エンジニアの方々が、
現在は、それぞれの専門分野において第一線で活躍されています。
そういった彼らの専門分野では、私が彼らに助けを求めたり、
時には彼らから教えて頂ける、といった頻度が少しづつ増えてきています。
このため、仕事ではなくても、何かしらの形で教育に携われるよう
私自身が継続的に精進していかなければならないと考えている次第です。


最後に。
2002/2/24に開催したライブ「Universal Summit」の

  • 時間
  • 空間
  • そして集った仲間たち

これらは皆、私の永遠の宝モノです。

本当に本当にありがとう。

How to set up baidu dperf

This article describes how to configure the baidu dperf.
GitHub - baidu/dperf: dperf is a DPDK based 100Gbps network performance and load testing software.

The dperf is a high-performance HTTP load testing tool based on DPDK.
It is especially suitable for TPut (through put), CPS (Connection per seconds), and CC (Concurrent Connection) load tests.

This article describes how to install and configure it for CentOS7/8.
It also provides supplementary explanations on the differences between using Mellanox NICs and other NICs *1.

In our environment, we were able to generate the following loads, and I will provide an example configuration at the end.

TPut : 93Gbps
CPS : 5M
CC : 300M

1.Overview

1-1.Environment
IA server                        : ProLiant DL360p Gen8
System ROM                       : P71 01/22/2018
NIC                              : Mellanox ConnectX-6 Dx (MCX623106AS-CDAT)

OS                               : CentOS7.9(2009)
Kernel                           : 3.10.0-1160.el7.x86_64
Installed Environment Groups     : 
  @^graphical-server-environment
  @base
  @core
  @development
  @virtualization-client
  @virtualization-hypervisor
  @virtualization-tools
DPDK                             :19.11.10

OS                               : CentOS8.5(2111)
Kernel                           : 4.18.0-348.el8.x86_64
Installed Environment Groups     : 
  @^graphical-server-environment
  @development
  @virtualization-client
  @virtualization-hypervisor
  @virtualization-tools 
DPDK                             :20.11.4
1-2.overall structure

f:id:metonymical:20220211231825j:plain
Since there is no 100Gbps L2SW, two servers are directly connected, one is configured as dperf Client and the other as dperf Server.
It can also be built in a virtual environment. *2

1-3 .Overall flow
  1. Advance Preparation
  2. Installation Method 1 : CentOS7.9 + DPDK19.11.10
  3. Installation Method 2 : CentOS8.5 + DPDK20.11.4
  4. Configure dperf
  5. load test
  6. Setting example of high load test

2.Advance Preparation

2-1.Configure hugepages

The minimum size of the hugepages should be 8GB and should be increased in a timely manner.

vi /etc/default/grub

nopku transparent_hugepage=never default_hugepagesz=1G hugepagesz=1G hugepages=8

grub2-mkconfig -o /etc/grub2.cfg
vi /etc/fstab

nodev  /dev/hugepages    hugetlbfs pagesize=1GB    0 0
2-2.Configure uio_pci_generic(For other than Mellanox NICs)
echo "uio_pci_generic" > /etc/modules-load.d/uio_pci_generic.conf
2-3.Installing OFED(For Mellanox NICs)
#CentOS7.9
yum -y install tcl tk unbound
mount -t iso9660 -o loop /root/tmp/MLNX_OFED_LINUX-5.5-1.0.3.2-rhel7.9-x86_64.iso /mnt/
/mnt/mlnxofedinstall --upstream-libs --dpdk --with-mft --with-mstflint

#CentOS8.5
dnf -y install tcl tk unbound tcsh gcc-gfortran && \
mount -t iso9660 -o loop /root/tmp/MLNX_OFED_LINUX-5.5-1.0.3.2-rhel8.5-x86_64.iso /mnt && \
/mnt/mlnxofedinstall --upstream-libs --dpdk --with-mft --with-mstflint

3.Installation Method 1 : CentOS7.9 + DPDK19.11.10

3-1.Build the DPDK
yum -y install numactl-devel libpcap-devel
mkdir dpdk
cd /root/dpdk/
wget http://fast.dpdk.org/rel/dpdk-19.11.10.tar.xz
tar xf dpdk-19.11.10.tar.xz
cd /root/dpdk/dpdk-stable-19.11.10

#The following settings are required for Mellanox NICs
sed -i -e "s/CONFIG_RTE_LIBRTE_MLX5_PMD=n/CONFIG_RTE_LIBRTE_MLX5_PMD=y/g" /root/dpdk/dpdk-stable-19.11.10/config/common_base
sed -i -e "s/CONFIG_RTE_LIBRTE_MLX5_DEBUG=n/CONFIG_RTE_LIBRTE_MLX5_DEBUG=y/g" /root/dpdk/dpdk-stable-19.11.10/config/common_base

export TARGET=x86_64-native-linuxapp-gcc
make install T=$TARGET -j4
3-2.Build the dperf
cd /root/dpdk
wget https://github.com/baidu/dperf/archive/refs/heads/main.zip

unzip main.zip
cd dperf-main/
export TARGET=x86_64-native-linuxapp-gcc
make -j4 RTE_SDK=/root/dpdk/dpdk-stable-19.11.10 RTE_TARGET=$TARGET

4.Installation Method 2 : CentOS8.5 + DPDK20.11.4

4-1.advance preparation*3
sed -i -e 's/enabled=0/enabled=1/g' /etc/yum.repos.d/CentOS-Linux-PowerTools.repo && \
dnf -y install numactl-devel meson ninja-build rdma-core && \
wget https://cbs.centos.org/kojifiles/packages/pyelftools/0.26/1.el8/noarch/python3-pyelftools-0.26-1.el8.noarch.rpm && \
dnf -y localinstall python3-pyelftools-0.26-1.el8.noarch.rpm
4-2.Build the DPDK
mkdir dpdk
cd /root/dpdk/
wget https://fast.dpdk.org/rel/dpdk-20.11.4.tar.xz
tar xf dpdk-20.11.4.tar.xz
cd /root/dpdk/dpdk-stable-20.11.4

meson build --prefix=/root/dpdk/dpdk-stable-20.11.4/mydpdk -Denable_kmods=true && \
ninja -C build install
4-3.Build the dperf
cd /root/dpdk
wget https://github.com/baidu/dperf/archive/refs/heads/main.zip

unzip main.zip
cd /root/dpdk/dperf-main/
export PKG_CONFIG_PATH=/root/dpdk/dpdk-stable-20.11.4/mydpdk/lib64/pkgconfig/
make
4-4.Configure ldconfig

Note
If you receive the following error message when starting dperf, please run ldconfig.

[root@c85g151 dperf-main]# ./build/dperf -c test/http/client-cps.conf
./build/dperf: error while loading shared libraries: librte_ethdev.so.21: cannot open shared object file: No such file or directory
vi /etc/ld.so.conf.d/libdpdk.conf

/root/dpdk/dpdk-stable-20.11.4/mydpdk/lib64

ldconfig
ldconfig -p |grep dpdk

5.Configure dperf

5-1.Configure dpdk-devbind

For other than Mellanox NICs, dpdk-devbind is required.
For Mellanox NICs, dpdk-devbind is not required.
Please check the bsf number and bind the NIC to the dpdk PMD driver. *4

lspci
lshw -businfo -c network
/root/dpdk/dpdk-stable-20.11.4/usertools/dpdk-devbind.py -s
/root/dpdk/dpdk-stable-20.11.4/usertools/dpdk-devbind.py -b uio_pci_generic 0000:03:00.0

The following example output shows dpdk-devbind running on CentOS8.5 on VMWare Work pro15.

[root@c85g151 dperf-main]# lspci
00:00.0 Host bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (rev 01)
00:01.0 PCI bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge (rev 01)
02:01.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)
03:00.0 Ethernet controller: VMware VMXNET3 Ethernet Controller (rev 01)
0b:00.0 Ethernet controller: VMware VMXNET3 Ethernet Controller (rev 01)

[root@c85g151 dperf-main]# /root/dpdk/dpdk-stable-20.11.4/usertools/dpdk-devbind.py -s
Network devices using kernel driver
===================================
0000:02:01.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=ens33 drv=e1000 unused=uio_pci_generic *Active*
0000:03:00.0 'VMXNET3 Ethernet Controller 07b0' if=ens192 drv=vmxnet3 unused=uio_pci_generic
0000:0b:00.0 'VMXNET3 Ethernet Controller 07b0' if=ens192 drv=vmxnet3 unused=uio_pci_generic

[root@c85g151 dperf-main]# /root/dpdk/dpdk-stable-20.11.4/usertools/dpdk-devbind.py -b uio_pci_generic 0000:03:00.0

[root@c85g151 dperf-main]# /root/dpdk/dpdk-stable-20.11.4/usertools/dpdk-devbind.py -s
Network devices using DPDK-compatible driver
============================================
0000:03:00.0 'VMXNET3 Ethernet Controller 07b0' drv=uio_pci_generic unused=vmxnet3

Network devices using kernel driver
===================================
0000:02:01.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=ens33 drv=e1000 unused=uio_pci_generic *Active*
0000:0b:00.0 'VMXNET3 Ethernet Controller 07b0' if=ens192 drv=vmxnet3 unused=uio_pci_generic
5-2.dperf client settings

The following settings have been modified from the sample config.

cd /root/dpdk/dperf-main
vi test/http/client-cps.conf

[root@c85g151 dperf-main]# vi test/http/client-cps.conf
mode                         client
tx_burst                     128
launch_num                   10
cpu                          0
payload_size                 1400
duration                     120s
cps                          400
cc                           2500
keepalive_request_interval   1ms
port         0000:00:08.0    100.64.12.155   100.64.12.156
client       16.0.0.1        100
server       48.0.0.1        1
listen       80              1

Note
The following is a description of what we noticed during the setup.

mode Select client/server.
tx_burst No need to change the settings.
launch_num If you get "Floating point exception" or other errors when you increase the number of CPU cores, try decreasing the value to 10, 6, 3, or 1.
cpu The number of CPUs must match the number of IPs in the server.
payload_size The minimum is 1Byte and the maximum is 1400Byte. If 1400 is set on the Client side, a string of 1400Byte will be inserted in the HTTP GET request.
duration Since the default setting is slow_start:30 seconds, the Client should be set to a value 30 seconds larger than the Server.
cps If you set it to 90 or lower, an error may be output. For this reason, set the value to 100 or higher.
cc CC is Concurrent Connection. In addition, if you want to do TPut testing, increase this value.
keepalive_request_interval If you set cc to a large value such as 100m, you can reduce the CPU load by setting it to 30s or 60s. Also, for the TPut test, use a smaller value such as 1ms.
port Column 1: PCIe Domain number: bsf number. column 2: own IP address. column 3: GW's IP address. column 4: GW's MAC address.
client column 1: starting IP address of HTTP Client. column 2: number of IP addresses. Maximum number 254.
server column 1: the starting IP address of the HTTP server. column 2: the number of IP addresses. This number of IPs must match the number of CPUs. For example, in the case of "cpu 0 1", the number of addresses of the server should also be set to 2, since a 2 core CPUs are assigned to the server.
listen column 1: port number to wait for. column 2: number of port numbers. For example, if this value is 4, TCP 80, 81, 82, and 83 will be listened to. If you increase this number, the hugepages will be used. 8GB or more should be set if hugepages capacity is insufficient.

For more details, please refer to the following URL
dperf/configuration.md at main · baidu/dperf · GitHub

5-3.dperf server settings

The following settings have been modified from the sample config.

cd /root/dpdk/dperf-main
vi test/http/server-cps.conf

[root@c85g154 dperf-main]# vi test/http/server-cps.conf
mode                        server
tx_burst                    128
cpu                         0
duration                    150s
payload_size                1400
keepalive                   1
port        0000:00:09.0    100.64.12.156   100.64.12.155
client      16.0.0.1        100
server      48.0.0.1        1
listen      80              1

Note
This section describes the points other than 5-2.

payload_size This is the HTTP content size. When testing TPut, we set ServerSide"1400" and ClientSide"1". when ClientSide"1400" is set, the same amount of TPut is generated in both directions (upstream and downstream) because a string is inserted in the GET request. Since we have confirmed that the downstream (from Server to Client) TPut does not reach the upper limit due to this effect, please set ServerSide"1400" and ClientSide"1".
keepalive For cc and TPut testing, set this to "1".

For more details, please refer to the following URL
dperf/configuration.md at main · baidu/dperf · GitHub

6.load test

To generate a load in the configuration described in this article, please run the program on the Client Side and Server Side almost simultaneously.
Note
In this case, the GW addresses are each other's own IP addresses, so if the programs are not run at the same time, arp resolution is not possible and the program will be displayed as bad gateway and will stop.
If the DUT*5 holds the GW address, there is no problem.
Or set the MAC address in the fourth column of Port.

6-1.Client Side
cd /root/dpdk/dperf-main
./build/dperf -c test/http/client-cps.conf

When you start dperf on the client side, you will see the following output.

[root@c85g151 dperf-main]# ./build/dperf -c test/http/client-cps.conf
EAL: Detected 4 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: No available hugepages reported in hugepages-2048kB
EAL: Probing VFIO support...
EAL: Probe PCI driver: mlx5_pci (15b3:101e) device: 0000:05:00.0 (socket 0)
EAL: No legacy callbacks, legacy socket not created
socket allocation succeeded, size 0.01GB num 131070

seconds 0                  cpuUsage 0
pktRx   0                  pktTx    0                  bitsRx   0                  bitsTx  0                  dropTx  0
arpRx   0                  arpTx    0                  icmpRx   0                  icmpTx  0                  otherRx 0          badRx 0
synRx   0                  synTx    0                  finRx    0                  finTx   0                  rstRx   0          rstTx 0
synRt   0                  finRt    0                  ackRt    0                  pushRt  0                  tcpDrop 0
skOpen  0                  skClose  0                  skCon    0                  skErr   0
httpGet 0                  http2XX  0                  httpErr  0
ierrors 0                  oerrors  0                  imissed  0

seconds 1                  cpuUsage 0
pktRx   0                  pktTx    0                  bitsRx   0                  bitsTx  0                  dropTx  0
arpRx   0                  arpTx    0                  icmpRx   0                  icmpTx  0                  otherRx 0          badRx 0
synRx   0                  synTx    0                  finRx    0                  finTx   0                  rstRx   0          rstTx 0
synRt   0                  finRt    0                  ackRt    0                  pushRt  0                  tcpDrop 0
skOpen  0                  skClose  0                  skCon    0                  skErr   0
httpGet 0                  http2XX  0                  httpErr  0
ierrors 0                  oerrors  0                  imissed  0

6-2.Server Side
cd /root/dpdk/dperf-main
./build/dperf -c test/http/server-cps.conf

When you start dperf on the server side, you will see the following output.

[root@c85g154 dperf-main]# ./build/dperf -c test/http/server-cps.conf
EAL: Detected 4 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: No available hugepages reported in hugepages-2048kB
EAL: Probing VFIO support...
EAL: Probe PCI driver: mlx5_pci (15b3:101e) device: 0000:05:00.0 (socket 0)
EAL: No legacy callbacks, legacy socket not created
socket allocation succeeded, size 0.78GB num 13107000

seconds 0                  cpuUsage 0
pktRx   0                  pktTx    0                  bitsRx   0                  bitsTx  0                  dropTx  0
arpRx   0                  arpTx    0                  icmpRx   0                  icmpTx  0                  otherRx 0          badRx 0
synRx   0                  synTx    0                  finRx    0                  finTx   0                  rstRx   0          rstTx 0
synRt   0                  finRt    0                  ackRt    0                  pushRt  0                  tcpDrop 0
skOpen  0                  skClose  0                  skCon    0                  skErr   0
httpGet 0                  http2XX  0                  httpErr  0
ierrors 0                  oerrors  0                  imissed  0

seconds 1                  cpuUsage 0
pktRx   0                  pktTx    0                  bitsRx   0                  bitsTx  0                  dropTx  0
arpRx   0                  arpTx    0                  icmpRx   0                  icmpTx  0                  otherRx 0          badRx 0
synRx   0                  synTx    0                  finRx    0                  finTx   0                  rstRx   0          rstTx 0
synRt   0                  finRt    0                  ackRt    0                  pushRt  0                  tcpDrop 0
skOpen  0                  skClose  0                  skCon    0                  skErr   0
httpGet 0                  http2XX  0                  httpErr  0
ierrors 0                  oerrors  0                  imissed  0

7.Setting example of high load test

The following is an example of the configuration when the following loads are applied in this configuration.

TPut : 93Gbps
CPS : 5M
CC : 300M

The configuration example shown here is based on the use of a 2-port NIC, but 1-port will provide the same performance.
(How to configure a 1-port NIC is described at the end of this section.)

7-1.TPut test

Client Side

[root@c85g151 dperf-main]# cat test/http/client-cps.conf
mode                         client
tx_burst                     128
launch_num                   3
cpu                          0 1 2 3
payload_size                 1
duration                     120s
cps                          500
cc                           10000
keepalive_request_interval   1ms
port         0000:07:00.0    100.64.12.155   100.64.12.156
client       16.0.0.1        200
server       48.0.0.1        2
port         0000:07:00.1    100.64.13.155   100.64.13.156
client       16.0.1.1        200
server       48.0.1.1        2
listen       80              1

Server Side

[root@c85g154 dperf-main]# cat test/http/server-cps.conf
mode                        server
tx_burst                    128
cpu                         0 1 2 3
duration                    150s
payload_size                1400
keepalive                   1
port        0000:07:00.0    100.64.12.156   100.64.12.155
client      16.0.0.1        200
server      48.0.0.1        2
port        0000:07:00.1    100.64.13.156   100.64.13.155
client      16.0.1.1        200
server      48.0.1.1        2
listen      80              1

TPut:93Gbps
f:id:metonymical:20220211172033p:plain
Note
When client's payload_size was set to 1400, both client side and server side bitsRX and bitsTX were 74Gbps.
f:id:metonymical:20220211233850p:plain

7-2.CPS test

Client Side

[root@c85g151 dperf-main]# cat test/http/client-cps.conf
mode                         client
tx_burst                     128
launch_num                   3
cpu                          0 1 2 3
payload_size                 1
duration                     120s
cps                          5.1m
port         0000:07:00.0    100.64.12.155   100.64.12.156
client       16.0.0.1        200
server       48.0.0.1        2
port         0000:07:00.1    100.64.13.155   100.64.13.156
client       16.0.1.1        200
server       48.0.1.1        2
listen       80              1

Server Side

[root@c85g154 dperf-main]# cat test/http/server-cps.conf
mode                        server
tx_burst                    128
cpu                         0 1 2 3
duration                    150s
payload_size                1
port        0000:07:00.0    100.64.12.156   100.64.12.155
client      16.0.0.1        200
server      48.0.0.1        2
port        0000:07:00.1    100.64.13.156   100.64.13.155
client      16.0.1.1        200
server      48.0.1.1        2
listen      80              1

CPS:5M
f:id:metonymical:20220211172212p:plain

7-3.CC test

Client Side

[root@c85g151 dperf-main]# cat test/http/client-cps.conf
mode                         client
tx_burst                     128
launch_num                   3
cpu                          0 1 2 3 4 5
payload_size                 1
duration                     1800s
cps                          1m
cc                           300m
keepalive_request_interval   60s
port         0000:07:00.0    100.64.12.155   100.64.12.156
client       16.0.0.1        200
server       48.0.0.1        3
port         0000:07:00.1    100.64.13.155   100.64.13.156
client       16.0.1.1        200
server       48.0.1.1        3
listen       80              4

Server Side

[root@c85g154 dperf-main]# cat test/http/server-cps.conf
mode                        server
tx_burst                    128
cpu                         0 1 2 3 4 5
duration                    1800s
payload_size                1
keepalive                   1
port        0000:07:00.0    100.64.12.156   100.64.12.155
client      16.0.0.1        200
server      48.0.0.1        3
port        0000:07:00.1    100.64.13.156   100.64.13.155
client      16.0.1.1        200
server      48.0.1.1        3
listen      80              4

CC:300M
f:id:metonymical:20220211172302p:plain

7-4.Configuration example with a single port NIC

As an example, we will change the setting of the 7-1.TPut test to a 1-port NIC setting.
The changed part is written in red letters, and the deleted part is grayed out.

Client Side

[root@c85g151 dperf-main]# cat test/http/client-cps.conf
mode                         client
tx_burst                     128
launch_num                   3
cpu                          0 1 2 3
payload_size                 1
duration                     120s
cps                          500
cc                           10000
keepalive_request_interval   1ms
port         0000:07:00.0    100.64.12.155   100.64.12.156
client       16.0.0.1        200
server       48.0.0.1        4
#port         0000:07:00.1    100.64.13.155   100.64.13.156
#client       16.0.1.1        200
#server       48.0.1.1        2
listen       80              1

Server Side

[root@c85g154 dperf-main]# cat test/http/server-cps.conf
mode                        server
tx_burst                    128
cpu                         0 1 2 3
duration                    150s
payload_size                1400
keepalive                   1
port        0000:07:00.0    100.64.12.156   100.64.12.155
client      16.0.0.1        200
server      48.0.0.1        4
#port        0000:07:00.1    100.64.13.156   100.64.13.155
#client      16.0.1.1        200
#server      48.0.1.1        2
listen      80              1

8.Finally

We referred to the following website.
GitHub - baidu/dperf: dperf is a DPDK based 100Gbps network performance and load testing software.

Although dperf has only recently been announced, we believe that it is a load tool that is likely to attract attention in the future because it can generate high loads with simple settings.

When using the ASTF mode of Cisco TRex, connection establishment became unstable during CPS testing, and Tput did not rise as expected during HTTP communication.
With dperf, however, it was possible to generate stable loads for TPut, CPS, and CC.

For this reason, we would like to utilize dperf especially for TCP and HTTP communication. *6

In addition to the settings introduced in this article, detailed settings such as simultaneous launching of Client and Server processes in the same server using the socket_mem setting are also possible, so I would like to try more things.

*1:Intel NICs, vmxnet3, etc.

*2:However, the expected performance may not be achieved, so if you want to generate a high load, we recommend a bare metal environment.

*3:Since CentOS8 is no longer supported, the repository settings have been changed from "mirror.centos.org" to "vault.centos.org".

*4:The bsf number is also required when configuring dperf, so please make sure you know which bsf number NIC you have bound.

*5:Abbreviation for Device Under Test. The device to be measured.

*6:TRex can read Pcap files, which is very useful for UDP communication(GTP-U packet etc.).