Write operational README
Replace the placeholder README with a full operational guide: architecture, user flow, quick start, config table, API reference (token profile URLs, admin-token-gated export), profile-package-v2 format, Pi/Android deployment, core sync, security notes, testing, and project layout. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
0b362bbd0b
commit
fd5f650861
184
README.md
184
README.md
|
|
@ -1,2 +1,186 @@
|
|||
# ria-ran--sim-drop
|
||||
|
||||
**Closed-loop eSIM provisioning for emergency / NTN 5G deployments.**
|
||||
|
||||
A self-contained appliance (Raspberry Pi or Android) that connects to a 5G gNB
|
||||
for backhaul, broadcasts an open WiFi AP, and hands out eSIM credentials to
|
||||
connecting devices through a captive portal. Users go from "no signal" to
|
||||
"connected to the ad-hoc 5G network" in under a minute, with no operator in the
|
||||
loop.
|
||||
|
||||
> Deep design rationale lives in [`plan/design.md`](plan/design.md). This README
|
||||
> is the operational guide. Notable changes are tracked in
|
||||
> [`CHANGELOG.md`](CHANGELOG.md).
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Server Host (srsRAN gNB) │
|
||||
│ - srsRAN gNB │
|
||||
│ - Open5GS Core (or free5gc) │
|
||||
│ - Subscriber database │
|
||||
└─────────────┬───────────────────────────┘
|
||||
│ 5G NR
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ UE WiFi AP Drop │
|
||||
│ (Android device or Raspberry Pi) │
|
||||
│ - WiFi AP (open network) │
|
||||
│ - eSIM Provisioning Server (Flask) │
|
||||
│ - Captive Portal (nginx + dnsmasq) │
|
||||
└─────────────┬───────────────────────────┘
|
||||
│ WiFi
|
||||
▼
|
||||
End User Devices
|
||||
```
|
||||
|
||||
## User flow
|
||||
|
||||
1. User connects to the open WiFi network `Emergency-5G`.
|
||||
2. The captive portal auto-redirects to the activation page.
|
||||
3. User taps **Activate eSIM**.
|
||||
4. The server generates a unique IMSI / Ki / OPc / ICCID.
|
||||
5. An eSIM profile is generated and offered as a one-time download.
|
||||
6. User installs the profile via device Settings.
|
||||
7. The device connects to the 5G network automatically.
|
||||
|
||||
## Quick start (local dev)
|
||||
|
||||
```bash
|
||||
git clone https://riahub.ai/qoherent/ria-ran--sim-drop.git
|
||||
cd ria-ran--sim-drop
|
||||
python3 -m venv venv && source venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
cp config.yaml.example config.yaml # edit MCC/MNC/op_key as needed
|
||||
python scripts/init_db.py
|
||||
python -m server.app # → http://localhost:5000
|
||||
```
|
||||
|
||||
Open <http://localhost:5000/activate> and click **Activate eSIM**.
|
||||
|
||||
## Configuration
|
||||
|
||||
All configuration is in `config.yaml` (start from `config.yaml.example`).
|
||||
|
||||
| Field | Description | Example |
|
||||
|-------|-------------|---------|
|
||||
| `network.mcc` | Mobile Country Code (3 digits) | `"302"` |
|
||||
| `network.mnc` | Mobile Network Code (2–3 digits) | `"720"` |
|
||||
| `network.op_key` | Operator key, 16-byte hex (32 chars) | `"63bfa50e…"` |
|
||||
| `wifi.ip` | WiFi AP IP address | `"192.168.4.1"` |
|
||||
| `server.host` / `server.port` | Flask bind address | `"0.0.0.0"` / `5000` |
|
||||
| `server.admin_token` | Token guarding `/api/export`; empty = export disabled | `""` |
|
||||
| `database.path` | SQLite database path | `"/opt/…/subscribers.db"` |
|
||||
| `rate_limiting.window_hours` | One profile per MAC per window | `1` |
|
||||
| `profile.apn` | APN / DNN used in the profile and core session | `"internet"` |
|
||||
| `profile.smdp_address` | SM-DP+ address embedded in the LPA activation code | `"esim.local"` |
|
||||
| `core.type` | Core adapter: `open5gs` / `free5gc` / `none` | `"open5gs"` |
|
||||
| `core.mongodb_uri` | MongoDB connection for the core | `"mongodb://localhost:27017"` |
|
||||
|
||||
`op_key` is validated at startup (must be 16-byte hex) and the config file is
|
||||
rejected if it is empty or missing a required section.
|
||||
|
||||
## API reference
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|----------|--------|-------------|
|
||||
| `/activate` | GET | Captive portal page |
|
||||
| `/api/provision` | POST | Generate credentials + profile; returns a one-time `profile_url` |
|
||||
| `/api/profile/<token>` | GET | Download the profile via its unguessable capability token |
|
||||
| `/api/export` | GET | Export all subscribers (JSON). Requires `X-Admin-Token`; disabled unless `server.admin_token` is set |
|
||||
| `/api/status` | GET | Health check (subscriber count, uptime, core adapter) |
|
||||
|
||||
`POST /api/provision` accepts `{"mac_address": "aa:bb:cc:dd:ee:ff"}`; if omitted,
|
||||
the server resolves the client MAC from the ARP table. Rate limiting is per MAC.
|
||||
|
||||
## Profile format
|
||||
|
||||
`create_esim_profile` produces a `profile-package-v2` bundle containing the raw
|
||||
credentials plus **real 3GPP field encodings** — `EF_ICCID` and `EF_IMSI`
|
||||
(nibble-swapped BCD, 3GPP TS 31.102) — and an SGP.22 **LPA activation code**
|
||||
(`LPA:1$<smdp>$<matching-id>`).
|
||||
|
||||
Full SGP.22 SIMalliance Interoperable Profile (ASN.1 UPP) generation via osmocom
|
||||
pySim is the planned follow-up; consumer over-the-air install additionally
|
||||
requires an SM-DP+ / LPA. The current package targets programmable SIMs and
|
||||
core-network sync. See [`CHANGELOG.md`](CHANGELOG.md).
|
||||
|
||||
## Deployment
|
||||
|
||||
### Raspberry Pi
|
||||
|
||||
Requirements: Pi 4 (4GB+), a compatible 5G modem (e.g. Quectel RM500Q), Raspberry
|
||||
Pi OS Lite 64-bit, Python 3.11+, and a pre-provisioned SIM for gNB backhaul.
|
||||
|
||||
```bash
|
||||
sudo bash scripts/setup_wifi_ap.sh
|
||||
```
|
||||
|
||||
This installs hostapd/dnsmasq/nginx, configures the AP and captive-portal
|
||||
redirect, deploys the server under `/opt/esim-provisioning`, creates the `esim`
|
||||
service user, restricts `config.yaml` to `600`, initialises the DB, and enables
|
||||
the systemd services. Then edit `/etc/esim-provisioning/config.yaml` and
|
||||
`systemctl restart esim-provisioning`.
|
||||
|
||||
### Android / Termux
|
||||
|
||||
```bash
|
||||
bash android/termux_setup.sh
|
||||
~/esim-provisioning/start.sh
|
||||
```
|
||||
|
||||
See [`android/README.md`](android/README.md) for details and limitations.
|
||||
|
||||
## Core network sync
|
||||
|
||||
With `core.type: none`, credentials are stored locally only. To push them to a
|
||||
core network:
|
||||
|
||||
```bash
|
||||
python scripts/sync_subscribers.py # sync unsynced subscribers to Open5GS/free5gc
|
||||
python scripts/export_subscribers.py # dump all subscribers as JSON (reads the DB directly)
|
||||
```
|
||||
|
||||
Adding a new core is a single class in `server/core_adapters/` implementing the
|
||||
`CoreAdapter` interface.
|
||||
|
||||
## Security notes
|
||||
|
||||
- Profiles are served at an unguessable one-time token URL, never an enumerable
|
||||
id — the profile body contains Ki/OPc.
|
||||
- `/api/export` returns all key material and is **disabled by default**; set
|
||||
`server.admin_token` and send it as `X-Admin-Token` to enable.
|
||||
- The deployed `config.yaml` (holds `op_key`) is `chmod 600`, owned by the
|
||||
service user; the systemd unit runs with `NoNewPrivileges`, `PrivateTmp`, and
|
||||
`ProtectSystem=strict`.
|
||||
- The WiFi network is intentionally open (emergency access); there is no
|
||||
transport encryption on the local link.
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
python -m pytest tests/ -q
|
||||
```
|
||||
|
||||
The suite covers credential generation and 3GPP encodings, the database and rate
|
||||
limiting, the core adapters, config/utility validation, and the Flask API
|
||||
(provisioning, token download, rate-limit and export auth).
|
||||
|
||||
## Project layout
|
||||
|
||||
```
|
||||
server/ Flask app, profile generator, database, core adapters
|
||||
portal/ Captive-portal frontend (HTML/CSS/JS)
|
||||
scripts/ init_db, sync/export subscribers, Pi AP setup
|
||||
configs/ nginx / dnsmasq / hostapd reference configs
|
||||
systemd/ Service units
|
||||
android/ Termux deployment
|
||||
tests/ Test suite
|
||||
plan/ Design doc and per-unit implementation notes
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT (or as appropriate for the deployment context).
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user