In breve: lo scripting di RouterOS è il linguaggio della console: gli stessi comandi che digiti a mano, messi in fila e resi automatici. Qui vediamo le basi — comandi e menu, variabili, le decisioni con :if, i cicli con :for e :foreach, e la selezione degli oggetti con [find] — con esempi minimi. Per gli usi pratici c’è la sezione howto di scripting.

Che cos’è lo scripting su RouterOS?

Non è un linguaggio a parte: è la stessa riga di comando di WinBox/terminale, automatizzata. Quando scrivi /ip address print stai già “scriptando”. Uno script è una sequenza di questi comandi, con in più variabili, condizioni e cicli, che puoi salvare (/system script), far partire da solo (/system scheduler) o in risposta a un evento (Netwatch, DHCP lease, ecc.).

Si prova senza rischio nel terminale: una riga alla volta, e vedi subito il risultato.

Comandi (:) e menu (/): due mondi che convivono

Due famiglie di parole, con due prefissi diversi.

  • I menu iniziano con /: sono la configurazione, divisa ad albero (/ip, /interface, /system…). Ci agisci con add, set, remove, print.
  • I comandi di script iniziano con :: sono le istruzioni del linguaggio (:local, :if, :for, :foreach, :put, :delay, :log…).

:put stampa a schermo, :log info "..." scrive nel log. Si concatenano le stringhe con il punto:

:put ("CPU al " . [/system resource get cpu-load] . "%")

Le variabili: :local e :global

Una variabile tiene un valore. :local vive solo dentro il suo blocco { }; :global resta in memoria e la rivedi anche in un altro script.

:local nome "ether1"
:global contatore 0
:set contatore ($contatore + 1)

RouterOS riconosce i tipi da solo: numeri, stringhe, indirizzi IP, tempo (5s, 200ms), booleani, e gli array (liste), che scrivi fra graffe: {1;2;3}.

Prendere decisioni: :if

Esegue qualcosa solo se una condizione è vera. La forma è :if (condizione) do={ ... } else={ ... }.

:local cpu [/system resource get cpu-load]
:if ($cpu > 80) do={
  :log warning ("CPU alta: " . $cpu . "%")
} else={
  :log info "CPU ok"
}

Gli operatori di confronto sono =, !=, <, >, <=, >=; quelli logici && (e), || (o), ! (non).

Ripetere: :for e :foreach

:for conta da un numero a un altro; :foreach scorre gli elementi di una lista.

:for i from=1 to=3 do={ :put ("giro " . $i) }

:local porte {"ether1";"ether2";"ether3"}
:foreach p in=$porte do={ :put ("configuro " . $p) }

Trovare gli oggetti: [find]

È il pezzo che all’inizio spiazza di più. Le parentesi quadre [ ] eseguono un comando e ne mettono il risultato lì dove sono scritte. Dentro, find è il comando di un menu che restituisce gli identificatori interni degli oggetti che soddisfano una condizione (che si scrive con where). Così non devi conoscere il numero di riga: lo trovi per caratteristica.

# remove the address on ether2, whatever it is
/ip address remove [find interface=ether2]

# disable the firewall rules with a given comment
/ip firewall filter disable [find comment="old rule"]

# the MAC of the interface named ether1
:put [/interface get [find name="ether1"] mac-address]

È uno dei comandi più usati in assoluto, e dà il meglio insieme ai commenti. Se marchi le righe di configurazione con un commento sensato, poi le ritrovi per quel commento e le accendi, spegni o cancelli in blocco: senza conoscere i numeri di riga, senza errori se l’ordine cambia o se sono già sparite. È il modo pulito per muovere grossi pezzi di configurazione da uno script.

# tag a block of rules with the same comment...
/ip firewall filter add chain=forward protocol=tcp dst-port=25 action=drop comment=block-smtp
/ip firewall filter add chain=forward protocol=tcp dst-port=587 action=drop comment=block-smtp

# ...then turn the whole block off or on in one line, by comment
/ip firewall filter disable [find comment=block-smtp]
/ip firewall filter enable [find comment=block-smtp]

# and when it is no longer needed, drop the whole block (no error if empty)
/ip firewall filter remove [find comment=block-smtp]

Da qui il consiglio: usa i commenti non solo per ricordarti cosa fa una riga, ma come etichette funzionali. Commenti intelligenti + [find] = configurazioni dinamiche: uno script che di giorno accende e di notte spegne un gruppo di regole, o che rifà da capo un blocco intero senza lasciare residui. È la leva che trasforma una configurazione statica in qualcosa che si muove da solo.

Attenzione a non confonderlo con :find (con i due punti), che è un’altra cosa: cerca la posizione di un pezzo di testo dentro una stringa o un elemento in un array. [find] seleziona oggetti di configurazione; :find lavora sul testo.

Aspettare e automatizzare

:delay mette in pausa (:delay 2s). Per far girare uno script da solo c’è lo scheduler:

/system scheduler add name=controllo interval=5m on-event="/system script run controllo"

…oppure lo lanci in risposta a un evento, per esempio quando Netwatch vede cadere un collegamento.

Un esempio che mette tutto insieme

:foreach r in=[/ip firewall filter find where chain=input] do={
  :local pkt [/ip firewall filter get $r packets]
  :if ($pkt > 1000000) do={
    :log info ("regola molto usata: " . [/ip firewall filter get $r comment] . " = " . $pkt)
  }
}

Scorre le regole di input (:foreach + [find where]), legge un valore (get), decide (:if) e scrive nel log. Sono le basi di tutto.

E adesso?

Queste sono le fondamenta. Per le “pillole” pratiche — avvisi su Telegram, script sui lease DHCP, Netwatch, e perfino far suonare una melodia al router — vai alla sezione Scripting e automazione degli howto del Dojo.

Sintassi verificata sulla documentazione RouterOS 7.x (console e developer guide): :local/:global, :if … do= … else=, :for from= to= do=, :foreach … in= do=, il comando di menu find … where con le parentesi di sostituzione [ ], e :find come ricerca su stringhe/array.

Domande frequenti

Qual è la differenza tra / e :?

Lo / apre un menu di configurazione (/ip, /interface); i : sono i comandi del linguaggio di script (:if, :for, :put). I primi cambiano la configurazione, i secondi guidano lo script.

Cosa fanno le parentesi quadre [ ]?

Eseguono un comando e inseriscono il risultato al loro posto. [/system resource get cpu-load] diventa il numero della CPU; [find …] diventa l’elenco degli oggetti trovati.

[find] e :find sono la stessa cosa?

No. [find] è il comando di un menu che restituisce gli id degli oggetti di configurazione (con where); :find cerca la posizione di un testo in una stringa o in un array.

Dove provo gli script senza fare danni?

Nel terminale, una riga alla volta: i comandi di sola lettura (print, get, :put) non cambiano niente. Per le prove serie, un router di laboratorio o un CHR.