Push Tracker
ria-ran--sim-drop/plan/08-system-configs.md

209 lines
4.3 KiB
Markdown
Raw Normal View History

# Unit 08 — System Configuration Files
## Goal
Production-ready nginx, dnsmasq, hostapd configs and systemd service units.
## Files
- `configs/nginx.conf`
- `configs/dnsmasq.conf`
- `configs/hostapd.conf`
- `systemd/esim-provisioning.service`
- `systemd/captive-portal.service`
---
## `configs/nginx.conf`
```nginx
# Captive portal + reverse proxy for eSIM provisioning server
server {
listen 80 default_server;
server_name _;
# Redirect any request not matching known paths to the activation portal
location = / {
return 302 http://192.168.4.1/activate;
}
# Serve the captive portal static files
location /activate {
alias /opt/esim-provisioning/portal/;
index index.html;
try_files $uri $uri/ /index.html;
}
location /css/ {
alias /opt/esim-provisioning/portal/css/;
}
location /js/ {
alias /opt/esim-provisioning/portal/js/;
}
# Proxy API calls to Flask backend
location /api/ {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 10s;
proxy_read_timeout 30s;
}
# Catch-all: redirect everything else to activate
location / {
return 302 http://192.168.4.1/activate;
}
}
```
---
## `configs/dnsmasq.conf`
```conf
# eSIM Provisioning - DNS/DHCP configuration
# Only listen on WiFi AP interface
interface=wlan0
bind-interfaces
# DHCP range
dhcp-range=192.168.4.10,192.168.4.250,24h
# DNS: return WiFi AP IP for ALL domains (captive portal hijacking)
address=/#/192.168.4.1
# Prevent upstream DNS resolution (keep it local)
no-resolv
# DHCP lease file
dhcp-leasefile=/var/lib/misc/dnsmasq.leases
# Log queries (useful for debugging)
log-queries
log-dhcp
```
---
## `configs/hostapd.conf`
```conf
# WiFi AP configuration for eSIM provisioning drop node
interface=wlan0
driver=nl80211
# Network identity
ssid=Emergency-5G
utf8_ssid=1
# Radio settings
hw_mode=g
channel=6
ieee80211n=1
wmm_enabled=1
# Open network (no password) — intentional for emergency access
auth_algs=1
ignore_broadcast_ssid=0
# Country code — adjust per deployment region
country_code=CA
# Max clients
max_num_sta=50
```
---
## `systemd/esim-provisioning.service`
```ini
[Unit]
Description=eSIM Provisioning Server
After=network.target
Wants=network.target
[Service]
Type=simple
User=esim
Group=esim
WorkingDirectory=/opt/esim-provisioning
Environment=CONFIG_PATH=/etc/esim-provisioning/config.yaml
ExecStart=/opt/esim-provisioning/venv/bin/python -m server.app
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=esim-provisioning
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/opt/esim-provisioning/data
[Install]
WantedBy=multi-user.target
```
---
## `systemd/captive-portal.service`
```ini
[Unit]
Description=Captive Portal (nginx + dnsmasq)
After=network.target hostapd.service
Wants=nginx.service dnsmasq.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/systemctl start nginx dnsmasq
ExecStop=/bin/systemctl stop nginx dnsmasq
[Install]
WantedBy=multi-user.target
```
---
## Deployment Notes
Install configs:
```bash
# nginx
sudo cp configs/nginx.conf /etc/nginx/sites-available/esim-provisioning
sudo ln -sf /etc/nginx/sites-available/esim-provisioning /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
# dnsmasq
sudo cp configs/dnsmasq.conf /etc/dnsmasq.d/esim-provisioning.conf
sudo systemctl restart dnsmasq
# hostapd
sudo cp configs/hostapd.conf /etc/hostapd/hostapd.conf
sudo systemctl unmask hostapd
sudo systemctl enable --now hostapd
# systemd services
sudo cp systemd/esim-provisioning.service /etc/systemd/system/
sudo cp systemd/captive-portal.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now esim-provisioning captive-portal
```
## Verification
```bash
sudo nginx -t # Config syntax check
sudo systemctl status esim-provisioning
sudo systemctl status captive-portal
nslookup google.com 192.168.4.1 # Should return 192.168.4.1
curl http://192.168.4.1/api/status # Should return JSON status
```