Call 0330 520 4093

Lodestar’s story / Build your own network

Chapter 06 of 18

Install and configure the 4G core

The core turns a radio connection into an authenticated data session. Keep its internal components on the same PC for your first build.

Published 1 November 2026
About 5 minutes to read, plus build time

The early AzurePCS home PC and radio setup
The original AzurePCS setup, photographed by Blake. This historical Band 3 setup inspired the guide.
In this chapter
  1. Install MongoDB for Ubuntu 24.04
  2. Install Open5GS and record the versions
  3. Let the MME listen to the radio
  4. Let the SGW-U carry radio traffic
  5. Use one IPv4 phone pool
  6. Check the phone tunnel interface
  7. Validate and start the core

Open5GS branch: after this chapter, continue to Protect the LAN. The next numbered chapter is the alternative VectorCore build.

Install MongoDB for Ubuntu 24.04

MongoDB stores the subscriptions. These commands use MongoDB's official 8.0 repository for Ubuntu 24.04 Noble. Do not substitute a Jammy repository or the unrelated Ubuntu mongodb package. Check MongoDB's current installation instructions if you choose another operating system.

curl -fsSL https://pgp.mongodb.com/server-8.0.asc   -o /tmp/mongodb-server-8.0.asc
sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-8.0.gpg   /tmp/mongodb-server-8.0.asc
echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg] https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0 multiverse'   | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
sudo apt update
sudo apt install mongodb-org
sudo systemctl enable --now mongod
systemctl is-active mongod

Expected result: active. Keep net.bindIp in /etc/mongod.conf restricted to 127.0.0.1 for this single-host lab. The later firewall also blocks remote database access. Subscriber backups contain long-term authentication secrets and need encrypted storage.

Install Open5GS and record the versions

sudo add-apt-repository ppa:open5gs/latest
sudo apt update
sudo apt install open5gs
apt-cache policy open5gs
dpkg-query -W 'open5gs*' mongodb-org
sudo cp -a /etc/open5gs /root/private-lte-backups/open5gs-initial
sudo cp -a /etc/freeDiameter /root/private-lte-backups/freeDiameter-initial

The public project provides both 4G and 5G functions. This guide uses its LTE EPC roles. Keep the package's working local connections, including its loopback control addresses, Diameter files and any NRF/SCP dependencies used by the installed SMF. There is no reason to expose every function simply because it is installed.

At publication, Open5GS 2.8.0 was the latest tagged release. The examples use that configuration family, not a promise that the PPA always installs the same version. Compare the installed files with the official quickstart. If their structure differs, follow the matching release documentation rather than inserting guessed keys.

Let the MME listen to the radio

Open /etc/open5gs/mme.yaml with sudo nano. Change the existing mme.s1ap.server address to 192.168.200.1. Change both PLMN entries, under gummei and tai, to the same MCC and two-digit MNC as your SIM. Keep the tracking area consistent with the radio. These are extracts within the existing mme: block:

  s1ap:
    server:
      - address: 192.168.200.1
  gummei:
    - plmn_id:
        mcc: 999
        mnc: 99
      mme_gid: 2
      mme_code: 1
  tai:
    - plmn_id:
        mcc: 999
        mnc: 99
      tac: 1
  security:
    integrity_order: [ EIA2, EIA1 ]
    ciphering_order: [ EEA2, EEA1 ]
  network_name:
    full: My Private LTE
    short: PrivateLTE

These MME settings select NAS protection algorithms for control signalling. Check the eNodeB's separate access-stratum security settings and verify that normal radio bearers also use supported non-null protection. The non-null integrity and cipher choices above deliberately avoid selecting the unprotected EIA0 and EEA0 algorithms in this normal LTE data lab. Check that the handset and eNodeB support the selected algorithms. Do not solve a security negotiation failure by silently enabling unprotected operation. Leave gtpc, Diameter and other internal addresses at the package defaults.

Save in nano with Ctrl+O, Enter, then Ctrl+X. Network display names may also come from SIM files or handset configuration, so changing this text alone does not guarantee the same name on every phone.

Let the SGW-U carry radio traffic

Open /etc/open5gs/sgwu.yaml. Change only its radio-facing GTP-U server address. The extract inside sgwu: is:

  gtpu:
    server:
      - address: 192.168.200.1

Keep the PFCP and other control connections at their local defaults. The same PC can bind the MME's SCTP signalling and SGW-U's UDP data to the same address because they use different protocols and ports. The release SGW-U configuration describes these fields.

Use one IPv4 phone pool

In /etc/open5gs/smf.yaml, edit the existing session and DNS lists. Remove the example IPv6 session and IPv6 DNS entries for this first IPv4 build. This extract belongs within smf::

  session:
    - subnet: 10.45.0.0/16
      gateway: 10.45.0.1
  dns:
    - 1.1.1.1
    - 9.9.9.9
  mtu: 1400

These are example public resolvers. Choose resolvers whose operation and privacy terms suit your network. In /etc/open5gs/upf.yaml, keep the matching IPv4 session and remove the example IPv6 session:

  session:
    - subnet: 10.45.0.0/16
      gateway: 10.45.0.1

Leave the UPF's GTP-U address local in this one-PC LTE layout. The external radio reaches SGW-U, not the UPF directly. A 1400-byte inner MTU is a cautious starting value, not a cure for all transport faults. Recheck it when adding IPsec. The SMF and UPF release examples explain the available fields.

Check the phone tunnel interface

ip -br address show ogstun
ip route show 10.45.0.0/16

The packaged installation normally prepares an ogstun interface for the phone pool. Expected: it is up with 10.45.0.1/16 and a connected route for that pool. If it is absent, check the installed package's network setup first. Do not create a second competing configuration. On a clean install with no package-managed ogstun, use this explicit systemd unit:

[Unit]
Description=Private LTE subscriber TUN
Before=open5gs-upfd.service
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/ip tuntap add dev ogstun mode tun
ExecStart=/usr/sbin/ip address add 10.45.0.1/16 dev ogstun
ExecStart=/usr/sbin/ip link set dev ogstun up
ExecStop=/usr/sbin/ip link delete dev ogstun

[Install]
WantedBy=multi-user.target

Verify no existing tool owns ogstun, then save the unit as /etc/systemd/system/private-lte-tun.service, then run sudo systemctl daemon-reload and sudo systemctl enable --now private-lte-tun. Use exactly one owner for the interface. An existing interface error is a reason to inspect, not to delete a live tunnel.

Validate and start the core

sudo python3 - <<'PY'
from pathlib import Path
import yaml
for name in ['mme', 'sgwu', 'smf', 'upf']:
    yaml.safe_load(Path('/etc/open5gs/' + name + '.yaml').read_text())
    print(name + ': YAML parsed')
PY
sudo systemctl restart open5gs-mmed open5gs-sgwud open5gs-smfd open5gs-upfd
systemctl is-active mongod open5gs-hssd open5gs-mmed open5gs-pcrfd   open5gs-sgwcd open5gs-sgwud open5gs-smfd open5gs-upfd
sudo ss -lnp -A sctp
sudo ss -lunp
systemctl --failed

YAML parsing checks layout, not whether Open5GS accepts every key. The services must remain active and their logs must show successful configuration, subscriber database and gateway peer connections. The MME should listen on 192.168.200.1 with SCTP port 36412. SGW-U should listen on UDP 2152 at that address. Internal connections should remain on loopback. If a service fails, inspect sudo journalctl -u open5gs-mmed -n 60 --no-pager, substituting the service that failed.

Make a new private backup when this checkpoint passes. Do not put live keys, database records or diagnostic logs into a public Git repository.