From f5720fee3689263487f3d44bed03809333b3a62f Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 10 Oct 2025 09:11:27 +0200 Subject: [PATCH 1/8] doc/mod/ssh-keys-import: reverse old and new --- doc/mod/ssh-keys-import.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/mod/ssh-keys-import.md b/doc/mod/ssh-keys-import.md index 02cd804e..434caa51 100644 --- a/doc/mod/ssh-keys-import.md +++ b/doc/mod/ssh-keys-import.md @@ -38,7 +38,7 @@ import that key: $SSHKeysImport "ssh-rsa AAAAB3Nza...QYZk8= user" admin; The third part of the key (`user` in this example) is inherited as -`key-owner` in RouterOS (or `info` starting with RouterOS 7.21beta2). Also +`info` in RouterOS (or `key-owner` with RouterOS 7.20.x and before). Also the `MD5` fingerprint is recorded, this helps to audit and verify the available keys. From c3fa6ef8b1a7909cb0e6cbb6c343305d934c6a63 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Sat, 7 Jun 2025 22:38:55 +0200 Subject: [PATCH 2/8] INITIAL-COMMANDS: drop the compatibility workaround... ... and make it depend in RouterOS 7.19 and its builtin certificates. --- INITIAL-COMMANDS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/INITIAL-COMMANDS.md b/INITIAL-COMMANDS.md index eb06ad29..df64aa7e 100644 --- a/INITIAL-COMMANDS.md +++ b/INITIAL-COMMANDS.md @@ -4,7 +4,7 @@ Initial commands [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.19-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -26,7 +26,7 @@ Run the complete base installation: :if (!((($CertSettings->"builtin-trust-anchors") = "trusted" || \ ($CertSettings->"builtin-trust-store") ~ "fetch" || \ ($CertSettings->"builtin-trust-store") = "all") && \ - [[ :parse (":return [ :len [ /certificate/builtin/find where common-name=\"" . $CertCommonName . "\" ] ]") ]] > 0)) do={ + [ :len [ /certificate/builtin/find where common-name=$CertCommonName ] ] > 0)) do={ :put "Importing certificate..."; /tool/fetch ($BaseUrl . "certs/" . $CertFileName) dst-path=$CertFileName as-value; :delay 1s; From 91cc0f7c7391ad9e67014cb3505b438ca608d25a Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Sat, 7 Jun 2025 22:41:29 +0200 Subject: [PATCH 3/8] global-functions: $CertificateAvailable: drop the compatibility workaround... ... and make it depend in RouterOS 7.19 and its builtin certificates. --- README.md | 2 +- global-functions.rsc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f9149217..14c2c010 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ RouterOS Scripts [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.19-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/global-functions.rsc b/global-functions.rsc index 5c70a463..94fc72ba 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -4,7 +4,7 @@ # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.19 # requires device-mode, fetch, scheduler # # global functions @@ -131,7 +131,7 @@ :if ((($CertSettings->"builtin-trust-anchors") = "trusted" || \ ($CertSettings->"builtin-trust-store") ~ $UseFor || \ ($CertSettings->"builtin-trust-store") = "all") && \ - [[ :parse (":return [ :len [ /certificate/builtin/find where common-name=\"" . $CommonName . "\" ] ]") ]] > 0) do={ + [ :len [ /certificate/builtin/find where common-name=$CommonName ] ] > 0) do={ :return true; } From c9f0c5a9f29fd48a453627aeae15e4865a19b072 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 12 Jan 2026 09:22:46 +0100 Subject: [PATCH 4/8] check-certificates: drop the compatibility workaround... ... and make it depend in RouterOS 7.19 and its builtin certificates. --- check-certificates.rsc | 7 ++----- doc/check-certificates.md | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/check-certificates.rsc b/check-certificates.rsc index 1dd61299..70e64d3e 100644 --- a/check-certificates.rsc +++ b/check-certificates.rsc @@ -3,7 +3,7 @@ # Copyright (c) 2013-2026 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.19 # requires device-mode, fetch # # check for certificate validity @@ -117,10 +117,7 @@ :local Return ""; :for I from=0 to=5 do={ :set Return ($Return . [ $ParseKeyValueStore ($CertVal->"issuer") ]->"CN"); - :local CertSettings [ /certificate/settings/get ]; - :if (([ :len ($CertSettings->"builtin-trust-anchors") ] > 0 || \ - [ :len ($CertSettings->"builtin-trust-store") ] > 0) && \ - [[ :parse (":return [ :len [ /certificate/builtin/find where skid=\"" . ($CertVal->"akid") . "\" ] ]") ]] > 0) do={ + :if ([ :len [ /certificate/builtin/find where skid=($CertVal->"akid") ] ] > 0) do={ :return $Return; } :do { diff --git a/doc/check-certificates.md b/doc/check-certificates.md index 456d4b1f..1e69af46 100644 --- a/doc/check-certificates.md +++ b/doc/check-certificates.md @@ -4,7 +4,7 @@ Renew certificates and notify on expiration [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.19-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) From 44663f0c38331860e9b68294b90228164889b997 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Tue, 13 Jan 2026 21:02:02 +0100 Subject: [PATCH 5/8] log-forward: use comparison for ids This was introduced with RouterOS 7.22beta1. --- log-forward.rsc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/log-forward.rsc b/log-forward.rsc index 26a23761..29e63ed8 100644 --- a/log-forward.rsc +++ b/log-forward.rsc @@ -24,7 +24,6 @@ :global LogForwardRateLimit; :global EitherOr; - :global HexToNum; :global IfThenElse; :global LogForwardFilterLogForwarding; :global LogPrint; @@ -38,6 +37,9 @@ :error false; } + # LogForwardLast is not initialized, by intention: we want + # to catch *0 on first invocation! + :if ([ :typeof $LogForwardRateLimit ] = "nothing") do={ :set LogForwardRateLimit 0; } @@ -51,7 +53,6 @@ :local Count 0; :local Duplicates false; - :local Last [ $IfThenElse ([ :len $LogForwardLast ] > 0) [ $HexToNum $LogForwardLast ] -1 ]; :local Messages ""; :local Warning false; :local MessageVal; @@ -63,14 +64,13 @@ :set LogForwardIncludeMessage [ $EitherOr $LogForwardIncludeMessage [] ]; :local LogForwardFilterLogForwardingCached [ $EitherOr [ $LogForwardFilterLogForwarding ] ("\$^") ]; - :foreach Message in=[ /log/find where (!(message="") and \ - !(message~$LogForwardFilterLogForwardingCached) and \ - !(topics~$LogForwardFilter) and !(message~$LogForwardFilterMessage)) or \ - topics~$LogForwardInclude or message~$LogForwardIncludeMessage ] do={ + :foreach Message in=[ /log/find where .id>$LogForwardLast and \ + ((!(message="") and !(message~$LogForwardFilterLogForwardingCached) and \ + !(topics~$LogForwardFilter) and !(message~$LogForwardFilterMessage)) or \ + topics~$LogForwardInclude or message~$LogForwardIncludeMessage) ] do={ :set MessageVal [ /log/get $Message ]; :local Bullet "information"; - :if ($Last < [ $HexToNum ($MessageVal->".id") ]) do={ :local DupCount ($MessageDups->($MessageVal->"message")); :if ($MessageVal->"topics" ~ "(warning)") do={ :set Warning true; @@ -88,7 +88,6 @@ } :set ($MessageDups->($MessageVal->"message")) ($DupCount + 1); :set Count ($Count + 1); - } } :if ($Count > 0) do={ From c46e44e8a9a65b97a05a4f4d624d4e2fd84bd8b5 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Tue, 13 Jan 2026 21:26:11 +0100 Subject: [PATCH 6/8] log-forward: fix indention --- log-forward.rsc | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/log-forward.rsc b/log-forward.rsc index 29e63ed8..a3a4bc9f 100644 --- a/log-forward.rsc +++ b/log-forward.rsc @@ -71,23 +71,23 @@ :set MessageVal [ /log/get $Message ]; :local Bullet "information"; - :local DupCount ($MessageDups->($MessageVal->"message")); - :if ($MessageVal->"topics" ~ "(warning)") do={ - :set Warning true; - :set Bullet "large-orange-circle"; - } - :if ($MessageVal->"topics" ~ "(emergency|alert|critical|error)") do={ - :set Warning true; - :set Bullet "large-red-circle"; - } - :if ($DupCount < 3) do={ - :set Messages ($Messages . "\n" . [ $SymbolForNotification $Bullet ] . \ - $MessageVal->"time" . " " . [ :tostr ($MessageVal->"topics") ] . " " . $MessageVal->"message"); - } else={ - :set Duplicates true; - } - :set ($MessageDups->($MessageVal->"message")) ($DupCount + 1); - :set Count ($Count + 1); + :local DupCount ($MessageDups->($MessageVal->"message")); + :if ($MessageVal->"topics" ~ "(warning)") do={ + :set Warning true; + :set Bullet "large-orange-circle"; + } + :if ($MessageVal->"topics" ~ "(emergency|alert|critical|error)") do={ + :set Warning true; + :set Bullet "large-red-circle"; + } + :if ($DupCount < 3) do={ + :set Messages ($Messages . "\n" . [ $SymbolForNotification $Bullet ] . \ + $MessageVal->"time" . " " . [ :tostr ($MessageVal->"topics") ] . " " . $MessageVal->"message"); + } else={ + :set Duplicates true; + } + :set ($MessageDups->($MessageVal->"message")) ($DupCount + 1); + :set Count ($Count + 1); } :if ($Count > 0) do={ From 577c226deb71f7a94f5b2a6ed863fa7d8fb34d1a Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Tue, 13 Jan 2026 22:46:54 +0100 Subject: [PATCH 7/8] log-forward: try to mitigate a race condition --- log-forward.rsc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/log-forward.rsc b/log-forward.rsc index a3a4bc9f..fdbe1173 100644 --- a/log-forward.rsc +++ b/log-forward.rsc @@ -63,8 +63,11 @@ :set LogForwardInclude [ $EitherOr $LogForwardInclude [] ]; :set LogForwardIncludeMessage [ $EitherOr $LogForwardIncludeMessage [] ]; + :local LogAll [ /log/find ]; + :local LogForwardMax ($LogAll->([ :len $LogAll ] - 1) ); :local LogForwardFilterLogForwardingCached [ $EitherOr [ $LogForwardFilterLogForwarding ] ("\$^") ]; - :foreach Message in=[ /log/find where .id>$LogForwardLast and \ + + :foreach Message in=[ /log/find where .id>$LogForwardLast and .id<=$LogForwardMax and \ ((!(message="") and !(message~$LogForwardFilterLogForwardingCached) and \ !(topics~$LogForwardFilter) and !(message~$LogForwardFilterMessage)) or \ topics~$LogForwardInclude or message~$LogForwardIncludeMessage) ] do={ @@ -105,8 +108,7 @@ :set LogForwardRateLimit [ $MAX 0 ($LogForwardRateLimit - 1) ]; } - :local LogAll [ /log/find ]; - :set LogForwardLast ($LogAll->([ :len $LogAll ] - 1) ); + :set LogForwardLast $LogForwardMax; } do={ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; } From 8dcdc4b086e4c9f0ac035b30cf85c7acf3940d8a Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Tue, 13 Jan 2026 21:33:26 +0100 Subject: [PATCH 8/8] global-functions: drop $HexToNum --- global-functions.rsc | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/global-functions.rsc b/global-functions.rsc index 94fc72ba..d4fe0aff 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -47,7 +47,6 @@ :global GetRandom20CharHex; :global GetRandomNumber; :global Grep; -:global HexToNum; :global HumanReadableNum; :global IfThenElse; :global IsDefaultRouteReachable; @@ -717,19 +716,6 @@ :return []; } -# convert from hex (string) to num -:set HexToNum do={ - :local Input [ :tostr $1 ]; - - :global HexToNum; - - :if ([ :pick $Input 0 ] = "*") do={ - :return [ $HexToNum [ :pick $Input 1 [ :len $Input ] ] ]; - } - - :return [ :tonum ("0x" . $Input) ]; -} - # return human readable number :set HumanReadableNum do={ :local Input [ :tonum $1 ];