3. OpenWISP¶
Il cuore dell'infrastruttura. Il playbook del repository openwisp2 installa in un solo CT:
- OpenWISP completo: controller, monitoring, network topology, firmware upgrader, RADIUS, IPAM, notifiche;
- le pagine di login Wi-Fi (openwisp-wifi-login-pages) per l'hotspot;
- il controller ZeroTier della VPN dei nodi;
- il firewall nftables, BIRD/Babel, la raccolta dei log dei router, il proxy LuCI.
Si appoggia al ruolo ufficiale ansible-openwisp2 e lo completa con le nostre parti.
Prima di iniziare¶
- CT del capitolo 1, con
/dev/net/tunesposto. - Nomi DNS e certificati del capitolo 2 già nel CT
(
/etc/ssl/acme/ninux-nnxx.it.*e/etc/ssl/acme/luci.ninux-nnxx.it.*). - Una casella di posta per le mail di OpenWISP (nel nostro caso
controller@ninux-nnxx.it, inviata tramite il nostro server di posta). - Ansible ≥ 2.13 sul computer da cui lanci il playbook.
Passi¶
1. Repository, ruoli e secret¶
git clone https://github.com/mikysal78/openwisp2.git
cd openwisp2
ansible-galaxy role install -r requirements.yml -p roles/ --force
ansible-galaxy collection install -r requirements.yml -p collections/ --force
cp secrets.example.yml secrets.yml # fuori da git
In secrets.yml vanno il secret RADIUS degli hotspot, la password SMTP, la
password di PostgreSQL e la chiave della mesh (mesh_password, 32 caratteri
casuali). Poi adatta:
hosts: il nome dell'host nell'inventario è il dominio di OpenWISP (openwisp.ninux-nnxx.it),ansible_hostè l'IP del CT;playbook.yml: domini delle pagine Wi-Fi, email, relay SMTP;owlp_organizations/: la configurazione della pagina Wi-Fi di ogni organizzazione (vedi sotto).
2. Primo lancio¶
ansible-playbook -i hosts playbook.yml
I play, nell'ordine:
| Play | Tag | Cosa fa |
|---|---|---|
| 1 | — | OpenWISP, PostgreSQL + PostGIS, pagine Wi-Fi, moduli, cron |
| 2 | zerotier |
controller ZeroTier self-hosted |
| 3 | firewall |
nftables, policy default drop |
| 4 | bird |
bird2 con Babel |
| 5 | router_logs |
rsyslog per syslog e netconsole dei router |
| 6 | luci_proxy |
virtual host nginx del proxy LuCI |
Prima installazione: freeradius
Su un CT nuovo l'handler che riavvia freeradius può partire prima che
nginx risponda su 443, e freeradius non si avvia. Se succede:
systemctl restart nginx && systemctl restart freeradius, poi rilancia il
playbook (le parti già fatte non vengono ripetute).
Ripristino da backup
Se ricostruisci da un backup del database, carica i dati prima del primo
lancio del playbook: altrimenti lo script iniziale crea l'utente
admin/admin e l'organizzazione di default, che poi vanno in conflitto.
3. Primo accesso¶
Vai su https://openwisp.ninux-nnxx.it/admin: l'utente iniziale è
admin / admin. Cambia subito la password da
/admin/password_change/.
Poi, nell'admin:
- Organizzazione: crea la tua (la nostra è Basilicata) e annota lo shared secret della registrazione automatica (Config settings): va nel firmware, capitolo 5.
- RADIUS: in Organization RADIUS settings trovi UUID e token dell'organizzazione, che servono alla pagina Wi-Fi.
- Credenziali SSH (Access credentials): la chiave con cui OpenWISP entra nei router per comandi, aggiornamenti firmware e LuCI. Attiva auto add, così viene assegnata da sola a ogni nuovo device (la nostra si chiama OpenWISP Default Ssh).
- Tema LuCI dei router: il firmware NINUX (tutti i device tranne x86) ha
il tema luci-theme-ninux,
con l'interruttore Base / Avanzato. In Base chi usa il router vede solo
le pagine essenziali (panoramica, Wi-Fi, interfacce, password, backup e
riavvio), senza le opzioni da esperti; in Avanzato c'è tutto LuCI. Logo,
nome e colori si scelgono per tutti nel playbook (
ninux_luci_logo,ninux_luci_brand,ninux_luci_accent,ninux_luci_accent_dark), che li passa a OpenWISP come variabili globaliluci_*; arrivano ai router con il template Tema LuCI ninux del passo 5. Ogni organizzazione li cambia, anche caricando il logo, nel riquadro Tema LuCI dei router della sua pagina (modulo openwisp-luci-theme); un solo router nelle sue variabili.luci_mode(basicoadvanced) sceglie la modalità con cui si apre LuCI,luci_allow_advanced(1o0) se c'è l'interruttore.

La modalità Base semplifica l'interfaccia ma non è un controllo di accesso: i permessi restano quelli degli utenti di LuCI.
4. VPN ZeroTier¶
La VPN collega i nodi remoti al server e tra loro, e su di essa gira Babel. OpenWISP non fa da gateway: ogni nodo esce su Internet dalla propria connessione.
- Admin → VPN servers → Add: backend ZeroTier, host
127.0.0.1:9993, AuthToken = contenuto di/var/lib/zerotier-one/authtoken.secretsul CT, subnet10.27.255.0/24. Salvando, OpenWISP crea la rete. - Admin → Templates → Add: tipo VPN-client, la VPN appena creata, automatic tunnel provisioning attivo.
Dettagli e verifiche: README di openwisp2, VPN ZeroTier.
5. Template dei router¶
I template sono versionati in
openwisp-templates/
e si importano nell'admin (Templates → Add, modalità avanzata </>), oppure
dalla shell Django come spiegato nel loro
README.
La nostra configurazione: i template richiesti vanno su ogni router, quelli default sui router nuovi (si possono togliere), gli altri si assegnano a mano.
| Template | Default | Richiesto | Note |
|---|---|---|---|
| Banner | sì | sì | messaggio al login SSH |
| Bird2 Babel (routing) | sì | sì | routing tra i nodi |
| SSH Keys | sì | sì | chiavi di accesso degli amministratori |
| DDNS nsupdate (br-lan / LuCI) | sì | sì | nome del router nella zona dyn |
| Mesh 802.11s 2.4GHz | sì | no | cifrata SAE, chiave mesh_password |
| VPN ZeroTier (client) | sì | no | generato dall'oggetto VPN |
| ZeroTier Moon (orbit hub) | sì | no | il server come moon di ZeroTier |
| NTP Servers | sì | no | fuso Europe/Rome e server INRIM |
| Log remoto (syslog) | sì | no | syslog verso il server |
| Nomi dei nodi (hosts) | sì | no | generato dal cron |
| AP WiFi 2.4GHz / dual band / dual SSID | no | no | gli access point |
| Hotspot uspot 2.4GHz | no | no | captive portal con RADIUS |
| Netconsole, usteer, Uplink LAN su wan | no | no | vedi il capitolo 6 |
| Router di confine | no | no | config completa del router x86 di confine |
| Tema LuCI ninux | no | no | logo, nome, colori e modalità del tema LuCI (variabili luci_*) |
Nel template della mesh, la variabile mesh_password va nei default values
del template in OpenWISP: nel repository pubblico c'è solo {{ mesh_password }}.
Il template DDNS usa la chiave TSIG della zona dyn di ansible-dns.
6. Pagina Wi-Fi e hotspot¶
- Per ogni organizzazione un file YAML in
owlp_organizations/con slug, UUID e token RADIUS, testi, loghi, termini e privacy; poi rilancia il playbook. La pagina risponde suhttps://wifi.ninux-nnxx.it/<slug>/. - Login con Google: crea un client OAuth in Google Cloud (tipo
applicazione web, URI di ritorno
https://openwisp.ninux-nnxx.it/accounts/google/login/callback/) e inserisci client ID e secret nell'admin, Social applications. Il playbook attiva già il provider. - Sui router l'hotspot è il template Hotspot uspot. Il walled garden deve contenere il sito della pagina Wi-Fi, i domini di Google per il login social e i siti che vuoi raggiungibili senza login.
- Il certificato del portale sui router (
wifiauth) viene aggiornato ogni notte dal cronsync_uspot_cert.py. - Il nome della rete dell'hotspot è la variabile
hotspot_ssiddel template (defaultNINUX Free WiFi): si cambia nella copia del template di ogni organizzazione o nelle variabili del singolo router. - Nel YAML dell'organizzazione il campo di login è
type: "text", così si entra con email, numero di telefono o nome utente: serve per i voucher del capitolo 8. Contype: "email"il browser rifiuta i nomi utente.
7. Topology Babel¶
Una volta sola: admin → Network Topology → Topologies → Add, label
Babel NINUX, parser NetJSON NetworkGraph, strategy RECEIVE,
expiration time 330. Il cron topology_babel_feed.py la aggiorna ogni 5
minuti con i vicini Babel di tutti i router.
8. Utente per Jenkins¶
Il caricamento automatico del firmware usa il token API di un utente con i
permessi sul firmware upgrader. Il token si ottiene con
POST /api/v1/users/token/ e va cifrato in ninux.yml (capitolo 5).
Un token per utente
OpenWISP dà un solo token per utente: se lo stesso utente lo usa anche altrove (per esempio l'app Android), revocarlo li blocca tutti.
Cron installati dal playbook¶
| Script | Frequenza | Cosa fa |
|---|---|---|
sync_node_hosts.py |
15 minuti | template «Nomi dei nodi»: IP e MAC → nome del nodo |
sync_ipam_hostnames.py |
periodico | nomi dei device nell'IPAM |
sync_uspot_cert.py |
ogni notte | certificato del portale sui router con hotspot |
topology_babel_feed.py |
5 minuti | topology «Babel NINUX» |
| rotazione dei log dei router | ogni ora | logrotate con i valori scelti in OpenWISP |
Controllo¶
- L'admin risponde in HTTPS con il certificato giusto.
- La pagina Wi-Fi risponde su
https://wifi.ninux-nnxx.it/<slug>/. -
systemctl status freeradiusè attivo. - Il CT ha fatto il join alla rete ZeroTier (
zerotier-cli listnetworks). -
birdcl show babel interfaceselenca le interfacce attese.