06_lab_5g_sa_docker

Part 6: Docker Lab - 5G SA Core with UERANSIM

Learning Objective: Build a working 5G Standalone (SA) core network with Open5GS and simulate gNB/UE with UERANSIM on Docker. Then explore SBI traffic, NF service discovery, network slicing, and NF resilience.


Table of Contents


Prerequisites

Software

docker --version
# Docker version 24.0.0 or higher

docker compose version
# Docker Compose version v2.20.0 or higher

Disk Space

Docker Images Used

Component Image Source
MongoDB mongo:6.0 Official MongoDB
Open5GS NFs borieher/open5gs-<nf>:v2.7.6 docker-open5gs
Open5GS WebUI borieher/open5gs-webui:v2.7.6 docker-open5gs
UERANSIM gNB louisroyer/ueransim-gnb:latest louisroyer Docker Hub
UERANSIM UE louisroyer/ueransim-ue:latest louisroyer Docker Hub
Note

Unlike Part 4 (4G EPC) which uses a monolithic gradiant/open5gs image, the 5G SA lab uses per-NF images from borieher/open5gs-<nf>. These images contain only 5G SA network functions (NRF, SCP, AMF, SMF, UPF, AUSF, UDM, UDR, PCF, NSSF, BSF). 4G-specific daemons (MME, HSS, PCRF, SGW-C, SGW-U) are not included in these images.


Lab Architecture

graph TB
    subgraph "Docker Host (Mac)"
        subgraph "SBI Network (172.22.0.0/24)"
            MongoDB[(MongoDB
172.22.0.2)] WebUI[WebUI
172.22.0.3
:9999] NRF[NRF
172.22.0.10] SCP[SCP
172.22.0.11] AMF[AMF
172.22.0.20] SMF[SMF
172.22.0.21] AUSF[AUSF
172.22.0.13] UDM[UDM
172.22.0.14] UDR[UDR
172.22.0.15] PCF[PCF
172.22.0.16] NSSF[NSSF
172.22.0.17] BSF[BSF
172.22.0.18] end subgraph "RAN Network (172.23.0.0/24)" UPF[UPF
172.23.0.10] gNB[UERANSIM gNB
172.23.0.2] UE[UERANSIM UE
172.23.0.3] end end Internet[Internet
via ogstun] UE <-->|RRC| gNB gNB <-->|N2 NGAP| AMF gNB <-->|N3 GTP-U| UPF AMF <-->|SBI| NRF SMF <-->|SBI| NRF AUSF <-->|SBI| NRF SMF <-->|N4 PFCP| UPF UPF <-->|N6 ogstun| Internet WebUI <-->|HTTP| MongoDB UDR <-->|MongoDB| MongoDB style MongoDB fill:#f9f style WebUI fill:#9ff style AMF fill:#fcc style UPF fill:#cfc style NRF fill:#ff9

Docker Network Design

Network Subnet Purpose
open5gs_sbi 172.22.0.0/24 SBI (HTTP/2) between NFs, MongoDB, WebUI
open5gs_ran 172.23.0.0/24 N2/N3 between AMF/UPF and UERANSIM
Note

Comparison with 4G EPC (Part 4): The 5G SA core uses SBI (HTTP/2, port 7777) for all inter-NF communication, replacing the Diameter (port 3868) and GTP-C (port 2123) signaling used in 4G. The RAN connects via NGAP (port 38412) instead of S1AP (port 36412).


Step 1: Project Setup

mkdir -p ~/open5gs_5g_lab/{config,ueransim,log}
cd ~/open5gs_5g_lab

Step 2: Docker Compose Configuration

Create docker-compose.yml:

version: '3.8'

services:
  # === Infrastructure ===
  mongodb:
    image: mongo:6.0
    container_name: open5gs_mongodb
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.2
    volumes:
      - mongodb_data:/data/db
    restart: unless-stopped

  webui:
    image: borieher/open5gs-webui:v2.7.6
    container_name: open5gs_webui
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.3
    ports:
      - "9999:9999"
    environment:
      - DB_URI=mongodb://172.22.0.2/open5gs
    depends_on:
      - mongodb
    restart: unless-stopped

  # === 5G Core NFs ===
  nrf:
    image: borieher/open5gs-nrf:v2.7.6
    container_name: open5gs_nrf
    volumes:
      - ./config/nrf.yaml:/etc/open5gs/nrf.yaml
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.10
    restart: unless-stopped

  scp:
    image: borieher/open5gs-scp:v2.7.6
    container_name: open5gs_scp
    volumes:
      - ./config/scp.yaml:/etc/open5gs/scp.yaml
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.11
    depends_on:
      - nrf
    restart: unless-stopped

  ausf:
    image: borieher/open5gs-ausf:v2.7.6
    container_name: open5gs_ausf
    volumes:
      - ./config/ausf.yaml:/etc/open5gs/ausf.yaml
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.13
    depends_on:
      - nrf
    restart: unless-stopped

  udm:
    image: borieher/open5gs-udm:v2.7.6
    container_name: open5gs_udm
    volumes:
      - ./config/udm.yaml:/etc/open5gs/udm.yaml
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.14
    depends_on:
      - nrf
    restart: unless-stopped

  udr:
    image: borieher/open5gs-udr:v2.7.6
    container_name: open5gs_udr
    volumes:
      - ./config/udr.yaml:/etc/open5gs/udr.yaml
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.15
    depends_on:
      - mongodb
      - nrf
    restart: unless-stopped

  pcf:
    image: borieher/open5gs-pcf:v2.7.6
    container_name: open5gs_pcf
    volumes:
      - ./config/pcf.yaml:/etc/open5gs/pcf.yaml
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.16
    depends_on:
      - nrf
    restart: unless-stopped

  nssf:
    image: borieher/open5gs-nssf:v2.7.6
    container_name: open5gs_nssf
    volumes:
      - ./config/nssf.yaml:/etc/open5gs/nssf.yaml
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.17
    depends_on:
      - nrf
    restart: unless-stopped

  bsf:
    image: borieher/open5gs-bsf:v2.7.6
    container_name: open5gs_bsf
    volumes:
      - ./config/bsf.yaml:/etc/open5gs/bsf.yaml
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.18
    depends_on:
      - nrf
    restart: unless-stopped

  amf:
    image: borieher/open5gs-amf:v2.7.6
    container_name: open5gs_amf
    volumes:
      - ./config/amf.yaml:/etc/open5gs/amf.yaml
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.20
      open5gs_ran:
        ipv4_address: 172.23.0.20
    depends_on:
      - nrf
    cap_add:
      - NET_ADMIN
    restart: unless-stopped

  smf:
    image: borieher/open5gs-smf:v2.7.6
    container_name: open5gs_smf
    volumes:
      - ./config/smf.yaml:/etc/open5gs/smf.yaml
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.21
    depends_on:
      - nrf
    restart: unless-stopped

  upf:
    image: borieher/open5gs-upf:v2.7.6
    container_name: open5gs_upf
    volumes:
      - ./config/upf.yaml:/etc/open5gs/upf.yaml
    networks:
      open5gs_sbi:
        ipv4_address: 172.22.0.30
      open5gs_ran:
        ipv4_address: 172.23.0.10
    cap_add:
      - NET_ADMIN
    privileged: true
    sysctls:
      - net.ipv4.ip_forward=1
    restart: unless-stopped

  # === UERANSIM ===
  ueransim_gnb:
    image: louisroyer/ueransim-gnb:latest
    container_name: ueransim_gnb
    volumes:
      - ./ueransim/gnb.yaml:/config/gnb.yaml
    networks:
      open5gs_ran:
        ipv4_address: 172.23.0.2
    cap_add:
      - NET_ADMIN
    depends_on:
      - amf
      - upf
    restart: unless-stopped

  ueransim_ue:
    image: louisroyer/ueransim-ue:latest
    container_name: ueransim_ue
    volumes:
      - ./ueransim/ue.yaml:/config/ue.yaml
    networks:
      open5gs_ran:
        ipv4_address: 172.23.0.3
    cap_add:
      - NET_ADMIN
    privileged: true
    depends_on:
      - ueransim_gnb
    restart: unless-stopped

networks:
  open5gs_sbi:
    driver: bridge
    ipam:
      config:
        - subnet: 172.22.0.0/24
  open5gs_ran:
    driver: bridge
    ipam:
      config:
        - subnet: 172.23.0.0/24

volumes:
  mongodb_data:
Warning

Mac Docker Note: The privileged: true flag on UPF and UE is needed for TUN device creation (ogstun / uesimtun0). On Linux hosts you can use devices: [/dev/net/tun] instead, but Mac Docker Desktop runs containers inside a Linux VM where /dev/net/tun access requires privileged mode.


Step 3: Open5GS NF Configurations

Create each config file in config/:

NRF (config/nrf.yaml)

logger:
  level: info

nrf:
  serving:
    - plmn_id:
        mcc: 001
        mnc: 01
  sbi:
    server:
      - address: 172.22.0.10
        port: 7777

SCP (config/scp.yaml)

logger:
  level: info

scp:
  sbi:
    server:
      - address: 172.22.0.11
        port: 7777
    client:
      nrf:
        - uri: http://172.22.0.10:7777

AMF (config/amf.yaml)

logger:
  level: info

amf:
  sbi:
    server:
      - address: 172.22.0.20
        port: 7777
    client:
      nrf:
        - uri: http://172.22.0.10:7777
      scp:
        - uri: http://172.22.0.11:7777
  ngap:
    server:
      - address: 172.23.0.20
  guami:
    - plmn_id:
        mcc: 001
        mnc: 01
      amf_id:
        region: 2
        set: 1
  tai:
    - plmn_id:
        mcc: 001
        mnc: 01
      tac: 1
  plmn_support:
    - plmn_id:
        mcc: 001
        mnc: 01
      s_nssai:
        - sst: 1
  security:
    integrity_order: [NIA2, NIA1, NIA0]
    ciphering_order: [NEA2, NEA1, NEA0]
Tip

Notice ciphering_order puts NEA2 first (AES-128). Never put NEA0 (null cipher) first in production — that's the downgrade attack from Part 9.

SMF (config/smf.yaml)

logger:
  level: info

smf:
  sbi:
    server:
      - address: 172.22.0.21
        port: 7777
    client:
      nrf:
        - uri: http://172.22.0.10:7777
      scp:
        - uri: http://172.22.0.11:7777
  pfcp:
    server:
      - address: 172.22.0.21
    client:
      upf:
        - address: 172.22.0.30
  subnet:
    - addr: 10.45.0.1/16
      dnn: internet
  dns:
    - 8.8.8.8
    - 8.8.4.4

UPF (config/upf.yaml)

logger:
  level: info

upf:
  pfcp:
    server:
      - address: 172.22.0.30
  gtpu:
    server:
      - address: 172.23.0.10
  subnet:
    - addr: 10.45.0.1/16
      dnn: internet

AUSF (config/ausf.yaml)

logger:
  level: info

ausf:
  sbi:
    server:
      - address: 172.22.0.13
        port: 7777
    client:
      nrf:
        - uri: http://172.22.0.10:7777
      scp:
        - uri: http://172.22.0.11:7777

UDM (config/udm.yaml)

logger:
  level: info

udm:
  sbi:
    server:
      - address: 172.22.0.14
        port: 7777
    client:
      nrf:
        - uri: http://172.22.0.10:7777
      scp:
        - uri: http://172.22.0.11:7777

UDR (config/udr.yaml)

logger:
  level: info

udr:
  sbi:
    server:
      - address: 172.22.0.15
        port: 7777
    client:
      nrf:
        - uri: http://172.22.0.10:7777
      scp:
        - uri: http://172.22.0.11:7777

db_uri: mongodb://172.22.0.2/open5gs

PCF (config/pcf.yaml)

logger:
  level: info

pcf:
  sbi:
    server:
      - address: 172.22.0.16
        port: 7777
    client:
      nrf:
        - uri: http://172.22.0.10:7777
      scp:
        - uri: http://172.22.0.11:7777

db_uri: mongodb://172.22.0.2/open5gs

NSSF (config/nssf.yaml)

logger:
  level: info

nssf:
  sbi:
    server:
      - address: 172.22.0.17
        port: 7777
    client:
      nrf:
        - uri: http://172.22.0.10:7777
      scp:
        - uri: http://172.22.0.11:7777
  nsi:
    - addr: 172.22.0.20
      port: 7777
      s_nssai:
        sst: 1

BSF (config/bsf.yaml)

logger:
  level: info

bsf:
  sbi:
    server:
      - address: 172.22.0.18
        port: 7777
    client:
      nrf:
        - uri: http://172.22.0.10:7777
      scp:
        - uri: http://172.22.0.11:7777

Step 4: UERANSIM Configuration

gNB (ueransim/gnb.yaml)

mcc: '001'
mnc: '01'
nci: '0x000000010'
idLength: 32
tac: 1

linkIp: 172.23.0.2
ngapIp: 172.23.0.2
gtpIp: 172.23.0.2

amfConfigs:
  - address: 172.23.0.20
    port: 38412

slices:
  - sst: 1

ignoreStreamIds: true
Note

UERANSIM gNB connects via NGAP (N2, port 38412) to AMF. This is a 5G SA connection. Compare this to the 4G S1AP interface (port 36412) used in Part 4's EPC lab.

UE (ueransim/ue.yaml)

supi: 'imsi-001010000000001'
mcc: '001'
mnc: '01'
routingIndicator: '0000'

# No SUCI encryption (null scheme for lab)
protectionScheme: 0
homeNetworkPublicKey: ''
homeNetworkPublicKeyId: 1

# Security keys (must match WebUI registration)
key: '465B5CE8B199B49FAA5F0A2EE238A6BC'
op: 'E8ED289DEBA952E4283B54E88E6183CA'
opType: 'OPC'

gnbSearchList:
  - 172.23.0.2

sessions:
  - type: 'IPv4'
    apn: 'internet'
    slice:
      sst: 1

integrity:
  IA1: true
  IA2: true
  IA3: true

ciphering:
  EA1: true
  EA2: true
  EA3: true

Step 5: Launch the Core

# Start infrastructure first
docker compose up -d mongodb
sleep 3

# Start NRF (service registry must be up before other NFs)
docker compose up -d nrf
sleep 2

# Start all other NFs
docker compose up -d scp ausf udm udr pcf nssf bsf amf smf upf webui

# Verify all containers are running
docker compose ps

Check NRF registrations

docker compose logs nrf | grep -i "registered"

Expected output:

NF registered: AMF (172.22.0.20)
NF registered: SMF (172.22.0.21)
NF registered: AUSF (172.22.0.13)
NF registered: UDM (172.22.0.14)
NF registered: PCF (172.22.0.16)

Step 6: Register a Subscriber

  1. Open browser: http://localhost:9999
  2. Login:
    • Username: admin
    • Password: 1423
  3. Click Subscribers -> + (Add)
  4. Fill in subscriber details:
    • IMSI: 001010000000001
    • K: 465B5CE8B199B49FAA5F0A2EE238A6BC
    • OPc: E8ED289DEBA952E4283B54E88E6183CA
    • APN/DNN: internet
    • SST: 1
  5. Click SAVE
Caution

The K/OPc values in the WebUI must exactly match the values in ue.yaml. A single character mismatch causes authentication failure (check AMF logs for MAC failure).


Step 7: Connect gNB and UE

Start gNB:

docker compose up -d ueransim_gnb
docker compose logs -f ueransim_gnb

Expected output:

[sctp] [info] Trying to establish SCTP connection... (172.23.0.20:38412)
[sctp] [info] SCTP connection established
[ngap] [info] NG Setup procedure is successful

Start UE:

docker compose up -d ueransim_ue
docker compose logs -f ueransim_ue

Expected output:

[nas] [info] UE switches to state [MM-REGISTERED/NORMAL-SERVICE]
[nas] [info] PDU Session establishment is successful PSI[1]
[app] [info] Connection setup for PDU session[1] is successful, TUN interface[uesimtun0, 10.45.0.2] is up.

Step 8: Verify Connectivity

Check UE Interface

docker exec -it ueransim_ue ip addr show uesimtun0

Output:

5: uesimtun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1400
    inet 10.45.0.2/32 scope global uesimtun0

Ping Test

docker exec -it ueransim_ue ping -I uesimtun0 -c 4 8.8.8.8

Output:

PING 8.8.8.8 (8.8.8.8) from 10.45.0.2 uesimtun0: 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=12.3 ms

Your 5G SA core is working end-to-end.


Packet Capture with tcpdump

Capture NGAP (N2 Control Plane)

docker exec -it open5gs_amf tcpdump -i any -w /tmp/ngap.pcap sctp
# Copy out: docker cp open5gs_amf:/tmp/ngap.pcap .

Wireshark filter: ngap

Capture GTP-U (N3 User Plane)

docker exec -it open5gs_upf tcpdump -i any -w /tmp/gtpu.pcap udp port 2152
# Copy out: docker cp open5gs_upf:/tmp/gtpu.pcap .

Wireshark filter: gtp

Capture SBI (HTTP/2 between NFs)

docker exec -it open5gs_amf tcpdump -i any -w /tmp/sbi.pcap tcp port 7777
# Copy out: docker cp open5gs_amf:/tmp/sbi.pcap .

Wireshark filter: http2


Deep Dive: SBA Service Discovery

Watch NRF Registrations

# See all NF registrations in real-time
docker compose logs -f nrf 2>&1 | grep -i "register\|profile\|discover"

Query NRF via API

The NRF exposes a REST API. From any container on the SBI network:

# List all registered NFs
docker exec -it open5gs_amf curl -s http://172.22.0.10:7777/nnrf-nfm/v1/nf-instances | python3 -m json.tool

# Discover SMF instances
docker exec -it open5gs_amf curl -s \
  "http://172.22.0.10:7777/nnrf-disc/v1/nf-instances?target-nf-type=SMF" | python3 -m json.tool

What You'll See

{
  "nfInstances": [
    {
      "nfInstanceId": "e8c835a4-...",
      "nfType": "SMF",
      "nfStatus": "REGISTERED",
      "ipv4Addresses": ["172.22.0.21"],
      "sNssais": [{"sst": 1}],
      "nfServices": [
        {
          "serviceName": "nsmf-pdusession",
          "versions": [{"apiVersionInUri": "v1"}],
          "scheme": "http"
        }
      ]
    }
  ]
}
Tip

This is exactly how AMF discovers SMF during PDU session setup — it queries NRF's Nnrf_NFDiscovery API. In the Part 9 threat model, we discuss how an attacker could poison NRF by registering a rogue NF.

Note

Comparison with 4G: In the 4G EPC (Part 4), there is no NRF. All peer addresses are hardcoded in config files (e.g., MME knows SGW-C's IP directly). SBA service discovery is a 5G SA innovation.


Deep Dive: SBI Traffic Analysis

Capture SBI between AMF and SMF

# Capture HTTP/2 traffic on the SBI network
docker exec -it open5gs_amf tcpdump -i any -w /tmp/sbi_amf.pcap tcp port 7777

# In another terminal, trigger a new PDU session by restarting UE
docker compose restart ueransim_ue

# Wait 10 seconds, then Ctrl+C the tcpdump
# Copy the capture out
docker cp open5gs_amf:/tmp/sbi_amf.pcap .

Wireshark Analysis

Open the pcap in Wireshark and look for:

Filter What You'll See
http2 SBI API calls between NFs
http2 && http2.header.name == ":path" API endpoints called
json Request/response payloads

Key SBI Calls to Find

POST /nsmf-pdusession/v1/sm-contexts         <- AMF asks SMF to create session
POST /nudm-sdm/v1/{supi}/sm-data             <- SMF asks UDM for subscription data
POST /npcf-smpolicycontrol/v1/sm-policies    <- SMF asks PCF for QoS policy
POST /nausf-auth/v1/ue-authentications        <- AMF asks AUSF to authenticate UE
Note

Comparison with 4G: In Part 4, you captured Diameter on port 3868 (S6a, Gx) and GTP-C on port 2123 (S11, S5-C). Here, all equivalent signaling flows over SBI HTTP/2 on port 7777. This consolidation is a defining feature of 5G SA's Service Based Architecture.


Deep Dive: Network Slicing — Add URLLC Slice

Step 1: Update AMF Config

Add SST=2 to the plmn_support in config/amf.yaml:

  plmn_support:
    - plmn_id:
        mcc: 001
        mnc: 01
      s_nssai:
        - sst: 1       # eMBB (existing)
        - sst: 2       # URLLC (new)

Step 2: Update SMF Config

Add a second subnet for the URLLC slice in config/smf.yaml:

  subnet:
    - addr: 10.45.0.1/16
      dnn: internet
      s_nssai:
        sst: 1
    - addr: 10.46.0.1/16
      dnn: iot
      s_nssai:
        sst: 2

Step 3: Update UPF Config

Add the second subnet in config/upf.yaml:

  subnet:
    - addr: 10.45.0.1/16
      dnn: internet
    - addr: 10.46.0.1/16
      dnn: iot

Step 4: Add Second UE for URLLC

Create ueransim/ue_urllc.yaml:

supi: 'imsi-001010000000002'
mcc: '001'
mnc: '01'
routingIndicator: '0000'
protectionScheme: 0
homeNetworkPublicKey: ''
homeNetworkPublicKeyId: 1

key: '465B5CE8B199B49FAA5F0A2EE238A6BC'
op: 'E8ED289DEBA952E4283B54E88E6183CA'
opType: 'OPC'

gnbSearchList:
  - 172.23.0.2

sessions:
  - type: 'IPv4'
    apn: 'iot'
    slice:
      sst: 2       # URLLC slice

integrity:
  IA1: true
  IA2: true
  IA3: true

ciphering:
  EA1: true
  EA2: true
  EA3: true

Step 5: Register URLLC Subscriber

In WebUI (http://localhost:9999):

Step 6: Verify Slice Assignment

docker compose logs ueransim_ue_urllc | grep -i "slice\|sst\|pdu"

Expected: UE gets IP from 10.46.0.0/16 range (URLLC slice), not 10.45.0.0/16 (eMBB slice).

Note

4G Comparison: Network slicing is a 5G SA-only feature. It requires NSSF, AMF, and SMF working together via SBA. The 4G EPC (Part 4) has no slice awareness — the MME does not support S-NSSAI selection.


Deep Dive: NF Resilience Testing

Kill a Critical NF

# Kill the SMF
docker compose stop smf

# Try to start a new PDU session (restart UE)
docker compose restart ueransim_ue

# Check UE logs — PDU session should fail
docker compose logs ueransim_ue | tail -10

# Restart SMF
docker compose start smf

# UE should recover on retry
docker compose restart ueransim_ue

Kill the NRF

# Kill NRF — what happens to existing sessions?
docker compose stop nrf

# Answer: Existing sessions continue (NFs already have each other's addresses)
# But NEW sessions fail (NFs can't discover each other)

# Verify: existing UE still pings fine
docker exec -it ueransim_ue ping -I uesimtun0 -c 2 8.8.8.8

# Restart NRF
docker compose start nrf
Important

This demonstrates why NRF is the heart of SBA. Losing NRF doesn't kill existing sessions (NFs cache discovery results), but prevents new sessions from being established. In production, NRF must be highly available.


Deep Dive: Metrics and Monitoring

Check Open5GS Metrics

If your NF configs include a metrics section:

  metrics:
    server:
      - address: 172.22.0.20
        port: 9090

You can scrape Prometheus metrics:

docker exec -it open5gs_amf curl -s http://172.22.0.20:9090/metrics | head -30

Look for:


Troubleshooting

NFs Cannot Register with NRF

docker compose logs nrf | tail -20
docker compose logs amf | grep -i "error\|failed"

Common causes:

UE Cannot Authenticate

docker compose logs amf | grep -i "mac\|auth\|fail"

Common causes:

No Internet from UE

# Check UPF TUN interface
docker exec -it open5gs_upf ip addr show ogstun

# Check UPF routing
docker exec -it open5gs_upf ip route

# Check NAT
docker exec -it open5gs_upf iptables -t nat -L

Fix: UPF needs NAT for outbound traffic:

docker exec -it open5gs_upf iptables -t nat -A POSTROUTING \
  -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE

Cleanup

docker compose down -v  # -v removes volumes (subscriber data)

Exercises

  1. Multi-UE: Add a second UE (imsi-001010000000002) with different security keys. Register it in the WebUI and modify docker-compose.yml to add ueransim_ue2.
  2. IP Pool: Change UPF/SMF subnet from 10.45.0.0/16 to 10.50.0.0/16. What do you need to update?
  3. Wireshark Analysis: Capture NGAP traffic and find the InitialUEMessage. What identifiers can you see? Is SUPI visible? (Hint: check protectionScheme in ue.yaml)
  4. DNS Test: From the UE, run docker exec ueransim_ue nslookup google.com 8.8.8.8 through the tunnel.
  5. NRF Discovery: Capture SBI traffic on port 7777 and observe how AMF discovers SMF via NRF during PDU session setup.
  6. 4G vs 5G Comparison: Compare the protocol captures from Part 4 (Diameter S6a, GTP-C S11) with the SBI HTTP/2 captures from this lab. List three specific differences in how authentication and session management work.

Summary

You have successfully:

Next: Part 7: Kubernetes Deployment ->