Make your own capture
Run a real 5G core and a simulated phone on your own laptop, record the phone registering, and read the recording in the inspector — then break it on purpose and compare the two. About 45 minutes the first time, five minutes after that. Nothing here costs money.
- What you will build
- Linux and Docker on Windows
- Start the 5G core
- Add a subscriber
- Record a registration
- Upload and read it
- Break it on purpose
- Stop and clean up
1What you will build
| Part | What it plays | Memory |
|---|---|---|
| WSL2 + Docker Engine | a small Linux machine inside Windows | ≈ 300 MB |
Open5GS 5G SA core (docker_open5gs) | the operator's network: AMF, SMF, UPF, AUSF, UDM, UDR, NRF… | ≈ 800 MB |
| UERANSIM gNB and UE | a base station and a phone with its SIM | ≈ 100 MB |
This fits an 8 GB laptop. It uses 5G because the 5G radio simulator (UERANSIM) is light; a 4G attach with srsRAN needs about four times the memory and a lot of CPU. On a Mac or Linux machine, skip step 2 and use Docker directly.
2Linux and Docker on Windows (once)
Administrator PowerShell, then reboot
wsl --install -d Ubuntu
Cap the Linux machine so Windows keeps enough memory: create
%UserProfile%\.wslconfig with
[wsl2] memory=3GB processors=2 vmIdleTimeout=-1
vmIdleTimeout=-1 matters: without it, WSL stops the machine when no Windows window
is attached to it, and every container dies with exit code 255 in the middle of a recording.
Ubuntu
sudo apt-get update && sudo apt-get install -y ca-certificates curl tcpdump curl -fsSL https://get.docker.com | sudo sh sudo usermod -aG docker $USER
Then wsl --shutdown in Windows, reopen Ubuntu, and check
docker run --rm hello-world. Docker Desktop is not needed.
3Start the 5G core
Clone inside Linux, not under /mnt/c: Windows line endings break the container
scripts there, and file access is much faster. Pull the prebuilt images rather than building them
(a build takes half an hour).
Ubuntu
cd ~ && git clone --depth 1 https://github.com/herlesupreeth/docker_open5gs.git && cd docker_open5gs for i in docker_open5gs docker_ueransim; do docker pull ghcr.io/herlesupreeth/$i:master && docker tag ghcr.io/herlesupreeth/$i:master $i done
Start it in order. A plain docker compose up races the database: the policy
function (PCF) exits with “Failed to connect to server”, and the registration later fails without
saying why.
c="docker compose -f sa-deploy.yaml up -d"
$c mongo
until docker exec mongo mongosh --quiet --eval 'db.runCommand({ping:1}).ok' | grep -q 1; do sleep 2; done
$c nrf scp && sleep 6
$c udr udm ausf pcf bsf nssf && sleep 6
$c smf upf amf && sleep 6
docker ps --format '{{.Names}}\t{{.Status}}'
Every function should say Up. If one has exited, docker start it once.
The network is PLMN 001/01 (test network), set in the clone's .env.
4Add a subscriber
The simulated phone's SIM identity and keys are in the clone's .env
(UE1_IMSI, UE1_KI, UE1_OP). The core must know the same
subscriber, or the phone is refused. The commands below read the values from that file, so you never
type or print a key.
One conversion is needed: the SIM is configured with the operator key OP, and the core
stores OPc, which is derived from OP and the subscriber key K
(OPc = AES-128(K, OP) XOR OP). Giving the core OP where it expects OPc fails exactly
like a wrong key.
Ubuntu, in ~/docker_open5gs
set -a; . ./.env; set +a
ENC=$(printf '%s' "$UE1_OP" | xxd -r -p | openssl enc -aes-128-ecb -K "$UE1_KI" -nopad | xxd -p -c 32)
OPC=$(python3 -c "print('%032x' % (int('$ENC',16) ^ int('$UE1_OP',16)))")
docker exec udr /open5gs/misc/db/open5gs-dbctl add_ue_with_apn "$UE1_IMSI" "$UE1_KI" "$OPC" internet
unset ENC OPC
lab/scripts/import-lab-subscriber.sh and
ueransim-attach.sh in the AminOpen5GS repository.5Record a registration
Record on the Docker bridge the core runs on, so every message between the functions is in the file. The filter leaves out database traffic, which is large and not signalling.
Ubuntu, first terminal
BR=br-$(docker network inspect docker_open5gs_default -f '{{printf "%.12s" .Id}}')
sudo tcpdump -i "$BR" -s 0 -U -w ~/register-ok.pcap 'not port 27017'
Ubuntu, second terminal, in ~/docker_open5gs
docker compose -f nr-gnb.yaml up -d && sleep 5 docker compose -f nr-ue.yaml up -d docker logs -f nr_ue # wait for "Initial Registration is successful", then Ctrl+C
Stop the recording with Ctrl+C in the first terminal, and copy the file where Windows can see it:
cp ~/register-ok.pcap /mnt/c/Users/$(cmd.exe /c 'echo %USERNAME%' 2>/dev/null | tr -d '\r')/Downloads/
6Upload and read it
In the inspector, sign in and drop register-ok.pcap on
Upload a capture. It is analysed in a few seconds and appears in the list with its interfaces
(NGAP carrying 5G NAS between the gNB and the AMF). Open it and follow the registration:
| Step | What to look for |
|---|---|
| Registration Request | the phone asks to join; its identity is a SUCI (the IMSI, concealed — in a test network, with the null scheme) |
| Authentication Request / Response | the AKA challenge from the core and the SIM's answer (lesson A3) |
| Security Mode Command / Complete | both sides switch on the keys AKA just produced |
| Registration Accept / Complete | the phone is in; a PDU session request follows for data |
Captures you upload are yours: other users do not see them.
7Break it on purpose
A failure teaches more when you can put it next to the success. Remove the subscriber from the core, record again, and compare.
Ubuntu, in ~/docker_open5gs
docker rm -f nr_ue set -a; . ./.env; set +a docker exec udr /open5gs/misc/db/open5gs-dbctl remove "$UE1_IMSI" # first terminal: the same tcpdump, written to ~/register-unknown.pcap docker compose -f nr-ue.yaml up -d && sleep 15 && docker logs nr_ue | tail -5
The phone is refused. Upload register-unknown.pcap, open it, and read
What went wrong; then pick register-ok in Compare with another capture.
The two flows run together until the core looks the subscriber up, and part there — the same place
the 4G sample open5gs-attach-user-unknown parts from its success, where the HSS answers
5001 and the phone gets Attach Reject cause 8.
Put the subscriber back with the add_ue_with_apn commands from step 4.
8Stop and clean up
cd ~/docker_open5gs docker rm -f nr_ue nr_gnb docker compose -f sa-deploy.yaml down --remove-orphans
Then wsl --shutdown in Windows gives the memory back.