A
8672b0de6b
Full working closed-loop eSIM provisioning stack (spec in claude.md / plan/): Flask API, SQLite subscriber store, credential/profile generator, Open5GS and free5gc core adapters, captive portal, operational scripts, systemd units, network configs, and a 44-test suite. Profile generation currently returns a mock JSON profile; real SGP.22 generation via pySim is the planned Phase-2 upgrade. Fixes two bugs found while getting the suite green: - generate_imsi hardcoded a 10-digit MSIN, producing 16-digit IMSIs for a 3-digit MNC; MSIN length is now 15 - len(mcc) - len(mnc). - check_rate_limit compared timestamps as strings across mismatched formats (SQLite CURRENT_TIMESTAMP vs Python isoformat); both sides now normalized via SQLite datetime() so the window check is chronologically correct. Add .gitignore for venv, caches, runtime config.yaml, and databases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
156 lines
4.6 KiB
Markdown
156 lines
4.6 KiB
Markdown
# Unit 09 — Android / Termux Deployment
|
|
|
|
## Goal
|
|
Automated setup script and instructions for running the provisioning stack on Android via Termux (no root required for basic operation).
|
|
|
|
## Files
|
|
- `android/README.md`
|
|
- `android/termux_setup.sh`
|
|
|
|
---
|
|
|
|
## Constraints & Differences from Raspberry Pi
|
|
|
|
| Feature | Raspberry Pi | Android (Termux) |
|
|
|---------|-------------|-----------------|
|
|
| WiFi AP | hostapd (full control) | Android Settings hotspot (limited) |
|
|
| DNS hijacking | dnsmasq full control | Limited without root |
|
|
| Port 80 | Direct | Need port >1024 or root; use 8080 |
|
|
| Captive portal trigger | iptables redirect | Relies on OS captive portal detection |
|
|
| Systemd | Yes | No — use Termux boot scripts |
|
|
|
|
---
|
|
|
|
## `android/termux_setup.sh`
|
|
|
|
```bash
|
|
#!/data/data/com.termux/files/usr/bin/bash
|
|
set -euo pipefail
|
|
|
|
echo "=== eSIM Provisioning Server — Termux Setup ==="
|
|
|
|
# Update Termux packages
|
|
pkg update -y && pkg upgrade -y
|
|
|
|
# Install core dependencies
|
|
pkg install -y python python-pip nginx
|
|
|
|
# Install Python dependencies
|
|
pip install flask cryptography pymongo pyyaml requests
|
|
|
|
# Create directory structure
|
|
INSTALL_DIR="$HOME/esim-provisioning"
|
|
mkdir -p "$INSTALL_DIR"/{server/core_adapters,portal/{css,js,assets},scripts,tests,data}
|
|
|
|
# Copy server code (assumes script run from repo root)
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
cp -r "$SCRIPT_DIR/server" "$INSTALL_DIR/"
|
|
cp -r "$SCRIPT_DIR/portal" "$INSTALL_DIR/"
|
|
cp -r "$SCRIPT_DIR/scripts" "$INSTALL_DIR/"
|
|
cp "$SCRIPT_DIR/config.yaml.example" "$INSTALL_DIR/config.yaml"
|
|
|
|
# Configure for Android (port 8080, data path in home)
|
|
sed -i 's|port: 5000|port: 8080|' "$INSTALL_DIR/config.yaml"
|
|
sed -i "s|/opt/esim-provisioning/data|$INSTALL_DIR/data|" "$INSTALL_DIR/config.yaml"
|
|
|
|
# Configure nginx for Android (port 8080 as reverse proxy target)
|
|
cat > "$PREFIX/etc/nginx/nginx.conf" << 'EOF'
|
|
worker_processes 1;
|
|
events { worker_connections 64; }
|
|
http {
|
|
server {
|
|
listen 8080 default_server;
|
|
server_name _;
|
|
location /activate {
|
|
alias /data/data/com.termux/files/home/esim-provisioning/portal/;
|
|
index index.html;
|
|
}
|
|
location /css/ { alias /data/data/com.termux/files/home/esim-provisioning/portal/css/; }
|
|
location /js/ { alias /data/data/com.termux/files/home/esim-provisioning/portal/js/; }
|
|
location /api/ { proxy_pass http://127.0.0.1:5000; }
|
|
location / { return 302 http://192.168.43.1:8080/activate; }
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Initialize database
|
|
cd "$INSTALL_DIR"
|
|
CONFIG_PATH=config.yaml python scripts/init_db.py
|
|
|
|
# Create start script
|
|
cat > "$INSTALL_DIR/start.sh" << 'STARTEOF'
|
|
#!/data/data/com.termux/files/usr/bin/bash
|
|
cd ~/esim-provisioning
|
|
echo "Starting eSIM provisioning server..."
|
|
nginx
|
|
CONFIG_PATH=config.yaml python -m server.app &
|
|
echo "Server started. Access at http://192.168.43.1:8080/activate"
|
|
echo "To stop: pkill nginx && pkill python"
|
|
STARTEOF
|
|
chmod +x "$INSTALL_DIR/start.sh"
|
|
|
|
# Termux:Boot integration (auto-start on reboot)
|
|
mkdir -p "$HOME/.termux/boot"
|
|
cp "$INSTALL_DIR/start.sh" "$HOME/.termux/boot/esim-provisioning.sh"
|
|
|
|
echo ""
|
|
echo "=== Setup Complete ==="
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo "1. Enable WiFi Hotspot in Android Settings"
|
|
echo " - SSID: Emergency-5G (or any name)"
|
|
echo " - No password"
|
|
echo "2. Run: ~/esim-provisioning/start.sh"
|
|
echo "3. Users connect to hotspot and visit http://192.168.43.1:8080/activate"
|
|
echo ""
|
|
echo "Note: Install Termux:Boot app for auto-start on reboot"
|
|
```
|
|
|
|
---
|
|
|
|
## `android/README.md`
|
|
|
|
### Prerequisites
|
|
- Android 9+
|
|
- Termux app (from F-Droid, NOT Play Store)
|
|
- Optional: Termux:Boot (for auto-start)
|
|
- 5G-capable device with pre-provisioned SIM for gNB backhaul
|
|
|
|
### Installation
|
|
```bash
|
|
# In Termux:
|
|
cd /path/to/esim-provisioning
|
|
bash android/termux_setup.sh
|
|
```
|
|
|
|
### Starting the Server
|
|
```bash
|
|
~/esim-provisioning/start.sh
|
|
```
|
|
|
|
### WiFi Hotspot Setup
|
|
1. Android Settings → Network → Hotspot
|
|
2. Set name to `Emergency-5G` (optional, any name works)
|
|
3. Remove password (open network)
|
|
4. Enable hotspot
|
|
|
|
### Captive Portal Limitation
|
|
Android's captive portal detection requires DNS manipulation. Without root, clients must navigate manually to `http://192.168.43.1:8080/activate`. With root + Termux, dnsmasq can be used for full DNS hijacking.
|
|
|
|
### Known Android Hotspot IPs
|
|
- Most Android: `192.168.43.1`
|
|
- Samsung: `192.168.0.1` or `192.168.43.1`
|
|
- Pixel: `192.168.43.1`
|
|
|
|
Update `config.yaml` and nginx config with your device's hotspot IP.
|
|
|
|
---
|
|
|
|
## Verification
|
|
```bash
|
|
# On Android in Termux:
|
|
~/esim-provisioning/start.sh
|
|
curl http://127.0.0.1:5000/api/status
|
|
curl http://127.0.0.1:8080/activate # through nginx
|
|
```
|