5. Firmware e Jenkins¶
I router usano un firmware OpenWrt NINUX compilato da noi: contiene i pacchetti della rete (BIRD, ZeroTier, uspot, netconsole…), l'agente openwisp-config già configurato per registrarsi da solo al nostro OpenWISP, le impostazioni di base (utenti, firewall) e, su tutti i device tranne x86, il tema LuCI luci-theme-ninux con le modalità Base e Avanzato (capitolo 3).
La compilazione la fa il repository ansible-ninux-openwrt: un ruolo Ansible e una pipeline Jenkins che compilano tutte le varianti e le caricano nel firmware upgrader di OpenWISP.
flowchart LR
gh["GitHub<br/>ansible-ninux-openwrt"] --> j["Jenkins<br/>job NinuxOpenwrt"]
j --> b["build OpenWrt<br/>(una per target e variante)"]
b --> up["firmware upgrader<br/>di OpenWISP (API)"]
b --> rel["release GitHub<br/>(facoltativa)"]
up --> r["router<br/>(sysupgrade da OpenWISP)"]
1. CT di Jenkins¶
CT Debian 13 su Proxmox con nesting=1 (capitolo 1).
| Risorsa | Minimo | Consigliato |
|---|---|---|
| CPU | 4 core | 12 core |
| RAM | 8 GB | 24 GB |
| Disco | 80 GB | 200 GB |
L'installazione è automatica:
git clone https://github.com/mikysal78/ansible-ninux-openwrt.git
cd ansible-ninux-openwrt
sudo ./setup/install-jenkins.sh
Lo script installa Java 21, Ansible (pipx), Jenkins LTS, le dipendenze della
build di OpenWrt, la ccache persistente, il tmpfs e i permessi sudo per
l'utente jenkins. La procedura manuale, passo per passo, è nel
README.
2. Configurazione di Jenkins¶
- Apri
http://<IP del CT>:8080, inserisci la password iniziale (/var/lib/jenkins/secrets/initialAdminPassword), installa i plugin suggeriti e crea l'amministratore. - Plugin aggiuntivi: Ansible, Timestamper, Build Timeout, Workspace Cleanup.
- Manage Jenkins → Tools → Ansible installations: nome
ansible, percorso degli eseguibili di Ansible installati da pipx. - Job: New Item →
NinuxOpenwrt→ Pipeline:- Do not allow concurrent builds, timeout 240 minuti;
- Pipeline script from SCM, Git,
https://github.com/mikysal78/ansible-ninux-openwrt.git, branch*/main, scriptJenkinsfile.
- Password del vault in
/var/lib/jenkins/.vault_pass(permessi 600, proprietariojenkins): serve a decifrare i secret inninux.yml.
I parametri del job (organizzazione, versione di OpenWrt, varianti VPN e captive portal, upload su OpenWISP…) sono descritti nel README.
Jenkins compila main
Il job prende il codice da GitHub: le modifiche al firmware vanno pushate prima di lanciare la build.
3. ninux.yml¶
Tutta la configurazione della build sta in ninux.yml (da ninux.yml.example):
- versione di OpenWrt e varianti da compilare (VPN, captive portal);
- per ogni organizzazione: URL di OpenWISP,
management_interface, shared secret della registrazione automatica (dal capitolo 3), token API per il caricamento; - le password di default di
roote dell'utente di servizioadmin(capitolo 6); - il feed dell'agente openwisp-config (il nostro fork, in
config/build.yml, capitolo 4).
In config/build.yml c'è anche il feed ninux_theme del tema LuCI. Le
correzioni ai feed di OpenWrt stanno in
roles/ninux_build_openwrt/files/feed-patches/<feed>/: oggi c'è la patch di
form.js di luci-base, che toglie l'errore RPCError … uci/get … Access
denied dalla console della pagina di login. Viene da LuCI master e non è
ancora nella 25.12. Se una release la rende inutile e la patch non si applica
più, la build si ferma con un errore chiaro: a quel punto va tolta.
I valori segreti si cifrano con ansible-vault, uno per uno:
ansible-vault encrypt_string --encrypt-vault-id default 'CHANGEME' --name 'shared_secret'
Esempi completi nel README, sezione Gestione segreti con ansible-vault.
4. Device e organizzazioni¶
Ogni modello di router ha il suo file in
config/organizations/<org>/<device>.config. Per un modello nuovo, o per una
nuova organizzazione, segui
Aggiungere device e organizzazioni.
Nel .config di un device nuovo, tranne gli x86, aggiungi anche la riga del
tema LuCI:
CONFIG_PACKAGE_luci-theme-ninux=y
Il tema si aggiunge a quelli di LuCI, non li sostituisce: Bootstrap resta nel firmware. Alla prima accensione diventa il tema predefinito; si torna a Bootstrap da Sistema → Sistema → Lingua e stile, e un aggiornamento del firmware non cambia la scelta fatta.
5. Firmware upgrader¶
La build carica ogni immagine in OpenWISP con l'API del firmware upgrader:
- una categoria per variante (es. «Ninux Basilicata - tplink_c2600 - Standard VPN-ZeroTier»), così ogni router riceve sempre la sua variante; il nome della categoria resta entro i 64 caratteri;
- il campo
typedell'immagine deve corrispondere a un modello noto a OpenWISP. I modelli che OpenWISP non conosce (es. TOTOLINK X5000R, TP-Link C2600, Zyxel NWA50AX Pro) sono dichiarati inOPENWISP_CUSTOM_OPENWRT_IMAGESnel playbook openwisp2: le due liste devono restare uguali.
Dopo la build, l'aggiornamento di un router si avvia da OpenWISP (pagina del device o aggiornamento di massa della build) oppure dall'app.
Router x86 di confine
Per x86 il firmware upgrader conosce solo l'immagine combined-efi (GPT),
mentre il nostro router di confine si avvia in BIOS con MBR. Il confine si
aggiorna a mano con l'immagine squashfs-combined della build:
copia con scp -O, prova con sysupgrade -T, poi sysupgrade. Non
avviare mai il suo aggiornamento da OpenWISP.
Controllo¶
- La prima build finisce SUCCESS e le immagini sono in OpenWISP (Firmware → Builds).
- Ogni device ha la sua categoria e l'immagine giusta.
- Un router aggiornato da OpenWISP torna online con la configurazione applicata.