diff --git a/CERTIFICATES.md b/CERTIFICATES.md index 0e0a867..69d6c18 100644 --- a/CERTIFICATES.md +++ b/CERTIFICATES.md @@ -61,7 +61,7 @@ Import a certificate by CommonName Running the function `$CertificateAvailable` with that name as parameter makes sure the certificate is available in the device's store: - $CertificateAvailable "ISRG Root X2" "fetch"; + $CertificateAvailable "ISRG Root X2"; If the certificate is actually available already nothing happens, and there is no output. Otherwise the certificate is downloaded and imported. diff --git a/INITIAL-COMMANDS.md b/INITIAL-COMMANDS.md index e580bc5..40f609b 100644 --- a/INITIAL-COMMANDS.md +++ b/INITIAL-COMMANDS.md @@ -17,16 +17,13 @@ Initial commands Run the complete base installation: { - :local BaseUrl "https://rsc.eworm.de/main/"; + :local BaseUrl "https://git.eworm.de/cgit/routeros-scripts/plain/"; :local CertCommonName "ISRG Root X2"; :local CertFileName "ISRG-Root-X2.pem"; :local CertFingerprint "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470"; - :local CertSettings [ /certificate/settings/get ]; - :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={ + :if (!(([ /certificate/settings/get ]->"builtin-trust-anchors") = "trusted" && \ + [[ :parse (":return [ :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; @@ -41,10 +38,13 @@ Run the complete base installation: :foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={ :put "Installing $Script..."; /system/script/remove [ find where name=$Script ]; - /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ($BaseUrl . $Script . ".rsc") output=user as-value ]->"data"); + /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ($BaseUrl . $Script . ".rsc") output=user as-value]->"data"); }; :put "Loading configuration and functions..."; /system/script { run global-config; run global-functions; }; + :put "Scheduling to load configuration and functions..."; + /system/scheduler/remove [ find where name="global-scripts" ]; + /system/scheduler/add name="global-scripts" start-time=startup on-event="/system/script { run global-config; run global-functions; }"; :if ([ :len [ /certificate/find where fingerprint=$CertFingerprint ] ] > 0) do={ :put "Renaming certificate by its common-name..."; :global CertificateNameByCN; diff --git a/Makefile b/Makefile index 5db0a30..8951741 100644 --- a/Makefile +++ b/Makefile @@ -2,45 +2,38 @@ # template scripts -> final scripts # markdown files -> html files -ALL_RSC := $(wildcard *.rsc */*.rsc) -GEN_RSC := $(wildcard *.capsman.rsc *.local.rsc *.wifi.rsc) +CAPSMAN = $(wildcard *.capsman.rsc) +LOCAL = $(wildcard *.local.rsc) +WIFI = $(wildcard *.wifi.rsc) -MARKDOWN := $(wildcard *.md doc/*.md doc/mod/*.md) -HTML := $(MARKDOWN:.md=.html) +MARKDOWN = $(wildcard *.md doc/*.md doc/mod/*.md) +HTML = $(MARKDOWN:.md=.html) -DATE ?= $(shell date --rfc-email) -VERSION ?= $(shell git symbolic-ref --short HEAD 2>/dev/null)/$(shell git rev-list --count HEAD 2>/dev/null)/$(shell git rev-parse --short=8 HEAD 2>/dev/null) -export DATE VERSION +all: $(CAPSMAN) $(LOCAL) $(WIFI) $(HTML) checksums.json -.PHONY: all checksums commitinfo docs rsc clean +%.html: %.md Makefile + markdown $< | sed 's/href="\([-_\./[:alnum:]]*\)\.md"/href="\1.html"/g' > $@ -all: checksums docs rsc +%.capsman.rsc: %.template.rsc Makefile + sed -e '/\/interface\/wifi\//d' -e '/\/interface\/wireless\//d' -e 's|%TEMPL%|.capsman|' \ + -e '/^# NOT \/caps-man\/ #$$/,/^# NOT \/caps-man\/ #$$/d' \ + -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ + < $< > $@ -checksums: checksums.json +%.local.rsc: %.template.rsc Makefile + sed -e '/\/caps-man\//d' -e '/\/interface\/wifi\//d' -e 's|%TEMPL%|.local|' \ + -e '/^# NOT \/interface\/wireless\/ #$$/,/^# NOT \/interface\/wireless\/ #$$/d' \ + -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ + < $< > $@ -checksums.json: contrib/checksums.sh $(ALL_RSC) - contrib/checksums.sh > $@ +%.wifi.rsc: %.template.rsc Makefile + sed -e '/\/caps-man\//d' -e '/\/interface\/wireless\//d' -e 's|%TEMPL%|.wifi|' \ + -e '/^# NOT \/interface\/wifi\/ #$$/,/^# NOT \/interface\/wifi\/ #$$/d' \ + -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ + < $< > $@ -commitinfo: global-functions.rsc - contrib/commitinfo.sh $< > $<~ - mv $<~ $< - -docs: $(HTML) - -%.html: %.md general/style.css contrib/html.sh contrib/html.sh.d/head.html contrib/html.sh.d/foot.html - contrib/html.sh $< > $@ - -rsc: $(GEN_RSC) - -%.capsman.rsc: %.template.rsc contrib/template-capsman.sh - contrib/template-capsman.sh $< > $@ - -%.local.rsc: %.template.rsc contrib/template-local.sh - contrib/template-local.sh $< > $@ - -%.wifi.rsc: %.template.rsc contrib/template-wifi.sh - contrib/template-wifi.sh $< > $@ +checksums.json: contrib/checksums.sh *.rsc */*.rsc + contrib/checksums.sh clean: rm -f $(HTML) checksums.json - make -C contrib/ clean diff --git a/README.d/01-download-certs.avif b/README.d/01-download-certs.avif index f2afeb5..d41ca05 100644 Binary files a/README.d/01-download-certs.avif and b/README.d/01-download-certs.avif differ diff --git a/README.d/02-import-certs.avif b/README.d/02-import-certs.avif index b31343c..bf7d577 100644 Binary files a/README.d/02-import-certs.avif and b/README.d/02-import-certs.avif differ diff --git a/README.d/03-check-certs.avif b/README.d/03-check-certs.avif index 1f03ad2..4717b3e 100644 Binary files a/README.d/03-check-certs.avif and b/README.d/03-check-certs.avif differ diff --git a/README.d/04-import-scripts.avif b/README.d/04-import-scripts.avif index c09949a..53439e4 100644 Binary files a/README.d/04-import-scripts.avif and b/README.d/04-import-scripts.avif differ diff --git a/README.d/05-run-and-schedule-scripts.avif b/README.d/05-run-and-schedule-scripts.avif new file mode 100644 index 0000000..37e1173 Binary files /dev/null and b/README.d/05-run-and-schedule-scripts.avif differ diff --git a/README.d/05-run-scripts.avif b/README.d/05-run-scripts.avif deleted file mode 100644 index 12d812c..0000000 Binary files a/README.d/05-run-scripts.avif and /dev/null differ diff --git a/README.d/06-schedule-update.avif b/README.d/06-schedule-update.avif index 158e13f..7c96f3a 100644 Binary files a/README.d/06-schedule-update.avif and b/README.d/06-schedule-update.avif differ diff --git a/README.d/07-edit-global-config-overlay.avif b/README.d/07-edit-global-config-overlay.avif index 9a5b903..f87fda8 100644 Binary files a/README.d/07-edit-global-config-overlay.avif and b/README.d/07-edit-global-config-overlay.avif differ diff --git a/README.d/08-apply-configuration.avif b/README.d/08-apply-configuration.avif index ab22cae..b66af1a 100644 Binary files a/README.d/08-apply-configuration.avif and b/README.d/08-apply-configuration.avif differ diff --git a/README.d/09-update-scripts.avif b/README.d/09-update-scripts.avif index e713ac2..f549fef 100644 Binary files a/README.d/09-update-scripts.avif and b/README.d/09-update-scripts.avif differ diff --git a/README.d/10-install-scripts.avif b/README.d/10-install-scripts.avif index cf26b16..00225b1 100644 Binary files a/README.d/10-install-scripts.avif and b/README.d/10-install-scripts.avif differ diff --git a/README.d/11-schedule-script.avif b/README.d/11-schedule-script.avif index 558614f..d6eb0f8 100644 Binary files a/README.d/11-schedule-script.avif and b/README.d/11-schedule-script.avif differ diff --git a/README.d/12-setup-lease-script.avif b/README.d/12-setup-lease-script.avif index 2a8bcb2..fb4024e 100644 Binary files a/README.d/12-setup-lease-script.avif and b/README.d/12-setup-lease-script.avif differ diff --git a/README.d/13-install-custom-script.avif b/README.d/13-install-custom-script.avif index 221b84e..2f01c43 100644 Binary files a/README.d/13-install-custom-script.avif and b/README.d/13-install-custom-script.avif differ diff --git a/README.d/14-remove-script.avif b/README.d/14-remove-script.avif index 3e4c105..a5c7daf 100644 Binary files a/README.d/14-remove-script.avif and b/README.d/14-remove-script.avif differ diff --git a/README.d/notification-news-and-changes.avif b/README.d/notification-news-and-changes.avif index d2e8aa7..d91b8a0 100644 Binary files a/README.d/notification-news-and-changes.avif and b/README.d/notification-news-and-changes.avif differ diff --git a/general/qr-code.png b/README.d/upstream.png similarity index 100% rename from general/qr-code.png rename to README.d/upstream.png diff --git a/README.md b/README.md index d562ada..243e1fc 100644 --- a/README.md +++ b/README.md @@ -55,18 +55,15 @@ Initial setup ### Get me ready! If you know how things work just copy and paste the -[initial commands](INITIAL-COMMANDS.md). These also support fixing an -existing but broken installation. Remember to edit and rerun +[initial commands](INITIAL-COMMANDS.md). Remember to edit and rerun `global-config-overlay`! - -> đŸ’Ąī¸ **Hint**: First time users should take -> [the long way in detail](#the-long-way-in-detail) below. +First time users should take the long way below. ### Live presentation Want to see it in action? I've had a presentation [Repository based RouterOS script distribution â†—ī¸](https://www.youtube.com/watch?v=B9neG3oAhcY) -including demonstration recorded live at [MUM Europe +including demonstation recorded live at [MUM Europe 2019 â†—ī¸](https://mum.mikrotik.com/2019/EU/) in Vienna. > âš ī¸ **Warning**: Some details changed. So see the presentation, then follow @@ -80,17 +77,14 @@ download the certificates. > đŸ’Ąī¸ **Hint**: RouterOS 7.19 comes with a builtin certificate store. You > can skip the steps regarding certificate download and import and jump > to [installation of scripts](#installation-of-scripts) if you set the -> trust for these builtin trust anchors: -> `/certificate/settings/set builtin-trust-anchors=trusted;` -> With RouterOS 7.21 the functionality was changed. Set this at minimum, -> but make sure not to drop other targets: -> `/certificate/settings/set builtin-trust-store=fetch;` +> trust for these builtin trust anchors: +> `/certificate/settings/set builtin-trust-anchors=trusted;` If you intend to download the scripts from a different location (for example from github.com) install the corresponding certificate chain. - /tool/fetch "https://rsc.eworm.de/main/certs/ISRG-Root-X2.pem" dst-path="isrg-root-x2.pem"; + /tool/fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/ISRG-Root-X2.pem" dst-path="isrg-root-x2.pem"; ![screenshot: download certs](README.d/01-download-certs.avif) @@ -128,16 +122,16 @@ date and time is set correctly! Now let's download the main scripts and add them in configuration on the fly. - :foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={ /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ("https://rsc.eworm.de/main/" . $Script . ".rsc") output=user as-value ]->"data"); }; + :foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={ /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ("https://git.eworm.de/cgit/routeros-scripts/plain/" . $Script . ".rsc") output=user as-value]->"data"); }; ![screenshot: import scripts](README.d/04-import-scripts.avif) -And finally run configuration and functions. This will also add the -scheduler for loading at system startup automatically. +And finally load configuration and functions and add the scheduler. /system/script { run global-config; run global-functions; }; + /system/scheduler/add name="global-scripts" start-time=startup on-event="/system/script { run global-config; run global-functions; }"; -![screenshot: run scripts](README.d/05-run-scripts.avif) +![screenshot: run and schedule scripts](README.d/05-run-and-schedule-scripts.avif) > đŸ’Ąī¸ **Hint**: You see complaints regarding syntax errors? Most likely the > RouterOS on your device is too old. Check for updates! @@ -179,7 +173,7 @@ This last step is required when ever you make changes to your configuration. > â„šī¸ **Info**: It is recommended to edit the configuration using the command > line interface. If using Winbox on Windows OS, the line endings may be -> missing. To fix this run: +> missing. To fix this run: > `/system/script/set source=[ :tocrlf [ get global-config-overlay source ] ] global-config-overlay;` Updating scripts @@ -225,7 +219,7 @@ cleanup add a scheduler entry. $ScriptInstallUpdate dhcp-to-dns,lease-script; /ip/dhcp-server/set lease-script=lease-script [ find ]; - /system/scheduler/add name="dhcp-to-dns" interval=5m start-time=startup on-event="/system/script/run dhcp-to-dns;"; + /system/scheduler/add name="dhcp-to-dns" interval=5m on-event="/system/script/run dhcp-to-dns;"; ![screenshot: setup lease script](README.d/12-setup-lease-script.avif) @@ -407,15 +401,14 @@ immediately remove the link in question. Upstream -------- -[rsc.eworm.de](https://rsc.eworm.de/) +[![upstream](README.d/upstream.png)](https://rsc.eworm.de/) -[![upstream](general/qr-code.png)](https://rsc.eworm.de/) +URL: +[GitHub.com](https://github.com/eworm-de/routeros-scripts#routeros-scripts) -### Code hosting - -* [git.eworm.de](https://git.eworm.de/cgit/routeros-scripts/about/) -* [GitHub.com](https://github.com/eworm-de/routeros-scripts#routeros-scripts) -* [GitLab.com](https://gitlab.com/eworm-de/routeros-scripts#routeros-scripts) +Mirror: +[eworm.de](https://git.eworm.de/cgit/routeros-scripts/about/) +[GitLab.com](https://gitlab.com/eworm-de/routeros-scripts#routeros-scripts) --- [âŦ†ī¸ Go back to top](#top) diff --git a/accesslist-duplicates.capsman.rsc b/accesslist-duplicates.capsman.rsc index 1da0366..5e6cf0a 100644 --- a/accesslist-duplicates.capsman.rsc +++ b/accesslist-duplicates.capsman.rsc @@ -22,7 +22,7 @@ :foreach AccList in=[ /caps-man/access-list/find where mac-address!="00:00:00:00:00:00" ] do={ :local Mac [ /caps-man/access-list/get $AccList mac-address ]; :if ($Seen->$Mac = 1) do={ - /caps-man/access-list/print without-paging where mac-address=$Mac; + /caps-man/access-list/print where mac-address=$Mac; :local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ]; :if ([ :typeof $Remove ] = "num") do={ diff --git a/accesslist-duplicates.local.rsc b/accesslist-duplicates.local.rsc index 03a9724..a6b4f41 100644 --- a/accesslist-duplicates.local.rsc +++ b/accesslist-duplicates.local.rsc @@ -22,7 +22,7 @@ :foreach AccList in=[ /interface/wireless/access-list/find where mac-address!="00:00:00:00:00:00" ] do={ :local Mac [ /interface/wireless/access-list/get $AccList mac-address ]; :if ($Seen->$Mac = 1) do={ - /interface/wireless/access-list/print without-paging where mac-address=$Mac; + /interface/wireless/access-list/print where mac-address=$Mac; :local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ]; :if ([ :typeof $Remove ] = "num") do={ diff --git a/accesslist-duplicates.template.rsc b/accesslist-duplicates.template.rsc index bf23147..e51198d 100644 --- a/accesslist-duplicates.template.rsc +++ b/accesslist-duplicates.template.rsc @@ -27,9 +27,9 @@ :local Mac [ /interface/wifi/access-list/get $AccList mac-address ]; :local Mac [ /interface/wireless/access-list/get $AccList mac-address ]; :if ($Seen->$Mac = 1) do={ - /caps-man/access-list/print without-paging where mac-address=$Mac; - /interface/wifi/access-list/print without-paging where mac-address=$Mac; - /interface/wireless/access-list/print without-paging where mac-address=$Mac; + /caps-man/access-list/print where mac-address=$Mac; + /interface/wifi/access-list/print where mac-address=$Mac; + /interface/wireless/access-list/print where mac-address=$Mac; :local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ]; :if ([ :typeof $Remove ] = "num") do={ diff --git a/accesslist-duplicates.wifi.rsc b/accesslist-duplicates.wifi.rsc index 528a73c..cadacb6 100644 --- a/accesslist-duplicates.wifi.rsc +++ b/accesslist-duplicates.wifi.rsc @@ -22,7 +22,7 @@ :foreach AccList in=[ /interface/wifi/access-list/find where mac-address!="00:00:00:00:00:00" ] do={ :local Mac [ /interface/wifi/access-list/get $AccList mac-address ]; :if ($Seen->$Mac = 1) do={ - /interface/wifi/access-list/print without-paging where mac-address=$Mac; + /interface/wifi/access-list/print where mac-address=$Mac; :local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ]; :if ([ :typeof $Remove ] = "num") do={ diff --git a/check-certificates.rsc b/check-certificates.rsc index 93641ee..c10e33b 100644 --- a/check-certificates.rsc +++ b/check-certificates.rsc @@ -21,7 +21,7 @@ :global CertWarnTime; :global Identity; - :global CertificateAvailable; + :global CertificateAvailable :global EscapeForRegEx; :global IfThenElse; :global LogPrint; @@ -189,7 +189,7 @@ fingerprint!=[ :tostr ($CertVal->"fingerprint") ] expires-after>$CertRenewTime ]; :local CertNewVal [ /certificate/get $CertNew ]; - :if ([ $CertificateAvailable ([ $ParseKeyValueStore ($CertNewVal->"issuer") ]->"CN") "fetch" ] = false) do={ + :if ([ $CertificateAvailable ([ $ParseKeyValueStore ($CertNewVal->"issuer") ]->"CN") ] = false) do={ $LogPrint warning $ScriptName ("The certificate chain is not available!"); } @@ -231,7 +231,7 @@ :local State [ $IfThenElse (($CertVal->"expired") = true) "expired" "is about to expire" ]; $SendNotification2 ({ origin=$ScriptName; \ - subject=([ $SymbolForNotification "lock-with-ink-pen,warning-sign" ] . "Certificate warning: " . ($CertVal->"name")); \ + subject=([ $SymbolForNotification "warning-sign" ] . "Certificate warning: " . ($CertVal->"name")); \ message=("A certificate on " . $Identity . " " . $State . ".\n\n" . [ $FormatInfo $Cert ]) }); $LogPrint info $ScriptName ("The certificate '" . ($CertVal->"name") . "' " . $State . \ ", it is invalid after " . ($CertVal->"invalid-after") . "."); diff --git a/check-health.d/state.rsc b/check-health.d/state.rsc index 5e4cbb8..2991935 100644 --- a/check-health.d/state.rsc +++ b/check-health.d/state.rsc @@ -11,8 +11,7 @@ :global CheckHealthPlugins; :set ($CheckHealthPlugins->[ :jobname ]) do={ - :local FuncName [ :tostr $0 ]; - :local ScriptName [ :tostr $1 ]; + :local FuncName [ :tostr $0 ]; :global CheckHealthLast; :global Identity; @@ -33,13 +32,13 @@ :if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={ :if ($CheckHealthLast->$Name = "ok" && \ $Value != "ok") do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "cross-mark" ] . "Health warning: " . $Name); \ message=("The device '" . $Name . "' on " . $Identity . " failed!") }); } :if ($CheckHealthLast->$Name != "ok" && \ $Value = "ok") do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \ message=("The device '" . $Name . "' on " . $Identity . " recovered!") }); } diff --git a/check-health.d/temperature.rsc b/check-health.d/temperature.rsc index 9f3f1a5..a2f632d 100644 --- a/check-health.d/temperature.rsc +++ b/check-health.d/temperature.rsc @@ -11,8 +11,7 @@ :global CheckHealthPlugins; :set ($CheckHealthPlugins->[ :jobname ]) do={ - :local FuncName [ :tostr $0 ]; - :local ScriptName [ :tostr $1 ]; + :local FuncName [ :tostr $0 ]; :global CheckHealthLast; :global CheckHealthTemperature; @@ -55,7 +54,7 @@ } :if ($Value > $CheckHealthTemperature->$Name && \ $CheckHealthTemperatureNotified->$Name != true) do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "fire" ] . "Health warning: " . $Name); \ message=("The " . $Name . " on " . $Identity . " is above threshold: " . \ $Value . "\C2\B0" . "C") }); @@ -63,7 +62,7 @@ } :if ($Value <= ($CheckHealthTemperature->$Name - $CheckHealthTemperatureDeviation) && \ $CheckHealthTemperatureNotified->$Name = true) do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \ message=("The " . $Name . " on " . $Identity . " dropped below threshold: " . \ $Value . "\C2\B0" . "C") }); diff --git a/check-health.d/voltage.rsc b/check-health.d/voltage.rsc index 5891fb4..9071c88 100644 --- a/check-health.d/voltage.rsc +++ b/check-health.d/voltage.rsc @@ -11,8 +11,7 @@ :global CheckHealthPlugins; :set ($CheckHealthPlugins->[ :jobname ]) do={ - :local FuncName [ :tostr $0 ]; - :local ScriptName [ :tostr $1 ]; + :local FuncName [ :tostr $0 ]; :global CheckHealthLast; :global CheckHealthVoltageLow; @@ -40,7 +39,7 @@ :if ($NumLast * (100 + $CheckHealthVoltagePercent) < $NumCurr * 100 || \ $NumLast * 100 > $NumCurr * (100 + $CheckHealthVoltagePercent)) do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification ("high-voltage-sign,chart-" . [ $IfThenElse ($NumLast < \ $NumCurr) "in" "de" ] . "creasing") ] . "Health warning: " . $Name); \ message=("The " . $Name . " on " . $Identity . " jumped more than " . $CheckHealthVoltagePercent . "%.\n\n" . \ @@ -48,12 +47,12 @@ [ $FormatLine "new value" ($Value . " V") 12 ]) }); } else={ :if ($NumCurr <= $CheckHealthVoltageLow && $NumLast > $CheckHealthVoltageLow) do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "high-voltage-sign,chart-decreasing" ] . "Health warning: Low " . $Name); \ message=("The " . $Name . " on " . $Identity . " dropped to " . $Value . " V below hard limit.") }); } :if ($NumCurr > $CheckHealthVoltageLow && $NumLast <= $CheckHealthVoltageLow) do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "high-voltage-sign,chart-increasing" ] . "Health recovery: Low " . $Name); \ message=("The " . $Name . " on " . $Identity . " recovered to " . $Value . " V above hard limit.") }); } diff --git a/check-health.rsc b/check-health.rsc index 760636d..4cb9940 100644 --- a/check-health.rsc +++ b/check-health.rsc @@ -92,16 +92,16 @@ :onerror Err { /system/script/run $Plugin; } do={ - $LogPrint error $ScriptName ("Plugin '" . $PluginVal->"name" . "' failed to run: " . $Err); + $LogPrint error $ScriptName ("Plugin '" . $ScriptVal->"name" . "' failed to run: " . $Err); } } else={ - $LogPrint error $ScriptName ("Plugin '" . $PluginVal->"name" . "' failed syntax validation, skipping."); + $LogPrint error $ScriptName ("Plugin '" . $ScriptVal->"name" . "' failed syntax validation, skipping."); } } :foreach PluginName,Discard in=$CheckHealthPlugins do={ ($CheckHealthPlugins->$PluginName) \ - ("\$CheckHealthPlugins->\"" . $PluginName . "\"") $ScriptName; + ("\$CheckHealthPlugins->\"" . $PluginName . "\""); } :set CheckHealthPlugins; diff --git a/check-perpetual-license.rsc b/check-perpetual-license.rsc index ff775c3..c2f0dff 100644 --- a/check-perpetual-license.rsc +++ b/check-perpetual-license.rsc @@ -42,7 +42,7 @@ $LogPrint warning $ScriptName ("Your license expired on " . ($License->"deadline-at") . "!"); :if ($SentCertificateNotification != "expired") do={ $SendNotification2 ({ origin=$ScriptName; \ - subject=([ $SymbolForNotification "scroll,cross-mark" ] . "License expired!"); \ + subject=([ $SymbolForNotification "warning-sign" ] . "License expired!"); \ message=("Your license expired on " . ($License->"deadline-at") . \ ", can no longer update RouterOS on " . $Identity . "...") }); :set SentCertificateNotification "expired"; @@ -55,7 +55,7 @@ $LogPrint warning $ScriptName ("Your license will expire on " . ($License->"deadline-at") . "!"); :if ($SentCertificateNotification != "warning") do={ $SendNotification2 ({ origin=$ScriptName; \ - subject=([ $SymbolForNotification "scroll,warning-sign" ] . "License about to expire!"); \ + subject=([ $SymbolForNotification "warning-sign" ] . "License about to expire!"); \ message=("Your license failed to renew and is about to expire on " . \ ($License->"deadline-at") . " on " . $Identity . "...") }); :set SentCertificateNotification "warning"; @@ -68,7 +68,7 @@ [ :totime ($License->"deadline-at") ] - 4w > [ :timestamp ]) do={ $LogPrint info $ScriptName ("Your license was successfully renewed."); $SendNotification2 ({ origin=$ScriptName; \ - subject=([ $SymbolForNotification "scroll,white-heavy-check-mark" ] . "License renewed"); \ + subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "License renewed"); \ message=("Your license was successfully renewed on " . $Identity . \ ". It is now valid until " . ($License->"deadline-at") . ".") }); :set SentCertificateNotification; diff --git a/check-routeros-update.rsc b/check-routeros-update.rsc index e5b2e18..8b80dde 100644 --- a/check-routeros-update.rsc +++ b/check-routeros-update.rsc @@ -39,11 +39,14 @@ :local DoUpdate do={ :local ScriptName [ :tostr $1 ]; + :global LogPrint; + :if ([ :len [ /system/script/find where name="packages-update" ] ] > 0) do={ /system/script/run packages-update; } else={ /system/package/update/install without-paging; } + $LogPrint info $ScriptName ("Waiting for system to reboot."); } :if ([ $ScriptLock $ScriptName ] = false) do={ diff --git a/contrib/Makefile b/contrib/Makefile deleted file mode 100644 index e755a1d..0000000 --- a/contrib/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Makefile - -HTML := $(shell grep -xl '' *.html) - -.PHONY: all docs clean - -all: docs - -badges.html: badges.md - markdown $< > $@ - -docs: static-html.sh $(HTML) badges.html - ./static-html.sh $(HTML) - -clean: - rm -f badges.html - git checkout HEAD -- $(HTML) diff --git a/contrib/badges.md b/contrib/badges.md deleted file mode 100644 index 24bd205..0000000 --- a/contrib/badges.md +++ /dev/null @@ -1,6 +0,0 @@ -[![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.15-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/contrib/checksums.sh b/contrib/checksums.sh index ab4e973..b472b49 100755 --- a/contrib/checksums.sh +++ b/contrib/checksums.sh @@ -6,4 +6,4 @@ set -e md5sum $(find -name '*.rsc' | sort) | \ sed -e "s| \./||" -e 's|.rsc$||' | \ - jq --raw-input --null-input '[ inputs | split (" ") | { (.[1]): (.[0]) }] | add' + jq --raw-input --null-input '[ inputs | split (" ") | { (.[1]): (.[0]) }] | add' > 'checksums.json' diff --git a/contrib/commitinfo.sh b/contrib/commitinfo.sh deleted file mode 100755 index 21faf9f..0000000 --- a/contrib/commitinfo.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -sed \ - -e "/^:global CommitId/c :global CommitId \"${COMMITID:-unknown}\";" \ - -e "/^:global CommitInfo/c :global CommitInfo \"${COMMITINFO:-unknown}\";" \ - < "${1}" diff --git a/contrib/html.sh b/contrib/html.sh deleted file mode 100755 index 03eba23..0000000 --- a/contrib/html.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -set -e - -RELTO="$(dirname "${1}")" - -sed \ - -e "s|__TITLE__|$(head -n1 "${1}")|" \ - -e "s|__GENERAL__|$(realpath --relative-to="${RELTO}" general/)|" \ - -e "s|__ROOT__|$(realpath --relative-to="${RELTO}" ./)|" \ - < "${0}.d/head.html" - -markdown -f toc,idanchor "${1}" | sed \ - -e 's/href="\([-_\./[:alnum:]]*\)\.md\(#[-[:alnum:]]*\)\?"/href="\1.html\2"/g' \ - -e '/| id="\L\1">|' \ - -e '//s|pre|pre class="code" onclick="CopyToClipboard(this)"|g' \ - -e '/The above link may be broken on code hosting sites/s|blockquote|blockquote style="display: none;"|' - -sed \ - -e "s|__DATE__|${DATE:-$(date --rfc-email)}|" \ - -e "s|__VERSION__|${VERSION:-unknown}|" \ - < "${0}.d/foot.html" diff --git a/contrib/html.sh.d/foot.html b/contrib/html.sh.d/foot.html deleted file mode 100644 index d304152..0000000 --- a/contrib/html.sh.d/foot.html +++ /dev/null @@ -1,5 +0,0 @@ - -

RouterOS Scripts documentation generated on __DATE__ for __VERSION__
-Copyright © 2013-2025 Christian Hesse <mail@eworm.de>

- - diff --git a/contrib/html.sh.d/head.html b/contrib/html.sh.d/head.html deleted file mode 100644 index 656a63c..0000000 --- a/contrib/html.sh.d/head.html +++ /dev/null @@ -1,16 +0,0 @@ - - -RouterOS Scripts :: __TITLE__ - - - - - - - - - -
eworm on meadowQR code: rsc.eworm.deRouterOS Scripts
- a collection of scripts for MikroTik RouterOS
-
- diff --git a/contrib/logo-color.d/style.css b/contrib/logo-color.d/style.css new file mode 100644 index 0000000..eb2ec6a --- /dev/null +++ b/contrib/logo-color.d/style.css @@ -0,0 +1,5 @@ +body { + font-family: fira-sans, sans-serif; + font-size: 10pt; + background-color: transparent; +} diff --git a/contrib/logo-color.html b/contrib/logo-color.html index e5bfb71..17942ce 100644 --- a/contrib/logo-color.html +++ b/contrib/logo-color.html @@ -1,30 +1,14 @@ - - - -RouterOS Scripts :: Logo Color Changer - - + + + + +RouterOS-Scripts Logo Color Changer + - + + - - - - -
eworm on meadowQR code: rsc.eworm.deRouterOS Scripts
- a collection of scripts for MikroTik RouterOS
-
- -

Logo Color Changer

- - - -

âŦ…ī¸ Go back to main README

- -

đŸ’Ąī¸ Hint: This site or links -on it may be broken on code hosting sites. Use -Logo Color Changer -instead.

+

RouterOS-Scripts Logo Color Changer

You want the logo for your own notifications? But you joined the Telegram Group and want @@ -40,23 +24,17 @@ something that differentiates? Color it!

Then right-click, click "Take Screenshot" and finally select the logo and download it.

-

Screenshot Browser 01

-

Screenshot Browser 02

-

Screenshot Browser 03

+

Screenshot Browser 01 +Screenshot Browser 02 +Screenshot Browser 03

(This example is with Firefox. The workflow for other browsers may differ.)

See how to -Set +Set a profile photo for your Telegram bot.

-
- -

âŦ…ī¸ Go back to main README
-âŦ†ī¸ Go back to top

- -

Copyright © 2013-2025 Christian Hesse <mail@eworm.de>

- - + + diff --git a/contrib/notification.d/style.css b/contrib/notification.d/style.css new file mode 100644 index 0000000..648ea23 --- /dev/null +++ b/contrib/notification.d/style.css @@ -0,0 +1,36 @@ +body { + font-family: fira-sans, sans-serif; + font-size: 10pt; + background-color: transparent; +} +div.notification { + position: relative; + float: right; + width: 600px; + border: 3px outset #6c5d53; + /* border-radius: 5px; */ + padding: 10px; + background-color: #e6e6e6; +} +div.content { + padding-left: 60px; +} +img.logo { + float: left; + border-radius: 50%; +} +p.heading { + margin: 0px; + font-weight: bold; + text-decoration: underline; +} +p.hint { + display: none; +} +pre { + font-family: fira-mono, monospace; + white-space: pre-wrap; +} +span.link { + color: #863600; +} diff --git a/contrib/notification.html b/contrib/notification.html index baa659c..7875036 100644 --- a/contrib/notification.html +++ b/contrib/notification.html @@ -1,57 +1,35 @@ - - - -RouterOS Scripts :: Notification Generator - - - - + + + + +RouterOS-Scripts Notification Generator + + + + - - - - -
eworm on meadowQR code: rsc.eworm.deRouterOS Scripts
- a collection of scripts for MikroTik RouterOS
-
- -

Notification Generator

- - - -

âŦ…ī¸ Go back to main README

- -

đŸ’Ąī¸ Hint: This site or links -on it may be broken on code hosting sites. Use -Notification Generator -instead.

+

RouterOS-Scripts Notification Generator

[MikroTik] â„šī¸ Subject

Message
- -

⏰ This message was queued since 2025-10-29 16:06:18 and may be obsolete.

-

âœ‚ī¸ The message was too long and has been truncated, cut off 13%!

+ +

⏰ This message was queued since oct/18/2022 18:30:48 and may be obsolete.

+

âœ‚ī¸ The message was too long and has been truncated, cut off 13%!

Hostname:

Subject:

Message:

-

Show link:

-

Queued since

+

Show link:

+

Queued since

Cut-off with percent

Then right-click, click "Take Screenshot" and finally select the notification and download it.

-
- -

âŦ…ī¸ Go back to main README
-âŦ†ī¸ Go back to top

- -

Copyright © 2013-2025 Christian Hesse <mail@eworm.de>

- - + + diff --git a/contrib/static-html.sh b/contrib/static-html.sh deleted file mode 100755 index 7acf104..0000000 --- a/contrib/static-html.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -set -e - -sed -i \ - -e '/href=/s|\.md|\.html|' \ - -e '/blockquote/s|/\* display \*/|display: none;|' \ - -e '//r badges.html' \ - -e '//d' \ - "${@}" diff --git a/contrib/template-capsman.sh b/contrib/template-capsman.sh deleted file mode 100755 index 5771b53..0000000 --- a/contrib/template-capsman.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -set -e - -sed \ - -e '/\/interface\/wifi\//d' \ - -e '/\/interface\/wireless\//d' \ - -e 's|%TEMPL%|.capsman|' \ - -e '/^# NOT \/caps-man\/ #$/,/^# NOT \/caps-man\/ #$/d' \ - -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ - < "${1}" diff --git a/contrib/template-local.sh b/contrib/template-local.sh deleted file mode 100755 index bc5b327..0000000 --- a/contrib/template-local.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -set -e - -sed \ - -e '/\/caps-man\//d' \ - -e '/\/interface\/wifi\//d' \ - -e 's|%TEMPL%|.local|' \ - -e '/^# NOT \/interface\/wireless\/ #$/,/^# NOT \/interface\/wireless\/ #$/d' \ - -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ - < "${1}" diff --git a/contrib/template-wifi.sh b/contrib/template-wifi.sh deleted file mode 100755 index 5e297d9..0000000 --- a/contrib/template-wifi.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -set -e - -sed \ - -e '/\/caps-man\//d' \ - -e '/\/interface\/wireless\//d' \ - -e 's|%TEMPL%|.wifi|' \ - -e '/^# NOT \/interface\/wifi\/ #$/,/^# NOT \/interface\/wifi\/ #$/d' \ - -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ - < "${1}" diff --git a/doc/accesslist-duplicates.d/01-example.avif b/doc/accesslist-duplicates.d/01-example.avif index d290a77..11b3fc5 100644 Binary files a/doc/accesslist-duplicates.d/01-example.avif and b/doc/accesslist-duplicates.d/01-example.avif differ diff --git a/doc/backup-cloud.d/notification.avif b/doc/backup-cloud.d/notification.avif index 5918a62..e533908 100644 Binary files a/doc/backup-cloud.d/notification.avif and b/doc/backup-cloud.d/notification.avif differ diff --git a/doc/backup-upload.d/notification.avif b/doc/backup-upload.d/notification.avif index 3bcc1f4..83cfb18 100644 Binary files a/doc/backup-upload.d/notification.avif and b/doc/backup-upload.d/notification.avif differ diff --git a/doc/check-certificates.d/notification-01-warn.avif b/doc/check-certificates.d/notification-01-warn.avif deleted file mode 100644 index e32e54b..0000000 Binary files a/doc/check-certificates.d/notification-01-warn.avif and /dev/null differ diff --git a/doc/check-certificates.d/notification-02-renew.avif b/doc/check-certificates.d/notification-02-renew.avif deleted file mode 100644 index 9ff1400..0000000 Binary files a/doc/check-certificates.d/notification-02-renew.avif and /dev/null differ diff --git a/doc/check-certificates.d/notification.avif b/doc/check-certificates.d/notification.avif new file mode 100644 index 0000000..7c250da Binary files /dev/null and b/doc/check-certificates.d/notification.avif differ diff --git a/doc/check-certificates.md b/doc/check-certificates.md index b8fece0..a9426db 100644 --- a/doc/check-certificates.md +++ b/doc/check-certificates.md @@ -19,10 +19,9 @@ Description This script tries to download and renew certificates, then notifies about certificates that are still about to expire. -### Sample notifications +### Sample notification -![check-certificates notification warning](check-certificates.d/notification-01-warn.avif) -![check-certificates notification renew](check-certificates.d/notification-02-renew.avif) +![check-certificates notification](check-certificates.d/notification.avif) Requirements and installation ----------------------------- diff --git a/doc/check-health.d/notification-01-cpu-utilization-high.avif b/doc/check-health.d/notification-01-cpu-utilization-high.avif index 7fbce3c..326e7fe 100644 Binary files a/doc/check-health.d/notification-01-cpu-utilization-high.avif and b/doc/check-health.d/notification-01-cpu-utilization-high.avif differ diff --git a/doc/check-health.d/notification-02-cpu-utilization-ok.avif b/doc/check-health.d/notification-02-cpu-utilization-ok.avif index f8e91a3..811ccd7 100644 Binary files a/doc/check-health.d/notification-02-cpu-utilization-ok.avif and b/doc/check-health.d/notification-02-cpu-utilization-ok.avif differ diff --git a/doc/check-health.d/notification-03-ram-utilization-high.avif b/doc/check-health.d/notification-03-ram-utilization-high.avif index 9015b4a..59155c5 100644 Binary files a/doc/check-health.d/notification-03-ram-utilization-high.avif and b/doc/check-health.d/notification-03-ram-utilization-high.avif differ diff --git a/doc/check-health.d/notification-04-ram-utilization-ok.avif b/doc/check-health.d/notification-04-ram-utilization-ok.avif index 8f949ec..d995b9a 100644 Binary files a/doc/check-health.d/notification-04-ram-utilization-ok.avif and b/doc/check-health.d/notification-04-ram-utilization-ok.avif differ diff --git a/doc/check-health.d/notification-05-voltage.avif b/doc/check-health.d/notification-05-voltage.avif index 9ef2d94..17a385b 100644 Binary files a/doc/check-health.d/notification-05-voltage.avif and b/doc/check-health.d/notification-05-voltage.avif differ diff --git a/doc/check-health.d/notification-06-temperature-high.avif b/doc/check-health.d/notification-06-temperature-high.avif index 908e8f2..60d3802 100644 Binary files a/doc/check-health.d/notification-06-temperature-high.avif and b/doc/check-health.d/notification-06-temperature-high.avif differ diff --git a/doc/check-health.d/notification-07-temperature-ok.avif b/doc/check-health.d/notification-07-temperature-ok.avif index 8f509e8..4afed02 100644 Binary files a/doc/check-health.d/notification-07-temperature-ok.avif and b/doc/check-health.d/notification-07-temperature-ok.avif differ diff --git a/doc/check-health.d/notification-08-state-fail.avif b/doc/check-health.d/notification-08-state-fail.avif index 8ba7bb9..ad049ac 100644 Binary files a/doc/check-health.d/notification-08-state-fail.avif and b/doc/check-health.d/notification-08-state-fail.avif differ diff --git a/doc/check-health.d/notification-09-state-ok.avif b/doc/check-health.d/notification-09-state-ok.avif index 9197741..26f5a74 100644 Binary files a/doc/check-health.d/notification-09-state-ok.avif and b/doc/check-health.d/notification-09-state-ok.avif differ diff --git a/doc/check-lte-firmware-upgrade.d/notification.avif b/doc/check-lte-firmware-upgrade.d/notification.avif index 2c2f692..c440da5 100644 Binary files a/doc/check-lte-firmware-upgrade.d/notification.avif and b/doc/check-lte-firmware-upgrade.d/notification.avif differ diff --git a/doc/check-perpetual-license.d/notification-01-warn.avif b/doc/check-perpetual-license.d/notification-01-warn.avif deleted file mode 100644 index aa36e45..0000000 Binary files a/doc/check-perpetual-license.d/notification-01-warn.avif and /dev/null differ diff --git a/doc/check-perpetual-license.d/notification-02-renew.avif b/doc/check-perpetual-license.d/notification-02-renew.avif deleted file mode 100644 index 471a22e..0000000 Binary files a/doc/check-perpetual-license.d/notification-02-renew.avif and /dev/null differ diff --git a/doc/check-perpetual-license.d/notification.avif b/doc/check-perpetual-license.d/notification.avif new file mode 100644 index 0000000..70ca603 Binary files /dev/null and b/doc/check-perpetual-license.d/notification.avif differ diff --git a/doc/check-perpetual-license.md b/doc/check-perpetual-license.md index a32c4c3..0335fb5 100644 --- a/doc/check-perpetual-license.md +++ b/doc/check-perpetual-license.md @@ -20,10 +20,9 @@ On *Cloud Hosted Router* (*CHR*) the licensing is perpetual: Buy once, use forever - but it needs regular renewal. This script checks licensing state and sends a notification to warn before expiration. -### Sample notifications +### Sample notification -![check-perpetual-license notification warn](check-perpetual-license.d/notification-01-warn.avif) -![check-perpetual-license notification renew](check-perpetual-license.d/notification-02-renew.avif) +![check-perpetual-license notification](check-perpetual-license.d/notification.avif) Requirements and installation ----------------------------- diff --git a/doc/check-routeros-update.d/notification-01-found.avif b/doc/check-routeros-update.d/notification-01-found.avif deleted file mode 100644 index 54dd2df..0000000 Binary files a/doc/check-routeros-update.d/notification-01-found.avif and /dev/null differ diff --git a/doc/check-routeros-update.d/notification-02-neighbor.avif b/doc/check-routeros-update.d/notification-02-neighbor.avif deleted file mode 100644 index db4e980..0000000 Binary files a/doc/check-routeros-update.d/notification-02-neighbor.avif and /dev/null differ diff --git a/doc/check-routeros-update.d/notification.avif b/doc/check-routeros-update.d/notification.avif new file mode 100644 index 0000000..50317cf Binary files /dev/null and b/doc/check-routeros-update.d/notification.avif differ diff --git a/doc/check-routeros-update.d/terminal.avif b/doc/check-routeros-update.d/terminal.avif deleted file mode 100644 index af95059..0000000 Binary files a/doc/check-routeros-update.d/terminal.avif and /dev/null differ diff --git a/doc/check-routeros-update.md b/doc/check-routeros-update.md index 029182d..a45e075 100644 --- a/doc/check-routeros-update.md +++ b/doc/check-routeros-update.md @@ -31,14 +31,13 @@ automatically is supported. > of view. At the same time it can be source of serve breakage. So test > versions in lab and read > [changelog â†—ī¸](https://mikrotik.com/download/changelogs/) and -> [forum â†—ī¸](https://forum.mikrotik.com/c/announcements/5) before deploying +> [forum â†—ī¸](https://forum.mikrotik.com/viewforum.php?f=21) before deploying > to your production environment! Automatic updates should be handled > with care! -### Sample notifications +### Sample notification -![check-routeros-update notification found](check-routeros-update.d/notification-01-found.avif) -![check-routeros-update notification neighbor](check-routeros-update.d/notification-02-neighbor.avif) +![check-routeros-update notification](check-routeros-update.d/notification.avif) Requirements and installation ----------------------------- @@ -88,8 +87,6 @@ Be notified when run from scheduler or run it manually: If an update is found you can install it right away. -![Terminal](check-routeros-update.d/terminal.avif) - Installing script [packages-update](packages-update.md) gives extra options. Tips & Tricks diff --git a/doc/collect-wireless-mac.d/notification.avif b/doc/collect-wireless-mac.d/notification.avif index 4b21b2f..a2833f0 100644 Binary files a/doc/collect-wireless-mac.d/notification.avif and b/doc/collect-wireless-mac.d/notification.avif differ diff --git a/doc/daily-psk.d/notification.avif b/doc/daily-psk.d/notification.avif index 79cfc3e..dd0b1b6 100644 Binary files a/doc/daily-psk.d/notification.avif and b/doc/daily-psk.d/notification.avif differ diff --git a/doc/log-forward.d/notification-01-info.avif b/doc/log-forward.d/notification-01-info.avif deleted file mode 100644 index 6d25467..0000000 Binary files a/doc/log-forward.d/notification-01-info.avif and /dev/null differ diff --git a/doc/log-forward.d/notification-02-warn.avif b/doc/log-forward.d/notification-02-warn.avif deleted file mode 100644 index ff61c0c..0000000 Binary files a/doc/log-forward.d/notification-02-warn.avif and /dev/null differ diff --git a/doc/log-forward.d/notification.avif b/doc/log-forward.d/notification.avif new file mode 100644 index 0000000..a0f9ab3 Binary files /dev/null and b/doc/log-forward.d/notification.avif differ diff --git a/doc/log-forward.md b/doc/log-forward.md index d5a2f13..f6086c8 100644 --- a/doc/log-forward.md +++ b/doc/log-forward.md @@ -35,10 +35,9 @@ The script works around the limitations, for example it does: It is intended to be run periodically from scheduler, then collects new log messages and forwards them via notification. -### Sample notifications +### Sample notification -![log-forward notification info](log-forward.d/notification-01-info.avif) -![log-forward notification warn](log-forward.d/notification-02-warn.avif) +![log-forward notification](log-forward.d/notification.avif) Requirements and installation ----------------------------- diff --git a/doc/mod/inspectvar.d/01-inspectvar.avif b/doc/mod/inspectvar.d/01-inspectvar.avif deleted file mode 100644 index 1be1358..0000000 Binary files a/doc/mod/inspectvar.d/01-inspectvar.avif and /dev/null differ diff --git a/doc/mod/inspectvar.d/inspectvar.avif b/doc/mod/inspectvar.d/inspectvar.avif new file mode 100644 index 0000000..f1da1d4 Binary files /dev/null and b/doc/mod/inspectvar.d/inspectvar.avif differ diff --git a/doc/mod/inspectvar.md b/doc/mod/inspectvar.md index e5c5629..7daba15 100644 --- a/doc/mod/inspectvar.md +++ b/doc/mod/inspectvar.md @@ -33,7 +33,7 @@ Call the function `$InspectVar` with a variable as parameter: $InspectVar $ModeButton; -![InspectVar](inspectvar.d/01-inspectvar.avif) +![InspectVar](inspectvar.d/inspectvar.avif) --- [âŦ…ī¸ Go back to main README](../../README.md) diff --git a/doc/mod/ipcalc.d/01-ipcalc.avif b/doc/mod/ipcalc.d/01-ipcalc.avif deleted file mode 100644 index aaad616..0000000 Binary files a/doc/mod/ipcalc.d/01-ipcalc.avif and /dev/null differ diff --git a/doc/mod/ipcalc.d/02-ipcalcreturn.avif b/doc/mod/ipcalc.d/02-ipcalcreturn.avif deleted file mode 100644 index 2459eaf..0000000 Binary files a/doc/mod/ipcalc.d/02-ipcalcreturn.avif and /dev/null differ diff --git a/doc/mod/ipcalc.d/ipcalc.avif b/doc/mod/ipcalc.d/ipcalc.avif new file mode 100644 index 0000000..fe726e8 Binary files /dev/null and b/doc/mod/ipcalc.d/ipcalc.avif differ diff --git a/doc/mod/ipcalc.d/ipcalcreturn.avif b/doc/mod/ipcalc.d/ipcalcreturn.avif new file mode 100644 index 0000000..5e4dd57 Binary files /dev/null and b/doc/mod/ipcalc.d/ipcalcreturn.avif differ diff --git a/doc/mod/ipcalc.md b/doc/mod/ipcalc.md index f8d407c..c07853e 100644 --- a/doc/mod/ipcalc.md +++ b/doc/mod/ipcalc.md @@ -43,7 +43,7 @@ It expects an IP address in CIDR notation as argument. $IPCalc 192.168.88.1/24; -![IPCalc](ipcalc.d/01-ipcalc.avif) +![IPCalc](ipcalc.d/ipcalc.avif) ### IPCalcReturn @@ -53,7 +53,7 @@ the information in a named array. :put ([ $IPCalcReturn 192.168.88.1/24 ]->"broadcast"); -![IPCalcReturn](ipcalc.d/02-ipcalcreturn.avif) +![IPCalcReturn](ipcalc.d/ipcalcreturn.avif) --- [âŦ…ī¸ Go back to main README](../../README.md) diff --git a/doc/mod/notification-matrix.d/01-authenticate.avif b/doc/mod/notification-matrix.d/01-authenticate.avif index d5b8025..b897943 100644 Binary files a/doc/mod/notification-matrix.d/01-authenticate.avif and b/doc/mod/notification-matrix.d/01-authenticate.avif differ diff --git a/doc/mod/notification-matrix.d/02-join-room.avif b/doc/mod/notification-matrix.d/02-join-room.avif index 20c4e79..ad99ffd 100644 Binary files a/doc/mod/notification-matrix.d/02-join-room.avif and b/doc/mod/notification-matrix.d/02-join-room.avif differ diff --git a/doc/mod/notification-matrix.md b/doc/mod/notification-matrix.md index ad4cf4f..da6d6de 100644 --- a/doc/mod/notification-matrix.md +++ b/doc/mod/notification-matrix.md @@ -49,7 +49,7 @@ your server in device's certificate store. The example below is for `matrix.org`, which uses a trust chain from *Google Trust Services*. Run this to import the required certificate: - $CertificateAvailable "GTS Root R4" "fetch"; + $CertificateAvailable "GTS Root R4"; Replace the CA certificate name with what ever is needed for your server. You may want to find the diff --git a/doc/mod/notification-telegram.d/02-getchatid.avif b/doc/mod/notification-telegram.d/02-getchatid.avif deleted file mode 100644 index 0112449..0000000 Binary files a/doc/mod/notification-telegram.d/02-getchatid.avif and /dev/null differ diff --git a/doc/mod/notification-telegram.d/getchatid.avif b/doc/mod/notification-telegram.d/getchatid.avif new file mode 100644 index 0000000..7792969 Binary files /dev/null and b/doc/mod/notification-telegram.d/getchatid.avif differ diff --git a/doc/mod/notification-telegram.d/01-newbot.avif b/doc/mod/notification-telegram.d/newbot.avif similarity index 100% rename from doc/mod/notification-telegram.d/01-newbot.avif rename to doc/mod/notification-telegram.d/newbot.avif diff --git a/doc/mod/notification-telegram.d/03-setuserpic.avif b/doc/mod/notification-telegram.d/setuserpic.avif similarity index 100% rename from doc/mod/notification-telegram.d/03-setuserpic.avif rename to doc/mod/notification-telegram.d/setuserpic.avif diff --git a/doc/mod/notification-telegram.md b/doc/mod/notification-telegram.md index d33f6fc..804104f 100644 --- a/doc/mod/notification-telegram.md +++ b/doc/mod/notification-telegram.md @@ -36,7 +36,7 @@ Configuration Open Telegram, then start a chat with [BotFather â†—ī¸](https://t.me/BotFather) and create your own bot: -![create new bot](notification-telegram.d/01-newbot.avif) +![create new bot](notification-telegram.d/newbot.avif) Set that token from *BotFather* (use your own!) to `TelegramTokenId`, for now just temporarily: @@ -49,7 +49,7 @@ then send your first message. Any text will do. On your device run $GetTelegramChatId; -![get chat id](notification-telegram.d/02-getchatid.avif) +![get chat id](notification-telegram.d/getchatid.avif) Finally edit `global-config-overlay`, add `TelegramTokenId` with the token from *BotFather* and `TelegramChatId` with your retrieved chat id. Then @@ -104,15 +104,12 @@ Tips & Tricks You can use a profile photo for your bot to make it recognizable. Open the chat with [BotFather â†—ī¸](https://t.me/BotFather) and set it there. -![set profile photo](notification-telegram.d/03-setuserpic.avif) +![set profile photo](notification-telegram.d/setuserpic.avif) -Have a look at my [Logo Color Changer](../../contrib/logo-color.html) +Have a look at my +[RouterOS-Scripts Logo Color Changer](https://git.eworm.de/cgit/routeros-scripts/plain/contrib/logo-color.html) to create a colored version of this scripts' logo. -> đŸ’Ąī¸ **Hint**: The above link may be broken on code hosting sites. -> Use [Logo Color Changer](https://rsc.eworm.de/main/contrib/logo-color.html) -> instead. - See also -------- diff --git a/doc/mod/scriptrunonce.d/01-scriptrunonce.avif b/doc/mod/scriptrunonce.d/01-scriptrunonce.avif deleted file mode 100644 index 461c398..0000000 Binary files a/doc/mod/scriptrunonce.d/01-scriptrunonce.avif and /dev/null differ diff --git a/doc/mod/scriptrunonce.d/scriptrunonce.avif b/doc/mod/scriptrunonce.d/scriptrunonce.avif new file mode 100644 index 0000000..27ccd41 Binary files /dev/null and b/doc/mod/scriptrunonce.d/scriptrunonce.avif differ diff --git a/doc/mod/scriptrunonce.md b/doc/mod/scriptrunonce.md index db861bb..955d12e 100644 --- a/doc/mod/scriptrunonce.md +++ b/doc/mod/scriptrunonce.md @@ -48,9 +48,9 @@ Usage and invocation The function `$ScriptRunOnce` expects an URL (or name if `ScriptRunOnceBaseUrl` is given) pointing to a script as parameter. - $ScriptRunOnce https://rsc.eworm.de/main/doc/mod/scriptrunonce.d/hello-world.rsc; + $ScriptRunOnce https://git.eworm.de/cgit/routeros-scripts/plain/doc/mod/scriptrunonce.d/hello-world.rsc; -![ScriptRunOnce](scriptrunonce.d/01-scriptrunonce.avif) +![ScriptRunOnce](scriptrunonce.d/scriptrunonce.avif) Giving multiple scripts is possible, separated by comma. diff --git a/doc/mod/ssh-keys-import.md b/doc/mod/ssh-keys-import.md index abf4d39..344f4bc 100644 --- a/doc/mod/ssh-keys-import.md +++ b/doc/mod/ssh-keys-import.md @@ -38,9 +38,8 @@ 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 -the `MD5` fingerprint is recorded, this helps to audit and verify the -available keys. +`key-owner` in RouterOS. Also the `MD5` fingerprint is recorded, this helps +to audit and verify the available keys. > â„šī¸ī¸ **Info**: Use `ssh-keygen` to show a fingerprint of an existing public > key file: `ssh-keygen -l -E md5 -f ~/.ssh/id_ed25519.pub` @@ -51,10 +50,12 @@ The functions `$SSHKeysImportFile` can read an `authorized_keys`-style file and import all the keys. The user given to the function can be overwritting from comments in the file. Create a file `keys.pub` with this content: - ssh-ed25519 AAAAC3Nza...3OcN8A user@client - ssh-rsa AAAAB3Nza...ozyts= worker@station - # user=example - ssh-rsa AAAAB3Nza...GXQVk= person@host +``` +ssh-ed25519 AAAAC3Nza...3OcN8A user@client +ssh-rsa AAAAB3Nza...ozyts= worker@station +# user=example +ssh-rsa AAAAB3Nza...GXQVk= person@host +``` Then import it with: diff --git a/doc/mode-button.md b/doc/mode-button.md index af95ddb..be15bc9 100644 --- a/doc/mode-button.md +++ b/doc/mode-button.md @@ -26,15 +26,17 @@ can configure the reset button to act the same, see Copy this code to terminal to check: - :if ([ :len [ /system/routerboard/mode-button/print as-value ] ] > 0) do={ - :put "Mode button is supported."; - } else={ - :if ([ :len [ /system/routerboard/reset-button/print as-value ] ] > 0) do={ - :put "Mode button is not supported, but reset button is."; - } else={ - :put "Neither mode button nor reset button is supported."; - } - } +``` +:if ([ :len [ /system/routerboard/mode-button/print as-value ] ] > 0) do={ + :put "Mode button is supported."; +} else={ + :if ([ :len [ /system/routerboard/reset-button/print as-value ] ] > 0) do={ + :put "Mode button is not supported, but reset button is."; + } else={ + :put "Neither mode button nor reset button is supported."; + } +} +``` Requirements and installation ----------------------------- diff --git a/doc/netwatch-notify.d/notification-01-down.avif b/doc/netwatch-notify.d/notification-01-down.avif index 2257a0d..894fb23 100644 Binary files a/doc/netwatch-notify.d/notification-01-down.avif and b/doc/netwatch-notify.d/notification-01-down.avif differ diff --git a/doc/netwatch-notify.d/notification-02-up.avif b/doc/netwatch-notify.d/notification-02-up.avif index 4147cb7..9021a93 100644 Binary files a/doc/netwatch-notify.d/notification-02-up.avif and b/doc/netwatch-notify.d/notification-02-up.avif differ diff --git a/doc/sms-forward.d/notification.avif b/doc/sms-forward.d/notification.avif index 14764a3..01eb7ba 100644 Binary files a/doc/sms-forward.d/notification.avif and b/doc/sms-forward.d/notification.avif differ diff --git a/fw-addr-lists.d/allow b/fw-addr-lists.d/allow index 8c4ca3c..8b59ed7 100644 --- a/fw-addr-lists.d/allow +++ b/fw-addr-lists.d/allow @@ -1,3 +1,3 @@ # an ip address list for use with fw-addr-lists script -# https://rsc.eworm.de/doc/fw-addr-lists.md -rsc.eworm.de +# https://git.eworm.de/cgit/routeros-scripts/about/doc/fw-addr-lists.md +git.eworm.de diff --git a/fw-addr-lists.d/block b/fw-addr-lists.d/block index 86a6c62..5e9fef2 100644 --- a/fw-addr-lists.d/block +++ b/fw-addr-lists.d/block @@ -1,5 +1,5 @@ # an ip address list for use with fw-addr-lists script -# https://rsc.eworm.de/doc/fw-addr-lists.md +# https://git.eworm.de/cgit/routeros-scripts/about/doc/fw-addr-lists.md # example.net 93.184.216.34 diff --git a/fw-addr-lists.rsc b/fw-addr-lists.rsc index e5a71aa..0c45f7e 100644 --- a/fw-addr-lists.rsc +++ b/fw-addr-lists.rsc @@ -22,12 +22,9 @@ :global EitherOr; :global FetchHuge; :global HumanReadableNum; - :global IfThenElse; :global LogPrint; :global LogPrintOnce; :global LogPrintVerbose; - :global NetMask4; - :global NetMask6; :global ScriptLock; :global WaitFullyConnected; @@ -74,7 +71,7 @@ :if ([ :len ($List->"cert") ] > 0) do={ :set CheckCertificate true; - :if ([ $CertificateAvailable ($List->"cert") "fetch" ] = false) do={ + :if ([ $CertificateAvailable ($List->"cert") ] = false) do={ $LogPrint warning $ScriptName ("Downloading required certificate (" . $FwListName . \ " / " . $List->"url" . ") failed, trying anyway."); } @@ -106,7 +103,7 @@ :foreach Line in=[ :deserialize $Data delimiter="\n" from=dsv options=dsv.plain ] do={ :set Line ($Line->0); :local Address; - :if ([ :pick $Line 0 1 ] = "{" && [ :pick $Line ([ :len $Line ] - 1) ] = "}") do={ + :if ([ :pick $Line 0 1 ] = "{") do={ :do { :set Address [ :tostr ([ :deserialize from=json $Line ]->"cidr") ]; } on-error={ } @@ -114,35 +111,22 @@ :set Address ([ :pick $Line 0 [ $FindDelim $Line ] ] . ($List->"cidr")); } :do { - :local Branch; + :local Branch [ $GetBranch $Address ]; :if ($Address ~ "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(/[0-9]{1,2})?\$") do={ - :local Net $Address; - :local CIDR 32; - :local Slash [ :find $Address "/" ]; - :if ([ :typeof $Slash ] = "num") do={ - :set Net [ :toip [ :pick $Address 0 $Slash ] ] - :set CIDR [ :pick $Address ($Slash + 1) [ :len $Address ] ]; - :set Address [ :tostr (([ :toip $Net ] & [ $NetMask4 $CIDR ]) . [ $IfThenElse ($CIDR < 32) ("/" . $CIDR) ]) ]; + :if ($Address ~ "/32\$") do={ + :set Address [ :pick $Address 0 ([ :len $Address ] - 3) ]; } - :set Branch [ $GetBranch $Address ]; :set ($IPv4Addresses->$Branch->$Address) $TimeOut; :error true; } :if ($Address ~ "^[0-9a-zA-Z]*:[0-9a-zA-Z:\\.]+(/[0-9]{1,3})?\$") do={ - :local Net $Address; - :local CIDR 128; - :local Slash [ :find $Address "/" ]; - :if ([ :typeof $Slash ] = "num") do={ - :set Net [ :toip6 [ :pick $Address 0 $Slash ] ] - :set CIDR [ :pick $Address ($Slash + 1) [ :len $Address ] ]; + :if ([ :typeof [ :find $Address "/" ] ] = "nil") do={ + :set Address ($Address . "/128"); } - :set Address (([ :toip6 $Net ] & [ $NetMask6 $CIDR ]) . "/" . $CIDR); - :set Branch [ $GetBranch $Address ]; :set ($IPv6Addresses->$Branch->$Address) $TimeOut; :error true; } :if ($Address ~ "^[\\.a-zA-Z0-9-]+\\.[a-zA-Z]{2,}\$") do={ - :set Branch [ $GetBranch $Address ]; :set ($IPv4Addresses->$Branch->$Address) $TimeOut; :set ($IPv6Addresses->$Branch->$Address) $TimeOut; :error true; diff --git a/general/clipboard.js b/general/clipboard.js deleted file mode 100644 index cbcfa4a..0000000 --- a/general/clipboard.js +++ /dev/null @@ -1,8 +0,0 @@ -/* copy code to clipboard */ -function CopyToClipboard(element) { - element.style.filter = 'invert(1)'; - navigator.clipboard.writeText(element.firstElementChild.textContent); - setTimeout(function() { - element.style.filter = 'invert(0)'; - }, 100); -} diff --git a/general/eworm-meadow.avif b/general/eworm-meadow.avif deleted file mode 100644 index f592d59..0000000 Binary files a/general/eworm-meadow.avif and /dev/null differ diff --git a/general/style.css b/general/style.css deleted file mode 100644 index c3e8690..0000000 --- a/general/style.css +++ /dev/null @@ -1,108 +0,0 @@ -/* stylesheet for RouterOS Scripts */ -body { - background-color: transparent; - font-family: fira-sans, sans-serif; - font-size: 10pt; - line-height: 1.6; -} -h2 { - border-bottom: 1px solid #ccc; - color: #000; -} -a { - text-decoration: none; -} -a:hover { - text-decoration: underline; -} -blockquote { - border-left: 4px solid #ccc; - padding: 0 10px; - color: #555; -} -code { - margin: 0 2px; - padding: 2px 5px; - border: 1px solid #ccc; - background-color: #f8f8f8; - border-radius: 3px; -} -div.notification { - position: relative; - float: none; - width: 600px; - border: 3px outset #6c5d53; - /* border-radius: 5px; */ - padding: 10px; - background-color: #e6e6e6; -} -div.content { - padding-left: 60px; -} -hr { - clear: both; -} -img.logo { - float: left; - /* border-radius: 50%; */ -} -p.foot { - color: #777; - text-align: center; -} -p.heading { - font-size: 120%; - margin: 0px; - font-weight: bold; - text-decoration: underline; -} -p.hint { - display: none; -} -pre { - font-family: fira-mono, monospace; - white-space: pre-wrap; -} -pre.code { - background-color: #f8f8f8; - border: 1px solid #ccc; - overflow: auto; - padding: 6px 10px; - border-radius: 3px; -} -pre code { - margin: 0; - padding: 0; - border: 0; -} -pre.code::before { - content: "📋 Copy!"; - float: right; - border: 1px solid #ccc; - border-radius: 3px; -} -span.link { - color: #863600; -} -td.head { - line-height: 1.2; - padding: 0 2em; -} -td.head .top { - font-size: 250%; - font-weight: bold; -} -td.head .bottom { - font-size: 125%; - color: #555; -} -@media only screen and (orientation: landscape) { - body { - margin-left: 10vw; - margin-right: 10vw; - } - div.notification { - float: right; - margin: 10px; - } -} diff --git a/global-config-overlay.rsc b/global-config-overlay.rsc index 88bb4d9..9afaceb 100644 --- a/global-config-overlay.rsc +++ b/global-config-overlay.rsc @@ -6,7 +6,7 @@ # https://rsc.eworm.de/#editing-configuration # Copy relevant configuration from global-config, paste and modify it here. -# https://rsc.eworm.de/main/global-config.rsc +# https://rsc.eworm.de/global-config.rsc # End of global-config-overlay diff --git a/global-functions.rsc b/global-functions.rsc index 4bd7128..829cbf2 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -61,8 +61,6 @@ :global MAX; :global MIN; :global MkDir; -:global NetMask4; -:global NetMask6; :global NotificationFunctions; :global ParseDate; :global ParseKeyValueStore; @@ -106,15 +104,11 @@ # check and download required certificate :set CertificateAvailable do={ :local CommonName [ :tostr $1 ]; - :local UseFor [ :tostr $2 ]; :global CertificateDownload; - :global EitherOr; :global LogPrint; :global ParseKeyValueStore; - :set UseFor [ $EitherOr $UseFor "undefined" ]; - :if ([ /system/resource/get free-hdd-space ] < 8388608 && \ [ /certificate/settings/get crl-download ] = true && \ [ /certificate/settings/get crl-store ] = "system") do={ @@ -127,10 +121,7 @@ :return false; } - :local CertSettings [ /certificate/settings/get ]; - :if ((($CertSettings->"builtin-trust-anchors") = "trusted" || \ - ($CertSettings->"builtin-trust-store") ~ $UseFor || \ - ($CertSettings->"builtin-trust-store") = "all") && \ + :if (([ /certificate/settings/get ]->"builtin-trust-anchors") = "trusted" && \ [[ :parse (":return [ :len [ /certificate/builtin/find where common-name=\"" . $CommonName . "\" ] ]") ]] > 0) do={ :return true; } @@ -142,11 +133,6 @@ } } - :if ([ :len [ /certificate/find where common-name=$CommonName ] ] > 1) do={ - $LogPrint info $0 ("There are " . $CertCount . " Certificates with CommonName '" . $CommonName . "'. Should be ok."); - :return true; - } - :local CertVal [ /certificate/get [ find where common-name=$CommonName ] ]; :while (($CertVal->"akid") != "" && ($CertVal->"akid") != ($CertVal->"skid")) do={ :if ([ :len [ /certificate/find where skid=($CertVal->"akid") ] ] = 0) do={ @@ -168,6 +154,7 @@ :global ScriptUpdatesBaseUrl; :global ScriptUpdatesUrlSuffix; + :global CertificateAvailable; :global CertificateNameByCN; :global CleanName; :global FetchUserAgentStr; @@ -404,7 +391,7 @@ :return true; } - :if ([ $CertificateAvailable "ISRG Root X1" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "ISRG Root X1" ] = false) do={ $LogPrint error $0 ("Downloading required certificate failed."); :return false; } @@ -473,7 +460,7 @@ :local Error [ :tostr $3 ]; :global IfThenElse; - :global LogPrint; + :global LogPrint; :if ($ExitOK = "false") do={ $LogPrint error $Name ([ $IfThenElse ([ :pick $Name 0 1 ] = "\$") \ @@ -539,16 +526,10 @@ :set FetchUserAgentStr do={ :local Caller [ :tostr $1 ]; - :global CommitId; - :global CommitInfo; - - :global IfThenElse; - :local Resource [ /system/resource/get ]; - :return ("User-Agent: Mikrotik/" . $Resource->"version" . " " . $Resource->"architecture-name" . \ - " " . $Caller . "/Fetch (https://rsc.eworm.de/" . [ $IfThenElse ($CommitId != "unknown") \ - ("; " . $CommitInfo . "/" . [ :pick $CommitId 0 8 ]) ] . ")"); + :return ("User-Agent: Mikrotik/" . $Resource->"version" . " " . \ + $Resource->"architecture-name" . " " . $Caller . "/Fetch (https://rsc.eworm.de/)"); } # check for existence of file, optionally with type @@ -646,7 +627,7 @@ } :do { - :if ([ $CertificateAvailable "GTS Root R4" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "GTS Root R4" ] = false) do={ $LogPrint warning $0 ("Downloading required certificate failed."); :error false; } @@ -1004,43 +985,6 @@ :return true; } -# return an IPv4 netmask for CIDR -:set NetMask4 do={ - :local CIDR [ :tonum $1 ]; - - :return ((255.255.255.255 << (32 - $CIDR)) & 255.255.255.255); -} - -# return an IPv6 netmask for CIDR -:set NetMask6 do={ - :local FuncName $0; - :local CIDR [ :tostr $1 ]; - - :global IfThenElse; - :global MAX; - :global MIN; - - :global NetMask6Cache; - - :if ([ :typeof ($NetMask6Cache->$CIDR) ] = "ip6") do={ - :return ($NetMask6Cache->$CIDR); - } - - :if ([ :typeof $NetMask6Cache ] = "nothing") do={ - :set NetMask6Cache ({}); - } - - :local Mask ""; - :for I from=0 to=7 do={ - :set Mask ($Mask . \ - [ :convert from=num to=hex (0xffff - (0xffff >> [ :tonum [ $MIN [ $MAX ($CIDR - (16 * $I)) 0 ] 16 ] ])) ] . \ - [ $IfThenElse ($I < 7) ":" ]); - } - :set Mask [ :toip6 $Mask ]; - :set ($NetMask6Cache->$CIDR) $Mask; - :return $Mask; -} - # prepare NotificationFunctions array :if ([ :typeof $NotificationFunctions ] != "array") do={ :set NotificationFunctions ({}); @@ -1254,7 +1198,7 @@ :global SymbolForNotification; :global ValidateSyntax; - :if ([ $CertificateAvailable "ISRG Root X2" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "ISRG Root X2" ] = false) do={ $LogPrint warning $0 ("Downloading certificate failed, trying without."); } @@ -1305,7 +1249,7 @@ } :if ([ :len ($ScriptInfo->"certificate") ] > 0) do={ - :if ([ $CertificateAvailable ($ScriptInfo->"certificate") "fetch" ] = false) do={ + :if ([ $CertificateAvailable ($ScriptInfo->"certificate") ] = false) do={ $LogPrint warning $0 ("Downloading certificate failed, trying without."); } } @@ -1322,19 +1266,9 @@ } } do={ $LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . "': " . $Err); - :if ($Err != "Fetch failed with status 404") do={ - :error false; - } - :if ($ScriptVal->"source" = "#!rsc by RouterOS\n") do={ $LogPrint warning $0 ("Removing dummy. Typo on installation?"); /system/script/remove $Script; - :error false; - } - :if ([ :len ($ScriptInfo->"base-url") ] = 0 && [ :len ($ScriptInfo->"url-suffix") ] = 0 && \ - [ :len $CheckSum ] = 0) do={ - $LogPrintOnce warning $0 \ - ("Added the script manually? Skip updates with 'ignore=true' in comment."); } :error false; } @@ -1672,12 +1606,9 @@ :set SymbolByUnicodeName do={ :local Name [ :tostr $1 ]; - :global EitherOr; :global LogPrintOnce; - :global SymbolsExtra; - - :local Symbols ({ + :local Symbols { "abacus"="\F0\9F\A7\AE"; "alarm-clock"="\E2\8F\B0"; "arrow-down"="\E2\AC\87"; @@ -1704,7 +1635,6 @@ "mobile-phone"="\F0\9F\93\B1"; "pushpin"="\F0\9F\93\8C"; "scissors"="\E2\9C\82"; - "scroll"="\F0\9F\93\9C"; "smiley-partying-face"="\F0\9F\A5\B3"; "smiley-smiling-face"="\E2\98\BA"; "smiley-winking-face-with-tongue"="\F0\9F\98\9C"; @@ -1713,21 +1643,14 @@ "star"="\E2\AD\90"; "warning-sign"="\E2\9A\A0"; "white-heavy-check-mark"="\E2\9C\85" - }, $SymbolsExtra); - - :local Magic [ :pick [ /system/clock/get date ] 4 10 ]; - :local Special { - "information-04-01"="\F0\9F\9A\BB"; - "large-orange-circle-04-01"="\F0\9F\8D\8A"; - "large-orange-circle-10-31"="\F0\9F\8E\83"; - "large-red-circle-04-01"="\F0\9F\8D\92" }; + } :if ([ :len ($Symbols->$Name) ] = 0) do={ $LogPrintOnce warning $0 ("No symbol available for name '" . $Name . "'!"); :return ""; } - :return ([ $EitherOr ($Special->($Name . $Magic)) ($Symbols->$Name) ] . "\EF\B8\8F"); + :return (($Symbols->$Name) . "\EF\B8\8F"); } # return symbol for notification @@ -1857,11 +1780,14 @@ :local Delay ([ $MAX [ $EitherOr $WaitTime 2s ] 100ms ] / 9); :do { - :retry { - /file/get $FileName; - :return true; + :retry { + :if ([ :len [ /file/find where name=$FileName ] ] = 0) do={ + :error false; + } } delay=$Delay max=10; - } on-error={ } + } on-error={ + :return false; + } :while ([ :len [ /file/find where name=$FileName ] ] > 0) do={ :do { @@ -1909,15 +1835,6 @@ } } -# add (and fix) global scripts scheduler -:local OnEvent "/system/script { run global-config; run global-functions; }"; -:if ([ :len [ /system/scheduler/find where name="global-scripts" ] ] = 0) do={ - /system/scheduler/add name="global-scripts" start-time=startup; -} -:if ([ /system/scheduler/get "global-scripts" on-event ] != $OnEvent) do={ - /system/scheduler/set "global-scripts" on-event=$OnEvent; -} - # Log success :local Resource [ /system/resource/get ]; $LogPrintOnce info $ScriptName ("Loaded on " . $Resource->"board-name" . \ diff --git a/log-forward.rsc b/log-forward.rsc index 3d7d054..be7eff7 100644 --- a/log-forward.rsc +++ b/log-forward.rsc @@ -95,7 +95,7 @@ :set LogForwardRateLimit ($LogForwardRateLimit + 10); $SendNotification2 ({ origin=$ScriptName; \ - subject=([ $SymbolForNotification ("memo" . [ $IfThenElse ($Warning = true) ",warning-sign" ]) ] . \ + subject=([ $SymbolForNotification [ $IfThenElse ($Warning = true) "warning-sign" "memo" ] ] . \ "Log Forwarding"); \ message=("The log on " . $Identity . " contains " . [ $IfThenElse ($Count = 1) "this message" \ ("these " . $Count . " messages") ] . " after " . [ /system/resource/get uptime ] . " uptime." . \ diff --git a/mod/ipcalc.rsc b/mod/ipcalc.rsc index d65d472..eacff6d 100644 --- a/mod/ipcalc.rsc +++ b/mod/ipcalc.rsc @@ -34,34 +34,20 @@ # calculate and return netmask, network, min host, max host and broadcast :set IPCalcReturn do={ :local Input [ :tostr $1 ]; - - :global NetMask4; - :global NetMask6; - - :local Address [ :pick $Input 0 [ :find $Input "/" ] ]; + :local Address [ :toip [ :pick $Input 0 [ :find $Input "/" ] ] ]; :local Bits [ :tonum [ :pick $Input ([ :find $Input "/" ] + 1) [ :len $Input ] ] ]; - :local Mask; - :local One; - :if ([ :typeof [ :toip $Address ] ] = "ip") do={ - :set Address [ :toip $Address ]; - :set Mask [ $NetMask4 $Bits ]; - :set One 0.0.0.1; - } else={ - :set Address [ :toip6 $Address ]; - :set Mask [ $NetMask6 $Bits ]; - :set One ::1; - } + :local Mask ((255.255.255.255 << (32 - $Bits)) & 255.255.255.255); - :local Return ({ + :local Return { "address"=$Address; "netmask"=$Mask; "networkaddress"=($Address & $Mask); "networkbits"=$Bits; "network"=(($Address & $Mask) . "/" . $Bits); - "hostmin"=(($Address & $Mask) | $One); - "hostmax"=(($Address | ~$Mask) ^ $One); + "hostmin"=(($Address & $Mask) | 0.0.0.1); + "hostmax"=(($Address | ~$Mask) ^ 0.0.0.1); "broadcast"=($Address | ~$Mask); - }); + } :return $Return; } diff --git a/mod/notification-email.rsc b/mod/notification-email.rsc index 668daba..ad9762a 100644 --- a/mod/notification-email.rsc +++ b/mod/notification-email.rsc @@ -101,11 +101,8 @@ $LogPrint warning $0 ("File '" . $File . "' does not exist, can not attach."); } } - :do { - /tool/e-mail/send from=[ $EMailGenerateFrom ] to=($Message->"to") \ - cc=($Message->"cc") subject=($Message->"subject") \ - body=($Message->"body") file=$Attach; - } on-error={ } + /tool/e-mail/send from=[ $EMailGenerateFrom ] to=($Message->"to") cc=($Message->"cc") \ + subject=($Message->"subject") body=($Message->"body") file=$Attach; :local Wait true; :do { :delay 1s; @@ -132,7 +129,7 @@ } :if ($AllDone = true && $QueueLen = [ :len $EmailQueue ]) do={ - /system/scheduler/remove [ find where name="_FlushEmailQueue" ]; + /system/scheduler/remove $Scheduler; :set EmailQueue; :return true; } diff --git a/mod/notification-ntfy.rsc b/mod/notification-ntfy.rsc index dd10812..7114020 100644 --- a/mod/notification-ntfy.rsc +++ b/mod/notification-ntfy.rsc @@ -109,7 +109,7 @@ :onerror Err { :if ($Server = "ntfy.sh") do={ - :if ([ $CertificateAvailable "ISRG Root X1" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "ISRG Root X1" ] = false) do={ $LogPrint warning $0 ("Downloading required certificate failed."); :error false; } diff --git a/mod/notification-telegram.rsc b/mod/notification-telegram.rsc index b1996a3..2eb90e1 100644 --- a/mod/notification-telegram.rsc +++ b/mod/notification-telegram.rsc @@ -21,7 +21,6 @@ :global TelegramQueue; :global TelegramMessageIDs; - :global CertificateAvailable; :global IsFullyConnected; :global LogPrint; @@ -30,11 +29,6 @@ :return false; } - :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" "fetch" ] = false) do={ - $LogPrint warning $0 ("Downloading required certificate failed."); - :return false; - } - :local AllDone true; :local QueueLen [ :len $TelegramQueue ]; @@ -72,7 +66,7 @@ :global CertificateAvailable; :global LogPrint; - :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" ] = false) do={ $LogPrint warning $0 ("Downloading required certificate failed."); :return false; } @@ -197,7 +191,7 @@ "&reply_to_message_id=" . ($Notification->"replyto") . "&message_thread_id=" . $ThreadId . \ "&disable_web_page_preview=true&parse_mode=MarkdownV2"); :onerror Err { - :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" ] = false) do={ $LogPrint warning $0 ("Downloading required certificate failed."); :error false; } diff --git a/mod/ssh-keys-import.rsc b/mod/ssh-keys-import.rsc index 8bea64e..7bdc95d 100644 --- a/mod/ssh-keys-import.rsc +++ b/mod/ssh-keys-import.rsc @@ -40,9 +40,7 @@ :local FingerPrintMD5 [ :convert from=base64 transform=md5 to=hex ($KeyVal->1) ]; - :local RegEx ("\\bmd5=" . $FingerPrintMD5 . "\\b"); - :if ([ :len [ /user/ssh-keys/find where user=$User \ - (key-owner~$RegEx or info~$RegEx) ] ] > 0) do={ + :if ([ :len [ /user/ssh-keys/find where user=$User key-owner~("\\bmd5=" . $FingerPrintMD5 . "\\b") ] ] > 0) do={ $LogPrint warning $0 ("The ssh public key (MD5:" . $FingerPrintMD5 . \ ") is already available for user '" . $User . "'."); :return false; @@ -87,7 +85,7 @@ :return false; } - :if ([ $FileExists $FileName ] = false) do={ + :if ([ $FileExists $FileName ] = true) do={ $LogPrint warning $0 ("File '" . $FileName . "' does not exist."); :return false; } diff --git a/netwatch-dns.rsc b/netwatch-dns.rsc index 6006405..4fa076a 100644 --- a/netwatch-dns.rsc +++ b/netwatch-dns.rsc @@ -94,8 +94,8 @@ :set ($HostInfo->"doh-url") ("https://" . [ $EitherOr $HostName ($HostVal->"host") ] . "/dns-query"); } - :if ($DohCurrent = $HostInfo->"doh-url" && [ $IsDNSResolving ] = true) do={ - $LogPrint debug $ScriptName ("Current DoH server is still up and resolving: " . $DohCurrent); + :if ($DohCurrent = $HostInfo->"doh-url") do={ + $LogPrint debug $ScriptName ("Current DoH server is still up: " . $DohCurrent); :set ExitOK true; :error true; } @@ -105,27 +105,25 @@ } :if ([ :len $DohCurrent ] > 0) do={ - $LogPrint info $ScriptName ("Current DoH server is down or not resolving, disabling: " . $DohCurrent); + $LogPrint info $ScriptName ("Current DoH server is down, disabling: " . $DohCurrent); /ip/dns/set use-doh-server=""; /ip/dns/cache/flush; } :foreach DohServer in=$DohServers do={ :if ([ :len ($DohServer->"doh-cert") ] > 0) do={ - :if ([ $CertificateAvailable ($DohServer->"doh-cert") "dns" ] = false) do={ + :if ([ $CertificateAvailable ($DohServer->"doh-cert") ] = false) do={ $LogPrint warning $ScriptName ("Downloading certificate failed, trying without."); } } :local Data false; :onerror Err { - :retry { - :set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \ - http-header-field=({ "accept: application/dns-message" }) \ - url=(($DohServer->"doh-url") . "?dns=" . [ :convert to=base64 ([ :rndstr length=2 ] . \ - "\01\00" . "\00\01" . "\00\00" . "\00\00" . "\00\00" . "\09doh-check\05eworm\02de\00" . \ - "\00\10" . "\00\01") ]) as-value ]->"data"); - } delay=1s max=3; + :set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \ + http-header-field=({ "accept: application/dns-message" }) \ + url=(($DohServer->"doh-url") . "?dns=" . [ :convert to=base64 ([ :rndstr length=2 ] . \ + "\01\00" . "\00\01" . "\00\00" . "\00\00" . "\00\00" . "\09doh-check\05eworm\02de\00" . \ + "\00\10" . "\00\01") ]) as-value ]->"data"); } do={ $LogPrint warning $ScriptName ("Request to DoH server " . ($DohServer->"doh-url") . \ " failed: " . $Err); diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index 1fcc203..00f03cd 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -62,14 +62,14 @@ :local FwAddrList ($ScriptName . "-" . [ $GetRandom20CharAlNum ]); :if ([ :typeof [ :toip $Expected ] ] = "ip") do={ - /ip/firewall/address-list/add address=$Name list=$FwAddrList dynamic=yes timeout=30s; + /ip/firewall/address-list/add address=$Name list=$FwAddrList dynamic=yes timeout=10s; :delay 20ms; :if ([ :len [ /ip/firewall/address-list/find where list=$FwAddrList address=$Expected ] ] > 0) do={ :return true; } } :if ([ :typeof [ :toip6 $Expected ] ] = "ip6") do={ - /ipv6/firewall/address-list/add address=$Name list=$FwAddrList dynamic=yes timeout=30s; + /ipv6/firewall/address-list/add address=$Name list=$FwAddrList dynamic=yes timeout=10s; :delay 20ms; :if ([ :len [ /ipv6/firewall/address-list/find where list=$FwAddrList address=$Expected ] ] > 0) do={ :return true; @@ -127,7 +127,7 @@ $LogPrint [ $IfThenElse ($HostInfo->"no-resolve-fail" != true) warning debug ] \ $ScriptName ("Resolving name '" . $HostInfo->"resolve" . [ $IfThenElse \ ($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \ - $HostInfo->"name") "" ] . "' failed third time: " . $Err); + $HostInfo->"name") "" ] . "' failed: " . $Err); } } } diff --git a/packages-update.rsc b/packages-update.rsc index 379e818..d3140f2 100644 --- a/packages-update.rsc +++ b/packages-update.rsc @@ -41,11 +41,6 @@ /system/reboot; } - :if ([ :len [ /system/scheduler/find where name="_RebootForUpdate" ] ] > 0) do={ - $LogPrint warning $ScriptName ("Scheduler for reboot already exists."); - :return false; - } - :local Interval [ $IfThenElse ([ :totime $PackagesUpdateDeferReboot ] >= 1d) \ $PackagesUpdateDeferReboot 1d ]; :local StartTime [ :tostr [ :totime (10800 + [ $GetRandomNumber 7200 ]) ] ]; diff --git a/sms-forward.rsc b/sms-forward.rsc index 161ae6b..feb640e 100644 --- a/sms-forward.rsc +++ b/sms-forward.rsc @@ -68,8 +68,8 @@ $LogPrint warning $ScriptName ("Failed to remove message: " . $Err); } } else={ - :set Messages ($Messages . "\n\n" . [ $SymbolForNotification "incoming-envelope" ] . \ - "On " . $SmsVal->"timestamp" . " type " . $SmsVal->"type" . ":\n" . $SmsVal->"message"); + :set Messages ($Messages . "\n\nOn " . $SmsVal->"timestamp" . \ + " type " . $SmsVal->"type" . ":\n" . $SmsVal->"message"); :foreach Hook in=$SmsForwardHooks do={ :if ($Phone~($Hook->"allowed-number") && ($SmsVal->"message")~($Hook->"match")) do={ :if ([ $ValidateSyntax ($Hook->"command") ] = true) do={ diff --git a/telegram-chat.rsc b/telegram-chat.rsc index 54872fb..7f7b7a7 100644 --- a/telegram-chat.rsc +++ b/telegram-chat.rsc @@ -61,7 +61,7 @@ :set TelegramRandomDelay 0; } - :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" ] = false) do={ $LogPrint warning $ScriptName ("Downloading required certificate failed."); :set ExitOK true; :error false; diff --git a/update-tunnelbroker.rsc b/update-tunnelbroker.rsc index 5372f4c..9057e1e 100644 --- a/update-tunnelbroker.rsc +++ b/update-tunnelbroker.rsc @@ -28,7 +28,7 @@ :error false; } - :if ([ $CertificateAvailable "Starfield Root Certificate Authority - G2" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "Starfield Root Certificate Authority - G2" ] = false) do={ $LogPrint error $ScriptName ("Downloading required certificate failed."); :set ExitOK true; :error false;