1/55
Wprowadzenie do skryptowania w MikroTik RouterOS
Slajd wprowadza słuchaczy w tematykę programowania skryptowego w systemie MikroTik RouterOS oraz przedstawia cele automatyzacji sieci.

Czym jest skryptowanie w systemie RouterOS?

  • Rola systemu RouterOS: specjalizowany system operacyjny oparty na Linuksie, zarządzający urządzeniami sieciowymi RouterBOARD.
  • Potrzeba automatyzacji: eliminacja żmudnych czynności manualnych przy konfiguracji routingu, zapory ogniowej i interfejsów.
  • Wbudowany interpreter: natywne środowisko wykonywania skryptów zintegrowane bezpośrednio z jądrem systemu sieciowego.
  • Zastosowania przemysłowe: automatyczne kopie zapasowe, monitoring łączy WAN, dynamiczny DNS oraz reagowanie na awarie.
MikroTik RouterOS: sieciowy system operacyjny rozwijany przez łotewską firmę MikroTik, instalowany na dedykowanych urządzeniach RouterBOARD (RB, CCR, CRS) lub maszynach wirtualnych (CHR). Udostępnia zaawansowane funkcje routingu (BGP, OSPF), zapory sieciowej, serwerów VPN oraz wbudowany obiektowo-strukturalny język skryptowy.
  +-------------------------------------------------------+
  |              EKOSYSTEM MIKROTIK ROUTEROS              |
  +-------------------------------------------------------+
  |  Hardware:   RouterBOARD (RB), Cloud Core Router (CCR)|
  |  System OS:  MikroTik RouterOS (v6 LTS / v7)          |
  |  Zarządzanie:WinBox (GUI), SSH (CLI), WebFig, API     |
  |  Automacja:  Skrypty (.rsc), Harmonogram (Scheduler)  |
  +-------------------------------------------------------+
        
2/55
RouterOS: system operacyjny routera
Slajd omawia architekturę systemu RouterOS oraz wieloplatformowe interfejsy administracyjne WinBox, WebFig, SSH i API.

Architektura i metody zarządzania

  • Aplikacja WinBox: autorskie, niezwykle szybkie narzędzie z graficznym interfejsem użytkownika (GUI) łączące się przez IP lub MAC.
  • Interfejs konsolowy (CLI): dostęp tekstowy przez protokół SSH lub port szeregowy, stanowiący fundament działania skryptów.
  • Panel WebFig: interfejs webowy dostępny przez przeglądarkę internetową, dublujący funkcjonalność WinBoksa.
  • Interfejs programistyczny API: możliwość integracji routera z zewnętrznymi aplikacjami w językach Python, C# czy PHP.
Interfejs WinBox: dedykowana aplikacja zarządzająca dla systemu Windows (działająca także pod Linuksem przez Wine), komunikująca się z procesami RouterOS za pomocą binarnego protokołu MNP na porcie TCP 8291.
  +-------------------------------------------------------+
  |              ARCHITEKTURA MIKROTIK ROUTEROS           |
  +-------------------------------------------------------+
  |   Aplikacje zarządzania: WinBox / WebFig / Konsola    |
  |   -------------------------------------------------   |
  |   Interpreter CLI & Silnik Skryptowy RouterOS        |
  |   -------------------------------------------------   |
  |   Jądro Linuksa (Linux Kernel) + Sterowniki Sieciowe  |
  |   -------------------------------------------------   |
  |   Sprzęt: Switch Chip (HW Offload), CPU, Interfejsy   |
  +-------------------------------------------------------+
        
3/55
Połączenie z routerem przez SSH
Slajd przedstawia procedurę bezpiecznego nawiązywania połączenia z konsolą RouterOS za pomocą protokołu SSH.

Zdalna sesja tekstowa w wierszu poleceń

  • Protokół SSH (port TCP 22): zapewnia szyfrowaną transmisję poleceń i wyników pomiędzy administratorem a routerem.
  • Uwierzytelnianie kluczem: rekomendowane logowanie za pomocą kluczy kryptograficznych zamiast podatnych haseł tekstowych.
  • Klienci terminalowi: wykorzystanie narzędzi OpenSSH w systemach Linux/Windows oraz popularnego programu PuTTY.
  • Zabezpieczenie dostępu: ograniczenie dostępu do portu SSH na zaporze sieciowej wyłącznie do zaufanych podsieci.
Protokół Secure Shell (SSH): kryptograficzny protokół sieciowy pracujący w architekturze klient-serwer, służący do bezpiecznego, szyfrowanego zdalnego sterowania urządzeniami sieciowymi w niezaufanych sieciach komputerowych.
  +---------------------+           +---------------------+
  | Stacja administratora|           |   Router MikroTik   |
  | (Klient SSH / PuTTY)| --------> |  Port TCP 22 (SSH)  |
  +---------------------+           +---------------------+
             |                                 |
             +---- Login: admin + Hasło/Klucz -+
             v
      [ Dostęp do pełnej konsoli CLI RouterOS ]
        
4/55
Struktura poleceń w RouterOS
Slajd wyjaśnia podział na ścieżki drzewa konfiguracji (z ukośnikiem) oraz polecenia języka skryptowego (z dwukropkiem).

Hierarchia drzewa konfiguracji i komendy systemowe

  • Ścieżki konfiguracji (/): polecenia rozpoczynające się od ukośnika odzwierciedlają strukturę menu, np. /ip address, /interface.
  • Instrukcje skryptowe (:): słowa kluczowe języka i polecenia powłoki bezwzględnie wymagają prefiksu dwukropka, np. :put, :set, :if.
  • Autouzupełnianie klawiszem Tab: system podpowiedzi i dopełniania poleceń ułatwiający nawigację w drzewie konfiguracyjnym.
  • Kontekst wykonania: możliwość przejścia do podmenu (np. wpisanie /ip firewall) i wykonywania komend lokalnie bez pełnej ścieżki.
Drzewo konfiguracyjne RouterOS: hierarchiczna struktura podmenu systemu RouterOS odwzorowująca logiczne warstwy modelu OSI, w której każdy węzeł (ścieżka) grupuje powiązane parametry i tabele danego protokołu sieciowego.
  +-------------------------------------------------------+
  |               STRUKTURA POLECEŃ ROUTEROS              |
  +-------------------------------------------------------+
  | 1. Ścieżki konfiguracyjne (zaczynają się od /):       |
  |    /ip address, /interface ethernet, /ip firewall     |
  |                                                       |
  | 2. Polecenia skryptowe i sterujące (dwukropek :):     |
  |    :local, :global, :put, :if, :foreach, :log         |
  +-------------------------------------------------------+
        
5/55
Nasz pierwszy skrypt
Slajd demonstruje budowę elementarnego skryptu RouterOS, wypisywanie danych poleceniem :put oraz rejestrację w logach.

Tworzenie i wykonywanie prostych instrukcji

  • Blok kodu w klamrach { }: ujęcie ciągu instrukcji w nawiasy klamrowe tworzy spójny blok kodu o lokalnym zasięgu zmiennych.
  • Polecenie :put: wypisuje zadaną wartość lub łańcuch tekstowy na ekranie bieżącego terminala konsoli.
  • Polecenie :log info: rejestruje komunikat w systemowym dzienniku zdarzeń widocznym w menu /log.
  • Wykonywanie w konsoli: wklejenie wielowierszowego bloku w klamrach wykonuje skrypt natychmiast jako jedną atomową operację.
Polecenie :put: wbudowana instrukcja interpretera RouterOS wypisująca przekazane wyrażenie lub obiekt bezpośrednio na standardowe wyjście bieżącej sesji terminalowej.
  +-------------------------------------------------------+
  |                 PIERWSZY SKRYPT ROUTEROS              |
  +-------------------------------------------------------+
  |  {                                                    |
  |      :local komunikat "Witaj w MikroTik RouterOS!"    |
  |      :put $komunikat                                  |
  |      :log info "Skrypt zostal wykonany pomyslnie"     |
  |  }                                                    |
  +-------------------------------------------------------+
        
6/55
Repozytorium skryptów
Slajd omawia repozytorium skryptów systemowych, uprawnienia (policies) oraz zasady przechowywania kodu w pamięci routera.

Zarządzanie skryptami w /system script

  • Lokalizacja /system script: centralna baza skryptów przechowywana w pamięci trwałej konfiguracji routera.
  • Matryca uprawnień (policy): każdy skrypt posiada precyzyjnie określone prawa: read, write, policy, test, password, sensitive.
  • Polecenie :execute: pozwala na asynchroniczne uruchomienie innego skryptu z poziomu bieżącego kodu w osobnym wątku.
  • Środowisko produkcyjne: przechowywanie kodu w repozytorium umożliwia wywoływanie go przez harmonogram i zdalne API.
Repozytorium skryptów (/system script): systemowa baza danych w RouterOS przechowująca nazwane procedury skryptowe wraz z ich kodem źródłowym, matrycą wymaganych uprawnień bezpieczeństwa oraz statystykami uruchomień.
  +-------------------------------------------------------+
  |                 REPOZYTORIUM SKRYPTÓW                 |
  +-------------------------------------------------------+
  |  Ścieżka: /system script                              |
  |  Atrybuty:                                            |
  |    - Name:     unikalna nazwa skryptu                 |
  |    - Policy:   uprawnienia (read, write, policy, ...) |
  |    - Source:   kod źródłowy skryptu                   |
  |    - Run Count:licznik uruchomień                     |
  +-------------------------------------------------------+
        
7/55
Harmonogram zadań: scheduler
Slajd przedstawia moduł /system scheduler, konfigurację interwałów czasowych oraz wywoływanie skryptów w tle.

Automatyczne cykliczne uruchamianie skryptów

  • Moduł /system scheduler: systemowy harmonogram zadań uruchamiający wskazany kod o określonej godzinie lub cyklicznie.
  • Parametr interval: definiuje odstęp czasu pomiędzy kolejnymi wykonaniami zadania (np. 10m, 1h, 1d).
  • Parametr start-time: określa dokładny czas pierwszego uruchomienia zadania w formacie GG:MM:SS lub startup.
  • Zgodność uprawnień: uprawnienia zdefiniowane w zadaniu schedulera muszą pokrywać się z uprawnieniami wywoływanego skryptu.
Harmonogram zadań (Scheduler): wbudowana usługa systemowa w RouterOS odpowiadająca za cykliczne lub jednorazowe uruchamianie zadań administracyjnych na podstawie wewnętrznego zegara systemowego (NTP).
  +---------------------+           +---------------------+
  | /system scheduler   |           | /system script      |
  | Zadanie harmonogramu| --------> | Kod skryptu         |
  +---------------------+           +---------------------+
             |                                 |
             +-- Interval (np. 1h, 1d) --------+
             +-- Start-Time (np. 03:00:00) ----+
        
8/55
Komentarze w skryptach
Slajd omawia zasady komentowania kodu skryptowego w RouterOS, stosowanie znaku # oraz dobre praktyki czytelności.

Dokumentowanie kodu za pomocą symbolu krzyżyka

  • Znak krzyżyka (#): cała treść od znaku # do końca wiersza jest całkowicie ignorowana przez interpreter RouterOS.
  • Komentarze nagłówkowe: opisywanie celu skryptu, autora, daty modyfikacji oraz wymaganych uprawnień na początku pliku.
  • Komentowanie sekcji logicznych: wyjaśnianie skomplikowanych warunków filtrowania zapory ogniowej lub obliczeń podsieci.
  • Tymczasowe wyłączanie kodu: zakomentowanie linii instrukcji podczas diagnozowania problemów i debugowania skryptu.
Komentarz w RouterOS: linia lub fragment wiersza kodu poprzedzony symbolem #, pomijany w fazie analizy leksykalnej przez interpreter, służący wyłącznie do dokumentowania logiki programu dla administratora.
# ==============================================
# Skrypt: sprawdz-interfejs.rsc
# Autor: Jan Kowalski
# Data: 2024-01-15
# Opis: Sprawdza status interfejsu ether1
# ==============================================

# Pobierz nazwę interfejsu do sprawdzenia
:local interfejs "ether1"

# Sprawdź, czy interfejs działa
:local status [/interface get [find name=$interfejs] running]

# Jeśli działa, zapisz informację w logu
:if ($status = true) do={
    :log info ("Interfejs " . $interfejs . " jest aktywny.")
}
9/55
Zmienne w RouterOS: podstawy
Slajd przedstawia podstawy pracy ze zmiennymi, prefiks dolara ($) oraz polecenie przypisania wartości :set.

Zasady deklarowania, nazewnictwa i modyfikacji

  • Deklaracja zmiennej: utworzenie zmiennej wymaga jawnego użycia słowa kluczowego :local lub :global.
  • Dostęp do wartości ($): odczytanie wartości zapisanej w zmiennej wymaga poprzedzenia jej nazwy znakiem dolara ($zmienna).
  • Modyfikacja poleceniem :set: zmiana wartości istniejącej zmiennej odbywa się za pomocą polecenia :set nazwa nowaWartosc.
  • Wielkość liter: nazwy zmiennych w RouterOS rozróżniają wielkość liter ($MojaZmienna to nie to samo co $mojazmienna).
Zmienna w RouterOS: nazwany obszar pamięci RAM routera przechowujący dane określonego typu (ciąg tekstowy, liczbę, adres IP, tablicę), identyfikowany w wyrażeniach za pomocą prefiksu $.
  +-------------------------------------------------------+
  |                ZMIENNE W MIKROTIK ROUTEROS            |
  +-------------------------------------------------------+
  | Deklaracja lokalna: :local nazwaWartosci "wartosc"   |
  | Deklaracja globalna::global nazwaWartosci "wartosc"   |
  | Odczyt wartości:    $nazwaWartosci                    |
  | Modyfikacja:        :set nazwaWartosci "nowa_wartosc" |
  +-------------------------------------------------------+
        
10/55
Zmienne lokalne: :local
Slajd wyjaśnia działanie zmiennych lokalnych deklarowanych słowem :local oraz ich automatyczne niszczenie po opuszczeniu bloku.

Izolacja środowiska w blokach kodu

  • Polecenie :local: deklaruje zmienną o zasięgu ograniczonym wyłącznie do bieżącego bloku kodu w klamrach { ... }.
  • Automatyczne zwalnianie pamięci: po zakończeniu wykonywania bloku zmienna lokalna jest bezpowrotnie usuwana z pamięci RAM.
  • Brak konfliktów nazw: użycie tej samej nazwy zmiennej lokalnej w różnych funkcjach lub skryptach nie wywołuje kolizji.
  • Złota reguła czystego kodu: wszystkie zmienne pomocnicze, liczniki pętli i bufory tymczasowe powinny być deklarowane jako :local.
Zmienna lokalna (:local): obiekt pamięci w interpreterze RouterOS, którego widoczność i cykl życia są ściśle powiązane z blokiem instrukcji, w którym został zadeklarowany, zapobiegający zanieczyszczaniu globalnego stanu systemu.
# Deklaracja zmiennej lokalnej z wartoscia tekstowa
:local imie "Anna"

# Deklaracja zmiennej lokalnej z liczba
:local wiek 25

# Deklaracja zmiennej lokalnej bez wartości
:local tymczasowyWynik

# Użycie zmiennej - poprzedź nazwę znakiem $
:put ("Mam na imię " . $imie)
:put ("Mam " . $wiek . " lat")

# Możesz zmienić wartość zmiennej
:set wiek 26
:put ("Teraz mam " . $wiek . " lat")
11/55
Zmienne globalne: :global
Slajd omawia zmienne globalne (:global), ich widoczność w całym systemie RouterOS oraz wykorzystanie do wymiany informacji.

Współdzielenie danych pomiędzy skryptami

  • Polecenie :global: deklaruje zmienną dostępną we wszystkich skryptach, harmonogramach i sesjach terminala routera.
  • Trwałość w pamięci: zmienna globalna istnieje w pamięci routera aż do momentu restartu urządzenia (reboot) lub jej usunięcia.
  • Wymóg deklaracji w każdym skrypcie: aby użyć istniejącej zmiennej globalnej w innym skrypcie, należy ją w nim ponownie zadeklarować przez :global.
  • Inspekcja zmiennych (/environment): menu /environment print wyświetla listę wszystkich aktywnych zmiennych globalnych w systemie.
Zmienna globalna (:global): obiekt środowiskowy w RouterOS rezydujący w globalnej tablicy symboli jądra systemu, pozwalający na przekazywanie stanów, flag awarii i liczników pomiędzy niezależnymi skryptami.
# --- Skrypt 1: Sprawdza stan i zapisuje go ---

# Deklaracja zmiennej globalnej (jeśli jeszcze nie istnieje)
:global poprzedniStatus

# Pobierz aktualny status
:local aktualnyStatus [/ping 8.8.8.8 count=1]

# Sprawdź, czy status się zmienił
:if ($aktualnyStatus != $poprzedniStatus) do={
    :log info ("Status zmienil sie z " . $poprzedniStatus . " na " . $aktualnyStatus)
    
    # Zapisz nowy status - będzie dostępny następnym razem
    :set poprzedniStatus $aktualnyStatus
}
12/55
Zmienne: dobre praktyki i pułapki
Slajd przedstawia zasady zarządzania zmiennymi w RouterOS, pułapkę wartości nothing oraz czyszczenie zmiennych.

Unikanie konfliktów i wartości niezdefiniowanych

  • Wartość niezdefiniowana (nothing): odwołanie do niezadeklarowanej zmiennej zwraca typ nothing, co może fałszować wyniki porównań.
  • Usuwanie zmiennych (:set nazwa): wywołanie :set nazwa bez podania wartości skutecznie czyści zmienną i zwalnia zasoby.
  • Konwencja nazewnicza: stosowanie przedrostków identyfikujących projekt lub moduł (np. gWanIp, lBackupPath) zapobiega kolizjom.
  • Izolacja skryptów testowych: testując polecenia w konsoli, zawsze zamykaj kod w klamrach { :local ... }, aby nie zaśmiecać sesji.
Typ pusty (nothing): specjalny stan w systemie typów RouterOS oznaczający brak przypisanej wartości lub odwołanie do nieistniejącego elementu tablicy konfiguracyjnej, odpowiednik wartości null.
:local mojTekst "Hello"
:local mojaLiczba 42
:local mojBool true

:put ("Typ mojTekst: " . [:typeof $mojTekst])
:put ("Typ mojaLiczba: " . [:typeof $mojaLiczba])
:put ("Typ mojBool: " . [:typeof $mojBool])

# Wynik:
# Typ mojTekst: str
# Typ mojaLiczba: num
# Typ mojBool: bool
13/55
Podstawowe typy danych w RouterOS
Slajd omawia elementarne typy danych wbudowane w system RouterOS oraz ich literały w języku skryptowym.

Liczby, teksty, wartości logiczne i adresy IP

  • Liczby całkowite (num): wartości numeryczne ze znakiem obsługujące standardowe operacje arytmetyczne.
  • Ciągi tekstowe (str): łańcuchy znaków ujęte w podwójne cudzysłowy; wspierają łączenie operatorem kropki.
  • Wartości logiczne (bool): reprezentowane przez słowa yes/true oraz no/false, wykorzystywane w instrukcjach warunkowych.
  • Adresy sieciowe (ip, ip-prefix): natywny typ adresu IPv4 oraz prefiksu podsieci z maską (np. 10.0.0.1/24).
Natywny typ sieciowy (ip-prefix): wyspecjalizowany typ danych w systemie RouterOS przechowujący adres sieciowy wraz z długością maski podsieci w notacji CIDR, umożliwiający bezpośrednie operacje logiczne na prefiksach routingu.
  +-------------------------------------------------------+
  |              PODSTAWOWE TYPY DANYCH ROUTEROS          |
  +-------------------------------------------------------+
  | num:     liczby całkowite (np. 10, -5, 100)           |
  | str:     ciągi tekstowe (np. "ether1", "LAN")         |
  | bool:    wartości logiczne (yes/true, no/false)       |
  | ip:      adresy IPv4 (np. 192.168.88.1)              |
  | ip-prefix:podsieci CIDR (np. 192.168.88.0/24)         |
  +-------------------------------------------------------+
        
14/55
Zaawansowane typy danych w RouterOS
Slajd przedstawia zaawansowane typy danych: przedziały czasowe (time), daty (date), tablice (array) oraz identyfikatory wewnętrzne (id).

Czas, daty, identyfikatory wewnętrzne i tablice

  • Interwały czasowe (time): reprezentacja czasu w jednostkach sieciowych, np. 5s, 10m, 02:00:00, 1d.
  • Daty systemowe (date): zapis daty w formacie angielskim (np. feb/24/2026) zwracany przez zegar routera.
  • Identyfikatory wewnętrzne (id): szesnastkowe wskaźniki obiektów (*1, *F) generowane przez polecenie find.
  • Tablice obiektów (array): uporządkowane listy wartości rozdzielane przecinkami lub średnikami w nawiasach okrągłych.
Wewnętrzny identyfikator obiektu (*id): unikalny, generowany dynamicznie przez bazę danych RouterOS klucz szesnastkowy identyfikujący konkretny wpis w tabeli konfiguracyjnej, wykorzystywany przez polecenia get i set.
  +-------------------------------------------------------+
  |            ZAAWANSOWANE TYPY DANYCH ROUTEROS          |
  +-------------------------------------------------------+
  | time:    przedziały czasowe (np. 10s, 01:30:00, 1d)   |
  | date:    daty kalendarzowe (np. jan/15/2026)          |
  | id:      wewnętrzne identyfikatory obiektów (*1, *A)  |
  | array:   uporządkowane listy elementów (tablice)      |
  | nothing: wartość pusta, brak referencji               |
  +-------------------------------------------------------+
        
15/55
Operatory arytmetyczne
Slajd omawia operatory arytmetyczne (+, -, *, /) oraz specyfikę operacji na liczbach całkowitych w RouterOS.

Działania matematyczne w skryptach RouterOS

  • Podstawowe działania: dodawanie (+), odejmowanie (-), mnożenie (*) oraz dzielenie całkowite (/).
  • Dzielenie z odrzuceniem reszty: dzielenie w RouterOS operuje na liczbach całkowitych i odrzuca część ułamkową (np. 7 / 2 daje 3).
  • Priorytety działań: mnożenie i dzielenie mają wyższy priorytet niż dodawanie; nawiasy okrągłe wymuszają kolejność obliczeń.
  • Przepełnienie bufora: RouterOS operuje na standardowych 32-bitowych lub 64-bitowych liczbach całkowitych ze znakiem.
Arytmetyka całkowita w RouterOS: podsystem ewaluacji matematycznej w interpreterze wykonujący obliczenia wyłącznie na liczbach całkowitych, zoptymalizowany pod kątem niskiego zużycia zasobów procesora routera.
:local a 10
:local b 3

:put ("a + b = " . ($a + $b))     # 13
:put ("a - b = " . ($a - $b))     # 7
:put ("a * b = " . ($a * $b))    # 30
:put ("a / b = " . ($a / $b))    # 3 (dzielenie całkowite)

# Operacje z mieszanymi typami
:local x 5
:local y 2.5
:put ("x + y = " . ($x + $y))    # 7.5

# Modyfikacja zmiennej
:set a ($a + 5)
:put ("a po dodaniu 5 = " . $a)  # 15
16/55
Operatory porównania
Slajd przedstawia operatory relacyjne: =, !=, <, >, <=, >= oraz ich zastosowanie w testach warunkowych.

Porównywanie wartości liczbowych, tekstowych i logicznych

  • Operator równości (=): sprawdza czy dwie wartości są identyczne pod względem typu i zawartości (pojedynczy znak równości).
  • Operator nierówności (!=): zwraca wartość logiczną true, jeżeli badane obiekty różnią się od siebie.
  • Operatory relacji wielkości (<, >, <=, >=): porównują liczby, interwały czasowe oraz porządek leksykograficzny łańcuchów znaków.
  • Porównania adresów IP: RouterOS umożliwia bezpośrednie porównywanie adresów IP i sprawdzanie relacji zawierania w podsieci.
Operator relacyjny w RouterOS: symbol logiczny weryfikujący relację pomiędzy dwoma wyrażeniami tego samego typu, zwracający wartość logiczną prawdy (true/yes) lub fałszu (false/no).
:local wiek 20
:local granica 18

:if ($wiek >= $granica) do={
    :put "Osoba jest pełnoletnia"
} else={
    :put "Osoba jest niepełnoletnia"
}

# Sprawdzenie nierówności (dwie równoważne formy)
:local imie "Anna"
:if ($imie != "Jan") do={
    :put "To nie jest Jan"
}

# Lub z negacją
:if (!($imie = "Jan")) do={
    :put "To nie jest Jan"
}
17/55
Operatory logiczne
Slajd omawia operatory algebry Boole'a w RouterOS, ich składnię oraz budowanie wielowarstwowych reguł decyzyjnych.

Łączenie warunków złożonych: and, or, not

  • Iloczyn logiczny (and): warunek złożony jest spełniony tylko wtedy, gdy oba człony składowe są prawdziwe.
  • Suma logiczna (or): warunek złożony jest spełniony, jeżeli przynajmniej jeden z członów ma wartość true.
  • Negacja logiczna (not lub !): odwraca stan logiczny wyrażenia (!true daje false).
  • Grupowanie nawiasami: używanie nawiasów okrągłych w złożonych warunkach zapobiega błędom interpretacji priorytetów operatorów.
Logika Boole'a w RouterOS: system formalny reguł dedukcyjnych interpretera poleceń umożliwiający agregację wielu kryteriów sieciowych (np. stan interfejsu AND czas doby) w pojedynczą decyzję wykonawczą.
:local wiek 25
:local maPrawoJazdy true
:local jestTrzeźwy true

# Sprawdzenie, czy osoba może prowadzić
:if ($wiek >= 18 and $maPrawoJazdy = true and $jestTrzeźwy = true) do={
    :put "Może prowadzić samochód"
} else={
    :put "Nie może prowadzić samochodu"
}

# Przykład z OR - przynajmniej jedno musi być spełnione
:local maKlucz false
:local znaKod true

:if ($maKlucz = true or $znaKod = true) do={
    :put "Można wejść do pomieszczenia"
}
18/55
Łączenie tekstów: konkatenacja
Slajd wyjaśnia mechanizm konkatenacji ciągów tekstowych w RouterOS za pomocą operatora kropki oraz interpolację zmiennych w cudzysłowach.

Operator kropki (.) i składanie łańcuchów znaków

  • Operator kropki (.): służy do bezpośredniego łączenia dwóch ciągów tekstowych: :put ("Wartość: " . $zmienna).
  • Interpolacja w cudzysłowie: umieszczenie zmiennej $zmienna wewnątrz podwójnego cudzysłowu automatycznie wstawia jej wartość.
  • Konwersja na tekst (:tostr): wartości nieliczbowe (np. IP, data) przed konkatenacją z tekstem należy przekształcić funkcją :tostr.
  • Budowanie komunikatów logów: składanie szczegółowych wpisów dziennika zawierających nazwy interfejsów, adresy IP i znaczniki czasu.
Konkatenacja (string concatenation): operacja połączenia dwóch lub więcej łańcuchów znaków w jeden ciągły łańcuch tekstowy, realizowana w RouterOS przy użyciu operatora dwuargumentowego kropki (.).
:local imie "Jan"
:local nazwisko "Kowalski"

# Proste połączenie dwóch tekstów
:local pelneImie ($imie . " " . $nazwisko)
:put $pelneImie  # Jan Kowalski

# Budowanie komunikatu
:local interfejs "ether1"
:local status "aktywny"
:put ("Interfejs " . $interfejs . " jest " . $status)
# Wynik: Interfejs ether1 jest aktywny

# Łączenie z liczbami
:local liczba 42
:put ("Odpowiedź to: " . $liczba)
# Wynik: Odpowiedź to: 42

# Uwaga: używaj nawiasów () przy zmiennych w konkatenacji
:put "Wynik: " . $liczba   # Działa
:put "Wynik: $liczba"     # To jest zwykły tekst, nie podstawi zmiennej!
19/55
Instrukcja warunkowa :if: podstawy
Slajd omawia składnię instrukcji warunkowej :if, blok wykonawczy do={ } oraz gałąź alternatywną else={ }.

Podejmowanie decyzji w skryptach RouterOS

  • Składnia bazowa :if: konstrukcja :if (warunek) do={ instrukcje } wykonuje blok poleceń przy spełnieniu testu.
  • Klauzula alternatywna else={ }: blok instrukcji wykonywany wtedy, gdy badany warunek logiczny zwróci wartość false.
  • Wymóg nawiasów klamrowych: ciało bloku wykonawczego do oraz else musi być bezwzględnie ujęte w nawiasy klamrowe.
  • Formatowanie kodu: stosowanie czytelnych wcięć ułatwia śledzenie przepływu sterowania w rozbudowanych skryptach.
Instrukcja warunkowa (:if): kluczowa struktura sterująca interpretera RouterOS decydująca o wykonaniu określonego bloku komend na podstawie ewaluacji logicznej testowanego predykatu sieciowego.
:if (warunek) do={
    # kod do wykonania, gdy warunek jest prawdziwy
}
:if (warunek) do={
    # kod gdy prawda
} else={
    # kod gdy fałsz
}
:local temperatura 22

:if ($temperatura > 25) do={
    :put "Jest gorąco - włącz klimatyzację"
} else={
    :put "Temperatura jest OK"
}

# Prostszy przykład bez else
:if ($temperatura > 30) do={
    :log warning "Uwaga! Bardzo goraco!"
}

:put "Skrypt zakończony"
20/55
Instrukcja :if: praktyczne przykłady
Slajd demonstruje praktyczne zastosowanie instrukcji :if do badania statusu interfejsu sieciowego oraz sprawdzania przypisanego adresu IP.

Weryfikacja stanu łączy i parametrów sieciowych

  • Badanie stanu interfejsu: sprawdzenie czy interfejs ethernetowy lub tunel VPN znajduje się w stanie aktywnym (running).
  • Pobieranie właściwości poleceniem get: konstrukcja [/interface get [find name="ether1"] running] zwraca wartość true lub false.
  • Reakcja na awarię: automatyczne wywołanie powiadomienia lub przełączenie tras routingu w razie utraty połączenia fizycznego.
  • Walidacja konfiguracji: sprawdzanie obecności domyślnej bramy sieciowej przed próbą wysłania raportu na serwer zewnętrzny.
Właściwość running: dynamiczna flaga logiczna obiektu interfejsu w RouterOS informująca o ustanowieniu fizycznej warstwy łącza danych (link up) lub aktywnego zestawienia tunelu VPN.
# Pobierz status interfejsu ether1
:local interfejs "ether1"
:local status [/interface get [find name=$interfejs] running]

:if ($status = true) do={
    :log info ("Interfejs " . $interfejs . " jest uruchomiony.")
} else={
    :log error ("Interfejs " . $interfejs . " jest wyłączony!")
}

# Sprawdzanie, czy zmienna ma wartość (nie jest nil)
:global mojaZmienna
:if ([:typeof $mojaZmienna] = "nil") do={
    :log info "Zmienna nie ma wartosci, ustawiam domyslna"
    :set mojaZmienna "wartość domyślna"
}
21/55
Zagnieżdżone instrukcje :if
Slajd omawia technikę zagnieżdżania instrukcji :if wewnątrz bloków do i else oraz strategie zachowania czytelności kodu.

Wielopoziomowe drzewa decyzyjne

  • Zagnieżdżanie bloków: umieszczenie kolejnej instrukcji :if wewnątrz sekcji else={ :if (...) do={ } } symuluje strukturę elseif.
  • Weryfikacja wieloetapowa: krokowe sprawdzanie warunków: obecność łącza, poprawność adresu IP, a następnie test pingu do bramy.
  • Czytelność i głębokość: unikanie zagnieżdżeń głębszych niż 3 poziomy w celu zapobiegania trudnym do wykrycia błędom logicznym.
  • Wczesne wychodzenie z bloku: stosowanie odwróconych warunków do szybkiego przerywania skryptu w razie niespełnienia wymagań wstępnych.
Zagnieżdżanie warunków (nested conditions): wzorzec programistyczny polegający na umieszczaniu struktur decyzyjnych wewnątrz innych bloków decyzyjnych, umożliwiający modelowanie złożonych, wielostanowych algorytmów sieciowych.
:local wiek 17
:local maBilets true

:if ($wiek >= 18) do={
    :if ($maBilets = true) do={
        :put "Możesz obejrzeć film"
    } else={
        :put "Masz wiek, ale nie masz biletu"
    }
} else={
    :put "Nie masz wymaganego wieku"
}

# Lepsza alternatywa - użycie else if
:if ($wiek < 13) do={
    :put "Bilet dziecięcy"
} else if ($wiek < 18) do={
    :put "Bilet ulgowy"
} else={
    :put "Bilet normalny"
}
22/55
Pętla :for
Slajd przedstawia składnię pętli licznikowej :for from=1 to=N step=K do={ }, służącej do powtarzania operacji zadaną liczbę razy.

Licznikowa iteracja w zadanym zakresie

  • Składnia pętli :for: parametry from=start, to=koniec oraz opcjonalny step=krok definiują zakres iteracji zmiennej licznikowej.
  • Zmienna iteracyjna: wskazana w nagłówku zmienna (np. :for i from=1 to=5 do={ :put $i }) przyjmuje kolejne wartości liczbowe.
  • Krok dekrementacji: podanie ujemnego kroku (step=-1) pozwala na realizację odliczania wstecz.
  • Zastosowania praktyczne: generowanie powtarzalnych adresów IP w podsieci, pakiety testowe ping czy cykliczne próby połączenia.
Pętla licznikowa (:for): struktura iteracyjna interpretera RouterOS wykonująca blok instrukcji dla każdego kolejnego punktu ciągu arytmetycznego wyznaczonego przez parametry from, to oraz step.
:for zmienna from=początek to=koniec step=krok do={
    # kod do wykonania
}
23/55
Pętla :foreach: wprowadzenie
Slajd omawia pętlę :foreach element in=kolekcja do={ }, zasady trawersowania list oraz iterację po elementach konfiguracji.

Najważniejsza pętla administracyjna w RouterOS

  • Rola pętli :foreach: podstawowe narzędzie do sekwencyjnego przetwarzania elementów tablic, list oraz rekordów konfiguracyjnych.
  • Składnia bazowa: konstrukcja :foreach element in=(lista) do={ :put $element } odwiedza każdy obiekt ze zbioru wejściowego.
  • Zmienna elementu: zmienna zdefiniowana w nagłówku pętli przyjmuje wartość bieżącego elementu w każdej iteracji.
  • Uniwersalność kolekcji: pętla potrafi przetwarzać zarówno proste literały tekstowe, jak i złożone zbiory identyfikatorów systemowych.
Pętla iteracyjna (:foreach): kluczowa konstrukcja powłoki RouterOS służąca do sekwencyjnego przechodzenia przez wszystkie elementy kolekcji, list parametrów lub wyników zapytań systemowych.
:foreach zmienna in=kolekcja do={
    # kod do wykonania dla każdego elementu
}
# Przykład 1: Iteracja po liście (tablicy)
:local mojaLista {1, 2, 3, 4, 5}

:foreach element in=$mojaLista do={
    :put ("Element: " . $element)
}

# Przykład 2: Iteracja po interfejsach
:foreach iface in=[/interface find] do={
    :local ifaceName [/interface get $iface name]
    :put ("Interfejs: " . $ifaceName)
}
24/55
Pętla :foreach z poleceniem find
Slajd wyjaśnia idiomatyczną współpracę pętli :foreach z poleceniem find do masowej rekonfiguracji interfejsów, reguł zapory i tras.

Masowe operacje na obiektach sieciowych

  • Wzorzec projektowy: zapis :foreach i in=[/interface find disabled=yes] do={ ... } wyszukuje i przetwarza obiekty w jednym kroku.
  • Identyfikator wewnętrzny ($i): zmienna pętli otrzymuje unikalny identyfikator (*id), a nie nazwę tekstową obiektu.
  • Filtrowanie w zapytaniu (where): klauzula where pozwala na precyzyjne zawężenie wyszukiwania, np. where comment~"Zapasowy".
  • Masowe modyfikacje: wywołanie poleceń remove, enable, disable lub set dla każdego odnalezionego rekordu w pętli.
Polecenie find z filtrem: wbudowane polecenie nawigacyjne w menu konfiguracyjnym RouterOS przeszukujące tabelę obiektów i zwracające tablicę identyfikatorów wewnętrznych spełniających zadaną klauzulę kryteriów.
# --- Przykład: Wyświetl wszystkie aktywne interfejsy ---

:foreach iface in=[/interface find running] do={
    :local nazwa [/interface get $iface name]
    :local typ [/interface get $iface type]
    :put ("Interfejs: " . $nazwa . " (typ: " . $typ . ")")
}

# --- Przykład: Wyłącz wszystkie interfejsy nieaktywne ---

:foreach iface in=[/interface find running=no] do={
    :local nazwa [/interface get $iface name]
    :log warning ("Wyłączam nieaktywny interfejs: " . $nazwa)
    /interface disable $iface
}
25/55
Pętla :while
Slajd omawia konstrukcję pętli warunkowej :while (warunek) do={ } oraz zabezpieczenia przed zablokowaniem procesora routera.

Powtarzanie operacji do momentu spełnienia warunku

  • Składnia pętli :while: wykonuje blok instrukcji tak długo, jak długo testowane wyrażenie logiczne ma wartość true.
  • Oczekiwanie na zasób: wykorzystywana do oczekiwania na pobranie adresu z serwera DHCP lub ustanowienie sesji BGP.
  • Konieczność opóźnienia (:delay): bezwzględny wymóg stosowania komendy :delay wewnątrz pętli, aby zapobiec obciążeniu CPU na 100%.
  • Licznik maksymalnych prób (timeout): dobra praktyka nakazuje wprowadzenie licznika pętli zapobiegającego zawieszeniu skryptu.
Pętla warunkowa (:while): struktura sterująca interpretera RouterOS powtarzająca wykonanie bloku kodu do momentu zmiany stanu logicznego warunku na fałsz, wymagająca kontroli limitu czasu i odciążania procesora poleceniem :delay.
:while (warunek) do={
    # kod
}
26/55
Tablice (listy): wprowadzenie
Slajd przedstawia sposób tworzenia tablic za pomocą nawiasów okrągłych i przecinków, indeksowanie od zera oraz funkcję :len.

Definiowanie i indeksowanie kolekcji w RouterOS

  • Tworzenie tablicy: deklaracja listy elementów w nawiasach okrągłych: :local mojaLista (1, "dwa", 10.0.0.1).
  • Indeksowanie od zera: dostęp do konkretnego elementu odbywa się za pomocą indeksu w nawiasach: ($mojaLista->0).
  • Długość tablicy (:len): wbudowana funkcja :len $mojaLista zwraca liczbę elementów znajdujących się w kolekcji.
  • Różnorodne typy danych: pojedyncza tablica w RouterOS może przechowywać elementy różnych typów danych jednocześnie.
Tablica w RouterOS (array): uporządkowana kolekcja elementów indeksowana liczbami całkowitymi począwszy od zera, reprezentowana składniowo w nawiasach okrągłych, z dostępem przez operator strzałki (->).
# Tworzenie tablicy z różnymi typami danych
:local sieci {"192.168.1.0/24", "10.0.0.0/8", "172.16.0.0/12"}

# Sprawdzenie liczby elementów
:local ilosc [:len $sieci]
:put ("Liczba sieci: " . $ilosc)  # 3

# Dostęp do pierwszego elementu (indeks 0)
:local pierwszaSiec [:pick $sieci 0]
:put ("Pierwsza sieć: " . $pierwszaSiec)  # 192.168.1.0/24

# Dostęp do ostatniego elementu
:local ostatniaSiec [:pick $sieci ($ilosc - 1)]
:put ("Ostatnia sieć: " . $ostatniaSiec)  # 172.16.0.0/12
27/55
Tablice: operacje na elementach
Slajd omawia operacje na tablicach: łączenie przecinkiem, dodawanie elementów operatorem , oraz usuwanie i wyszukiwanie.

Dodawanie, łączenie i modyfikacja kolekcji

  • Dodawanie elementów: konstrukcja :set $tablica ($tablica , "nowyElement") powiększa tablicę o nowy element na końcu.
  • Łączenie dwóch tablic: zestawienie dwóch tablic operatorem przecinka scala je w jedną większą kolekcję elementów.
  • Pobieranie wycinków: RouterOS nie posiada natywnego wycinania zakresów tablic; operację realizuje się pętlą :for z indeksem.
  • Zastosowania: gromadzenie dynamicznych list adresów IP, nazw uszkodzonych interfejsów lub parametrów konfiguracyjnych.
Operacja scalania tablic: mechanizm alokacji nowej kolekcji w pamięci interpretera RouterOS powstałej z połączenia dwóch istniejących tablic za pomocą separatora przecinka.
# Tworzenie pustej tablicy
:global mojaTablica [:toarray ""]

# Dodawanie elementów
:set ($mojaTablica->0) "pierwszy"
:set ($mojaTablica->1) "drugi"
:set ($mojaTablica->2) "trzeci"

:put ("Liczba elementów: " . [:len $mojaTablica])

# Modyfikacja elementu
:set ($mojaTablica->1) "nowy drugi"

# Iteracja przez wszystkie elementy
:foreach element in=$mojaTablica do={
    :put ("Element: " . $element)
}
28/55
Funkcje w RouterOS: :parse
Slajd wyjaśnia mechanizm emulacji funkcji w RouterOS za pomocą polecenia :parse oraz przekazywanie parametrów w skryptach.

Dynamiczne kompilowanie i wykonywanie bloków kodu

  • Brak tradycyjnego słowa function: język RouterOS nie posiada tradycyjnej deklaracji funkcji; jej rolę pełnią zmienne z kodem.
  • Polecenie :parse: zamienia łańcuch tekstowy zawierający kod na wykonywalny blok kodu skryptowego.
  • Wywoływanie funkcji ($mojaFunkcja): uruchomienie skompilowanego bloku poprzez odwołanie się do zmiennej ze znakiem dolara: [$mojaFunkcja arg1].
  • Zwracanie wartości (:return): polecenie :return kończy działanie funkcji i przekazuje wyliczoną wartość z powrotem do wywołującego.
Kompilator w locie (:parse): wbudowana funkcja interpretera RouterOS przekształcająca ciąg znaków tekstowych w skompilowane drzewo instrukcji języka skryptowego z możliwością dynamicznego wykonania.
# Definicja funkcji "powitania"
:global powitaj [:parse ":put \"Witaj w RouterOS!\""]

# Wywołanie funkcji
$powitaj
$powitaj

# Funkcja z parametrem
:global powitajImieniem [:parse ":put (\"Witaj, \" . \$imie . \"!\")"]

# Wywołanie z parametrem
$powitajImieniem imie="Anna"
$powitajImieniem imie="Jan"

# Funkcja zwracająca wartość
:global obliczSume [:parse ":return ((\$a) + (\$b))"]
:local wynik [$obliczSume a=5 b=3]
:put ("Suma: " . $wynik)
29/55
Zarządzanie konfiguracją: find, get, set
Slajd przedstawia fundamentalne trio poleceń zarządczych: wyszukiwanie find, odczyt właściwości get oraz modyfikację parametrów set.

Trzy filary administracji urządzeniem w skryptach

  • Polecenie find: lokalizuje rekordy w tabeli spełniające kryteria i zwraca ich identyfikatory szesnastkowe.
  • Polecenie get: odczytuje wartość określonej właściwości obiektu wskazanego identyfikatorem (np. [/ip address get $id address]).
  • Polecenie set: modyfikuje wybrane parametry wskazanego obiektu (np. [/interface set $id comment="Nowy opis"]).
  • Atomowość operacji: wykonywanie operacji bezpośrednio w drzewie konfiguracji zapewnia natychmiastowe zastosowanie zmian w urządzeniu.
Trójka zarządcza (find, get, set): podstawowy paradygmat programowego odczytu i modyfikacji bazy konfiguracyjnej RouterOS, stanowiący odpowiednik zapytań SELECT i UPDATE w relacyjnych bazach danych.
# Znajdź ID interfejsu o nazwie ether1
:local id [/interface find name="ether1"]

# Pobierz właściwość tego interfejsu (np. status running)
:local status [/interface get $id running]

# Zmień właściwość - wyłącz interfejs
/interface set $id disabled=yes

# Wszystko w jednym linii (bez zmiennych)
:if ([/interface get [find name="ether1"] running] = true) do={
    :put "Interfejs ether1 jest aktywny"
}
30/55
Dodawanie i usuwanie elementów: add i remove
Slajd omawia polecenia add (tworzenie nowych reguł, adresów, tras) oraz remove (usuwanie zbędnych wpisów) w drzewie konfiguracji.

Dynamiczna modyfikacja obiektów sieciowych

  • Polecenie add: tworzy nowy obiekt w bieżącym podmenu z podanymi parametrami (np. /ip firewall address-list add ...).
  • Zwracanie identyfikatora: polecenie add w skrypcie zwraca identyfikator newly created obiektu, umożliwiając dalsze operacje.
  • Polecenie remove: trwale usuwa wskazany obiekt lub listę obiektów przekazanych w nawiasie: [/ip route remove [find ...]].
  • Zastosowanie produkcyjne: dynamiczne blokowanie adresów IP na zaporze sieciowej oraz dodawanie tymczasowych tras statycznych.
Polecenie add / remove: instrukcje modyfikujące zawartość tabel systemowych RouterOS, odpowiadające za alokację nowych zasobów konfiguracyjnych oraz ich destrukcję i zwalnianie pamięci w jądrze systemu.
# Dodaj nowy adres IP
/ip address add address=192.168.99.1/24 interface=ether2 comment="Nowy LAN"

# Dodaj regułę firewalla blokującą adres IP
/ip firewall address-list add list=blokowani address=1.2.3.4 comment="Atakujący"

# Znajdź i usuń regułę
:local idReguly [/ip firewall address-list find address="1.2.3.4"]
:if ([:len $idReguly] > 0) do={
    /ip firewall address-list remove $idReguly
    :log info "Usunięto zablokowany adres IP"
}

# Usuń wszystkie wyłączone interfejsy
:foreach iface in=[/interface find disabled=yes] do={
    /interface remove $iface
}
31/55
Dostęp do parametrów systemu
Slajd przedstawia metody odczytu stanu urządzenia z gałęzi /system resource, /system identity oraz /system health.

Pobieranie danych o sprzęcie, zasobach i tożsamości routera

  • Nazwa urządzenia (/system identity): odczyt unikalnej tożsamości routera: [/system identity get name], przydatny w nagłówkach raportów.
  • Zasoby sprzętowe (/system resource): monitorowanie zużycia procesora (cpu-load), wolnej pamięci RAM (free-memory) oraz czasu pracy (uptime).
  • Stan zasilania i temperatury (/system health): odczyt parametrów napięcia zasilania oraz temperatury procesora i płyty głównej.
  • Wersja oprogramowania: weryfikacja aktualnej wersji systemu RouterOS (właściwość version w zasobach systemowych).
Moduł /system resource: tabela jądra systemu RouterOS udostępniająca w czasie rzeczywistym parametry wydajnościowe sprzętu: obciążenie procesora, alokację pamięci operacyjnej oraz czas nieprzerwanej pracy routera.
# Pobierz podstawowe informacje o systemie
:local nazwaRoutera [/system identity get name]
:local wersja [/system resource get version]
:local data [/system clock get date]
:local czas [/system clock get time]
:local uptime [/system resource get uptime]

:put ("========================================")
:put ("Router: " . $nazwaRoutera)
:put ("Wersja RouterOS: " . $wersja)
:put ("Data: " . $data . " " . $czas)
:put ("Czas pracy: " . $uptime)
:put ("========================================")

# Sprawdz ilosc pamieci RAM
:local ram [/system resource get total-memory]
:local freeRam [/system resource get free-memory]
:put ("RAM calkowita: " . ($ram / 1024 / 1024) . " MB")
:put ("RAM wolna: " . ($freeRam / 1024 / 1024) . " MB")
32/55
Zapisywanie do logów systemowych: :log
Slajd omawia polecenie :log, poziomy istotności zdarzeń (info, warning, error, debug) oraz konfigurację celów logowania w /system logging.

Rejestracja komunikatów i poziomy istotności zdarzeń

  • Składnia polecenia :log: wywołanie :log info "Treść komunikatu" umieszcza wpis w centralnym buforze zdarzeń routera.
  • Poziomy istotności: kategoryzacja komunikatów na informacyjne (info), ostrzegawcze (warning) oraz błędy krytyczne (error).
  • Zewnętrzne serwery Syslog: możliwość automatycznego przesyłania zdarzeń wygenerowanych przez skrypt na centralny serwer Syslog w sieci.
  • Kluczowy element audytu: każdy skrypt produkcyjny powinien rejestrować moment startu, napotkane anomalie oraz pomyślne zakończenie pracy.
Dziennik zdarzeń RouterOS (:log): wbudowany w jądro systemowe podsystem rejestracji komunikatów operacyjnych i diagnostycznych, wspierający lokalne bufory pamięci oraz zdalną transmisję protokołem Syslog (UDP 514).
# Podstawowe logowanie
:log info "Skrypt uruchomiony pomyślnie"
:log warning "Cos wymaga uwagi"
:log error "Wystąpił błąd!"

# Przykład: skrypt z logowaniem
:local interfejs "ether1"

:log info ("Rozpoczynam sprawdzanie interfejsu " . $interfejs)

:local status [/interface get [find name=$interfejs] running]

:if ($status = true) do={
    :log info ("Interfejs " . $interfejs . " jest aktywny - wszystko OK")
} else={
    :log error ("Interfejs " . $interfejs . " jest wyłączony! - wymaga interwencji!")
}

:log info "Skrypt zakonczony"
33/55
Argumenty skryptu
Slajd wyjaśnia metody parametryzacji skryptów w RouterOS za pomocą zmiennych globalnych oraz argumentów polecenia :execute.

Przekazywanie parametrów przez zmienne globalne i wywołania

  • Brak natywnych parametrów wiersza: skrypty w /system script nie przyjmują bezpośrednich argumentów pozycyjnych $1, $2.
  • Wzorzec zmiennej globalnej: skrypt wywołujący ustawia zmienną :global parametrWymagany, którą skrypt docelowy odczytuje.
  • Przekazywanie przez :parse: dynamiczne skompilowanie kodu z wstrzykniętymi wartościami zmiennych lokalnych.
  • Czyszczenie parametrów: natychmiastowe zerowanie zmiennych globalnych po ich odczytaniu w celu uniknięcia kolizji w kolejnych wywołaniach.
Parametryzacja skryptów w RouterOS: architektoniczny wzorzec projektowy wymuszony brakiem bezpośrednich argumentów wywołania, polegający na wykorzystaniu współdzielonej pamięci zmiennych globalnych lub dynamicznego parsowania kodu.
# --- Skrypt: sprawdz-interfejs.rsc ---
# Oczekuje argumentów: interfejs, akcja

# Odczytaj argumenty (jeśli nie podane, użyj wartości domyślnych)
:global interfejs
:global akcja

:if ([:typeof $interfejs] = "nil") do={
    :set interfejs "ether1"
}
:if ([:typeof $akcja] = "nil") do={
    :set akcja "status"
}

:put ("Sprawdzam interfejs: " . $interfejs)
:put ("Akcja: " . $akcja)

# Uruchomienie:
# /system script run sprawdz-interfejs interfejs=ether2 akcja=info
34/55
Odczyt z plików w RouterOS
Slajd omawia strukturę magazynu dyskowego /file, odczyt zawartości plików tekstowych oraz ograniczenia bufora w RouterOS.

Zarządzanie magazynem plików i polecenie /file

  • Menu /file: zarządza fizycznymi plikami w pamięci flash lub na zewnętrznych nośnikach pamięci USB/microSD.
  • Pobieranie zawartości (contents): odczyt treści pliku tekstowego: [/file get [find name="plik.txt"] contents].
  • Ograniczenie rozmiaru bufora: w starszych wersjach RouterOS właściwość contents obcinała pliki powyżej 4096 bajtów (limit 4 KB).
  • Pliki konfiguracyjne: odczytywanie zewnętrznych list blokowanych adresów IP lub parametrów środowiskowych przygotowanych wcześniej.
Magazyn plików (/file): podsystem pamięci masowej w RouterOS zarządzający lokalnym systemem plików pamięci NAND/eMMC routera oraz zewnętrznymi nośnikami dyskowymi.
# Najpierw stwórz plik testowy (np. przez export)
# /file print file=mojplik.txt

# Odczytaj zawartość pliku
:local zawartosc [/file get mojplik.txt contents]

:put ("Zawartosc pliku:")
:put $zawartosc

# Sprawdź długość tekstu
:local dlugosc [:len $zawartosc]
:put ("Długość: " . $dlugosc . " znaków")

# Podziel tekst na elementy (zakładając format CSV - wartości po przecinkach)
:local elementy [:toarray $zawartosc]
:foreach elem in=$elementy do={
    :put ("Element: " . $elem)
}
35/55
Zapis do plików w RouterOS
Slajd przedstawia techniki tworzenia i modyfikowania plików tekstowych na dysku routera za pomocą komend /print file= oraz poleceń API.

Generowanie raportów i polecenie /print file=

  • Przekierowanie wyniku (/print file=): dodanie parametru file=nazwa_pliku do dowolnego polecenia print zapisuje tabelę do pliku tekstowego.
  • Modyfikacja zawartości pliku: polecenie /file set [find name="plik.txt"] contents="Nowa treść" nadpisuje plik tekstowy.
  • Eksport konfiguracji (/export file=): zrzut pełnej lub częściowej konfiguracji routera w postaci skryptu tekstowego .rsc na dysk.
  • Rotacja plików: usuwanie przestarzałych plików raportów w celu ochrony ograniczonej pamięci flash urządzenia przed zapełnieniem.
Eksport konfiguracyjny (/export): wbudowane polecenie diagnostyczno-archiwizacyjne generujące kompletny skrypt poleceń wiersza poleceń RouterOS odtwarzający stan bieżącej konfiguracji urządzenia.
# --- Tworzenie i zapisywanie do pliku ---

# Krok 1: Stwórz pusty plik
/file print file=raport.txt

# Krok 2: Zapisz do niego tekst
:local raport "To jest tresc raportu.\nData: "
:local data [/system clock get date]
:set raport ($raport . $data)

/file set raport.txt contents=$raport

# Krok 3: Sprawdź, czy plik został utworzony
:local pliki [/file print where name~"raport"]
:log info ("Utworzono plik, rozmiar listy: " . [:len $pliki])

# --- Praktyczny przykład: Eksport adresów IP ---
/ip address export file=adresy-ip
:log info "Wyeksportowano adresy IP do pliku adresy-ip.rsc"
36/55
Przydatne funkcje tekstowe
Slajd omawia wbudowane funkcje manipulacji tekstem: :find, :pick, :len, :tostr oraz :tonum w języku RouterOS.

Wyszukiwanie, wycinanie podciągów i konwersja typów

  • Wyszukiwanie podciągu (:find): zwraca indeks pozycji pierwszego wystąpienia zadanego fragmentu tekstu w łańcuchu.
  • Ekstrakcja podciągu (:pick): wycina fragment tekstu na podstawie indeksu początkowego i końcowego: :pick $tekst 0 5.
  • Konwersja na liczbę (:tonum): przekształca ciąg cyfr tekstowych na liczbę całkowitą umożliwiającą operacje arytmetyczne.
  • Parsowanie adresów IP: wycinanie samych oktetów lub maski z adresu podsieci za pomocą kombinacji funkcji :find oraz :pick.
Funkcja wycinania tekstu (:pick): wbudowana instrukcja operująca na łańcuchach znaków w RouterOS, wyodrębniająca podciąg w zadanym przedziale indeksów początkowego i końcowego.
:local tekst "Hello World"

# Długość tekstu
:put ("Długość: " . [:len $tekst])  # 11

# Pobierz fragment (od znaku 0 do 5)
:put ([:pick $tekst 0 5])           # Hello

# Znajdź pozycję słowa
:put ([:find $tekst "World"])       # 6

# Zamień tekst
:local nowy [:replace $tekst "World" "RouterOS"]
:put $nowy                           # Hello RouterOS

# Konwersja typów
:local liczba 42
:local tekstZLiczby [:tostr $liczba]
:put ([:typeof $tekstZLiczby])       # str

:local tekstLiczbowy "123"
:local liczbaZTekstu [:tonum $tekstLiczbowy]
:put ([:typeof $liczbaZTekstu])      # num
37/55
Obsługa błędów: :do i :on-error
Slajd wyjaśnia architekturę obsługi wyjątków za pomocą konstrukcji :do { ... } on-error={ ... } w celu ochrony stabilności skryptu.

Zabezpieczanie skryptów przed niespodziewanym przerwaniem

  • Domyślne zachowanie przy błędzie: wystąpienie jakiegokolwiek błędu wykonawczego natychmiast przerywa działanie całego skryptu RouterOS.
  • Struktura :do on-error: kod ryzykowny umieszcza się w bloku :do { }; w razie awarii sterowanie natychmiast przejmuje sekcja on-error={ }.
  • Bezpieczne operacje sieciowe: bezwzględna konieczność otaczania blokiem on-error zapytań /tool fetch oraz poleceń ping do serwerów zewnętrznych.
  • Rejestracja awarii w logu: umieszczenie wpisu :log error "Napotkano problem" w sekcji on-error pozwala na późniejszą diagnozę przyczyny.
Obsługa wyjątków (:do on-error): jedyny wbudowany mechanizm przechwytywania błędów wykonawczych w języku skryptowym RouterOS, zapobiegający awaryjnemu zrzuceniu wątku interpretera i umożliwiający podjęcie akcji naprawczych.
:do {
    # kod, który może się nie udać
} on-error={
    # kod wykonany, gdy wystąpi błąd
}
38/55
Wybór wielowariantowy: emulacja switch-case
Slajd przedstawia metody implementacji wielowariantowego podejmowania decyzji w RouterOS za pomocą tablic asocjacyjnych i pętli.

Struktury decyzyjne w języku RouterOS

  • Brak natywnej instrukcji switch: język RouterOS nie posiada wbudowanego słowa kluczowego switch ani case.
  • Emulacja sekwencją :if else: najprostsze rozwiązanie oparte na kaskadowym zagnieżdżaniu warunków :if.
  • Emulacja tablicą mieszającą: zaawansowany wzorzec mapujący wartości na komendy w tablicy i wywołujący dopasowany blok funkcją :parse.
  • Zastosowanie w menu: obsługa wyborów profilu jakości usługi (QoS), trybów pracy zapory lub statusów interfejsów WAN.
Emulacja switch-case: wzorzec architektoniczny w językach pozbawionych natywnej instrukcji wyboru, pozwalający na czytelne kierowanie przepływem programu w zależności od wartości dyskretnej zmiennej sterującej.
:local status "aktywny"

# Symulacja switch-case za pomocą elseif
:if ($status = "aktywny") do={
    :put "Status: System działa poprawnie"
} else if ($status = "ostrzeżenie") do={
    :put "Status: Uwaga - możliwe problemy"
} else if ($status = "błąd") do={
    :put "Status: Krytyczny błąd systemu"
} else={
    :put "Status: Nieznany"
}

# Przykład z akcjami
:local akcja "restart"

:if ($akcja = "start") do={
    :log info "Uruchamiam usluge"
} else if ($akcja = "stop") do={
    :log info "Zatrzymuje usluge"
} else if ($akcja = "restart") do={
    :log info "Restartuje usluge"
} else={
    :log warning ("Nieznana akcja: " . $akcja)
}
39/55
Projekt: automatyczny backup konfiguracji
Slajd prezentuje implementację skryptu tworzącego binarny backup oraz tekstowy eksport konfiguracji i wysyłającego je pocztą e-mail.

Kompleksowy skrypt archiwizacji ze stemplem czasu i wysyłką e-mail

  • Podwójna kopia bezpieczeństwa: jednoczesne tworzenie binarnego pliku .backup (do pełnego odzyskania) oraz skryptu .rsc (do analizy tekstu).
  • Unikalny stempel czasu: wygenerowanie nazwy pliku zawierającej tożsamość routera, bieżący rok, miesiąc oraz dzień.
  • Wysyłka pocztą (/tool e-mail): zautomatyzowane wysłanie archiwum jako załącznika na adres e-mail administratora przez serwer SMTP.
  • Automatyczne czyszczenie: usunięcie plików tymczasowych z pamięci flash routera bezpośrednio po zakończeniu transmisji pocztowej.
Narzędzie pocztowe (/tool e-mail): wbudowany w RouterOS klient poczty elektronicznej SMTP/TLS umożliwiający wysyłanie powiadomień alarmowych, raportów stanu oraz plików kopii zapasowej na zewnętrzne skrzynki pocztowe.
# ==============================================
# Skrypt: backup-konfiguracji
# Automatyczny backup konfiguracji routera
# Uruchamiaj codziennie przez scheduler
# ==============================================

# --- Konfiguracja ---
:local przechowujOstatnie 7    # ile ostatnich backupów trzymać
# --------------------

:local routerName [/system identity get name]
:local dateStr [/system clock get date]

# Formatuj datę do postaci RRRR-MM-DD
:local formattedDate ([:pick $dateStr 7 11] . "-" . [:pick $dateStr 0 3] . "-" . [:pick $dateStr 4 6])

:local backupFileName ($routerName . "-" . $formattedDate)

:log info ("Rozpoczynam tworzenie backupu: " . $backupFileName)

# Twórz backup binarny
/system backup save name=$backupFileName
:log info "Backup binarny (.backup) utworzony"

# Twórz backup tekstowy
/export file=$backupFileName
:log info "Backup tekstowy (.rsc) utworzony"

# Opcjonalnie: wyślij e-mailem
# /tool e-mail send to="admin@firma.pl" subject=("Backup " . $routerName . " z " . $dateStr) file=($backupFileName . ".backup")

:log info "Tworzenie backupu zakończone pomyślnie"
40/55
Projekt: aktualizacja Dynamic DNS (DDNS)
Slajd omawia skrypt cyklicznej weryfikacji publicznego adresu IP na interfejsie WAN i aktualizacji rekordu DNS u zewnętrznego dostawcy.

Automatyczna synchronizacja publicznego adresu IP WAN

  • Wykrywanie zmian adresu WAN: pobranie aktualnego adresu IP z interfejsu WAN lub zewnętrznego serwisu HTTP (np. checkip).
  • Porównanie z poprzednim adresem: użycie zmiennej globalnej do zapamiętania poprzedniego adresu IP w celu ograniczenia zapytań do API.
  • Wysłanie aktualizacji (/tool fetch): wywołanie zapytania HTTP GET do serwera DDNS (np. Cloudflare, No-IP, DynDNS) z nowym adresem.
  • Natywna usługa Cloud (/ip cloud): omówienie wbudowanej w RouterOS bezpłatnej alternatywy DDNS udostępnianej przez MikroTik.
Dynamiczny DNS (DDNS): technologia sieciowa automatycznie aktualizująca wpisy w bazie serwerów nazw domenowych (DNS) w czasie rzeczywistym w przypadku zmiany dynamicznie przydzielanego adresu IP przez dostawcę internetowego (ISP).
# ==============================================
# Skrypt: aktualizacja-ddns
# Sprawdza i aktualizuje adres IP w usłudze DDNS
# ==============================================

# --- Konfiguracja (dostosuj do swojego dostawcy DDNS) ---
:local ddnsHost "twoja-domena.pl"
:local ddnsUser "twój użytkownik"
:local ddnsPass "twoje haslo"
:local ddnsInterface "pppoe-out1"
# UWAGA: Zmień URL aktualizacji zgodnie z dokumentacją dostawcy DDNS
:local updateUrl "https://twoj-ddns.pl/nic/update?hostname=HOST&myip=IP"
# -------------------------------------------------------------

:global lastKnownIp

# Pobierz aktualny adres IP z interfejsu WAN
:local currentIp [/ip address get [find interface=$ddnsInterface] address]

# Usuń maskę sieci (np. 192.168.1.100/24 -> 192.168.1.100)
:set currentIp [:pick $currentIp 0 [:find $currentIp "/"]]

# Sprawdź, czy adres się zmienił
:if ($currentIp != $lastKnownIp) do={
    :log info ("DDNS: Wykryto nowy adres IP: " . $currentIp)
    
    # Zbuduj URL aktualizacji
    :local url [:replace $updateUrl "HOST" $ddnsHost]
    :set url [:replace $url "IP" $currentIp]
    
    # Wyślij żądanie aktualizacji
    /tool fetch url=$url keep-result=no mode=https
    
    # Zapamiętaj nowy adres
    :set lastKnownIp $currentIp
    :log info "DDNS: Adres IP zaktualizowany"
} else={
    :log info ("DDNS: Adres IP bez zmian (" . $currentIp . ")")
}
41/55
Projekt: ochrona przed atakami SSH (Brute-Force)
Slajd przedstawia zaawansowany skrypt i reguły firewall implementujące wieloetapowe wykrywanie i automatyczne blokowanie ataków na port SSH.

Dynamiczne czarne listy adresów w zaporze ogniowej

  • Zasada list adresowych (address-list): wykorzystanie dynamicznych list adresów w /ip firewall address-list do kwarantanny atakujących.
  • Wieloetapowe etykietowanie: rejestrowanie nieudanych prób logowania w etapowych listach (ssh_stage1, ssh_stage2, ssh_stage3).
  • Blokada permanentna: przeniesienie adresu IP po 3 nieudanych próbach do czarnej listy ssh_blacklist na okres 7 dni.
  • Automatyczne czyszczenie: skrypt okresowo sprawdzający i raportujący statystyki zablokowanych adresów IP.
Ochrona przed atakami siłowymi (Brute-Force Protection): mechanizm zapory ogniowej RouterOS polegający na dynamicznym śledzeniu częstotliwości prób nawiązywania połączeń na chronione porty i automatycznym blokowaniu złośliwych adresów IP na poziomie reguł filtra drop.
# ==============================================
# Skrypt: blokuj-atakujacych-ssh
# Automatycznie blokuje adresy IP atakujące SSH
# ==============================================

# Znajdz wpisy w logach dotyczacych nieudanych logowan SSH
:local failedLogins [/log find message~"login failure.*via ssh"]

:if ([:len $failedLogins] > 0) do={
    :foreach logEntry in=$failedLogins do={
        :local logLine [/log get $logEntry message]
        
        # Wyciągnij adres IP z logu (format: "login failure for user admin from 1.2.3.4 via ssh")
        :local ipStart ([:find $logLine "from "] + 5)
        :local viaPos [:find $logLine " via"]
        :local remoteIp [:pick $logLine $ipStart $viaPos]
        
        # Sprawdź, czy adres nie jest już na czarnej liście
        :local jestNaLiscie [/ip firewall address-list find list="ssh-blacklist" address=$remoteIp]
        
        :if ([:len $jestNaLiscie] = 0) do={
            :log warning ("Blokuje adres IP atakujacego SSH: " . $remoteIp)
            
            # Dodaj do czarnej listy na 1 dzień (timeout=1d)
            /ip firewall address-list add list="ssh-blacklist" address=$remoteIp \
                comment="Auto-block SSH brute-force" timeout=1d
        }
    }
}

:log info "Sprawdzanie atakow SSH zakonczone"
42/55
Automatyczne reagowanie z Netwatch
Slajd omawia narzędzie /tool netwatch, cykliczne wysyłanie pakietów ping oraz wykonywanie skryptów przy zmianie stanu łącza.

Monitoring hostów ICMP i zdarzenia Up / Down

  • Moduł /tool netwatch: niezależna usługa systemowa monitorująca dostępność wskazanego adresu IP za pomocą protokołu ICMP (ping).
  • Zdarzenie Up (łącze aktywne): skrypt zdefiniowany w sekcji up-script wykonuje się automatycznie w momencie przywrócenia komunikacji.
  • Zdarzenie Down (awaria łącza): skrypt w sekcji down-script wykonuje się natychmiast po wykryciu utraty odpowiedzi ping od monitorowanego celu.
  • Szybki czas reakcji: idealne narzędzie do natychmiastowego przełączania zapasowych tras routingu lub restartu interfejsów LTE.
Narzędzie Netwatch (/tool netwatch): wbudowany w RouterOS mechanizm badania osiągalności hostów sieciowych w oparciu o zapytania echo-request protokołu ICMP, wyzwalający dedykowane procedury skryptowe przy zmianie statusu logicznego.
# ==============================================
# Skrypt: netwatch-alerter
# Uruchamiany przez Netwatch przy zmianie stanu hosta
# ==============================================

:global host      # automatycznie ustawiane przez Netwatch
:global status    # automatycznie ustawiane przez Netwatch ("up" lub "down")

:local message

:if ($status = "down") do={
    :set message ("ALARM: Host " . $host . " nie odpowiada!")
    :log error $message
    
    # Możesz dodać dodatkowe akcje:
    # - Wysłanie e-maila
    # - Przełączenie na zapasowe łącze
    # - Odtworzenie alarmu
    
} else={
    :set message ("OK: Host " . $host . " jest ponownie dostępny")
    :log info $message
    
    # Akcja przy powrocie do normy
}

# --- Przykładowa konfiguracja Netwatch ---
# /tool netwatch add host=8.8.8.8 interval=10s on-down-script=netwatch-alerter on-up-script=netwatch-alerter
# Skrypt "netwatch-alerter" musi być najpierw zapisany w /system script
43/55
Dobre praktyki pisania skryptów w RouterOS
Slajd przedstawia reguły tworzenia bezpiecznych skryptów: formatowanie, minimalizacja obciążenia procesora i unikanie pętli bez opóźnień.

Zasady czytelności, wydajności i bezpieczeństwa kodu

  • Zawsze używaj :local: deklaruj zmienne lokalnie, aby zapobiec niekontrolowanemu nadpisywaniu zmiennych w innych procesach.
  • Niezbędne opóźnienia (:delay): wstawiaj :delay 1s w długich pętlach i po operacjach I/O, aby dać procesorowi czas na obsługę ruchu sieciowego.
  • Ochrona blokiem on-error: zabezpieczaj operacje dyskowe i sieciowe przed niespodziewanym zrzuceniem skryptu.
  • Ograniczanie operacji zapisu: unikaj częstego zapisywania danych do plików w pamięci flash, aby zapobiec fizycznemu zużyciu kości NAND.
Higiena skryptowa w RouterOS: zbiór dobrych praktyk minimalizujących narzut na procesor routera, eliminujących wycieki pamięci oraz chroniących pamięć trwałą przed nadmierną degradacją komórek flash.
# ==============================================
# Skrypt: sprawdz-pamięć
# Sprawdza wykorzystanie pamieci RAM
# ==============================================

# --- Konfiguracja ---
:local progOstrzezenia 80    # % pamięci, gdy ostrzegamy
# --------------------

# Pobierz dane o pamięci
:local totalRam [/system resource get total-memory]
:local freeRam [/system resource get free-memory]

# Oblicz procent wykorzystania
:local usedRam ($totalRam - $freeRam)
:local percentUsed (($usedRam * 100) / $totalRam)

# Sprawdź i zaloguj
:if ($percentUsed > $progOstrzezenia) do={
    :log warning ("UWAGA: Pamięć RAM na " . $percentUsed . "%! Może brakować RAM.")
    :put ("Ostrzeżenie: Pamięć na " . $percentUsed . "%")
} else={
    :log info ("Pamięć RAM na " . $percentUsed . "% - stan OK")
    :put ("RAM: " . $percentUsed . "%")
}
44/55
Typowe błędy i metody ich unikania
Slajd omawia najczęstsze usterki w skryptach RouterOS: brak dwukropka, mylenie zmiennych, dzielenie przez zero i brak uprawnień.

Analiza najczęstszych problemów początkujących

  • Brak dwukropka przed komendą: wpisanie local zamiast :local lub put zamiast :put generuje natychmiastowy błąd składni.
  • Literówki w nazwach zmiennych: zmienne są wrażliwe na wielkość liter; odwołanie do $MojaZmienna przy deklaracji $mojazmienna zwróci nothing.
  • Brak uprawnień w schedulerze: skrypt wymaga uprawnienia sensitive, a zadanie harmonogramu ma tylko read i write.
  • Zablokowanie wątku: pętla :while bez instrukcji :delay prowadzi do natychmiastowego wzrostu obciążenia procesora do 100%.
Błąd składniowy (syntax error): stan przerwania parsowania kodu przez interpreter RouterOS wywołany naruszeniem gramatyki języka (brakujący dwukropek, niedomknięty nawias klamrowy lub niepoprawny parametr polecenia).
# --- Poprawne i bledne przyklady ---

# BŁĄD: Zapomniane $
:local x 10
:put "x"           # Wyświetli: x (tekst!)
:put $x            # Wyświetli: 10 (wartość)

# POPRAWNIE: Nawiasy w wyrażeniach
:put "Wynik: " . $x           # Działa
:put ("Wynik: " . ($x + 5))   # Działa

# POPRAWNIE: Sprawdzenie czy coś znaleziono
:local id [/interface find name="nieistnieje"]
:if ([:len $id] > 0) do={
    # Coś znaleziono
} else={
    :log info "Nie znaleziono interfejsu"
}

# POPRAWNIE: Porównanie
:if ($x = 10) do={}   # POPRAWNE
:if ($x == 10) do={}  # BŁĄD - nie używaj ==
45/55
Debugowanie skryptów w RouterOS
Slajd przedstawia metody diagnozowania problemów: wypisywanie kontrolne :put, inspekcja zmiennych w /environment oraz logowanie diagnostyczne.

Techniki inspekcji zmiennych i śledzenia wykonania

  • Wypisywanie krokowe (:put): wstawianie poleceń :put ["DEBUG: krok 1, wartosc=" . $zmienna] w newralgicznych punktach algorytmu.
  • Inspekcja w środowisku WinBox: podgląd wartości zmiennych globalnych w menu System -> Environment w czasie rzeczywistym.
  • Logowanie z tematem debug: użycie :log debug $komunikat do rejestracji szczegółowych stanów bez zaśmiecania głównego logu info.
  • Uruchamianie z poziomu konsoli: manualne wywołanie /system script run nazwa_skryptu pozwala natychmiast dostrzec błędy parsera.
Debugowanie skryptu RouterOS: systematyczny proces weryfikacji poprawności logicznej i składniowej kodu za pomocą komunikatów diagnostycznych i podglądu stanu środowiska wykonawczego w konsoli lub aplikacji WinBox.
# ==============================================
# Techniki debugowania
# ==============================================

# 1. Wyświetl wartość zmiennej
:local mojaWartosc 42
:put ("DEBUG: mojaWartosc = " . $mojaWartosc)

# 2. Zapisz informację w logu
:log info ("DEBUG: Dotarłem do tego miejsca, zmienna = " . $mojaWartosc)

# 3. Sprawdź typ zmiennej
:put ("DEBUG: Typ zmiennej = " . [:typeof $mojaWartosc])

# 4. Komentowanie fragmentów kodu
# Zakomentuj całą sekcję, dodając # przed każdą linię:
# :local staraWartosc 100
# :set mojaWartosc $staraWartosc
# :log info "To jest wyłączone"

# 5. Sprawdzenie warunku krok po kroku
:local x 5
:put ("x = " . $x)
:if ($x > 0) do={
    :put "x jest większe od 0"
    :if ($x > 3) do={
        :put "x jest większe od 3"
    }
}
46/55
Projekt: czyszczenie starych logów i plików
Slajd prezentuje implementację skryptu monitorującego przestrzeń dyskową, usuwającego stare pliki kopii i czyszczącego bufory pamięci.

Automatyczna konserwacja zasobów dyskowych

  • Cel skryptu: ochrona routera przed przepełnieniem pamięci flash przez nagromadzone pliki eksportów i archiwów.
  • Pobranie wolnej pamięci (/system resource): weryfikacja czy właściwość free-hdd-space spadła poniżej bezpiecznego progu (np. 10 MB).
  • Selektywne usuwanie starych plików: wyszukanie i usunięcie plików .backup starszych niż zadana liczba dni.
  • Raportowanie w logu: zapisanie informacji o odzyskanej przestrzeni dyskowej w dzienniku zdarzeń routera.
Konserwacja zasobów dyskowych: zautomatyzowana procedura administracyjna zapobiegająca awariom routera wywołanym wyczerpaniem wolnej przestrzeni w pamięci masowej NAND/eMMC urządzenia.
# ==============================================
# Skrypt: czysczenie-logow
# Usuwa stare logi systemowe
# ==============================================

# --- Konfiguracja ---
:local ileDniTrzymac 7    # ile dni logów zachować
# --------------------

:log info "Rozpoczynam czyszczenie starych logow"

# Policz logi przed
:local logiPrzed [/log print count-only]
:put ("Logów przed czyszczeniem: " . $logiPrzed)

# Znajdź stare logi (starsze niż X dni)
# RouterOS nie ma prostej funkcji "logi starsze niż", 
# ale możemy usunąć logi powyżej określonej liczby:
:local maxLogow 1000    # maksymalna liczba logów do zachowania

:local aktualnaLiczbaLogow [/log print count-only]

:if ($aktualnaLiczbaLogow > $maxLogow) do={
    :local doUsuniecia ($aktualnaLiczbaLogow - $maxLogow)
    :log info ("Usuwam " . $doUsuniecia . " najstarszych logów")
    
    # Pobierz najstarsze logi i usuń je
    :local stareLogi [:pick [/log print as-value] 0 $doUsuniecia]
    :foreach log in=$stareLogi do={
        /log remove [find .id=$log]
    }
} else={
    :log info "Nie ma logów do usunięcia"
}

# Policz logi po
:local logiPo [/log print count-only]
:put ("Logów po czyszczeniu: " . $logiPo)
:log info ("Czyszczenie logów zakończone. Usunięto: " . ($logiPrzed - $logiPo))
47/55
Projekt: failover - automatyczne przełączanie łączy
Slajd omawia implementację zaawansowanego skryptu nadzorującego stan łącza podstawowego WAN1 i przełączającego ruch na zapasowe łącze WAN2.

Niezawodność dostępu do Internetu z dwoma dostawcami WAN

  • Architektura z dwoma łączami WAN: konfiguracja routera z łączem głównym (np. światłowód) i zapasowym (np. modem LTE).
  • Weryfikacja dostępności trasy: cykliczne badanie osiągalności zewnętrznych serwerów DNS (np. 8.8.8.8, 1.1.1.1) przez konkretną bramę.
  • Przełączanie dystansów routingu: modyfikacja parametru distance w /ip route poleceniem :set w momencie stwierdzenia awarii.
  • Automatyczny powrót (Failback): przywrócenie priorytetu łącza głównego natychmiast po wznowieniu stabilnej transmisji pakietów.
Przełączanie awaryjne (Failover): mechanizm zapewniania wysokiej dostępności (High Availability) polegający na automatycznym przekierowaniu ruchu teleinformatycznego na zapasowe łącze telekomunikacyjne w razie awarii łącza podstawowego.
# ==============================================
# Skrypt: sprawdz-failover
# Sprawdza główne łącze i przełącza na zapasowe
# ==============================================

# --- Konfiguracja ---
:local glownyHost 8.8.8.8        # host do pingowania (np. DNS Google)
:local interfejsGlowny "pppoe-out1"
:local interfejsZapasowy "ether3"
# --------------------

:global czyZapasoweAktywne

# Sprawdź, czy główne łącze działa
:local pingWynik [/ping $glownyHost count=3 interface=$interfejsGlowny]

:if ($pingWynik > 0) do={
    # Główne łącze działa
    :if ($czyZapasoweAktywne = true) do={
        :log info "Główne łącze działa, powracam z zapasowego"
        # Wyłącz zapasowe łącze
        /interface disable $interfejsZapasowy
        :set czyZapasoweAktywne false
    }
} else={
    # Główne łącze nie działa
    :if ($czyZapasoweAktywne = false) do={
        :log warning ("Główne łącze nie działa! Przełączam na zapasowe!")
        # Włącz zapasowe łącze
        /interface enable $interfejsZapasowy
        :set czyZapasoweAktywne true
    } else={
        :log warning "Główne łącze nadal nie działa, zapasowe już aktywne"
    }
}
48/55
Środowisko skryptów i zmienne systemowe
Slajd przedstawia zmienne systemowe i parametry kontekstu wykonania dostępne w interpreterze RouterOS.

Wbudowane właściwości i metadane wykonania

  • Zmienna tożsamości routera: dostęp do nazwy hosta i unikalnego identyfikatora urządzenia w skryptach.
  • Parametry czasu i daty: wbudowane właściwości zwracające aktualny czas zegara systemowego zsynchronizowanego przez NTP.
  • Zarządzanie sesjami użytkowników: inspekcja aktywnych połączeń administratorskich w menu /user active.
  • Bezpieczeństwo poświadczeń: przechowywanie haseł i kluczy API w chronionych zmiennych z uprawnieniem sensitive.
Kontekst wykonawczy skryptu: zbiór parametrów środowiskowych, poziomu uprawnień oraz powiązań systemowych, w ramach których wykonywany jest konkretny wątek interpretera RouterOS.
# --- Przeglądanie zmiennych środowiska ---

# Wyświetl środowisko skryptów
:put "Zmienne globalne w środowisku:"
/system script environment print

# --- Definiowanie zmiennych konfiguracyjnych ---
# Zamiast wpisywać wartości bezpośrednio w kodzie,
# możesz użyć zmiennych globalnych jako "konfiguracji"

:global cfgInterwal 5m
:global cfgEmailAdmin "admin@firma.pl"
:global cfgDebugMode true

# W kodzie używasz zmiennych:
:if ($cfgDebugMode = true) do={
    :put ("Debug: Interwał = " . $cfgInterwal)
}

# --- Aktualizacja konfiguracji bez edycji skryptu ---
# Możesz zmienić wartość zmiennej globalnej bez edycji skryptu:
# /system script environment set cfgDebugMode false
49/55
Podsumowanie wykładu
Slajd podsumowuje materiał dydaktyczny kursu skryptowania w RouterOS, akcentując najważniejsze wzorce i techniki programistyczne.

Rekapitulacja kluczowych umiejętności skryptowania

  • Opanowane struktury: znajomość poleceń :local, :global, instrukcji warunkowych :if oraz pętli :for i :foreach.
  • Zarządzanie konfiguracją: umiejętność bezpiecznego stosowania poleceń find, get, set, add oraz remove w drzewie systemu.
  • Praktyczna automatyzacja: wdrożenie skryptów automatycznego backupu, Dynamic DNS, ochrony firewall i monitoringu Netwatch.
  • Odporność na awarie: stosowanie bloku :do on-error oraz dbałość o nieprzeciążanie procesora routera poleceniem :delay.
Inżynieria automatyzacji RouterOS: dyscyplina projektowania odpornych, zoptymalizowanych skryptów zarządzających infrastrukturą sieciową MikroTik w oparciu o najlepsze praktyki branżowe i minimalizację ryzyka przestojów.
  +-------------------------------------------------------+
  |                PODSUMOWANIE KURSU SKRYPTOWANIA        |
  +-------------------------------------------------------+
  | 1. Składnia: dwukropek dla poleceń, ukośnik dla menu  |
  | 2. Zmienne:  :local w blokach, :global w systemie     |
  | 3. Przepływ: :if, :for, :foreach in=[... find]        |
  | 4. Ochrona:  :do { ... } on-error={ ... }             |
  | 5. Automacja:Scheduler, Netwatch, automatyczny backup |
  +-------------------------------------------------------+
        
50/55
Gdzie szukać pomocy i dalsza nauka
Slajd wskazuje autoryzowane źródła wiedzy technicznej, oficjalną dokumentację MikroTik Help oraz społeczność użytkowników.

Dokumentacja oficjalna, fora i literatura techniczna

  • Oficjalna dokumentacja MikroTik: nowoczesna platforma pomocy technicznej pod adresem https://help.mikrotik.com/docs/.
  • Społeczność forum MikroTik: ogólnoświatowe forum inżynierów sieciowych dzielących się gotowymi rozwiązaniami skryptowymi.
  • Baza wiedzy MikroTik Wiki: historyczne, lecz wciąż cenne kompendium wiedzy o architekturze RouterOS v6.
  • Certyfikacja techniczna: ścieżki certyfikacji producenta: MTCNA, MTCRE, MTCSE potwierdzające kompetencje sieciowe.
Platforma MikroTik Help: oficjalna baza dokumentacji technicznej i podręczników tworzona przez inżynierów firmy MikroTik, zawierająca kompletną specyfikację składni języka skryptowego RouterOS.
  +-------------------------------------------------------+
  |               ŹRÓDŁA WIEDZY I DOKUMENTACJA            |
  +-------------------------------------------------------+
  | Oficjalna pomoc: https://help.mikrotik.com/docs/      |
  | Forum MikroTik:  https://forum.mikrotik.com/          |
  | MikroTik Wiki:   https://wiki.mikrotik.com/           |
  | Stowarzyszenia:  Polskie Towarzystwo Informatyczne    |
  +-------------------------------------------------------+
        
51/55
Dodatek: przydatne polecenia skryptowe
Slajd prezentuje podręczną ściągawkę najważniejszych wbudowanych komend skryptowych RouterOS i ich zastosowanie.

Zestawienie komend narzędziowych interpretera

  • Polecenia wyświetlania: :put (wypisanie tekstu w terminalu), :log (zapisanie zdarzenia do dziennika systemowego).
  • Polecenia zarządzania zmiennymi: :local (deklaracja lokalna), :global (deklaracja globalna), :set (przypisanie wartości).
  • Polecenia konwersji typów: :tostr (konwersja na ciąg tekstowy), :tonum (konwersja na liczbę całkowitą).
  • Polecenia sterujące czasem: :delay (wstrzymanie wykonania na zadany czas), :time (pomiar czasu trwania operacji).
Zestawienie komend skryptowych: kanoniczna grupa poleceń wbudowanych w interpreter RouterOS, stanowiąca elementarz każdego administratora automatyzującego urządzenia MikroTik.
  +-------------------------------------------------------+
  |             ŚCIĄGAWKA POLECEŃ SKRYPTOWYCH             |
  +-------------------------------------------------------+
  | :put         | Wyświetlenie tekstu w konsoli          |
  | :log info    | Zapis zdarzenia do logu systemowego    |
  | :set         | Modyfikacja wartości zmiennej          |
  | :len         | Sprawdzenie długości tekstu lub tablicy|
  | :tostr/:tonum| Konwersja typów danych                 |
  +-------------------------------------------------------+
        
52/55
Dodatek: operacje na tablicach: podsumowanie
Slajd rekapituluje metody tworzenia, łączenia, modyfikowania i indeksowania tablic danych w języku RouterOS.

Skrócone zestawienie metod pracy z kolekcjami

  • Deklaracja i inicjalizacja: zapis w nawiasach okrągłych z elementami rozdzielanymi przecinkami: (element1, element2).
  • Dostęp do elementów: składnia operatora strzałki ($tablica->indeks), gdzie indeksowanie rozpoczyna się od zera.
  • Łączenie i rozszerzanie: operator przecinka ($tablica , nowyElement) tworzący nową powiększoną tablicę.
  • Iteracja po tablicy: zastosowanie konstrukcji :foreach x in=$tablica do={ ... } do przetwarzania każdego elementu.
Kolekcja danych (array operations): zbiór technik algorytmicznych pozwalających na przechowywanie i przetwarzanie uporządkowanych struktur informacji w pamięci interpretera RouterOS.
# --- Tworzenie i operacje na tablicach ---

# Tablica liczb
:local liczby {10, 20, 30, 40, 50}

# Pobierz elementy
:put ("Pierwszy: " . [:pick $liczby 0])     # 10
:put ("Ostatni: " . [:pick $liczby ([:len $liczby] - 1)])  # 50

# Modyfikuj element
:set ($liczby->2) 35
:put ("Trzeci po modyfikacji: " . [:pick $liczby 2])  # 35

# Dodaj nowy element
:set ($liczby->5) 60

# Iteruj przez wszystkie
:foreach liczba in=$liczby do={
    :put ("Element: " . $liczba)
}

# Filtrowanie tablicy (symulacja)
:local parzyste {}
:foreach liczba in=$liczby do={
    :if (($liczba % 2) = 0) do={
        :set ($parzyste->[:len $parzyste]) $liczba
    }
}
:put ("Parzyste: " . $parzyste)
53/55
Dodatek: sposoby uruchamiania skryptów
Slajd omawia metody uruchamiania skryptów: z wiersza poleceń, przez scheduler, z poziomu WinBoksa oraz zdalnie przez SSH i API.

Cztery metody egzekucji kodu w RouterOS

  • Uruchomienie manualne w konsoli: komenda /system script run nazwa_skryptu uruchamiająca procedurę w bieżącej sesji.
  • Uruchomienie przez Scheduler: cykliczne wywołanie w tle bez udziału operatora z uprawnieniami zadania harmonogramu.
  • Uruchomienie z aplikacji WinBox: kliknięcie przycisku Run Script w oknie edycji skryptu w graficznym interfejsie.
  • Zdalne wywołanie przez SSH / API: przekazanie polecenia w sesji SSH bez konieczności logowania interaktywnego.
Egzekucja skryptu (script execution): proces załadowania kodu z pamięci masowej lub strumienia wejściowego, jego kompilacji leksykalnej oraz wykonania instrukcji w dedykowanym wątku interpretera RouterOS.
# --- Przykładowe konfiguracje scheduler ---

# Codziennie o północy
/system scheduler add name=daily-backup interval=1d \
    on-event=backup policy=read,write,test start-time=00:00:00

# Co godzinę
/system scheduler add name=hourly-check interval=1h \
    on-event=sprawdz-interfejsy policy=read,write

# Co 5 minut
/system scheduler add name=frequent interval=5m \
    on-event=monitoring policy=read

# Jednorazowo, za 10 minut
/system scheduler add name=once interval=10m \
    on-event=jednorazowy-skrypt policy=read,write

# Przy starcie routera
/system scheduler add name=on-boot interval=0 \
    on-event=konfiguracja-początkowa policy=read,write,reboot \
    start-time=startup
54/55
Dodatek: przykładowy harmonogram zadań
Slajd prezentuje wzorcowy harmonogram zadań administracyjnych dla produkcyjnego routera brzegowego w małym i średnim przedsiębiorstwie.

Kompletny plan cyklicznych zadań produkcyjnych

  • Zadanie nocnego backupu: codzienne generowanie i wysyłanie kopii zapasowej o godzinie 01:00 w nocy przy minimalnym ruchu.
  • Zadanie Dynamic DNS: sprawdzanie i ewentualna aktualizacja adresu IP na interfejsie WAN co 15 minut.
  • Zadanie monitoringu Failover: badanie dostępności bramy domyślnej co 30 sekund z natychmiastową reakcją przełączenia.
  • Zadanie czyszczenia list zapory: okresowe usuwanie wygasłych wpisów kwarantanny z czarnych list co 1 godzinę.
Plan utrzymania routera (maintenance schedule): zestaw skoordynowanych procedur automatyzacyjnych zapewniających ciągłość działania, bezpieczeństwo oraz aktualność stanu bazy konfiguracyjnej urządzenia sieciowego.
  +-------------------------------------------------------+
  |             PRZYKŁADOWY HARMONOGRAM PRODUKCYJNY       |
  +-------------------------------------------------------+
  | 01:00 codziennie | Backup konfiguracji i wysyłka mail |
  | co 15 minut      | Aktualizacja adresu Dynamic DNS    |
  | co 5 minut       | Weryfikacja łącza WAN (Failover)   |
  | co 1 godzinę     | Czyszczenie wygasłych wpisów list  |
  +-------------------------------------------------------+
        
55/55
Dodatek: słownik pojęć
Slajd podsumowuje kluczowe pojęcia związane z architekturą i skryptowaniem w środowisku MikroTik RouterOS.

Podsumowanie terminologii MikroTik RouterOS

  • RouterBOARD i RouterOS: RouterBOARD jako dedykowana platforma sprzętowa; RouterOS jako sieciowy system operacyjny.
  • WinBox i WebFig: aplikacja okienkowa oraz interfejs przeglądarkowy służące do wygodnego administrowania routerem.
  • Netwatch i Scheduler: narzędzia monitoringu osiągalności hostów ICMP oraz harmonogramowania zadań skryptowych.
  • HW Offload: sprzętowa akceleracja przełączania pakietów bezpośrednio na układzie scalonym switch chipa bez udziału CPU.
Sprzętowa akceleracja (HW Offload): zaawansowana funkcja architektury RouterOS przekazująca przetwarzanie ramek Ethernet bezpośrednio do dedykowanego procesora przełączającego (Switch Chip), co odciąża główny procesor CPU urządzenia.
  +-------------------------------------------------------+
  |                 SŁOWNIK POJĘĆ ROUTEROS                |
  +-------------------------------------------------------+
  | RouterBOARD: platforma sprzętowa MikroTik             |
  | WinBox:      natywna aplikacja graficzna zarządzania  |
  | Netwatch:    narzędzie monitoringu hostów przez ICMP  |
  | Scheduler:   wbudowany harmonogram zadań cyklicznych  |
  | HW Offload:  sprzętowe przełączanie pakietów na chipie|
  +-------------------------------------------------------+