MikroTik Dojo · prova di esistenza (OpenTimestamps) Versione: 4 Registrato il: 2026-11-10T13:06:43+00:00 Verifica: ots verify mikrotikdojo-3099-v4.txt.ots (o su https://opentimestamps.org) Indirizzo: https://mikrotikdojo.com/dojo/swos-api-nascosta/ ID: 3099 (post) Titolo: SwOS ha un'API nascosta: gestire lo switch senza GUI (e confrontarla con SNMP) Pubblicato: 2026-11-09T22:19:21Z Immagini (sha256 del file): 550dea9d02a6bd08ccfdc307c6a4a8e9493481acd1ca9dc3d50b0e87ff703e1a https://mikrotikdojo.com/wp-content/uploads/2026/11/3099-2.jpg --- Contenuto (HTML originale, in italiano) ---

«SwOS non ha un'API, si gestisce solo dal browser.» È quello che dice la documentazione ufficiale, ed è vero… a metà. Vale per gli smart switch MikroTik che montano SwOS — la serie CRS3xx e affini. Perché quando apri la web interface di uno switch MikroTik della serie CRS3xx in SwOS, quella pagina non è generata dallo switch: è JavaScript statico che, dietro le quinte, legge e scrive una manciata di file sul dispositivo via HTTP. Quei file sono l'API. Non documentata, un po' ruvida, ma c'è — e con essa puoi configurare VLAN, leggere i contatori, automatizzare i backup, tutto da riga di comando.

In questo articolo apriamo quel canale a mano, decodifichiamo il formato byte per byte, configuriamo una VLAN via POST, e mettiamo l'API grezza a confronto con quello che lo stesso switch espone via SNMP. Alla fine rilasciamo dojo.swos, una piccola libreria Python che incapsula tutto.

I «b-file»: l'API che non sapevi di avere

La web UI di SwOS parla con lo switch tramite file con estensione .b, serviti via HTTP con Digest authentication (niente HTTPS). Una GET legge, una POST scrive. Il primo da guardare è sys.b:

$ curl --digest -u admin: http://192.0.2.10/sys.b
{upt:0x0000d32c,cip:0x3c000d0a,mac:'e48d8c000001',brd:'…',
 sid:'…',id:'53574f53',ver:'322e3136',temp:0x00000027,
 fan1:0x00000b6d,allp:0x03ff,ip:0x0158090a, … }

Somiglia a JSON ma non lo è. Le regole di codifica sono poche e, una volta capite, tutto si apre:

ElementoCome è scrittoEsempioSignifica
Numeroesadecimale 0x.., lunghezza pari0x0000002739 (°C)
Stringacoppie esadecimali ASCII, apici singoli'53574f53'SWOS
Bitmask porteun numero, bit 0 = porta 10x03ffporte 1–10
Arrayparentesi quadre[0x02,0x07][2, 7]
Indirizzo IPintero little-endian0x0158090a10.9.88.1

Applichiamole a sys.b: id:'53574f53' è la stringa esadecimale di «SWOS» (l'identity); ver:'322e3136' è «2.16»; temp:0x00000027 sono 39 °C; fan1:0x00000b6d sono 2925 giri/min della ventola; allp:0x03ff è la bitmask delle dieci porte. E i due indirizzi: cip:0x3c000d0a, letto al contrario byte a byte, è l'IP che lo switch ha preso in DHCP; ip:0x0158090a è l'IP di fallback statico. Il little-endian è la trappola che frega tutti la prima volta.

Leggere lo stato delle porte

link.b è lo stato dei collegamenti. I nomi delle porte arrivano come stringhe esadecimali, i flag come bitmask:

$ curl --digest -u admin: http://192.0.2.10/link.b
{en:0x03ff, lnk:0x0001, …
 nm:['506f727431','506f727432', … '5346502b31','5346502b32']}

en:0x03ff: tutte e dieci le porte abilitate. lnk:0x0001: solo il bit 0 è acceso, quindi link attivo unicamente sulla porta 1 (l'unico cavo collegato). E nm è l'array dei nomi: 506f727431 → «Port1», … 5346502b31 → «SFP+1». Nessun MIB, nessuna libreria: solo curl e la tabella qui sopra.

Configurare una VLAN… via POST

Qui SwOS sorprende: la stessa URL che leggi in GET la scrivi in POST. La tabella VLAN sta in vlan.b. Di fabbrica è vuota:

$ curl --digest -u admin: http://192.0.2.10/vlan.b
[]

Creiamo la VLAN 10 sulle porte 2 e 3. Le porte membro sono una bitmask: porta 2 = bit 1, porta 3 = bit 2 → 0x0006. La postiamo:

$ curl --digest -u admin: -X POST \
    --data-binary "[{vid:0x000a,mbr:0x0006}]" \
    http://192.0.2.10/vlan.b

$ curl --digest -u admin: http://192.0.2.10/vlan.b
[{nm:'',mbr:0x0006,vid:0x000a,piso:0x00,lrn:0x01,mrr:0x00,igmp:0x00}]

Lo switch ha accettato la scrittura e ci ha restituito l'entry completa, rivelando tutti i campi: vid (VLAN id), mbr (porte membro), nm (nome), piso (isolamento), lrn (learning), mrr (mirror), igmp (snooping). Due dettagli preziosi scoperti provando:

Monitorare: i contatori grezzi

!stats.b è una miniera: per ogni porta, array di byte e pacchetti ricevuti/trasmessi, unicast/multicast/broadcast, persino l'istogramma per dimensione del frame (p64, p128, …) e i frame con FCS errato. Tutto in esadecimale, tutto per-porta. È la materia prima per un grafico di traffico fatto in casa, senza dipendere da nient'altro che curl.

L'altra faccia: SNMP

Lo stesso switch, se abiliti SNMP (anche quello si fa con un POST a snmp.b), espone i suoi dati in forma standard e già leggibile:

$ snmpwalk -v2c -c public 192.0.2.10 1.3.6.1.2.1.1
sysDescr.0     = STRING: CRS3xx SwOS v2.16
sysName.0      = STRING: SWOS
sysObjectID.0  = enterprises.14988   (MikroTik)

$ snmpwalk -v2c -c public 192.0.2.10 ifOperStatus
ifOperStatus.1 = up(1)
ifOperStatus.2 = down(2)   …

Sono gli stessi fatti dei b-file, ma vestiti di MIB: sysDescr contiene modello e versione (che nei b-file erano brd+ver in esadecimale), ifOperStatus.1 = up è il bit 0 di lnk:0x0001, ifInOctets sono gli stessi byte di rb in !stats.b. Due facce, un solo switch:

b-file (API nascosta)SNMP
Letturasì (grezza, esadecimale)sì (standard, leggibile)
Scrittura/configsì (VLAN, porte, SNMP…)no (read-only)
Coperturatutto ciò che vede la GUI (temp, ventole, PoE…)sistema, interfacce, bridge
Strumenticurl + un parserqualsiasi NMS (Prometheus, LibreNMS, ntopng)
Standardno, reverse-engineeringsì (RFC)

Ma attenzione a cosa SNMP non ti dà, verificato a mano su uno switch reale. Lo stack SNMP di SwOS implementa la BRIDGE-MIB di base (tabella MAC, mappa porte) ma non la Q-BRIDGE-MIB delle VLAN (1.3.6.1.2.1.17.7 → «No Such Object»): crei pure una VLAN via b-file, in SNMP resta invisibile. Niente nemmeno la POWER-ETHERNET-MIB (1.3.6.1.2.1.105): PoE e consumi non escono via SNMP standard. Quello che invece c'è, nella MIB enterprise MikroTik, è la temperatura (…14988.1.1.3.11.0, in decimi di grado) e il monitoraggio DDM degli SFP. Morale: VLAN, PoE, ventole e tensioni del PSU si leggono (e si scrivono) solo dai b-file; SNMP copre sistema, interfacce, traffico, MAC e temperatura.

Una mappa di OID pronti all'uso

Se vuoi agganciare lo switch a Prometheus, LibreNMS o a un semplice snmpget in cron, questi sono i rami che SwOS espone davvero (community di default public, SNMP v2c):

CosaOIDEsempio
Descrizione (modello+versione)1.3.6.1.2.1.1.1.0CRS3xx SwOS v2.16
Identity1.3.6.1.2.1.1.5.0SWOS
Uptime1.3.6.1.2.1.1.3.0timeticks
Nome porta1.3.6.1.2.1.2.2.1.2.NPort1
Stato porta (up/down)1.3.6.1.2.1.2.2.1.8.Nup(1)
MAC della porta1.3.6.1.2.1.2.2.1.6.Nhex
Byte rx/tx (32 bit)…2.2.1.10.N / .16.Ncounter
Byte rx/tx (64 bit)1.3.6.1.2.1.31.1.1.1.6.N / .10.Ncounter64
Velocità (Mbps)1.3.6.1.2.1.31.1.1.1.15.N1000

E qui i rami fuori standard, nella MIB enterprise MikroTik (1.3.6.1.4.1.14988) — le cose che un NMS generico non cerca da solo ma che vale la pena aggiungere:

CosaOIDNota
Temperatura…14988.1.1.3.11.0in decimi di grado: 380 = 38,0 °C
Numero di serie…14988.1.1.7.3.0stringa
Versione SwOS…14988.1.1.7.4.02.16
Diagnostica SFP (DDM)…14988.1.1.19.1.1temp, tensione, potenza Tx/Rx del modulo

E le assenze, dette con franchezza perché contano: niente carico CPU (SwOS non implementa la HOST-RESOURCES-MIB: 1.3.6.1.2.1.25 → «No Such Object» — su RouterOS invece hrProcessorLoad c'è), niente VLAN, niente PoE, niente ventole o tensioni del PSU via SNMP. Per quei dati, e per scrivere qualunque cosa, si torna ai b-file. Confidiamo che una futura versione di SwOS allarghi la copertura SNMP — intanto la si completa dall'altra porta.

La regola pratica: SNMP per monitorare (lo agganci a un sistema di metriche in cinque minuti), b-file per configurare (è l'unico modo di scrivere senza aprire il browser).

La libreria: dojo.swos

Decodificare esadecimale a mano è istruttivo una volta; dalla seconda diventa lavoro. Così abbiamo scritto dojo.swos, il primo mattone delle librerie dojo.*: incapsula il formato b-file, la Digest auth e il little-endian, e ti dà oggetti pronti. Esiste in due versioni gemelle, Python e PHP — stessa logica, stessi metodi.

from dojo.swos import SwOS

sw = SwOS("192.0.2.10")              # admin / password vuota (default SwOS)

s = sw.system()
print(s["identity"], s["version"], s["temp_c"], "°C")
#  SWOS 2.16 39 °C

for p in sw.ports():
    print(p["name"], "UP" if p["link"] else "down")
#  Port1 UP / Port2 down / …

# configurare una VLAN (occhio alla porta di gestione!)
sw.set_vlans([{"vid": 10, "ports": [2, 3], "name": "lab"}])

# e la verifica incrociata: scrivi col b-file, rileggi via SNMP
sw.set_snmp(location="sala-rack")
# snmpget … sysLocation.0 = STRING: sala-rack

La libreria copre lettura di sistema, porte, VLAN, RSTP, SNMP, tabella MAC e contatori, e la scrittura sicura di identity, SNMP e VLAN. Un get()/post() grezzo resta disponibile per qualunque .b. In PHP è identica, con il namespace Dojo\Swos:

use Dojo\Swos\SwOS;

$sw = new SwOS("192.0.2.10");
echo $sw->system()["identity"];      // -> SWOS
$sw->setVlans([["vid" => 10, "ports" => [2, 3]]]);

Si installa dall'indice del dojo: ognuno ha il suo indirizzo personale (lo trovi nella pagina della libreria o nella tua area iscritti), così nessuno può spacciare un pacchetto dojo-* omonimo.

# Python
pip install --index-url https://mikrotikdojo.com/pypi/<il-tuo-indirizzo>/simple/ dojo-swos

# PHP
composer config repositories.dojo composer https://mikrotikdojo.com/composer/<il-tuo-indirizzo>/
composer require dojo/swos

[dojo_libreria nome="dojo.swos"]

Licenza MIT. La pagina della libreria mostra le due versioni (Python e PHP) con impronta SHA-256, marca temporale e changelog.

Se invece devi scriptare un router con RouterOS, e non uno switch SwOS, c'è la libreria cugina dojo.ros, che parla l'API di RouterOS (binaria o REST) da Python e PHP.

Due cose da sapere prima di iniziare

Una nota onesta: tutto questo è reverse-engineering. MikroTik potrebbe cambiare il formato dei b-file tra una versione e l'altra senza preavviso, e confidiamo che prima o poi arrivi un'API ufficiale e documentata anche per SwOS. Nel frattempo, lo switch ha già tutto quello che serve per automatizzarlo: bastava sapere dove guardare.