commit 983ddd903baa106987f62da7a16f254492568166 Author: astromech73 Date: Thu May 21 09:38:51 2026 -0500 Initial commit: firmware pusher app, GenieACS docs, network file - firmware-pusher/: standalone HTML app for GenieACS firmware pushes - genieacs/: NBI API usage, device IDs, troubleshooting - calix_home_network.txt: live network documentation diff --git a/README.md b/README.md new file mode 100644 index 0000000..c131962 --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# Calix + +Documentation, configuration, and tooling for the Calix home network. + +## Contents + +### calix_home_network.txt +Live network documentation — device IPs, credentials, SSIDs, GenieACS server info. +**Keep this file updated** whenever network changes are made. + +### firmware-pusher/ +A standalone HTML app for pushing firmware to GenieSpire satellites via the GenieACS NBI API. + +Files: +- `index.html` — the UI (single file, no build step) +- `nginx.conf` — nginx config with HTTP Basic Auth +- `docker-compose.yml` — container deployment +- `README.md` — setup and usage docs + +Access: `https://calix.yoda.ddnsgeek.com` +Login: `admin` / GenieACS admin password + +### genieacs/ +Documentation on GenieACS configuration, quirks, and tips for this setup. + +## Device Inventory + +| Device | IP | Serial | Software | Notes | +|--------|----|--------|----------|-------| +| Main Router (4220E) | 192.168.1.1 | 422208213826 | u6.1 | Mesh controller | +| Back Hallway Sat (4220E) | 192.168.1.109 | 422208213783 | u6.1 | AP mode | +| Office Sat (4220E) | 192.168.1.155 | 422208213919 | u6.1 | AP mode | +| GenieSpire (CXNK010F208F) | 173.21.51.61 | - | 25.2.0.0.44 | Offline/NAT'd | +| GenieSpire (CXNK010F20EC) | 192.168.1.109 | - | 25.2.0.0.44 | Via GenieACS | +| GenieSpire (CXNK010F2064) | 192.168.1.155 | - | 25.2.0.0.44 | Via GenieACS | + +GenieSpire satellites are TR-069/GenieACS managed — no local web UI. \ No newline at end of file diff --git a/firmware-pusher/.htpasswd b/firmware-pusher/.htpasswd new file mode 100644 index 0000000..91bb1c2 --- /dev/null +++ b/firmware-pusher/.htpasswd @@ -0,0 +1,3 @@ +# Password for calix.yoda.ddnsgeek.com: admin / 966QPr@*rCTMrWE9xSGm +# To regenerate: docker run --rm httpd:alpine htpasswd -nb admin +admin:$apr1$8f4x.t5E$yHZFFxIxiUyL7wXlfBSav. \ No newline at end of file diff --git a/firmware-pusher/README.md b/firmware-pusher/README.md new file mode 100644 index 0000000..21b62a4 --- /dev/null +++ b/firmware-pusher/README.md @@ -0,0 +1,78 @@ +# GenieACS Firmware Pusher + +Standalone HTML app for pushing firmware upgrades to GenieSpire satellites via GenieACS NBI API. + +## Access + +**URL:** `https://calix.yoda.ddnsgeek.com` +**Auth:** HTTP Basic Auth — `admin` + GenieACS admin password + +## Setup + +```bash +# On VPS (root@161.97.153.158) +cd /opt/firmware-pusher && docker compose up -d +``` + +## Architecture + +``` +User browser (HTTPS) + ↓ +Traefik (calix.yoda.ddnsgeek.com → firmware-pusher container) + ↓ +nginx:alpine (auth + static files) + ↓ +firmware-pusher/index.html (the UI) + +UI → NBI API: https://nbi.yoda.ddnsgeek.com/devices + (NBI also protected by same HTTP Basic Auth) +``` + +## Files + +| File | Purpose | +|------|---------| +| `index.html` | The UI — single file, no build | +| `nginx.conf` | nginx config with auth | +| `.htpasswd` | HTTP Basic Auth password hash | +| `docker-compose.yml` | Container definition + Traefik labels | + +## How It Works + +1. **Device list** — fetches from `GET /devices` (NBI API) +2. **Firmware files** — fetches from `GET /files` (NBI API) +3. **Push** — POSTs to `POST /devices/{id}/tasks` with: + ```json + { + "name": "download", + "fileType": "1 Firmware Upgrade Image", + "fileName": "FullRel_EXOS_SIGNED_E5_R25.2.0.0.img", + "productClass": "GigaSpire" + } + ``` + +## Changing Password + +```bash +# Generate new htpasswd +docker run --rm httpd:alpine htpasswd -nb admin NEW_PASSWORD + +# Update the .htpasswd file, then: +docker exec firmware-pusher nginx -s reload +``` + +## Firmware Versions Available + +| Version | File | +|---------|------| +| R23.3.0.5 | FullRel_EXOS_SIGNED_E5_R23.3.0.5.img | +| R24.1.0.2 | FullRel_EXOS_SIGNED_E5_R24.1.0.2.img | +| R24.4.0.0 | FullRel_EXOS_SIGNED_E5_R24.4.0.0.img | +| R25.2.0.0 | FullRel_EXOS_SIGNED_E5_R25.2.0.0.img | + +## Troubleshooting + +- **blank page / 404**: Check `docker logs firmware-pusher` +- **auth not working**: Verify `.htpasswd` exists inside container: `docker exec firmware-pusher cat /etc/nginx/.htpasswd` +- **push fails**: Check GenieACS fault queue at `https://genieacs.yoda.ddnsgeek.com` \ No newline at end of file diff --git a/firmware-pusher/docker-compose.yml b/firmware-pusher/docker-compose.yml new file mode 100644 index 0000000..f809bde --- /dev/null +++ b/firmware-pusher/docker-compose.yml @@ -0,0 +1,25 @@ +services: + firmware-pusher: + image: nginx:alpine + container_name: firmware-pusher + restart: unless-stopped + ports: + - '8080:80' + volumes: + - ./html:/usr/share/nginx/html:ro + - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro + - ./nginx/.htpasswd:/etc/nginx/.htpasswd:ro + networks: + - traefik-network + labels: + - 'traefik.enable=true' + - 'traefik.http.routers.firmware-pusher.rule=Host(`calix.yoda.ddnsgeek.com`)' + - 'traefik.http.routers.firmware-pusher.entrypoints=websecure' + - 'traefik.http.routers.firmware-pusher.tls=true' + - 'traefik.http.routers.firmware-pusher.tls.certResolver=letsencrypt' + - 'traefik.http.routers.firmware-pusher.priority=100' + - 'traefik.http.services.firmware-pusher.loadbalancer.server.port=80' + +networks: + traefik-network: + external: true \ No newline at end of file diff --git a/firmware-pusher/index.html b/firmware-pusher/index.html new file mode 100644 index 0000000..7e95b4e --- /dev/null +++ b/firmware-pusher/index.html @@ -0,0 +1,476 @@ + + + + + + GenieACS Firmware Pusher + + + + + + + + +
+ +
+ Connected + +
+ +
+ +
+
+ + +
+
+
+ +
+ + +
+
+ + + +
+
+ +
GenieACS Firmware Pusher v1.0
+ + + + diff --git a/firmware-pusher/nginx.conf b/firmware-pusher/nginx.conf new file mode 100644 index 0000000..302815d --- /dev/null +++ b/firmware-pusher/nginx.conf @@ -0,0 +1,21 @@ +server { + listen 80; + root /usr/share/nginx/html; + index index.html; + + location = / { + auth_basic "GenieACS Firmware Pusher"; + auth_basic_user_file /etc/nginx/.htpasswd; + try_files /index.html =404; + } + + location = /index.html { + return 404; + } + + location / { + auth_basic "GenieACS Firmware Pusher"; + auth_basic_user_file /etc/nginx/.htpasswd; + try_files $uri $uri/ /index.html?$query_string =404; + } +} diff --git a/genieacs/README.md b/genieacs/README.md new file mode 100644 index 0000000..b70b0d4 --- /dev/null +++ b/genieacs/README.md @@ -0,0 +1,98 @@ +# GenieACS + +TR-069 ACS (Auto Configuration Server) for managing Calix GigaSpire satellites. + +## Access + +| URL | Purpose | +|-----|---------| +| `https://genieacs.yoda.ddnsgeek.com` | Admin UI | +| `https://nbi.yoda.ddnsgeek.com` | NBI API (7557) | +| `https://acs.yoda.ddnsgeek.com` | CWMP/TR-069 (7547) | + +**Admin credentials:** `admin` / `966QPr@*rCTMrWE9xSGm` +**VPS:** `root@161.97.153.158` + +## Version + +GenieACS container: `drumsergio/genieacs:latest` +VPS docker compose: `/var/lib/docker/volumes/portainer_data/_data/compose/58/docker-compose.yml` + +## NBI API (port 7557) + +All firmware push operations use the NBI API, not the provision framework. + +**Base URL:** `http://127.0.0.1:7557` (on VPS) — also proxied via Traefik at `https://nbi.yoda.ddnsgeek.com` + +**Auth:** HTTP Basic Auth — `admin` + GenieACS admin password + +### Useful NBI Endpoints + +``` +GET /devices — list all devices +GET /devices/{id} — device detail +GET /devices/{id}/tasks — task history +POST /devices/{id}/tasks — create task (firmware push) +GET /files — uploaded firmware files +POST /files — upload firmware file +DELETE /devices/{id}/tasks/{id} — cancel task +``` + +### Firmware Push Task + +```bash +curl -X POST http://127.0.0.1:7557/devices/{device_id}/tasks \ + -u admin:PASSWORD \ + -H "Content-Type: application/json" \ + -d '{ + "name": "download", + "fileType": "1 Firmware Upgrade Image", + "fileName": "FullRel_EXOS_SIGNED_E5_R25.2.0.0.img", + "productClass": "GigaSpire" + }' +``` + +Returns a task ID. Poll `/devices/{id}/tasks/{task_id}` to check status. + +### Device IDs + +``` +b89470-GigaSpire-CXNK010F208F (Living room — offline/NAT'd) +b89470-GigaSpire-CXNK010F20EC (Back hallway sat) +b89470-GigaSpire-CXNK010F2064 (Office sat) +``` + +## Fault Queue + +GenieACS 1.2.16 has a known issue where the provision-based `download` task +throws "Invalid arguments" faults. Use the NBI API instead. + +To clear stale faults: +```bash +ssh root@161.97.153.158 +docker exec -i genieacs-mongo mongo genieacs --quiet --eval 'db.faults.deleteMany({})' +``` + +## GenieACS Doesn't Store + +- EXOS web UI passwords (not part of TR-069 data model) +- WiFi passphrase (only stored in 4220E config, not GenieSpire) +- WPA keys beyond what GenieSpire devices report via Inform + +## Troubleshooting + +### Device not connecting to GenieACS +- Check firewall: port 7547 (CWMP) must be open on VPS +- Check device has correct ACS URL configured +- Check device has internet access (TR-069 requires outbound HTTPS) + +### Firmware push not working +1. Verify file exists: `GET /files` — check `fileName` matches exactly +2. Check fault queue for "Invalid arguments" — means wrong provision path +3. Use NBI API directly to confirm task was created +4. Check device Download table: `GET /devices/{id}` → look for `Downloads` parameter + +### Devices showing offline +- GenieACS marks devices offline after ~30 minutes without Inform +- Device may need to be power-cycled to reconnect +- Check `LastContact` field on device detail page \ No newline at end of file