Mikrotik : Praktikum Script Terjadwal dan Diagnosa Kegagalan

Revision as of 16:01, 19 October 2026 by Maintenance script (talk | contribs) (Protected "Mikrotik : Praktikum Script Terjadwal dan Diagnosa Kegagalan": Proteksi editorial: edit/move sysop ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite)))
(diff) ← Older revision | Latest revision (diff) | Newer revision β†’ (diff)

Script yang berhasil dijalankan belum tentu script yang benar. Di lab ini kita membangun satu script pemantau sederhana, menjadwalkannya, lalu sengaja merusaknya dengan enam skenario kegagalan yang paling sering terjadi di lapangan.

Tujuannya bukan menghafal perintah, tetapi bisa menjawab satu pertanyaan: kalau script ini gagal malam ini, dari mana saya tahu dan apa buktinya?

🎯 Tujuan

Setelah menyelesaikan praktikum ini, kamu mampu:

  • Membedakan script yang **sekadar jalan** dengan script yang **terbukti berhasil**.
  • Membaca empat lapis pemeriksaan: sintaks, scope variabel, policy, dan lingkungan eksekusi.
  • Membuat script pemantau pool DHCP yang menulis bukti ke log.
  • Menjadwalkan script dan memverifikasi lewat `run-count`, `last-started`, dan `/system script job`.
  • Melakukan enam uji kerusakan terkontrol dan memetakan gejala ke penyebabnya.
  • Menulis script yang aman dijalankan berulang (idempoten) dan tidak menumpuk instance.

πŸ“ Konteks nyata

Bayangkan SOP tertulis di bengkel. Kertasnya rapi, ditempel di dinding, dan semua orang tahu ada SOP. Tapi SOP itu tidak pernah diuji saat mesin masih normal. Baru saat mesin rusak, ketahuan langkahnya salah urutan.

Script RouterOS bekerja sama. Karena dijalankan mesin, ia bisa tampak "sukses" hanya karena tidak ada yang membacanya. Tidak ada yang berteriak, tidak ada yang menanyakan hasil.

πŸ”₯ Kasus nyata: Sebuah SMK memasang script backup konfigurasi tiap pukul 23:00 ke flashdisk USB yang ditancapkan di router. Selama tiga minggu guru jaringan yakin aman karena `run-count` terus naik. Saat router benar-benar rusak dan perlu di-restore, file backup tidak ada: USB sudah lama terlepas, dan script tidak pernah memeriksa apakah file benar-benar terbentuk. Script tetap "jalan" 21 kali, tetapi tidak pernah "berhasil".

🧠 Konsep singkat

Prinsip pertama: **eksekusi bukan bukti keberhasilan**. RouterOS akan menaikkan `run-count` begitu script dipanggil, bahkan jika baris pertama langsung error. Karena itu kita butuh bukti kedua: log, file, atau perubahan konfigurasi yang bisa diperiksa.

πŸ”Ή Empat lapis pemeriksaan

  • **Sintaks** β€” apakah baris bisa diparse. Salah tulis `:local` atau kurung kurawal langsung gagal.
  • **Scope** β€” apakah variabel masih hidup saat dipakai. Setiap baris terminal adalah scope sendiri.
  • **Policy** β€” apakah script punya hak melakukan aksinya. Policy kurang menghasilkan `not enough permissions (9)`.
  • **Lingkungan eksekusi** β€” dijalankan dari CLI, scheduler, Netwatch, atau DHCP lease-script. Output dan waktu jalan berbeda.

πŸ’‘ Tips: Urutkan pemeriksaan dari atas ke bawah. Sebagian besar waktu troubleshooting habis karena orang langsung menuduh policy, padahal masalahnya variabel yang sudah mati.

πŸ”Ή Beda "jalan di CLI" dan "jalan di scheduler"

| Aspek | Dijalankan manual di CLI | Dijalankan scheduler | |---|---|---| | Output `:put` | Terlihat di layar | Hilang, tidak masuk log | | Policy | Policy user yang login | Policy script dan scheduler | | Waktu | Kamu yang menentukan | `start-time` dan `interval` | | Riwayat | Tidak tercatat | `run-count`, `last-started`, log | | Error | Muncul di layar | Hanya jejaknya di log |

πŸ“Š Angka penting: `start-time=startup` berarti script dijalankan **3 detik setelah sistem menyala**. Jika `interval` bukan `0s`, scheduler tidak menjalankan script saat startup.

πŸ”Ή Menangani error tanpa menghentikan seluruh script

Secara default, satu error runtime menghentikan sisa baris script. Untuk menangkapnya, gunakan `:onerror`:

:onerror err in={
    :local gw [/ip route get [find dst-address="0.0.0.0/0"] gateway]
    :log info "gateway=$gw"
} do={
    :log error "gagal baca gateway: $err"
}

Urutan parameter penting: variabel error harus ditulis **sebelum** blok `do=`, kalau tidak blok itu tidak bisa melihat variabelnya.

`:onerror` mengembalikan `false` bila tidak ada error dan `true` bila ada error, sehingga bisa dipakai langsung di `:if`. Untuk gangguan sementara seperti DNS atau koneksi, ada `:retry` dengan `delay` dan `max`.

πŸ”Ή Mencegah script menumpuk

Script yang berjalan lama bisa dipanggil lagi sebelum yang lama selesai. Hasilnya dua instance berebut data yang sama. Pola pengamannya memakai `:jobname`:

:if ([/system script job print count-only where script=[:jobname]] > 1) do={
    :error "instance lain masih berjalan"
}

Angka pembandingnya `> 1` karena instance yang sedang berjalan juga terhitung di daftar job.

🧩 Istilah penting

| Istilah | Arti sederhana | |---|---| | Scope | Wilayah hidup sebuah variabel. Di luar kurung kurawal, variabel lokal mati. | | Environment | Daftar variabel global yang tersimpan, dilihat dengan `/system script environment print`. | | Policy | Daftar izin script: `read`, `write`, `test`, `reboot`, dan lain-lain. | | Trigger | Pemicu script: scheduler, Netwatch, DHCP lease-script, atau manual. | | `run-count` | Penghitung berapa kali script dipanggil, bukan berapa kali berhasil. | | `last-started` | Waktu terakhir script mulai dijalankan. | | Job | Instance script yang sedang berjalan, dilihat di `/system script job print`. | | Idempoten | Aman dijalankan berkali-kali tanpa menggandakan efek. | | `:execute` | Menjalankan script di latar belakang, maksimal 64 kB. | | `dont-require-permissions` | Melewati pemeriksaan policy. Berbahaya, hanya untuk lab. |

πŸ”§ Praktik: Script Terjadwal yang Bisa Dipercaya

Lab ini memakai satu router uji. Jangan lakukan uji kerusakan di router produksi.

πŸ”Ή Persiapan lab

  • Router MikroTik (perangkat fisik atau CHR) dengan akses Winbox dan terminal.
  • Satu interface LAN bernama `ether2`.
  • DHCP Server aktif untuk `10.10.10.0/24`, pool `lab-pool` berisi `10.10.10.100-10.10.10.150` (51 alamat).
  • Dua client (laptop atau ponsel) yang sudah pernah meminta lease, supaya angka tidak nol.
  • Catatan: seluruh uji memakai prefix nama `uji-` agar mudah dibersihkan.

πŸ”Ή Langkah 1: kumpulkan bukti awal

Jalankan dan catat hasilnya di lembar kerja:

/ip address print where interface=ether2
/ip pool print where name="lab-pool"
/ip dhcp-server lease print count-only
/system script print
/system scheduler print

πŸ§ͺ Uji cepat: `:put [/ip dhcp-server lease print count-only]` harus mengembalikan angka, bukan pesan error. Kalau error, DHCP Server belum siap dan lab belum bisa dilanjutkan.

πŸ”Ή Langkah 2: tulis script pemantau pool

Script ini membaca jumlah lease, menghitung persentase, lalu menulis ke log. Perhatikan bahwa ambang batas dan kapasitas pool ditulis eksplisit supaya mudah dibaca siswa.

/system script add name=cek-pool policy=read,write,test comment="lab: pantau pool DHCP" source={
    :local kapasitas 51
    :local batas 40
    :local dipakai [/ip dhcp-server lease print count-only]
    :local persen (($dipakai * 100) / $kapasitas)

    :if ($dipakai >= $batas) do={
        :log warning ("cek-pool: " . $dipakai . "/" . $kapasitas . " terpakai (" . $persen . "%) - mendekati penuh")
    } else={
        :log info ("cek-pool: " . $dipakai . "/" . $kapasitas . " terpakai (" . $persen . "%)")
    }
}

πŸ’‘ Tips: Selalu beri prefix nama script di setiap pesan log, misalnya `cek-pool:`. Saat router punya sepuluh script, prefix inilah yang membuat log bisa difilter.

πŸ”Ή Langkah 3: uji manual sebelum dijadwalkan

/system script run cek-pool
/log print where message~"cek-pool"
/system script print detail where name="cek-pool"

Yang harus terlihat: satu baris log baru, `run-count=1`, dan `last-started` terisi waktu sekarang.

⚠️ Hati-hati: Kalau log tidak muncul tetapi `run-count` naik, jangan langsung mengubah script. Cek dulu apakah kamu melihat log yang benar: `/log print` hanya menampilkan buffer terbatas, dan topic log bisa tersaring.

πŸ”Ή Langkah 4: jadwalkan dan buktikan benar-benar jalan

Lihat jam router, lalu buat jadwal satu kali dua menit ke depan:

/system clock print
/system scheduler add name=jadwal-cek-pool on-event=cek-pool start-time=HH:MM:SS interval=0s policy=read,write,test comment="lab: satu kali"

Tunggu sampai waktu terlewati, lalu periksa:

/system scheduler print detail where name="jadwal-cek-pool"
/log print where message~"cek-pool"

Setelah terbukti, ubah menjadi harian:

/system scheduler set [find name="jadwal-cek-pool"] start-time=07:00:00 interval=1d

πŸ“Š Angka penting: `interval=1d` sudah cukup untuk kebutuhan harian. Kombinasi `interval=1d` dengan parameter `days` tidak didukung, jadi jangan mencampurnya.

πŸ”Ή Langkah 5: Uji A - variabel tanpa deklarasi

Sengaja menghilangkan `:local`:

/system script add name=uji-scope policy=read,write,test source={
    :set pesan "tes scope"
    :log info $pesan
}
/system script run uji-scope
/log print where message~"uji-scope"

Hasil yang diharapkan: script berhenti dengan script error, tidak ada log, tetapi `run-count` tetap naik. Inilah bukti pertama bahwa hitungan jalan bukan bukti sukses.

Perbaiki dengan mendeklarasikan variabel:

/system script set [find name="uji-scope"] source={
    :local pesan "tes scope"
    :log info ("uji-scope: " . $pesan)
}

πŸ”Ή Langkah 6: Uji B - policy kurang

Script yang mencoba mengubah konfigurasi tetapi hanya diberi policy `read`:

/system script add name=uji-policy policy=read source={
    /ip firewall address-list add list="uji-policy" address=10.10.10.200 comment="dari script"
}
/system script run uji-policy
/log print where message~"uji-policy"

Gejala yang muncul: `not enough permissions (9)`, dan tidak ada entri address-list. Perbaiki policy lalu jalankan ulang:

/system script set [find name="uji-policy"] policy=read,write,test
/system script run uji-policy
/ip firewall address-list print where list="uji-policy"

⚠️ Hati-hati: Policy ada di dua tempat, yaitu di script dan di scheduler. Script boleh punya policy cukup, tetapi scheduler dengan policy lebih rendah tetap bisa gagal saat memanggilnya.

πŸ”Ή Langkah 7: Uji C - `:put` tidak terlihat di scheduler

/system script add name=uji-put policy=read,write,test source={
    :put "uji-put: pesan ini hanya ke console"
}
/system script run uji-put

Saat dijalankan manual, pesan terlihat. Sekarang jadwalkan satu kali seperti Langkah 4, lalu cari di log. Pesan itu tidak akan pernah muncul.

Perbaikannya bukan menambah policy, tetapi mengganti `:put` dengan `:log`:

/system script set [find name="uji-put"] source={
    :log info "uji-put: sekarang masuk log"
}

πŸ”Ή Langkah 8: Uji D - dua instance berjalan bersamaan

Buat script yang sengaja lambat:

/system script add name=uji-lama policy=read,write,test source={
    :log info "uji-lama: mulai"
    :delay 40s
    :log info "uji-lama: selesai"
}
/system scheduler add name=jadwal-uji-lama on-event=uji-lama start-time=HH:MM:SS interval=15s policy=read,write,test comment="lab: uji tumpuk"

Setelah satu menit, lihat daftar job:

/system script job print

Akan terlihat lebih dari satu instance `uji-lama`. Tambahkan pengaman di awal script:

/system script set [find name="uji-lama"] source={
    :if ([/system script job print count-only where script=[:jobname]] > 1) do={
        :error "uji-lama: instance lain masih berjalan"
    }
    :log info "uji-lama: mulai"
    :delay 40s
    :log info "uji-lama: selesai"
}

πŸ§ͺ Uji cepat: Setelah pengaman dipasang, job list hanya boleh berisi satu `uji-lama`. Kalau masih menumpuk, hapus dulu job lama dengan `/system script job remove [find script="uji-lama"]`.

πŸ”Ή Langkah 9: Uji E - satu error menghentikan sisa script

/system script add name=uji-error policy=read,write,test source={
    :log info "uji-error: baris 1 jalan"
    :local gw [/ip route get [find dst-address="0.0.0.0/0"] gateway]
    :log info ("uji-error: gateway " . $gw)
}
/system script run uji-error
/log print where message~"uji-error"

Jika router tidak punya default route, baris kedua error dan baris ketiga tidak pernah jalan. Log hanya berisi "baris 1 jalan".

Bungkus bagian rawan dengan `:onerror`:

/system script set [find name="uji-error"] source={
    :log info "uji-error: baris 1 jalan"
    :onerror err in={
        :local gw [/ip route get [find dst-address="0.0.0.0/0"] gateway]
        :log info ("uji-error: gateway " . $gw)
    } do={
        :log error ("uji-error: gagal baca gateway - " . $err)
    }
    :log info "uji-error: baris terakhir tetap jalan"
}

Sekarang log memuat pesan error yang jelas dan baris terakhir tetap dieksekusi.

πŸ”Ή Langkah 10: Uji F - script startup sebelum interface siap

/system script add name=uji-startup policy=read,write,test source={
    :local jalan [/interface print count-only where running=yes]
    :local rute [/ip route print count-only where dst-address="0.0.0.0/0" and active=yes]
    :log info ("uji-startup: interface running=" . $jalan . " default-route=" . $rute)
}
/system scheduler add name=jadwal-uji-startup on-event=uji-startup start-time=startup interval=0s policy=read,write,test comment="lab: uji startup"

Reboot router, lalu baca log. Pada detik-detik awal, angka interface atau default route sering masih nol.

Perbaikan: tunggu dengan batas waktu, jangan menunggu tanpa akhir.

/system script set [find name="uji-startup"] source={
    :local n 0
    :local rute 0
    :while (($rute = 0) and ($n < 12)) do={
        :delay 5s
        :set n ($n + 1)
        :set rute [/ip route print count-only where dst-address="0.0.0.0/0" and active=yes]
    }
    :log info ("uji-startup: tunggu " . $n . "x5s, default-route=" . $rute)
}

πŸ’‘ Tips: Batas 12 kali lima detik sama dengan satu menit. Loop tanpa batas adalah cara paling cepat membuat router menggantung saat interface memang tidak pernah naik.

πŸ”Ή Langkah 11: bersih-bersih dan lembar hasil

/system scheduler remove [find name~"jadwal-uji"]
/system script job remove [find script~"uji-lama"]
/system script remove [find name~"uji-"]
/ip firewall address-list remove [find list="uji-policy"]

Isi lembar hasil berikut sebelum menutup lab:

| Uji | Yang dilakukan | Bukti yang dicatat | Pelajaran | |---|---|---|---| | A | Hapus `:local` | Error, log kosong, run-count naik | Jalan bukan berarti berhasil | | B | Policy `read` saja | `not enough permissions (9)` | Policy script dan scheduler harus cukup | | C | `:put` di scheduler | Pesan hilang | Scheduler tidak punya layar | | D | Interval 15s, durasi 40s | Job menumpuk | Pakai pengaman `:jobname` | | E | `find` tanpa hasil | Baris setelah error tidak jalan | Bungkus dengan `:onerror` | | F | `start-time=startup` | Data nol di detik awal | Tunggu interface dengan batas waktu |

🏭 Dipakai di dunia kerja

  • **Sekolah:** lab komputer dengan pool DHCP terbatas. Script mencatat pemakaian pool dan memberi peringatan di 80 persen, sehingga teknisi bisa menambah kapasitas sebelum ujian berbasis komputer dimulai.
  • **Kantor cabang:** tidak ada staf IT di malam hari. Script memeriksa default route dan menulis log setiap pagi, lalu tim pusat membaca log itu sebagai laporan kesehatan harian.
  • **ISP dan warnet:** pembersihan user hotspot kedaluwarsa dijalankan terjadwal. Pengaman `:jobname` mencegah dua proses pembersihan berjalan bersamaan dan menghapus voucher yang sama.
  • **Industri:** backup konfigurasi harian wajib memverifikasi ukuran file sebelum menulis "sukses" ke log. Backup nol byte lebih berbahaya daripada tidak ada backup, karena memberi rasa aman palsu.
  • **Laboratorium virtual:** provisioning router CHR memakai `:execute` untuk menjalankan script di latar belakang, sementara job dipantau agar tidak menumpuk saat siswa membuat lab bersamaan.
  • **NOC:** automation runbook memakai policy minimum. Script yang hanya membaca status tidak diberi `write`, sehingga kerusakan script tidak bisa mengubah konfigurasi produksi.

βœ… Verifikasi

Jalankan seluruh pemeriksaan ini setelah lab selesai:

/system script print detail where name~"cek-pool"
/system scheduler print detail where name~"jadwal-cek-pool"
/log print where message~"cek-pool"
/system script job print
/system script environment print

| Yang diperiksa | Hasil yang benar | |---|---| | `run-count` script | Bertambah setiap jadwal berjalan | | `last-started` | Terisi waktu eksekusi terakhir | | Log | Ada baris berprefix `cek-pool:` | | Scheduler | `next-run` masuk akal, bukan tanggal lampau | | Job | Tidak ada instance menggantung | | Error | Tidak ada `not enough permissions` atau script error baru |

πŸ§ͺ Uji cepat: Hapus satu lease client, jalankan `/system script run cek-pool`, lalu cek log. Angka pemakaian harus turun satu. Kalau tidak berubah, script membaca menu yang salah atau output `count-only` gagal.

⚠️ Kesalahan umum & troubleshooting

| Gejala | Penyebab | Perbaikan | |---|---|---| | Script diam, `run-count` naik | Error runtime di baris awal | Cari pesan script error di log, jalankan manual untuk melihatnya | | `syntax error` saat mengetik di terminal | `:local` dipakai lintas baris | Bungkus dalam `{ }` atau pakai `:global` | | `not enough permissions (9)` | Policy script atau scheduler kurang | Tambah policy yang benar, jangan langsung `dont-require-permissions` | | Pesan tidak muncul di log | Memakai `:put`, bukan `:log` | Ganti ke `:log info` dengan prefix nama script | | Dua proses berjalan bersamaan | Interval lebih pendek dari durasi script | Perpanjang interval atau pasang pengaman `:jobname` | | `no such item` | `find` tidak menemukan apa pun, lalu `get` dipaksa | Cek `count-only` dulu sebelum `get` | | `:onerror` tidak menangkap error | Urutan parameter salah | Tulis variabel error sebelum blok `do=` | | Scheduler tidak pernah jalan | `start-time=startup` dengan `interval` bukan nol | Set `start-time` konkret seperti `07:00:00` | | `run-count` kembali 0 | Router reboot | Normal, gunakan log sebagai riwayat | | Data kosong saat startup | Interface belum aktif 3 detik setelah boot | Tunggu dengan loop berbatas waktu |

⚠️ Hati-hati: Jangan menguji script yang mengubah firewall atau mematikan service di router produksi. Satu `:error` yang tidak tertangani bisa meninggalkan konfigurasi setengah jadi.

πŸ” Catatan keamanan & etika

  • **Beri policy minimum.** Script pemantau cukup `read,write,test`. Jangan pakai policy default yang mencakup `ftp`, `reboot`, `password`, `sniff`, dan `sensitive`.
  • **Jangan simpan password di source script.** Export konfigurasi menyalin isi script apa adanya, sehingga kredensial ikut bocor ke file `.rsc`.
  • **Hindari `dont-require-permissions=yes` di produksi.** Opsi ini melewati pemeriksaan hak dan hanya cocok untuk lab.
  • **Batasi siapa yang boleh membuat script.** Script berjalan dengan hak router; user yang bisa menulis script praktis bisa mengubah konfigurasi.
  • **Perlakukan log sebagai data pribadi.** Log lease berisi MAC dan IP siswa. Simpan secukupnya, batasi akses, dan jangan dibagikan bebas.
  • **Review sebelum menjalankan script orang lain.** Script dari forum atau grup chat bisa berisi perintah destruktif yang tidak terlihat saat dibaca sekilas.

πŸ“Œ Kesimpulan

  • `run-count` membuktikan script **dipanggil**, bukan **berhasil**. Bukti sebenarnya ada di log, file, atau perubahan konfigurasi.
  • Empat lapis pemeriksaan yang berurutan menghemat waktu: sintaks, scope, policy, lalu lingkungan eksekusi.
  • Script yang baik selalu punya pengaman: `:onerror`, batas loop, dan pencegah instance ganda.

Langkah berikutnya: ambil satu script buatanmu, tambahkan `:onerror` dan pengaman `:jobname`, lalu jalankan dua kali berturut-turut. Kalau hasilnya tetap sama dan log tetap rapi, script itu sudah layak dipakai di lab sekolah.

πŸ”— Materi terkait

πŸ“š Referensi