aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--BRANCHES.md10
-rw-r--r--CERTIFICATES.d/01-dialog-A.avifbin0 -> 29972 bytes
-rw-r--r--CERTIFICATES.d/02-dialog-B.avifbin0 -> 28821 bytes
-rw-r--r--CERTIFICATES.d/03-window.avifbin0 -> 48111 bytes
-rw-r--r--CERTIFICATES.d/04-certificate.avifbin0 -> 22386 bytes
-rw-r--r--CERTIFICATES.md83
-rw-r--r--CONTRIBUTIONS.md11
-rw-r--r--DEBUG.md63
-rw-r--r--INITIAL-COMMANDS.md40
-rw-r--r--Makefile7
-rw-r--r--README.d/01-download-certs.avifbin4420 -> 4890 bytes
-rw-r--r--README.d/02-import-certs.avifbin3606 -> 3605 bytes
-rw-r--r--README.d/03-check-certs.avifbin12089 -> 8047 bytes
-rw-r--r--README.md184
-rw-r--r--accesslist-duplicates.capsman.rsc21
-rw-r--r--accesslist-duplicates.local.rsc21
-rw-r--r--accesslist-duplicates.template.rsc21
-rw-r--r--accesslist-duplicates.wifi.rsc21
-rw-r--r--backup-cloud.rsc38
-rw-r--r--backup-email.rsc55
-rw-r--r--backup-partition.rsc99
-rw-r--r--backup-upload.rsc61
-rw-r--r--capsman-download-packages.capsman.rsc42
-rw-r--r--capsman-download-packages.template.rsc42
-rw-r--r--capsman-download-packages.wifi.rsc42
-rw-r--r--capsman-rolling-upgrade.capsman.rsc24
-rw-r--r--capsman-rolling-upgrade.template.rsc24
-rw-r--r--capsman-rolling-upgrade.wifi.rsc24
-rw-r--r--certificate-renew-issued.rsc22
-rw-r--r--certs/Certum-Trusted-Network-CA.pem29
-rw-r--r--certs/Cloudflare-Inc-ECC-CA-3.pem163
-rw-r--r--certs/DigiCert-Global-G2-TLS-RSA-SHA256-2020-CA1.pem182
-rw-r--r--certs/DigiCert-Global-Root-G2.pem29
-rw-r--r--certs/DigiCert-Global-Root-G3.pem22
-rw-r--r--certs/DigiCert-TLS-Hybrid-ECC-SHA384-2020-CA1.pem174
-rw-r--r--certs/E1.pem124
-rw-r--r--certs/GTS-CA-1C3.pem242
-rw-r--r--certs/GTS-CA-1P5.pem238
-rw-r--r--certs/GTS-Root-R1.pem38
-rw-r--r--certs/GTS-Root-R4.pem20
-rw-r--r--certs/GlobalSign-Atlas-R3-DV-TLS-CA-2022-Q3.pem177
-rw-r--r--certs/Go-Daddy-Root-Certificate-Authority-G2.pem30
-rw-r--r--certs/Go-Daddy-Secure-Certificate-Authority-G2.pem178
-rw-r--r--certs/ISRG-Root-X1.pem38
-rw-r--r--certs/ISRG-Root-X2.pem21
-rw-r--r--certs/Makefile58
-rw-r--r--certs/R3.pem237
-rw-r--r--certs/Starfield-Root-Certificate-Authority-G2.pem30
-rw-r--r--certs/Starfield-Secure-Certificate-Authority-G2.pem179
-rw-r--r--certs/USERTrust-RSA-Certification-Authority.pem41
-rw-r--r--check-certificates.rsc78
-rw-r--r--check-health.d/state.rsc48
-rw-r--r--check-health.d/temperature.rsc74
-rw-r--r--check-health.d/voltage.rsc63
-rw-r--r--check-health.rsc132
-rw-r--r--check-lte-firmware-upgrade.rsc30
-rw-r--r--check-perpetual-license.rsc78
-rw-r--r--check-routeros-update.rsc107
-rw-r--r--collect-wireless-mac.capsman.rsc22
-rw-r--r--collect-wireless-mac.local.rsc22
-rw-r--r--collect-wireless-mac.template.rsc22
-rw-r--r--collect-wireless-mac.wifi.rsc22
-rwxr-xr-xcontrib/checksums.sh9
-rw-r--r--daily-psk.capsman.rsc30
-rw-r--r--daily-psk.local.rsc30
-rw-r--r--daily-psk.template.rsc32
-rw-r--r--daily-psk.wifi.rsc32
-rw-r--r--dhcp-lease-comment.capsman.rsc22
-rw-r--r--dhcp-lease-comment.local.rsc22
-rw-r--r--dhcp-lease-comment.template.rsc22
-rw-r--r--dhcp-lease-comment.wifi.rsc22
-rw-r--r--dhcp-to-dns.rsc28
-rw-r--r--doc/accesslist-duplicates.md2
-rw-r--r--doc/backup-cloud.md7
-rw-r--r--doc/backup-email.md4
-rw-r--r--doc/backup-partition.md27
-rw-r--r--doc/backup-upload.md5
-rw-r--r--doc/capsman-download-packages.md2
-rw-r--r--doc/capsman-rolling-upgrade.md2
-rw-r--r--doc/certificate-renew-issued.md2
-rw-r--r--doc/check-certificates.md3
-rw-r--r--doc/check-health.d/notification-08-state-fail.avif (renamed from doc/check-health.d/notification-08-psu-fail.avif)bin3474 -> 3474 bytes
-rw-r--r--doc/check-health.d/notification-09-state-ok.avif (renamed from doc/check-health.d/notification-09-psu-ok.avif)bin3531 -> 3531 bytes
-rw-r--r--doc/check-health.md49
-rw-r--r--doc/check-lte-firmware-upgrade.md6
-rw-r--r--doc/check-perpetual-license.d/notification.avifbin0 -> 4004 bytes
-rw-r--r--doc/check-perpetual-license.md71
-rw-r--r--doc/check-routeros-update.md8
-rw-r--r--doc/collect-wireless-mac.md3
-rw-r--r--doc/daily-psk.md3
-rw-r--r--doc/dhcp-lease-comment.md2
-rw-r--r--doc/dhcp-to-dns.md2
-rw-r--r--doc/firmware-upgrade-reboot.md2
-rw-r--r--doc/fw-addr-lists.md26
-rw-r--r--doc/global-wait.md2
-rw-r--r--doc/gps-track.md2
-rw-r--r--doc/hotspot-to-wpa.md2
-rw-r--r--doc/ip-addr-bridge.md2
-rw-r--r--doc/ipsec-to-dns.md2
-rw-r--r--doc/ipv6-update.md14
-rw-r--r--doc/lease-script.md2
-rw-r--r--doc/leds-mode.md2
-rw-r--r--doc/log-forward.md17
-rw-r--r--doc/mod/bridge-port-to.md2
-rw-r--r--doc/mod/bridge-port-vlan.md2
-rw-r--r--doc/mod/inspectvar.md2
-rw-r--r--doc/mod/ipcalc.md2
-rw-r--r--doc/mod/notification-email.md5
-rw-r--r--doc/mod/notification-gotify.d/appsetup.avifbin0 -> 18099 bytes
-rw-r--r--doc/mod/notification-gotify.md97
-rw-r--r--doc/mod/notification-matrix.md16
-rw-r--r--doc/mod/notification-ntfy.md14
-rw-r--r--doc/mod/notification-telegram.d/getchatid.avifbin0 -> 3896 bytes
-rw-r--r--doc/mod/notification-telegram.md36
-rw-r--r--doc/mod/scriptrunonce.md2
-rw-r--r--doc/mod/ssh-keys-import.md8
-rw-r--r--doc/mode-button.md2
-rw-r--r--doc/netwatch-dns.md21
-rw-r--r--doc/netwatch-notify.md20
-rw-r--r--doc/ospf-to-leds.md2
-rw-r--r--doc/packages-update.md6
-rw-r--r--doc/ppp-on-up.md2
-rw-r--r--doc/sms-action.md2
-rw-r--r--doc/sms-forward.md3
-rw-r--r--doc/super-mario-theme.md2
-rw-r--r--doc/telegram-chat.md2
-rw-r--r--doc/unattended-lte-firmware-upgrade.md2
-rw-r--r--doc/update-gre-address.md2
-rw-r--r--doc/update-tunnelbroker.md2
-rw-r--r--firmware-upgrade-reboot.rsc24
-rw-r--r--fw-addr-lists.rsc145
-rw-r--r--global-config-overlay.rsc8
-rw-r--r--global-config.rsc93
-rw-r--r--global-functions.rsc635
-rw-r--r--global-wait.rsc11
-rw-r--r--gps-track.rsc29
-rw-r--r--hotspot-to-wpa-cleanup.capsman.rsc28
-rw-r--r--hotspot-to-wpa-cleanup.template.rsc28
-rw-r--r--hotspot-to-wpa-cleanup.wifi.rsc28
-rw-r--r--hotspot-to-wpa.capsman.rsc25
-rw-r--r--hotspot-to-wpa.template.rsc25
-rw-r--r--hotspot-to-wpa.wifi.rsc25
-rw-r--r--ip-addr-bridge.rsc6
-rw-r--r--ipsec-to-dns.rsc23
-rw-r--r--ipv6-update.rsc44
-rw-r--r--lease-script.rsc30
-rw-r--r--leds-day-mode.rsc6
-rw-r--r--leds-night-mode.rsc6
-rw-r--r--leds-toggle-mode.rsc12
-rw-r--r--log-forward.rsc33
-rw-r--r--logo.avifbin2001 -> 1744 bytes
-rw-r--r--logo.pngbin4428 -> 4406 bytes
-rw-r--r--mod/bridge-port-to.rsc14
-rw-r--r--mod/bridge-port-vlan.rsc14
-rw-r--r--mod/inspectvar.rsc37
-rw-r--r--mod/ipcalc.rsc19
-rw-r--r--mod/notification-email.rsc132
-rw-r--r--mod/notification-gotify.rsc139
-rw-r--r--mod/notification-matrix.rsc63
-rw-r--r--mod/notification-ntfy.rsc55
-rw-r--r--mod/notification-telegram.rsc96
-rw-r--r--mod/scriptrunonce.rsc46
-rw-r--r--mod/ssh-keys-import.rsc54
-rw-r--r--mode-button.rsc47
-rw-r--r--netwatch-dns.rsc60
-rw-r--r--netwatch-notify.rsc57
-rw-r--r--news-and-changes.rsc19
-rw-r--r--ospf-to-leds.rsc22
-rw-r--r--packages-update.rsc111
-rw-r--r--ppp-on-up.rsc26
-rw-r--r--sms-action.rsc22
-rw-r--r--sms-forward.rsc44
-rw-r--r--super-mario-theme.rsc6
-rw-r--r--telegram-chat.rsc87
-rw-r--r--unattended-lte-firmware-upgrade.rsc31
-rw-r--r--update-gre-address.rsc22
-rw-r--r--update-tunnelbroker.rsc33
178 files changed, 3754 insertions, 3446 deletions
diff --git a/.gitignore b/.gitignore
index cf89f87..8abdc28 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,5 +9,8 @@
# html files (as generated from markdown)
*.html
+# checksums file as used by $ScriptInstallUpdate
+checksums.json
+
# Mac OS X folder settings file
.DS_Store
diff --git a/BRANCHES.md b/BRANCHES.md
index f1062bb..dc4f4ac 100644
--- a/BRANCHES.md
+++ b/BRANCHES.md
@@ -4,7 +4,7 @@ Installing from branches
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -13,7 +13,7 @@ Installing from branches
> ⚠️ **Warning**: Living on the edge? Great, read on!
> If not: Please use the `main` branch and leave this page!
-These scripts are developed in a [git](https://git-scm.com/) repository.
+These scripts are developed in a [git ↗️](https://git-scm.com/) repository.
Development and experimental branches are used to provide early access
for specific changes. You can install scripts from these branches
for testing.
@@ -22,13 +22,13 @@ for testing.
To install a single script from `next` branch:
- $ScriptInstallUpdate script-name "url-suffix=?h=next";
+ $ScriptInstallUpdate script-name "base-url=https://rsc.eworm.de/next/";
## Switch existing script
Alternatively switch an existing script to update from `next` branch:
- /system/script/set comment="url-suffix=?h=next" script-name;
+ /system/script/set comment="base-url=https://rsc.eworm.de/next/" script-name;
$ScriptInstallUpdate;
## Switch installation
@@ -36,7 +36,7 @@ Alternatively switch an existing script to update from `next` branch:
Last but not least - to switch the complete installation to the `next`
branch edit `global-config-overlay` and add:
- :global ScriptUpdatesUrlSuffix "?h=next";
+ :global ScriptUpdatesBaseUrl "https://rsc.eworm.de/next/";
... then reload the configuration and update:
diff --git a/CERTIFICATES.d/01-dialog-A.avif b/CERTIFICATES.d/01-dialog-A.avif
new file mode 100644
index 0000000..2fc3c9b
--- /dev/null
+++ b/CERTIFICATES.d/01-dialog-A.avif
Binary files differ
diff --git a/CERTIFICATES.d/02-dialog-B.avif b/CERTIFICATES.d/02-dialog-B.avif
new file mode 100644
index 0000000..5e408ab
--- /dev/null
+++ b/CERTIFICATES.d/02-dialog-B.avif
Binary files differ
diff --git a/CERTIFICATES.d/03-window.avif b/CERTIFICATES.d/03-window.avif
new file mode 100644
index 0000000..96039a3
--- /dev/null
+++ b/CERTIFICATES.d/03-window.avif
Binary files differ
diff --git a/CERTIFICATES.d/04-certificate.avif b/CERTIFICATES.d/04-certificate.avif
new file mode 100644
index 0000000..e666314
--- /dev/null
+++ b/CERTIFICATES.d/04-certificate.avif
Binary files differ
diff --git a/CERTIFICATES.md b/CERTIFICATES.md
new file mode 100644
index 0000000..69d6c18
--- /dev/null
+++ b/CERTIFICATES.md
@@ -0,0 +1,83 @@
+Certificate name from browser
+=============================
+
+[![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)
+
+[⬅️ Go back to main README](README.md)
+
+All well known desktop, mobile and server operating systems come with a
+certificate store that is populated with a set of well known and trusted
+certificates, acting as *trust anchors*.
+
+However RouterOS does not, still sometimes a specific certificate is
+required to properly verify a chain of trust. One example is downloading
+the scripts from this repository with `fetch` command, thus the very
+first step of [installation](README.md#the-long-way-in-detail) is importing
+the certificate.
+
+The scripts can install additional certificates when required. This happens
+from this repository if available, or from [mkcert.org ↗️](https://mkcert.org)
+as a fallback.
+
+Get the certificate's CommonName
+--------------------------------
+
+But how to determine what certificate may be required? Often easiest way
+is to use a desktop browser to get that information. This demonstration uses
+[Mozilla Firefox ↗️](https://www.mozilla.org/firefox/).
+
+Let's assume we want to make sure the certificate for
+[git.eworm.de](https://git.eworm.de/) is available. Open that page in the
+browser, then click the *lock* icon in addressbar, followed by "*Connection
+secure*".
+
+![screenshot: dialog A](CERTIFICATES.d/01-dialog-A.avif)
+
+The dialog will change, click "*More information*".
+
+![screenshot: dialog B](CERTIFICATES.d/02-dialog-B.avif)
+
+A new window opens, click the button "*View Certificate*". (That window
+can be closed now.)
+
+![screenshot: window](CERTIFICATES.d/03-window.avif)
+
+A new tab opens, showing information on the server certificate and its
+chain of trust. The leftmost certificate is what we are interested in.
+
+![screenshot: certificate](CERTIFICATES.d/04-certificate.avif)
+
+Now we know that "`ISRG Root X2`" is required, some scripts need just
+that information.
+
+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";
+
+If the certificate is actually available already nothing happens, and there
+is no output. Otherwise the certificate is downloaded and imported.
+
+If importing a certificate with that exact name fails a warning is given
+and nothing is actually imported.
+
+See also
+--------
+
+* [Download, import and update firewall address-lists](doc/fw-addr-lists.md)
+* [Manage DNS and DoH servers from netwatch](doc/netwatch-dns.md)
+* [Send notifications via Gotify](doc/mod/notification-gotify.md)
+* [Send notifications via Matrix](doc/mod/notification-matrix.md)
+* [Send notifications via Ntfy](doc/mod/notification-ntfy.md)
+
+---
+[⬅️ Go back to main README](README.md)
+[⬆️ Go back to top](#top)
diff --git a/CONTRIBUTIONS.md b/CONTRIBUTIONS.md
index 13d0508..00861c1 100644
--- a/CONTRIBUTIONS.md
+++ b/CONTRIBUTIONS.md
@@ -4,7 +4,7 @@ Past Contributions
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -20,7 +20,11 @@ for details!
* [Anatoly Bubenkov](mailto:bubenkoff@gmail.com) (@bubenkoff)
* [Ben Harris](mailto:mail@bharr.is) (@bharrisau)
* [Daniel Ziegenberg](mailto:daniel@ziegenberg.at) (@ziegenberg)
+* [Ignacio Serrano](mailto:ignic@ignic.com) (@ignic)
+* [Ilya Kulakov](mailto:kulakov.ilya@gmail.com) (@Kentzo)
+* [Leonardo David Monteiro](mailto:leo@cub3.xyz) (@leosfsm)
* [Michael Gisbers](mailto:michael@gisbers.de) (@mgisbers)
+* [Miquel Bonastre](mailto:mbonastre@yahoo.com) (@mbonastre)
* @netravnen
* [netztrip](mailto:dave-tvg@netztrip.de) (@netztrip)
* [Stefan Müller](mailto:stefan.mueller.83@gmail.com) (@PackElend)
@@ -28,15 +32,17 @@ for details!
## Donations
Add yourself to the list,
-[donate with PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)!
+[donate with PayPal ↗️](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)!
* Abdul Mannan Abbasi
+* Alex Maier
* Andrea Ruffini Perico
* Andrew Cox
* Christoph Boss (@Kampfwurst)
* Daniel Ziegenberg (@ziegenberg)
* Devin Dean (@dd2594gh)
* Evaldo Gardenal
+* Florian Estraviz
* Giorgio Bikos
* Harold Schoemaker
* Hugo BV
@@ -47,6 +53,7 @@ Add yourself to the list,
* Marek Čábák
* Oleksandr Yukhymchuk
* Peter Holtkamp
+* Peter Ponzel
* Reiner Vehrenkamp
* Richard Österreicher
* Simon Hitzemann
diff --git a/DEBUG.md b/DEBUG.md
new file mode 100644
index 0000000..66bf728
--- /dev/null
+++ b/DEBUG.md
@@ -0,0 +1,63 @@
+Debug output and logs
+=====================
+
+[![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)
+
+[⬅️ Go back to main README](README.md)
+
+Sometimes scripts do not behave as expected. In these cases debug output
+or logs can help.
+
+## Debug output
+
+Run this command in a terminal:
+
+ :set PrintDebug true;
+
+You will then see debug output when running the script from terminal.
+
+To revert to default output run:
+
+ :set PrintDebug false;
+
+### Debug output for specific script
+
+Even having debug output for a specific script or function only (or a
+set of) is possible. To enable debug output for `telegram-chat` run:
+
+ :set ($PrintDebugOverride->"telegram-chat") true;
+
+## Debug logs
+
+The debug info can go to system log. To make it show up in `memory` run:
+
+ /system/logging/add topics=script,debug action=memory;
+
+Other actions (`disk`, `email`, `remote` or `support`) can be used as
+well. I do not recommend using `echo` - use [debug output](#debug-output)
+instead.
+
+Disable or remove that setting to restore regular logging.
+
+## Verbose output
+
+Specific scripts can generate huge amount of output. These do use a function
+`$LogPrintVerbose`, which is declared, but has no code, intentionally.
+
+If you *really* want that output set the function to be the same as
+`$LogPrint`:
+
+ :set LogPrintVerbose $LogPrint;
+
+To revert that change just run:
+
+ :set LogPrintVerbose;
+
+---
+[⬅️ Go back to main README](README.md)
+[⬆️ Go back to top](#top)
diff --git a/INITIAL-COMMANDS.md b/INITIAL-COMMANDS.md
index 4a12197..40f609b 100644
--- a/INITIAL-COMMANDS.md
+++ b/INITIAL-COMMANDS.md
@@ -4,38 +4,52 @@ 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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
[⬅️ Go back to main README](README.md)
-> ⚠️ **Warning**: These command are inteneded for initial setup. If you are
+> ⚠️ **Warning**: These commands are intended for initial setup. If you are
> not aware of the procedure please follow
> [the long way in detail](README.md#the-long-way-in-detail).
Run the complete base installation:
{
- /tool/fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/E1.pem" dst-path="letsencrypt-E1.pem" as-value;
- :delay 1s;
- /certificate/import file-name=letsencrypt-E1.pem passphrase="";
- :if ([ :len [ /certificate/find where fingerprint="46494e30379059df18be52124305e606fc59070e5b21076ce113954b60517cda" or fingerprint="69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470" ] ] != 2) do={
- :error "Something is wrong with your certificates!";
+ :local BaseUrl "https://git.eworm.de/cgit/routeros-scripts/plain/";
+ :local CertCommonName "ISRG Root X2";
+ :local CertFileName "ISRG-Root-X2.pem";
+ :local CertFingerprint "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470";
+
+ :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;
+ /certificate/import file-name=$CertFileName passphrase="";
+ :if ([ :len [ /certificate/find where fingerprint=$CertFingerprint ] ] != 1) do={
+ :error "Something is wrong with your certificates!";
+ };
+ :delay 1s;
};
- /file/remove [ find where name="letsencrypt-E1.pem" ];
- :delay 1s;
+ :put "Renaming global-config-overlay, if exists...";
/system/script/set name=("global-config-overlay-" . [ /system/clock/get date ] . "-" . [ /system/clock/get time ]) [ find where name="global-config-overlay" ];
: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 ("https://git.eworm.de/cgit/routeros-scripts/plain/" . $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; }";
- :global CertificateNameByCN;
- $CertificateNameByCN "E1";
- $CertificateNameByCN "ISRG Root X2";
+ :if ([ :len [ /certificate/find where fingerprint=$CertFingerprint ] ] > 0) do={
+ :put "Renaming certificate by its common-name...";
+ :global CertificateNameByCN;
+ $CertificateNameByCN $CertFingerprint;
+ };
};
Then continue setup with
diff --git a/Makefile b/Makefile
index d21713c..8951741 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ WIFI = $(wildcard *.wifi.rsc)
MARKDOWN = $(wildcard *.md doc/*.md doc/mod/*.md)
HTML = $(MARKDOWN:.md=.html)
-all: $(CAPSMAN) $(LOCAL) $(WIFI) $(HTML)
+all: $(CAPSMAN) $(LOCAL) $(WIFI) $(HTML) checksums.json
%.html: %.md Makefile
markdown $< | sed 's/href="\([-_\./[:alnum:]]*\)\.md"/href="\1.html"/g' > $@
@@ -32,5 +32,8 @@ all: $(CAPSMAN) $(LOCAL) $(WIFI) $(HTML)
-e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \
< $< > $@
+checksums.json: contrib/checksums.sh *.rsc */*.rsc
+ contrib/checksums.sh
+
clean:
- rm -f $(HTML)
+ rm -f $(HTML) checksums.json
diff --git a/README.d/01-download-certs.avif b/README.d/01-download-certs.avif
index b27b23b..d41ca05 100644
--- a/README.d/01-download-certs.avif
+++ b/README.d/01-download-certs.avif
Binary files differ
diff --git a/README.d/02-import-certs.avif b/README.d/02-import-certs.avif
index d42994b..bf7d577 100644
--- a/README.d/02-import-certs.avif
+++ b/README.d/02-import-certs.avif
Binary files differ
diff --git a/README.d/03-check-certs.avif b/README.d/03-check-certs.avif
index 0477c39..4717b3e 100644
--- a/README.d/03-check-certs.avif
+++ b/README.d/03-check-certs.avif
Binary files differ
diff --git a/README.md b/README.md
index b6e529d..243e1fc 100644
--- a/README.md
+++ b/README.md
@@ -4,19 +4,20 @@ 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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
![RouterOS Scripts Logo](logo.svg)
-[RouterOS](https://mikrotik.com/software) is the operating system developed
-by [MikroTik](https://mikrotik.com/aboutus) for networking tasks. This
-repository holds a number of [scripts](https://wiki.mikrotik.com/wiki/Manual:Scripting)
+[RouterOS ↗️](https://mikrotik.com/software) is the operating system developed
+by [MikroTik ↗️](https://mikrotik.com/aboutus) for networking tasks. This
+repository holds a number of [scripts ↗️](https://wiki.mikrotik.com/wiki/Manual:Scripting)
to manage RouterOS devices or extend their functionality.
*Use at your own risk*, pay attention to
-[license and warranty](#license-and-warranty)!
+[license and warranty](#license-and-warranty), and
+[disclaimer on external links](#disclaimer-on-external-links)!
Requirements
------------
@@ -34,6 +35,12 @@ Specific scripts may require even newer RouterOS version.
> ℹ️ **Info**: The `main` branch is now RouterOS v7 only. If you are still
> running RouterOS v6 switch to `routeros-v6` branch!
+Starting with RouterOS 7.17 the
+[device-mode ↗️](https://help.mikrotik.com/docs/spaces/ROS/pages/93749258/Device-mode)
+has been extended to give more fine-grained control over what features are
+available. You need to enable `scheduler` and `fetch` at least, specific
+scripts may require additional features.
+
### Hardware
RouterOS packages increase in size with each release. This becomes a
@@ -55,9 +62,9 @@ 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)
+RouterOS script distribution ↗️](https://www.youtube.com/watch?v=B9neG3oAhcY)
including demonstation recorded live at [MUM Europe
-2019](https://mum.mikrotik.com/2019/EU/) in Vienna.
+2019 ↗️](https://mum.mikrotik.com/2019/EU/) in Vienna.
> ⚠️ **Warning**: Some details changed. So see the presentation, then follow
> the steps below for up-to-date commands.
@@ -65,43 +72,50 @@ including demonstation recorded live at [MUM Europe
### The long way in detail
The update script does server certificate verification, so first step is to
-download the certificates. If you intend to download the scripts from a
+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;`
+
+If you intend to download the scripts from a
different location (for example from github.com) install the corresponding
certificate chain.
- /tool/fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/E1.pem" dst-path="letsencrypt-E1.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)
Note that the commands above do *not* verify server certificate, so if you
want to be safe download with your workstations's browser and transfer the
-files to your MikroTik device.
+file to your MikroTik device.
-* [ISRG Root X2](https://letsencrypt.org/certs/isrg-root-x2.pem)
-* Let's Encrypt [E1](https://letsencrypt.org/certs/lets-encrypt-e1.pem)
+* [ISRG Root X2 ↗️](https://letsencrypt.org/certs/isrg-root-x2.pem)
-Then we import the certificates.
+Then we import the certificate.
- /certificate/import file-name=letsencrypt-E1.pem passphrase="";
+ /certificate/import file-name="isrg-root-x2.pem" passphrase="";
Do not worry that the command is not shown - that happens because it contains
a sensitive property, the passphrase.
![screenshot: import certs](README.d/02-import-certs.avif)
-For basic verification we rename the certificates and print them by
-fingerprint. Make sure exactly these two certificates ("*E1*" and
-"*ISRG-Root-X2*") are shown. Also remove the left over file.
+For basic verification we rename the certificate and print it by
+fingerprint. Make sure exactly this one certificate ("*ISRG-Root-X2*")
+is shown.
- /certificate/set name="E1" [ find where common-name="E1" ];
/certificate/set name="ISRG-Root-X2" [ find where common-name="ISRG Root X2" ];
- /certificate/print proplist=name,fingerprint where fingerprint="46494e30379059df18be52124305e606fc59070e5b21076ce113954b60517cda" or fingerprint="69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470";
- /file/remove [ find where name="letsencrypt-E1.pem" ];
+ /certificate/print proplist=name,fingerprint where fingerprint="69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470";
![screenshot: check certs](README.d/03-check-certs.avif)
Always make sure there are no certificates installed you do not know or want!
+#### Installation of scripts
+
All following commands will verify the server certificate. For validity the
certificate's lifetime is checked with local time, so make sure the device's
date and time is set correctly!
@@ -119,6 +133,9 @@ And finally load configuration and functions and add the scheduler.
![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!
+
### Scheduled automatic updates
The last step is optional: Add this scheduler **only** if you want the
@@ -157,7 +174,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:
-> `/system/script/set source=[ $Unix2Dos [ get global-config-overlay source ] ] global-config-overlay;`
+> `/system/script/set source=[ :tocrlf [ get global-config-overlay source ] ] global-config-overlay;`
Updating scripts
----------------
@@ -188,7 +205,7 @@ Scheduler and events
--------------------
Most scripts are designed to run regularly from
-[scheduler](https://wiki.mikrotik.com/wiki/Manual:System/Scheduler). We just
+[scheduler ↗️](https://wiki.mikrotik.com/wiki/Manual:System/Scheduler). We just
added `check-routeros-update`, so let's run it daily to make sure not to
miss an update.
@@ -211,60 +228,62 @@ There's much more to explore... Have fun!
Available scripts
-----------------
-* [Find and remove access list duplicates](doc/accesslist-duplicates.md)
-* [Upload backup to Mikrotik cloud](doc/backup-cloud.md)
-* [Send backup via e-mail](doc/backup-email.md)
-* [Save configuration to fallback partition](doc/backup-partition.md)
-* [Upload backup to server](doc/backup-upload.md)
-* [Download packages for CAP upgrade from CAPsMAN](doc/capsman-download-packages.md)
-* [Run rolling CAP upgrades from CAPsMAN](doc/capsman-rolling-upgrade.md)
-* [Renew locally issued certificates](doc/certificate-renew-issued.md)
-* [Renew certificates and notify on expiration](doc/check-certificates.md)
-* [Notify about health state](doc/check-health.md)
-* [Notify on LTE firmware upgrade](doc/check-lte-firmware-upgrade.md)
-* [Notify on RouterOS update](doc/check-routeros-update.md)
-* [Collect MAC addresses in wireless access list](doc/collect-wireless-mac.md)
-* [Use wireless network with daily psk](doc/daily-psk.md)
-* [Comment DHCP leases with info from access list](doc/dhcp-lease-comment.md)
-* [Create DNS records for DHCP leases](doc/dhcp-to-dns.md)
-* [Automatically upgrade firmware and reboot](doc/firmware-upgrade-reboot.md)
-* [Download, import and update firewall address-lists](doc/fw-addr-lists.md)
-* [Wait for global functions und modules](doc/global-wait.md)
-* [Send GPS position to server](doc/gps-track.md)
-* [Use WPA network with hotspot credentials](doc/hotspot-to-wpa.md)
-* [Create DNS records for IPSec peers](doc/ipsec-to-dns.md)
-* [Update configuration on IPv6 prefix change](doc/ipv6-update.md)
-* [Manage IP addresses with bridge status](doc/ip-addr-bridge.md)
-* [Run other scripts on DHCP lease](doc/lease-script.md)
-* [Manage LEDs dark mode](doc/leds-mode.md)
-* [Forward log messages via notification](doc/log-forward.md)
-* [Mode button with multiple presses](doc/mode-button.md)
-* [Manage DNS and DoH servers from netwatch](doc/netwatch-dns.md)
-* [Notify on host up and down](doc/netwatch-notify.md)
-* [Visualize OSPF state via LEDs](doc/ospf-to-leds.md)
-* [Manage system update](doc/packages-update.md)
-* [Run scripts on ppp connection](doc/ppp-on-up.md)
-* [Act on received SMS](doc/sms-action.md)
-* [Forward received SMS](doc/sms-forward.md)
-* [Play Super Mario theme](doc/super-mario-theme.md)
-* [Chat with your router and send commands via Telegram bot](doc/telegram-chat.md)
-* [Install LTE firmware upgrade](doc/unattended-lte-firmware-upgrade.md)
-* [Update GRE configuration with dynamic addresses](doc/update-gre-address.md)
-* [Update tunnelbroker configuration](doc/update-tunnelbroker.md)
+* [Find and remove access list duplicates](doc/accesslist-duplicates.md) (`accesslist-duplicates`)
+* [Upload backup to Mikrotik cloud](doc/backup-cloud.md) (`backup-cloud`)
+* [Send backup via e-mail](doc/backup-email.md) (`backup-email`)
+* [Save configuration to fallback partition](doc/backup-partition.md) (`backup-partition`)
+* [Upload backup to server](doc/backup-upload.md) (`backup-upload`)
+* [Download packages for CAP upgrade from CAPsMAN](doc/capsman-download-packages.md) (`capsman-download-packages`)
+* [Run rolling CAP upgrades from CAPsMAN](doc/capsman-rolling-upgrade.md) (`capsman-rolling-upgrade`)
+* [Renew locally issued certificates](doc/certificate-renew-issued.md) (`certificate-renew-issued`)
+* [Renew certificates and notify on expiration](doc/check-certificates.md) (`check-certificates`)
+* [Notify about health state](doc/check-health.md) (`check-health`)
+* [Notify on LTE firmware upgrade](doc/check-lte-firmware-upgrade.md) (`check-lte-firmware-upgrade`)
+* [Check perpetual license on CHR](doc/check-perpetual-license.md) (`check-perpetual-license`)
+* [Notify on RouterOS update](doc/check-routeros-update.md) (`check-routeros-update`)
+* [Collect MAC addresses in wireless access list](doc/collect-wireless-mac.md) (`collect-wireless-mac`)
+* [Use wireless network with daily psk](doc/daily-psk.md) (`daily-psk`)
+* [Comment DHCP leases with info from access list](doc/dhcp-lease-comment.md) (`dhcp-lease-comment`)
+* [Create DNS records for DHCP leases](doc/dhcp-to-dns.md) (`dhcp-to-dns`)
+* [Automatically upgrade firmware and reboot](doc/firmware-upgrade-reboot.md) (`firmware-upgrade-reboot`)
+* [Download, import and update firewall address-lists](doc/fw-addr-lists.md) (`fw-addr-lists`)
+* [Wait for global functions und modules](doc/global-wait.md) (`global-wait`)
+* [Send GPS position to server](doc/gps-track.md) (`gps-track`)
+* [Use WPA network with hotspot credentials](doc/hotspot-to-wpa.md) (`hotspot-to-wpa` & `hotspot-to-wpa-cleanup`)
+* [Create DNS records for IPSec peers](doc/ipsec-to-dns.md) (`ipsec-to-dns`)
+* [Update configuration on IPv6 prefix change](doc/ipv6-update.md) (`ipv6-update`)
+* [Manage IP addresses with bridge status](doc/ip-addr-bridge.md) (`ip-addr-bridge`)
+* [Run other scripts on DHCP lease](doc/lease-script.md) (`lease-script`)
+* [Manage LEDs dark mode](doc/leds-mode.md) (`leds-day-mode`, `leds-night-mode` & `leds-toggle-mode`)
+* [Forward log messages via notification](doc/log-forward.md) (`log-forward`)
+* [Mode button with multiple presses](doc/mode-button.md) (`mode-button`)
+* [Manage DNS and DoH servers from netwatch](doc/netwatch-dns.md) (`netwatch-dns`)
+* [Notify on host up and down](doc/netwatch-notify.md) (`netwatch-notify`)
+* [Visualize OSPF state via LEDs](doc/ospf-to-leds.md) (`ospf-to-leds`)
+* [Manage system update](doc/packages-update.md) (`packages-update`)
+* [Run scripts on ppp connection](doc/ppp-on-up.md) (`ppp-on-up`)
+* [Act on received SMS](doc/sms-action.md) (`sms-action`)
+* [Forward received SMS](doc/sms-forward.md) (`sms-forward`)
+* [Play Super Mario theme](doc/super-mario-theme.md) (`super-mario-theme`)
+* [Chat with your router and send commands via Telegram bot](doc/telegram-chat.md) (`telegram-chat`)
+* [Install LTE firmware upgrade](doc/unattended-lte-firmware-upgrade.md) (`unattended-lte-firmware-upgrade`)
+* [Update GRE configuration with dynamic addresses](doc/update-gre-address.md) (`update-gre-address`)
+* [Update tunnelbroker configuration](doc/update-tunnelbroker.md) (`update-tunnelbroker`)
Available modules
-----------------
-* [Manage ports in bridge](doc/mod/bridge-port-to.md)
-* [Manage VLANs on bridge ports](doc/mod/bridge-port-vlan.md)
-* [Inspect variables](doc/mod/inspectvar.md)
-* [IP address calculation](doc/mod/ipcalc.md)
-* [Send notifications via e-mail](doc/mod/notification-email.md)
-* [Send notifications via Matrix](doc/mod/notification-matrix.md)
-* [Send notifications via Ntfy](doc/mod/notification-ntfy.md)
-* [Send notifications via Telegram](doc/mod/notification-telegram.md)
-* [Download script and run it once](doc/mod/scriptrunonce.md)
-* [Import ssh keys for public key authentication](doc/mod/ssh-keys-import.md)
+* [Manage ports in bridge](doc/mod/bridge-port-to.md) (`mod/bridge-port-to`)
+* [Manage VLANs on bridge ports](doc/mod/bridge-port-vlan.md) (`mod/bridge-port-vlan`)
+* [Inspect variables](doc/mod/inspectvar.md) (`mod/inspectvar`)
+* [IP address calculation](doc/mod/ipcalc.md) (`mod/ipcalc`)
+* [Send notifications via e-mail](doc/mod/notification-email.md) (`mod/notification-email`)
+* [Send notifications via Gotify](doc/mod/notification-gotify.md) (`mod/notification-gotify`)
+* [Send notifications via Matrix](doc/mod/notification-matrix.md) (`mod/notification-matrix`)
+* [Send notifications via Ntfy](doc/mod/notification-ntfy.md) (`mod/notification-ntfy`)
+* [Send notifications via Telegram](doc/mod/notification-telegram.md) (`mod/notification-telegram`)
+* [Download script and run it once](doc/mod/scriptrunonce.md) (`mod/scriptrunonce`)
+* [Import ssh keys for public key authentication](doc/mod/ssh-keys-import.md) (`mod/ssh-keys-import`)
Installing custom scripts & modules
-----------------------------------
@@ -321,7 +340,7 @@ Possibly a scheduler and other configuration has to be removed as well.
Contact
-------
-We have a Telegram Group [RouterOS-Scripts](https://t.me/routeros_scripts)!
+We have a Telegram Group [RouterOS-Scripts ↗️](https://t.me/routeros_scripts)!
[![RouterOS Scripts Telegram Group](README.d/telegram-group.avif)](https://t.me/routeros_scripts)
@@ -345,7 +364,7 @@ at github.
This project is developed in private spare time and usage is free of charge
for you. If you like the scripts and think this is of value for you or your
business please consider to
-[donate with PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J).
+[donate with PayPal ↗️](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J).
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=for-the-badge)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
@@ -364,10 +383,25 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
[GNU General Public License](COPYING.md) for more details.
+Disclaimer on external links
+----------------------------
+
+Our website contains links to the websites of third parties ("external
+links"). As the content of these websites is not under our control, we
+cannot assume any liability for such external content. In all cases, the
+provider of information of the linked websites is liable for the content
+and accuracy of the information provided. At the point in time when the
+links were placed, no infringements of the law were recognisable to us.
+As soon as an infringement of the law becomes known to us, we will
+immediately remove the link in question.
+
+> 💡️ **Hint**: All external links are marked with an arrow pointing
+> diagonally in an up-right (or north-east) direction (↗️).
+
Upstream
--------
-![upstream](README.d/upstream.png)
+[![upstream](README.d/upstream.png)](https://rsc.eworm.de/)
URL:
[GitHub.com](https://github.com/eworm-de/routeros-scripts#routeros-scripts)
diff --git a/accesslist-duplicates.capsman.rsc b/accesslist-duplicates.capsman.rsc
index 781ae78..5e6cf0a 100644
--- a/accesslist-duplicates.capsman.rsc
+++ b/accesslist-duplicates.capsman.rsc
@@ -1,19 +1,20 @@
#!rsc by RouterOS
# RouterOS script: accesslist-duplicates.capsman
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# print duplicate antries in wireless access list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/accesslist-duplicates.md
+# https://rsc.eworm.de/doc/accesslist-duplicates.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:local Seen ({});
@@ -31,4 +32,6 @@
}
:set ($Seen->$Mac) 1;
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/accesslist-duplicates.local.rsc b/accesslist-duplicates.local.rsc
index b79a724..a6b4f41 100644
--- a/accesslist-duplicates.local.rsc
+++ b/accesslist-duplicates.local.rsc
@@ -1,19 +1,20 @@
#!rsc by RouterOS
# RouterOS script: accesslist-duplicates.local
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# print duplicate antries in wireless access list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/accesslist-duplicates.md
+# https://rsc.eworm.de/doc/accesslist-duplicates.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:local Seen ({});
@@ -31,4 +32,6 @@
}
:set ($Seen->$Mac) 1;
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/accesslist-duplicates.template.rsc b/accesslist-duplicates.template.rsc
index b8067c8..e51198d 100644
--- a/accesslist-duplicates.template.rsc
+++ b/accesslist-duplicates.template.rsc
@@ -1,20 +1,21 @@
#!rsc by RouterOS
# RouterOS script: accesslist-duplicates%TEMPL%
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# print duplicate antries in wireless access list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/accesslist-duplicates.md
+# https://rsc.eworm.de/doc/accesslist-duplicates.md
#
# !! This is just a template to generate the real script!
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:local Seen ({});
@@ -40,4 +41,6 @@
}
:set ($Seen->$Mac) 1;
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/accesslist-duplicates.wifi.rsc b/accesslist-duplicates.wifi.rsc
index c05e02c..cadacb6 100644
--- a/accesslist-duplicates.wifi.rsc
+++ b/accesslist-duplicates.wifi.rsc
@@ -1,19 +1,20 @@
#!rsc by RouterOS
# RouterOS script: accesslist-duplicates.wifi
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# print duplicate antries in wireless access list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/accesslist-duplicates.md
+# https://rsc.eworm.de/doc/accesslist-duplicates.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:local Seen ({});
@@ -31,4 +32,6 @@
}
:set ($Seen->$Mac) 1;
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/backup-cloud.rsc b/backup-cloud.rsc
index 88dd345..e41db27 100644
--- a/backup-cloud.rsc
+++ b/backup-cloud.rsc
@@ -1,18 +1,19 @@
#!rsc by RouterOS
# RouterOS script: backup-cloud
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: backup-script, order=40
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# upload backup to MikroTik cloud
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/backup-cloud.md
+# https://rsc.eworm.de/doc/backup-cloud.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global BackupRandomDelay;
@@ -25,6 +26,7 @@
:global LogPrint;
:global MkDir;
:global RandomDelay;
+ :global RmDir;
:global ScriptFromTerminal;
:global ScriptLock;
:global SendNotification2;
@@ -34,8 +36,17 @@
:if ([ $ScriptLock $ScriptName ] = false) do={
:set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
:error false;
}
+
+ :if ([ :len [ /system/scheduler/find where name="running-from-backup-partition" ] ] > 0) do={
+ $LogPrint warning $ScriptName ("Running from backup partition, refusing to act.");
+ :set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
+ :error false;
+ }
+
$WaitFullyConnected;
:if ([ $ScriptFromTerminal $ScriptName ] = false && $BackupRandomDelay > 0) do={
@@ -44,6 +55,7 @@
:if ([ $MkDir ("tmpfs/backup-cloud") ] = false) do={
$LogPrint error $ScriptName ("Failed creating directory!");
+ :set ExitOK true;
:error false;
}
@@ -66,6 +78,10 @@
} while=([ $WaitForFile "tmpfs/backup-cloud/done" 200ms ] = false && $I > 0);
:if ([ $WaitForFile "tmpfs/backup-cloud/done" ] = true) do={
+ :if ($I < 4) do={
+ :log warning ($ScriptName . ": Retry successful, please discard previous connection errors.");
+ }
+
:local Cloud [ /system/backup/cloud/get ([ find ]->0) ];
$SendNotification2 ({ origin=$ScriptName; \
@@ -82,5 +98,7 @@
$LogPrint error $ScriptName ("Failed uploading backup for " . $Identity . " to cloud!");
:set PackagesUpdateBackupFailure true;
}
- /file/remove "tmpfs/backup-cloud";
-} on-error={ }
+ $RmDir "tmpfs/backup-cloud";
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/backup-email.rsc b/backup-email.rsc
index c32eb27..8015bea 100644
--- a/backup-email.rsc
+++ b/backup-email.rsc
@@ -1,18 +1,19 @@
#!rsc by RouterOS
# RouterOS script: backup-email
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: backup-script, order=20
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# create and email backup and config file
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/backup-email.md
+# https://rsc.eworm.de/doc/backup-email.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global BackupPassword;
@@ -26,6 +27,7 @@
:global CleanName;
:global DeviceInfo;
+ :global FileExists;
:global FormatLine;
:global LogPrint;
:global MkDir;
@@ -39,19 +41,30 @@
:if ([ :typeof $SendEMail2 ] = "nothing") do={
$LogPrint error $ScriptName ("The module for sending notifications via e-mail is not installed.");
+ :set ExitOK true;
:error false;
}
:if ($BackupSendBinary != true && \
$BackupSendExport != true) do={
$LogPrint error $ScriptName ("Configured to send neither backup nor config export.");
+ :set ExitOK true;
:error false;
}
:if ([ $ScriptLock $ScriptName ] = false) do={
:set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
:error false;
}
+
+ :if ([ :len [ /system/scheduler/find where name="running-from-backup-partition" ] ] > 0) do={
+ $LogPrint warning $ScriptName ("Running from backup partition, refusing to act.");
+ :set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
+ :error false;
+ }
+
$WaitFullyConnected;
:if ([ $ScriptFromTerminal $ScriptName ] = false && $BackupRandomDelay > 0) do={
@@ -69,6 +82,7 @@
:if ([ $MkDir $DirName ] = false) do={
$LogPrint error $ScriptName ("Failed creating directory!");
+ :set ExitOK true;
:error false;
}
@@ -111,14 +125,19 @@
attach=$Attach; remove-attach=true });
# wait for the mail to be sent
- :local I 0;
- :while ([ :len [ /file/find where name ~ ($FilePath . "\\.(backup|rsc)\$") ] ] > 0) do={
- :if ($I >= 120) do={
- $LogPrint warning $ScriptName ("Files are still available, sending e-mail failed.");
- :set PackagesUpdateBackupFailure true;
- :error false;
- }
- :delay 1s;
- :set I ($I + 1);
+ :do {
+ :retry {
+ :if ([ $FileExists ($FilePath . ".conf") ".conf file" ] = true || \
+ [ $FileExists ($FilePath . ".backup") "backup" ] = true || \
+ [ $FileExists ($FilePath . ".rsc") "script" ] = true) do={
+ :error "Files are still available.";
+ }
+ } delay=1s max=120;
+ } on-error={
+ $LogPrint warning $ScriptName ("Files are still available, sending e-mail failed.");
+ :set PackagesUpdateBackupFailure true;
}
-} on-error={ }
+ # do not remove the files here, as the mail is still queued!
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/backup-partition.rsc b/backup-partition.rsc
index fc186c0..ae7ad03 100644
--- a/backup-partition.rsc
+++ b/backup-partition.rsc
@@ -1,33 +1,65 @@
#!rsc by RouterOS
# RouterOS script: backup-partition
-# Copyright (c) 2022-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2022-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: backup-script, order=70
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, scheduler
#
# save configuration to fallback partition
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/backup-partition.md
+# https://rsc.eworm.de/doc/backup-partition.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
+ :global BackupPartitionCopyBeforeFeatureUpdate;
:global PackagesUpdateBackupFailure;
:global LogPrint;
+ :global ScriptFromTerminal;
:global ScriptLock;
+ :global VersionToNum;
+
+ :local CopyTo do={
+ :local ScriptName [ :tostr $1 ];
+ :local FallbackTo [ :toid $2 ];
+ :local FallbackToName [ :tostr $3 ];
+
+ :global LogPrint;
+
+ :onerror Err {
+ /partitions/copy-to $FallbackTo;
+ $LogPrint info $ScriptName ("Copied RouterOS to partition '" . $FallbackToName . "'.");
+ } do={
+ $LogPrint error $ScriptName ("Failed copying RouterOS to partition '" . \
+ $FallbackToName . "': " . $Err);
+ :return false;
+ }
+ :return true;
+ }
:if ([ $ScriptLock $ScriptName ] = false) do={
:set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
+ :error false;
+ }
+
+ :if ([ :len [ /system/scheduler/find where name="running-from-backup-partition" ] ] > 0) do={
+ $LogPrint warning $ScriptName ("Running from backup partition, refusing to act.");
+ :set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
:error false;
}
:if ([ :len [ /partitions/find ] ] < 2) do={
$LogPrint error $ScriptName ("Device does not have a fallback partition.");
:set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
:error false;
}
@@ -36,22 +68,61 @@
:if ([ :len $ActiveRunning ] < 1) do={
$LogPrint error $ScriptName ("Device is not running from active partition.");
:set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
:error false;
}
- :local FallbackTo [ /partitions/get $ActiveRunning fallback-to ];
+ :local FallbackToName [ /partitions/get $ActiveRunning fallback-to ];
+ :local FallbackTo [ /partition/find where name=$FallbackToName !active ];
+
+ :if ([ :len $FallbackTo ] < 1) do={
+ $LogPrint error $ScriptName ("There is no inactive partition named '" . $FallbackToName . "'.");
+ :set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
+ :error false;
+ }
+
+ :if ([ /partitions/get $ActiveRunning version ] != [ /partitions/get $FallbackTo version]) do={
+ :if ([ $ScriptFromTerminal $ScriptName ] = true) do={
+ :put ("The partitions have different RouterOS versions. Copy over to '" . $FallbackToName . "'? [y/N]");
+ :if (([ /terminal/inkey timeout=60 ] % 32) = 25) do={
+ :if ([ $CopyTo $ScriptName $FallbackTo $FallbackToName ] = false) do={
+ :set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
+ :error false;
+ }
+ }
+ } else={
+ :local Update [ /system/package/update/get ];
+ :local NumInstalled [ $VersionToNum ($Update->"installed-version") ];
+ :local NumLatest [ $VersionToNum ($Update->"latest-version") ];
+ :local BitMask [ $VersionToNum "255.255zero0" ];
+ :if ($BackupPartitionCopyBeforeFeatureUpdate = true && $NumLatest > 0 && \
+ ($NumInstalled & $BitMask) != ($NumLatest & $BitMask)) do={
+ :if ([ $CopyTo $ScriptName $FallbackTo $FallbackToName ] = false) do={
+ :set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
+ :error false;
+ }
+ }
+ }
+ }
- :do {
+ :onerror Err {
/system/scheduler/add start-time=startup name="running-from-backup-partition" \
on-event=(":log warning (\"Running from partition '\" . " . \
"[ /partitions/get [ find where running ] name ] . \"'!\")");
/partitions/save-config-to $FallbackTo;
/system/scheduler/remove "running-from-backup-partition";
- $LogPrint info $ScriptName ("Saved configuration to partition '" . $FallbackTo . "'.");
- } on-error={
+ $LogPrint info $ScriptName ("Saved configuration to partition '" . $FallbackToName . "'.");
+ } do={
/system/scheduler/remove [ find where name="running-from-backup-partition" ];
- $LogPrint error $ScriptName ("Failed saving configuration to partition '" . $FallbackTo . "'!");
+ $LogPrint error $ScriptName ("Failed saving configuration to partition '" . \
+ $FallbackToName . "': " . $Err);
:set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
:error false;
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/backup-upload.rsc b/backup-upload.rsc
index 1dc98d5..e6b9f92 100644
--- a/backup-upload.rsc
+++ b/backup-upload.rsc
@@ -1,18 +1,20 @@
#!rsc by RouterOS
# RouterOS script: backup-upload
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: backup-script, order=50
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, fetch
#
# create and upload backup and config file
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/backup-upload.md
+# https://rsc.eworm.de/doc/backup-upload.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global BackupPassword;
@@ -33,6 +35,8 @@
:global LogPrint;
:global MkDir;
:global RandomDelay;
+ :global RmDir;
+ :global RmFile;
:global ScriptFromTerminal;
:global ScriptLock;
:global SendNotification2;
@@ -43,13 +47,23 @@
:if ($BackupSendBinary != true && \
$BackupSendExport != true) do={
$LogPrint error $ScriptName ("Configured to send neither backup nor config export.");
+ :set ExitOK true;
:error false;
}
:if ([ $ScriptLock $ScriptName ] = false) do={
:set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
+ :error false;
+ }
+
+ :if ([ :len [ /system/scheduler/find where name="running-from-backup-partition" ] ] > 0) do={
+ $LogPrint warning $ScriptName ("Running from backup partition, refusing to act.");
+ :set PackagesUpdateBackupFailure true;
+ :set ExitOK true;
:error false;
}
+
$WaitFullyConnected;
:if ([ $ScriptFromTerminal $ScriptName ] = false && $BackupRandomDelay > 0) do={
@@ -67,6 +81,7 @@
:if ([ $MkDir $DirName ] = false) do={
$LogPrint error $ScriptName ("Failed creating directory!");
+ :set ExitOK true;
:error false;
}
@@ -75,18 +90,18 @@
/system/backup/save encryption=aes-sha256 name=$FilePath password=$BackupPassword;
$WaitForFile ($FilePath . ".backup");
- :do {
+ :onerror Err {
/tool/fetch upload=yes url=($BackupUploadUrl . "/" . $FileName . ".backup") \
user=$BackupUploadUser password=$BackupUploadPass src-path=($FilePath . ".backup");
:set BackupFile [ /file/get ($FilePath . ".backup") ];
:set ($BackupFile->"name") ($FileName . ".backup");
- } on-error={
- $LogPrint error $ScriptName ("Uploading backup file failed!");
+ } do={
+ $LogPrint error $ScriptName ("Uploading backup file failed: " . $Err);
:set BackupFile "failed";
:set Failed 1;
}
- /file/remove ($FilePath . ".backup");
+ $RmFile ($FilePath . ".backup");
}
# create configuration export
@@ -94,18 +109,18 @@
/export terse show-sensitive file=$FilePath;
$WaitForFile ($FilePath . ".rsc");
- :do {
+ :onerror Err {
/tool/fetch upload=yes url=($BackupUploadUrl . "/" . $FileName . ".rsc") \
user=$BackupUploadUser password=$BackupUploadPass src-path=($FilePath . ".rsc");
:set ExportFile [ /file/get ($FilePath . ".rsc") ];
:set ($ExportFile->"name") ($FileName . ".rsc");
- } on-error={
- $LogPrint error $ScriptName ("Uploading configuration export failed!");
+ } do={
+ $LogPrint error $ScriptName ("Uploading configuration export failed: " . $Err);
:set ExportFile "failed";
:set Failed 1;
}
- /file/remove ($FilePath . ".rsc");
+ $RmFile ($FilePath . ".rsc");
}
# global-config-overlay
@@ -115,18 +130,18 @@
file=($FilePath . ".conf\00");
$WaitForFile ($FilePath . ".conf");
- :do {
+ :onerror Err {
/tool/fetch upload=yes url=($BackupUploadUrl . "/" . $FileName . ".conf") \
user=$BackupUploadUser password=$BackupUploadPass src-path=($FilePath . ".conf");
:set ConfigFile [ /file/get ($FilePath . ".conf") ];
:set ($ConfigFile->"name") ($FileName . ".conf");
- } on-error={
- $LogPrint error $ScriptName ("Uploading global-config-overlay failed!");
+ } do={
+ $LogPrint error $ScriptName ("Uploading global-config-overlay failed: " . $Err);
:set ConfigFile "failed";
:set Failed 1;
}
- /file/remove ($FilePath . ".conf");
+ $RmFile ($FilePath . ".conf");
}
:local FileInfo do={
@@ -157,5 +172,7 @@
:if ($Failed = 1) do={
:set PackagesUpdateBackupFailure true;
}
- /file/remove $DirName;
-} on-error={ }
+ $RmDir $DirName;
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/capsman-download-packages.capsman.rsc b/capsman-download-packages.capsman.rsc
index f5695f4..2ea1667 100644
--- a/capsman-download-packages.capsman.rsc
+++ b/capsman-download-packages.capsman.rsc
@@ -1,30 +1,34 @@
#!rsc by RouterOS
# RouterOS script: capsman-download-packages.capsman
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# download and cleanup packages for CAP installation from CAPsMAN
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/capsman-download-packages.md
+# https://rsc.eworm.de/doc/capsman-download-packages.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global CleanFilePath;
:global DownloadPackage;
+ :global FileGet;
:global LogPrint;
:global MkDir;
+ :global RmFile;
:global ScriptLock;
:global WaitFullyConnected;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
$WaitFullyConnected;
@@ -35,20 +39,22 @@
:if ([ :len $PackagePath ] = 0) do={
$LogPrint warning $ScriptName ("The CAPsMAN package path is not defined, can not download packages.");
+ :set ExitOK true;
:error false;
}
- :if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={
+ :if ([ $FileGet $PackagePath ] = false) do={
:if ([ $MkDir $PackagePath ] = false) do={
$LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \
$PackagePath . ") failed!");
+ :set ExitOK true;
:error false;
}
$LogPrint info $ScriptName ("Created directory at CAPsMAN package path (" . $PackagePath . \
"). Please place your packages!");
}
- :foreach Package in=[ /file/find where type=package \
+ :foreach Package in=[ /file/find where type="package" \
package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={
:local File [ /file/get $Package ];
:if ($File->"package-architecture" = "mips") do={
@@ -57,11 +63,11 @@
:if ([ $DownloadPackage ($File->"package-name") $InstalledVersion \
($File->"package-architecture") $PackagePath ] = true) do={
:set Updated true;
- /file/remove $Package;
+ $RmFile ($File->"name");
}
}
- :if ([ :len [ /file/find where type=package name~("^" . $PackagePath) ] ] = 0) do={
+ :if ([ :len [ /file/find where type="package" name~("^" . $PackagePath) ] ] = 0) do={
$LogPrint info $ScriptName ("No packages available, downloading default set.");
:foreach Arch in={ "arm"; "mipsbe" } do={
:foreach Package in={ "routeros"; "wireless" } do={
@@ -73,11 +79,15 @@
}
:if ($Updated = true) do={
- :local Script ([ /system/script/find where source~"\n# provides: capsman-rolling-upgrade\n" ]->0);
- :if ([ :len $Script ] > 0) do={
- /system/script/run $Script;
+ :local Scripts [ /system/script/find where source~"\n# provides: capsman-rolling-upgrade.capsman\r?\n" ];
+ :if ([ :len $Scripts ] > 0) do={
+ :foreach Script in=$Scripts do={
+ /system/script/run $Script;
+ }
} else={
/caps-man/remote-cap/upgrade [ find where version!=$InstalledVersion ];
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/capsman-download-packages.template.rsc b/capsman-download-packages.template.rsc
index 762dbb6..f95212a 100644
--- a/capsman-download-packages.template.rsc
+++ b/capsman-download-packages.template.rsc
@@ -1,31 +1,35 @@
#!rsc by RouterOS
# RouterOS script: capsman-download-packages%TEMPL%
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# download and cleanup packages for CAP installation from CAPsMAN
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/capsman-download-packages.md
+# https://rsc.eworm.de/doc/capsman-download-packages.md
#
# !! This is just a template to generate the real script!
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global CleanFilePath;
:global DownloadPackage;
+ :global FileGet;
:global LogPrint;
:global MkDir;
+ :global RmFile;
:global ScriptLock;
:global WaitFullyConnected;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
$WaitFullyConnected;
@@ -37,20 +41,22 @@
:if ([ :len $PackagePath ] = 0) do={
$LogPrint warning $ScriptName ("The CAPsMAN package path is not defined, can not download packages.");
+ :set ExitOK true;
:error false;
}
- :if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={
+ :if ([ $FileGet $PackagePath ] = false) do={
:if ([ $MkDir $PackagePath ] = false) do={
$LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \
$PackagePath . ") failed!");
+ :set ExitOK true;
:error false;
}
$LogPrint info $ScriptName ("Created directory at CAPsMAN package path (" . $PackagePath . \
"). Please place your packages!");
}
- :foreach Package in=[ /file/find where type=package \
+ :foreach Package in=[ /file/find where type="package" \
package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={
:local File [ /file/get $Package ];
:if ($File->"package-architecture" = "mips") do={
@@ -59,11 +65,11 @@
:if ([ $DownloadPackage ($File->"package-name") $InstalledVersion \
($File->"package-architecture") $PackagePath ] = true) do={
:set Updated true;
- /file/remove $Package;
+ $RmFile ($File->"name");
}
}
- :if ([ :len [ /file/find where type=package name~("^" . $PackagePath) ] ] = 0) do={
+ :if ([ :len [ /file/find where type="package" name~("^" . $PackagePath) ] ] = 0) do={
$LogPrint info $ScriptName ("No packages available, downloading default set.");
# NOT /interface/wifi/ #
:foreach Arch in={ "arm"; "mipsbe" } do={
@@ -83,12 +89,16 @@
}
:if ($Updated = true) do={
- :local Script ([ /system/script/find where source~"\n# provides: capsman-rolling-upgrade\n" ]->0);
- :if ([ :len $Script ] > 0) do={
- /system/script/run $Script;
+ :local Scripts [ /system/script/find where source~"\n# provides: capsman-rolling-upgrade%TEMPL%\r?\n" ];
+ :if ([ :len $Scripts ] > 0) do={
+ :foreach Script in=$Scripts do={
+ /system/script/run $Script;
+ }
} else={
/caps-man/remote-cap/upgrade [ find where version!=$InstalledVersion ];
/interface/wifi/capsman/remote-cap/upgrade [ find where version!=$InstalledVersion ];
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/capsman-download-packages.wifi.rsc b/capsman-download-packages.wifi.rsc
index 79aa9a7..03fd9e7 100644
--- a/capsman-download-packages.wifi.rsc
+++ b/capsman-download-packages.wifi.rsc
@@ -1,30 +1,34 @@
#!rsc by RouterOS
# RouterOS script: capsman-download-packages.wifi
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# download and cleanup packages for CAP installation from CAPsMAN
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/capsman-download-packages.md
+# https://rsc.eworm.de/doc/capsman-download-packages.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global CleanFilePath;
:global DownloadPackage;
+ :global FileGet;
:global LogPrint;
:global MkDir;
+ :global RmFile;
:global ScriptLock;
:global WaitFullyConnected;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
$WaitFullyConnected;
@@ -35,20 +39,22 @@
:if ([ :len $PackagePath ] = 0) do={
$LogPrint warning $ScriptName ("The CAPsMAN package path is not defined, can not download packages.");
+ :set ExitOK true;
:error false;
}
- :if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={
+ :if ([ $FileGet $PackagePath ] = false) do={
:if ([ $MkDir $PackagePath ] = false) do={
$LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \
$PackagePath . ") failed!");
+ :set ExitOK true;
:error false;
}
$LogPrint info $ScriptName ("Created directory at CAPsMAN package path (" . $PackagePath . \
"). Please place your packages!");
}
- :foreach Package in=[ /file/find where type=package \
+ :foreach Package in=[ /file/find where type="package" \
package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={
:local File [ /file/get $Package ];
:if ($File->"package-architecture" = "mips") do={
@@ -57,11 +63,11 @@
:if ([ $DownloadPackage ($File->"package-name") $InstalledVersion \
($File->"package-architecture") $PackagePath ] = true) do={
:set Updated true;
- /file/remove $Package;
+ $RmFile ($File->"name");
}
}
- :if ([ :len [ /file/find where type=package name~("^" . $PackagePath) ] ] = 0) do={
+ :if ([ :len [ /file/find where type="package" name~("^" . $PackagePath) ] ] = 0) do={
$LogPrint info $ScriptName ("No packages available, downloading default set.");
:foreach Arch in={ "arm"; "arm64" } do={
:local Packages { "arm"={ "routeros"; "wifi-qcom"; "wifi-qcom-ac" };
@@ -75,11 +81,15 @@
}
:if ($Updated = true) do={
- :local Script ([ /system/script/find where source~"\n# provides: capsman-rolling-upgrade\n" ]->0);
- :if ([ :len $Script ] > 0) do={
- /system/script/run $Script;
+ :local Scripts [ /system/script/find where source~"\n# provides: capsman-rolling-upgrade.wifi\r?\n" ];
+ :if ([ :len $Scripts ] > 0) do={
+ :foreach Script in=$Scripts do={
+ /system/script/run $Script;
+ }
} else={
/interface/wifi/capsman/remote-cap/upgrade [ find where version!=$InstalledVersion ];
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/capsman-rolling-upgrade.capsman.rsc b/capsman-rolling-upgrade.capsman.rsc
index 2c9ae3d..0d4114a 100644
--- a/capsman-rolling-upgrade.capsman.rsc
+++ b/capsman-rolling-upgrade.capsman.rsc
@@ -1,27 +1,29 @@
#!rsc by RouterOS
# RouterOS script: capsman-rolling-upgrade.capsman
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# provides: capsman-rolling-upgrade
-# requires RouterOS, version=7.13
+# provides: capsman-rolling-upgrade.capsman
+# requires RouterOS, version=7.15
#
# upgrade CAPs one after another
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/capsman-rolling-upgrade.md
+# https://rsc.eworm.de/doc/capsman-rolling-upgrade.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global LogPrint;
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -43,4 +45,6 @@
:delay ($Delay . "s");
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/capsman-rolling-upgrade.template.rsc b/capsman-rolling-upgrade.template.rsc
index 2098bc0..690d73d 100644
--- a/capsman-rolling-upgrade.template.rsc
+++ b/capsman-rolling-upgrade.template.rsc
@@ -1,28 +1,30 @@
#!rsc by RouterOS
# RouterOS script: capsman-rolling-upgrade%TEMPL%
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# provides: capsman-rolling-upgrade
-# requires RouterOS, version=7.13
+# provides: capsman-rolling-upgrade%TEMPL%
+# requires RouterOS, version=7.15
#
# upgrade CAPs one after another
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/capsman-rolling-upgrade.md
+# https://rsc.eworm.de/doc/capsman-rolling-upgrade.md
#
# !! This is just a template to generate the real script!
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global LogPrint;
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -51,4 +53,6 @@
:delay ($Delay . "s");
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/capsman-rolling-upgrade.wifi.rsc b/capsman-rolling-upgrade.wifi.rsc
index 36b8c0f..8e32ab2 100644
--- a/capsman-rolling-upgrade.wifi.rsc
+++ b/capsman-rolling-upgrade.wifi.rsc
@@ -1,27 +1,29 @@
#!rsc by RouterOS
# RouterOS script: capsman-rolling-upgrade.wifi
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# provides: capsman-rolling-upgrade
-# requires RouterOS, version=7.13
+# provides: capsman-rolling-upgrade.wifi
+# requires RouterOS, version=7.15
#
# upgrade CAPs one after another
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/capsman-rolling-upgrade.md
+# https://rsc.eworm.de/doc/capsman-rolling-upgrade.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global LogPrint;
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -44,4 +46,6 @@
:delay ($Delay . "s");
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/certificate-renew-issued.rsc b/certificate-renew-issued.rsc
index 7815443..14917e4 100644
--- a/certificate-renew-issued.rsc
+++ b/certificate-renew-issued.rsc
@@ -1,17 +1,18 @@
#!rsc by RouterOS
# RouterOS script: certificate-renew-issued
-# Copyright (c) 2019-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# renew locally issued certificates
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/certificate-renew-issued.md
+# https://rsc.eworm.de/doc/certificate-renew-issued.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global CertIssuedExportPass;
@@ -21,6 +22,7 @@
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -45,4 +47,6 @@
$LogPrint info $ScriptName ("Issued a new certificate for '" . $CertVal->"common-name" . "'.");
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/certs/Certum-Trusted-Network-CA.pem b/certs/Certum-Trusted-Network-CA.pem
new file mode 100644
index 0000000..a48e706
--- /dev/null
+++ b/certs/Certum-Trusted-Network-CA.pem
@@ -0,0 +1,29 @@
+# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
+# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
+# Label: "Certum Trusted Network CA"
+# Serial: 279744
+# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78
+# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e
+# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e
+-----BEGIN CERTIFICATE-----
+MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
+MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
+ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
+cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
+WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
+Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
+IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
+UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
+TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
+BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
+kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
+AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
+sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
+I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
+J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
+VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
+03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
+-----END CERTIFICATE-----
diff --git a/certs/Cloudflare-Inc-ECC-CA-3.pem b/certs/Cloudflare-Inc-ECC-CA-3.pem
deleted file mode 100644
index fa91603..0000000
--- a/certs/Cloudflare-Inc-ECC-CA-3.pem
+++ /dev/null
@@ -1,163 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 0a:37:87:64:5e:5f:b4:8c:22:4e:fd:1b:ed:14:0c:3c
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
- Validity
- Not Before: Jan 27 12:48:08 2020 GMT
- Not After : Dec 31 23:59:59 2024 GMT
- Subject: C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
- Subject Public Key Info:
- Public Key Algorithm: id-ecPublicKey
- Public-Key: (256 bit)
- pub:
- 04:b9:ad:4d:66:99:14:0b:46:ec:1f:81:d1:2a:50:
- 1e:9d:03:15:2f:34:12:7d:2d:96:b8:88:38:9b:85:
- 5f:8f:bf:bb:4d:ef:61:46:c4:c9:73:d4:24:4f:e0:
- ee:1c:ce:6c:b3:51:71:2f:6a:ee:4c:05:09:77:d3:
- 72:62:a4:9b:d7
- ASN1 OID: prime256v1
- NIST CURVE: P-256
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- A5:CE:37:EA:EB:B0:75:0E:94:67:88:B4:45:FA:D9:24:10:87:96:1F
- X509v3 Authority Key Identifier:
- E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
- X509v3 CRL Distribution Points:
- Full Name:
- URI:http://crl3.digicert.com/Omniroot2025.crl
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.114412.1.1
- CPS: https://www.digicert.com/CPS
- Policy: 2.16.840.1.114412.1.2
- Policy: 2.23.140.1.2.1
- Policy: 2.23.140.1.2.2
- Policy: 2.23.140.1.2.3
- Signature Algorithm: sha256WithRSAEncryption
- Signature Value:
- 05:24:1d:dd:1b:b0:2a:eb:98:d6:85:e3:39:4d:5e:6b:57:9d:
- 82:57:fc:eb:e8:31:a2:57:90:65:05:be:16:44:38:5a:77:02:
- b9:cf:10:42:c6:e1:92:a4:e3:45:27:f8:00:47:2c:68:a8:56:
- 99:53:54:8f:ad:9e:40:c1:d0:0f:b6:d7:0d:0b:38:48:6c:50:
- 2c:49:90:06:5b:64:1d:8b:cc:48:30:2e:de:08:e2:9b:49:22:
- c0:92:0c:11:5e:96:92:94:d5:fc:20:dc:56:6c:e5:92:93:bf:
- 7a:1c:c0:37:e3:85:49:15:fa:2b:e1:74:39:18:0f:b7:da:f3:
- a2:57:58:60:4f:cc:8e:94:00:fc:46:7b:34:31:3e:4d:47:82:
- 81:3a:cb:f4:89:5d:0e:ef:4d:0d:6e:9c:1b:82:24:dd:32:25:
- 5d:11:78:51:10:3d:a0:35:23:04:2f:65:6f:9c:c1:d1:43:d7:
- d0:1e:f3:31:67:59:27:dd:6b:d2:75:09:93:11:24:24:14:cf:
- 29:be:e6:23:c3:b8:8f:72:3f:e9:07:c8:24:44:53:7a:b3:b9:
- 61:65:a1:4c:0e:c6:48:00:c9:75:63:05:87:70:45:52:83:d3:
- 95:9d:45:ea:f0:e8:31:1d:7e:09:1f:0a:fe:3e:dd:aa:3c:5e:
- 74:d2:ac:b1
------BEGIN CERTIFICATE-----
-MIIDzTCCArWgAwIBAgIQCjeHZF5ftIwiTv0b7RQMPDANBgkqhkiG9w0BAQsFADBa
-MQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJl
-clRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTIw
-MDEyNzEyNDgwOFoXDTI0MTIzMTIzNTk1OVowSjELMAkGA1UEBhMCVVMxGTAXBgNV
-BAoTEENsb3VkZmxhcmUsIEluYy4xIDAeBgNVBAMTF0Nsb3VkZmxhcmUgSW5jIEVD
-QyBDQS0zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEua1NZpkUC0bsH4HRKlAe
-nQMVLzQSfS2WuIg4m4Vfj7+7Te9hRsTJc9QkT+DuHM5ss1FxL2ruTAUJd9NyYqSb
-16OCAWgwggFkMB0GA1UdDgQWBBSlzjfq67B1DpRniLRF+tkkEIeWHzAfBgNVHSME
-GDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0l
-BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYI
-KwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
-b20wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL09t
-bmlyb290MjAyNS5jcmwwbQYDVR0gBGYwZDA3BglghkgBhv1sAQEwKjAoBggrBgEF
-BQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzALBglghkgBhv1sAQIw
-CAYGZ4EMAQIBMAgGBmeBDAECAjAIBgZngQwBAgMwDQYJKoZIhvcNAQELBQADggEB
-AAUkHd0bsCrrmNaF4zlNXmtXnYJX/OvoMaJXkGUFvhZEOFp3ArnPEELG4ZKk40Un
-+ABHLGioVplTVI+tnkDB0A+21w0LOEhsUCxJkAZbZB2LzEgwLt4I4ptJIsCSDBFe
-lpKU1fwg3FZs5ZKTv3ocwDfjhUkV+ivhdDkYD7fa86JXWGBPzI6UAPxGezQxPk1H
-goE6y/SJXQ7vTQ1unBuCJN0yJV0ReFEQPaA1IwQvZW+cwdFD19Ae8zFnWSfda9J1
-CZMRJCQUzym+5iPDuI9yP+kHyCREU3qzuWFloUwOxkgAyXVjBYdwRVKD05WdRerw
-6DEdfgkfCv4+3ao8XnTSrLE=
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 33554617 (0x20000b9)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
- Validity
- Not Before: May 12 18:46:00 2000 GMT
- Not After : May 12 23:59:00 2025 GMT
- Subject: C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a3:04:bb:22:ab:98:3d:57:e8:26:72:9a:b5:79:
- d4:29:e2:e1:e8:95:80:b1:b0:e3:5b:8e:2b:29:9a:
- 64:df:a1:5d:ed:b0:09:05:6d:db:28:2e:ce:62:a2:
- 62:fe:b4:88:da:12:eb:38:eb:21:9d:c0:41:2b:01:
- 52:7b:88:77:d3:1c:8f:c7:ba:b9:88:b5:6a:09:e7:
- 73:e8:11:40:a7:d1:cc:ca:62:8d:2d:e5:8f:0b:a6:
- 50:d2:a8:50:c3:28:ea:f5:ab:25:87:8a:9a:96:1c:
- a9:67:b8:3f:0c:d5:f7:f9:52:13:2f:c2:1b:d5:70:
- 70:f0:8f:c0:12:ca:06:cb:9a:e1:d9:ca:33:7a:77:
- d6:f8:ec:b9:f1:68:44:42:48:13:d2:c0:c2:a4:ae:
- 5e:60:fe:b6:a6:05:fc:b4:dd:07:59:02:d4:59:18:
- 98:63:f5:a5:63:e0:90:0c:7d:5d:b2:06:7a:f3:85:
- ea:eb:d4:03:ae:5e:84:3e:5f:ff:15:ed:69:bc:f9:
- 39:36:72:75:cf:77:52:4d:f3:c9:90:2c:b9:3d:e5:
- c9:23:53:3f:1f:24:98:21:5c:07:99:29:bd:c6:3a:
- ec:e7:6e:86:3a:6b:97:74:63:33:bd:68:18:31:f0:
- 78:8d:76:bf:fc:9e:8e:5d:2a:86:a7:4d:90:dc:27:
- 1a:39
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:3
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Signature Algorithm: sha1WithRSAEncryption
- Signature Value:
- 85:0c:5d:8e:e4:6f:51:68:42:05:a0:dd:bb:4f:27:25:84:03:
- bd:f7:64:fd:2d:d7:30:e3:a4:10:17:eb:da:29:29:b6:79:3f:
- 76:f6:19:13:23:b8:10:0a:f9:58:a4:d4:61:70:bd:04:61:6a:
- 12:8a:17:d5:0a:bd:c5:bc:30:7c:d6:e9:0c:25:8d:86:40:4f:
- ec:cc:a3:7e:38:c6:37:11:4f:ed:dd:68:31:8e:4c:d2:b3:01:
- 74:ee:be:75:5e:07:48:1a:7f:70:ff:16:5c:84:c0:79:85:b8:
- 05:fd:7f:be:65:11:a3:0f:c0:02:b4:f8:52:37:39:04:d5:a9:
- 31:7a:18:bf:a0:2a:f4:12:99:f7:a3:45:82:e3:3c:5e:f5:9d:
- 9e:b5:c8:9e:7c:2e:c8:a4:9e:4e:08:14:4b:6d:fd:70:6d:6b:
- 1a:63:bd:64:e6:1f:b7:ce:f0:f2:9f:2e:bb:1b:b7:f2:50:88:
- 73:92:c2:e2:e3:16:8d:9a:32:02:ab:8e:18:dd:e9:10:11:ee:
- 7e:35:ab:90:af:3e:30:94:7a:d0:33:3d:a7:65:0f:f5:fc:8e:
- 9e:62:cf:47:44:2c:01:5d:bb:1d:b5:32:d2:47:d2:38:2e:d0:
- fe:81:dc:32:6a:1e:b5:ee:3c:d5:fc:e7:81:1d:19:c3:24:42:
- ea:63:39:a9
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
-DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
-ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
-VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
-mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
-IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
-mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
-XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
-dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
-jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
-BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
-DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
-9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
-jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
-Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
-ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
-R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
------END CERTIFICATE-----
diff --git a/certs/DigiCert-Global-G2-TLS-RSA-SHA256-2020-CA1.pem b/certs/DigiCert-Global-G2-TLS-RSA-SHA256-2020-CA1.pem
deleted file mode 100644
index 12084ee..0000000
--- a/certs/DigiCert-Global-G2-TLS-RSA-SHA256-2020-CA1.pem
+++ /dev/null
@@ -1,182 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 0c:f5:bd:06:2b:56:02:f4:7a:b8:50:2c:23:cc:f0:66
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
- Validity
- Not Before: Mar 30 00:00:00 2021 GMT
- Not After : Mar 29 23:59:59 2031 GMT
- Subject: C=US, O=DigiCert Inc, CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:cc:f7:10:62:4f:a6:bb:63:6f:ed:90:52:56:c5:
- 6d:27:7b:7a:12:56:8a:f1:f4:f9:d6:e7:e1:8f:bd:
- 95:ab:f2:60:41:15:70:db:12:00:fa:27:0a:b5:57:
- 38:5b:7d:b2:51:93:71:95:0e:6a:41:94:5b:35:1b:
- fa:7b:fa:bb:c5:be:24:30:fe:56:ef:c4:f3:7d:97:
- e3:14:f5:14:4d:cb:a7:10:f2:16:ea:ab:22:f0:31:
- 22:11:61:69:90:26:ba:78:d9:97:1f:e3:7d:66:ab:
- 75:44:95:73:c8:ac:ff:ef:5d:0a:8a:59:43:e1:ac:
- b2:3a:0f:f3:48:fc:d7:6b:37:c1:63:dc:de:46:d6:
- db:45:fe:7d:23:fd:90:e8:51:07:1e:51:a3:5f:ed:
- 49:46:54:7f:2c:88:c5:f4:13:9c:97:15:3c:03:e8:
- a1:39:dc:69:0c:32:c1:af:16:57:4c:94:47:42:7c:
- a2:c8:9c:7d:e6:d4:4d:54:af:42:99:a8:c1:04:c2:
- 77:9c:d6:48:e4:ce:11:e0:2a:80:99:f0:43:70:cf:
- 3f:76:6b:d1:4c:49:ab:24:5e:c2:0d:82:fd:46:a8:
- ab:6c:93:cc:62:52:42:75:92:f8:9a:fa:5e:5e:b2:
- b0:61:e5:1f:1f:b9:7f:09:98:e8:3d:fa:83:7f:47:
- 69:a1
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- 74:85:80:C0:66:C7:DF:37:DE:CF:BD:29:37:AA:03:1D:BE:ED:CD:17
- X509v3 Authority Key Identifier:
- 4E:22:54:20:18:95:E6:E3:6E:E6:0F:FA:FA:B9:12:ED:06:17:8F:39
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
- CA Issuers - URI:http://cacerts.digicert.com/DigiCertGlobalRootG2.crt
- X509v3 CRL Distribution Points:
- Full Name:
- URI:http://crl3.digicert.com/DigiCertGlobalRootG2.crl
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.114412.2.1
- Policy: 2.23.140.1.1
- Policy: 2.23.140.1.2.1
- Policy: 2.23.140.1.2.2
- Policy: 2.23.140.1.2.3
- Signature Algorithm: sha256WithRSAEncryption
- Signature Value:
- 90:f1:70:cb:28:97:69:97:7c:74:fd:c0:fa:26:7b:53:ab:ad:
- cd:65:fd:ba:9c:06:9c:8a:d7:5a:43:87:ed:4d:4c:56:5f:ad:
- c1:c5:b5:05:20:2e:59:d1:ff:4a:f5:a0:2a:d8:b0:95:ad:c9:
- 2e:4a:3b:d7:a7:f6:6f:88:29:fc:30:3f:24:84:bb:c3:b7:7b:
- 93:07:2c:af:87:6b:76:33:ed:00:55:52:b2:59:9e:e4:b9:d0:
- f3:df:e7:0f:fe:dd:f8:c4:b9:10:72:81:09:04:5f:cf:97:9e:
- 2e:32:75:8e:cf:9a:58:d2:57:31:7e:37:01:81:b2:66:6d:29:
- 1a:b1:66:09:6d:d1:6e:90:f4:b9:fa:2f:01:14:c5:5c:56:64:
- 01:d9:7d:87:a8:38:53:9f:8b:5d:46:6d:5c:c6:27:84:81:d4:
- 7e:8c:8c:a3:9b:52:e7:c6:88:ec:37:7c:2a:fb:f0:55:5a:38:
- 72:10:d8:00:13:cf:4c:73:db:aa:37:35:a8:29:81:69:9c:76:
- bc:de:18:7b:90:d4:ca:cf:ef:67:03:fd:04:5a:21:16:b1:ff:
- ea:3f:df:dc:82:f5:eb:f4:59:92:23:0d:24:2a:95:25:4c:ca:
- a1:91:e6:d4:b7:ac:87:74:b3:f1:6d:a3:99:db:f9:d5:bd:84:
- 40:9f:07:98
------BEGIN CERTIFICATE-----
-MIIEyDCCA7CgAwIBAgIQDPW9BitWAvR6uFAsI8zwZjANBgkqhkiG9w0BAQsFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
-MjAeFw0yMTAzMzAwMDAwMDBaFw0zMTAzMjkyMzU5NTlaMFkxCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMzAxBgNVBAMTKkRpZ2lDZXJ0IEdsb2Jh
-bCBHMiBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAMz3EGJPprtjb+2QUlbFbSd7ehJWivH0+dbn4Y+9lavyYEEV
-cNsSAPonCrVXOFt9slGTcZUOakGUWzUb+nv6u8W+JDD+Vu/E832X4xT1FE3LpxDy
-FuqrIvAxIhFhaZAmunjZlx/jfWardUSVc8is/+9dCopZQ+GssjoP80j812s3wWPc
-3kbW20X+fSP9kOhRBx5Ro1/tSUZUfyyIxfQTnJcVPAPooTncaQwywa8WV0yUR0J8
-osicfebUTVSvQpmowQTCd5zWSOTOEeAqgJnwQ3DPP3Zr0UxJqyRewg2C/Uaoq2yT
-zGJSQnWS+Jr6Xl6ysGHlHx+5fwmY6D36g39HaaECAwEAAaOCAYIwggF+MBIGA1Ud
-EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFHSFgMBmx9833s+9KTeqAx2+7c0XMB8G
-A1UdIwQYMBaAFE4iVCAYlebjbuYP+vq5Eu0GF485MA4GA1UdDwEB/wQEAwIBhjAd
-BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYIKwYBBQUHAQEEajBoMCQG
-CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQAYIKwYBBQUHMAKG
-NGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RH
-Mi5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29t
-L0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDA9BgNVHSAENjA0MAsGCWCGSAGG/WwC
-ATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgGBmeBDAECAzANBgkqhkiG
-9w0BAQsFAAOCAQEAkPFwyyiXaZd8dP3A+iZ7U6utzWX9upwGnIrXWkOH7U1MVl+t
-wcW1BSAuWdH/SvWgKtiwla3JLko716f2b4gp/DA/JIS7w7d7kwcsr4drdjPtAFVS
-slme5LnQ89/nD/7d+MS5EHKBCQRfz5eeLjJ1js+aWNJXMX43AYGyZm0pGrFmCW3R
-bpD0ufovARTFXFZkAdl9h6g4U5+LXUZtXMYnhIHUfoyMo5tS58aI7Dd8KvvwVVo4
-chDYABPPTHPbqjc1qCmBaZx2vN4Ye5DUys/vZwP9BFohFrH/6j/f3IL16/RZkiMN
-JCqVJUzKoZHm1Lesh3Sz8W2jmdv51b2EQJ8HmA==
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 03:3a:f1:e6:a7:11:a9:a0:bb:28:64:b1:1d:09:fa:e5
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
- Validity
- Not Before: Aug 1 12:00:00 2013 GMT
- Not After : Jan 15 12:00:00 2038 GMT
- Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bb:37:cd:34:dc:7b:6b:c9:b2:68:90:ad:4a:75:
- ff:46:ba:21:0a:08:8d:f5:19:54:c9:fb:88:db:f3:
- ae:f2:3a:89:91:3c:7a:e6:ab:06:1a:6b:cf:ac:2d:
- e8:5e:09:24:44:ba:62:9a:7e:d6:a3:a8:7e:e0:54:
- 75:20:05:ac:50:b7:9c:63:1a:6c:30:dc:da:1f:19:
- b1:d7:1e:de:fd:d7:e0:cb:94:83:37:ae:ec:1f:43:
- 4e:dd:7b:2c:d2:bd:2e:a5:2f:e4:a9:b8:ad:3a:d4:
- 99:a4:b6:25:e9:9b:6b:00:60:92:60:ff:4f:21:49:
- 18:f7:67:90:ab:61:06:9c:8f:f2:ba:e9:b4:e9:92:
- 32:6b:b5:f3:57:e8:5d:1b:cd:8c:1d:ab:95:04:95:
- 49:f3:35:2d:96:e3:49:6d:dd:77:e3:fb:49:4b:b4:
- ac:55:07:a9:8f:95:b3:b4:23:bb:4c:6d:45:f0:f6:
- a9:b2:95:30:b4:fd:4c:55:8c:27:4a:57:14:7c:82:
- 9d:cd:73:92:d3:16:4a:06:0c:8c:50:d1:8f:1e:09:
- be:17:a1:e6:21:ca:fd:83:e5:10:bc:83:a5:0a:c4:
- 67:28:f6:73:14:14:3d:46:76:c3:87:14:89:21:34:
- 4d:af:0f:45:0c:a6:49:a1:ba:bb:9c:c5:b1:33:83:
- 29:85
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 4E:22:54:20:18:95:E6:E3:6E:E6:0F:FA:FA:B9:12:ED:06:17:8F:39
- Signature Algorithm: sha256WithRSAEncryption
- Signature Value:
- 60:67:28:94:6f:0e:48:63:eb:31:dd:ea:67:18:d5:89:7d:3c:
- c5:8b:4a:7f:e9:be:db:2b:17:df:b0:5f:73:77:2a:32:13:39:
- 81:67:42:84:23:f2:45:67:35:ec:88:bf:f8:8f:b0:61:0c:34:
- a4:ae:20:4c:84:c6:db:f8:35:e1:76:d9:df:a6:42:bb:c7:44:
- 08:86:7f:36:74:24:5a:da:6c:0d:14:59:35:bd:f2:49:dd:b6:
- 1f:c9:b3:0d:47:2a:3d:99:2f:bb:5c:bb:b5:d4:20:e1:99:5f:
- 53:46:15:db:68:9b:f0:f3:30:d5:3e:31:e2:8d:84:9e:e3:8a:
- da:da:96:3e:35:13:a5:5f:f0:f9:70:50:70:47:41:11:57:19:
- 4e:c0:8f:ae:06:c4:95:13:17:2f:1b:25:9f:75:f2:b1:8e:99:
- a1:6f:13:b1:41:71:fe:88:2a:c8:4f:10:20:55:d7:f3:14:45:
- e5:e0:44:f4:ea:87:95:32:93:0e:fe:53:46:fa:2c:9d:ff:8b:
- 22:b9:4b:d9:09:45:a4:de:a4:b8:9a:58:dd:1b:7d:52:9f:8e:
- 59:43:88:81:a4:9e:26:d5:6f:ad:dd:0d:c6:37:7d:ed:03:92:
- 1b:e5:77:5f:76:ee:3c:8d:c4:5d:56:5b:a2:d9:66:6e:b3:35:
- 37:e5:32:b6
------BEGIN CERTIFICATE-----
-MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
-MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
-b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
-2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
-1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
-q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
-tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
-vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
-BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
-5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
-1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
-NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
-Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
-8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
-pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
-MrY=
------END CERTIFICATE-----
diff --git a/certs/DigiCert-Global-Root-G2.pem b/certs/DigiCert-Global-Root-G2.pem
new file mode 100644
index 0000000..8af6c7a
--- /dev/null
+++ b/certs/DigiCert-Global-Root-G2.pem
@@ -0,0 +1,29 @@
+# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Global Root G2"
+# Serial: 4293743540046975378534879503202253541
+# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44
+# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4
+# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
+MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
+2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
+1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
+q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
+tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
+vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
+5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
+1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
+NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
+Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
+8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
+pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
+MrY=
+-----END CERTIFICATE-----
diff --git a/certs/DigiCert-Global-Root-G3.pem b/certs/DigiCert-Global-Root-G3.pem
new file mode 100644
index 0000000..12324dc
--- /dev/null
+++ b/certs/DigiCert-Global-Root-G3.pem
@@ -0,0 +1,22 @@
+# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Global Root G3"
+# Serial: 7089244469030293291760083333884364146
+# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca
+# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e
+# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0
+-----BEGIN CERTIFICATE-----
+MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
+Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
+EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
+IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
+fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
+Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
+AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
+oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
+sycX
+-----END CERTIFICATE-----
diff --git a/certs/DigiCert-TLS-Hybrid-ECC-SHA384-2020-CA1.pem b/certs/DigiCert-TLS-Hybrid-ECC-SHA384-2020-CA1.pem
deleted file mode 100644
index 446f56f..0000000
--- a/certs/DigiCert-TLS-Hybrid-ECC-SHA384-2020-CA1.pem
+++ /dev/null
@@ -1,174 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 07:f2:f3:5c:87:a8:77:af:7a:ef:e9:47:99:35:25:bd
- Signature Algorithm: sha384WithRSAEncryption
- Issuer: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
- Validity
- Not Before: Apr 14 00:00:00 2021 GMT
- Not After : Apr 13 23:59:59 2031 GMT
- Subject: C = US, O = DigiCert Inc, CN = DigiCert TLS Hybrid ECC SHA384 2020 CA1
- Subject Public Key Info:
- Public Key Algorithm: id-ecPublicKey
- Public-Key: (384 bit)
- pub:
- 04:c1:1b:c6:9a:5b:98:d9:a4:29:a0:e9:d4:04:b5:
- db:eb:a6:b2:6c:55:c0:ff:ed:98:c6:49:2f:06:27:
- 51:cb:bf:70:c1:05:7a:c3:b1:9d:87:89:ba:ad:b4:
- 13:17:c9:a8:b4:83:c8:b8:90:d1:cc:74:35:36:3c:
- 83:72:b0:b5:d0:f7:22:69:c8:f1:80:c4:7b:40:8f:
- cf:68:87:26:5c:39:89:f1:4d:91:4d:da:89:8b:e4:
- 03:c3:43:e5:bf:2f:73
- ASN1 OID: secp384r1
- NIST CURVE: P-384
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- 0A:BC:08:29:17:8C:A5:39:6D:7A:0E:CE:33:C7:2E:B3:ED:FB:C3:7A
- X509v3 Authority Key Identifier:
- keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
-
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
- CA Issuers - URI:http://cacerts.digicert.com/DigiCertGlobalRootCA.crt
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.114412.2.1
- Policy: 2.23.140.1.1
- Policy: 2.23.140.1.2.1
- Policy: 2.23.140.1.2.2
- Policy: 2.23.140.1.2.3
-
- Signature Algorithm: sha384WithRSAEncryption
- 47:59:81:7f:d4:1b:1f:b0:71:f6:98:5d:18:ba:98:47:98:b0:
- 7e:76:2b:ea:ff:1a:8b:ac:26:b3:42:8d:31:e6:4a:e8:19:d0:
- ef:da:14:e7:d7:14:92:a1:92:f2:a7:2e:2d:af:fb:1d:f6:fb:
- 53:b0:8a:3f:fc:d8:16:0a:e9:b0:2e:b6:a5:0b:18:90:35:26:
- a2:da:f6:a8:b7:32:fc:95:23:4b:c6:45:b9:c4:cf:e4:7c:ee:
- e6:c9:f8:90:bd:72:e3:99:c3:1d:0b:05:7c:6a:97:6d:b2:ab:
- 02:36:d8:c2:bc:2c:01:92:3f:04:a3:8b:75:11:c7:b9:29:bc:
- 11:d0:86:ba:92:bc:26:f9:65:c8:37:cd:26:f6:86:13:0c:04:
- aa:89:e5:78:b1:c1:4e:79:bc:76:a3:0b:51:e4:c5:d0:9e:6a:
- fe:1a:2c:56:ae:06:36:27:a3:73:1c:08:7d:93:32:d0:c2:44:
- 19:da:8d:f4:0e:7b:1d:28:03:2b:09:8a:76:ca:77:dc:87:7a:
- ac:7b:52:26:55:a7:72:0f:9d:d2:88:4f:fe:b1:21:c5:1a:a1:
- aa:39:f5:56:db:c2:84:c4:35:1f:70:da:bb:46:f0:86:bf:64:
- 00:c4:3e:f7:9f:46:1b:9d:23:05:b9:7d:b3:4f:0f:a9:45:3a:
- e3:74:30:98
------BEGIN CERTIFICATE-----
-MIIEFzCCAv+gAwIBAgIQB/LzXIeod6967+lHmTUlvTANBgkqhkiG9w0BAQwFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
-QTAeFw0yMTA0MTQwMDAwMDBaFw0zMTA0MTMyMzU5NTlaMFYxCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMDAuBgNVBAMTJ0RpZ2lDZXJ0IFRMUyBI
-eWJyaWQgRUNDIFNIQTM4NCAyMDIwIENBMTB2MBAGByqGSM49AgEGBSuBBAAiA2IA
-BMEbxppbmNmkKaDp1AS12+umsmxVwP/tmMZJLwYnUcu/cMEFesOxnYeJuq20ExfJ
-qLSDyLiQ0cx0NTY8g3KwtdD3ImnI8YDEe0CPz2iHJlw5ifFNkU3aiYvkA8ND5b8v
-c6OCAYIwggF+MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAq8CCkXjKU5
-bXoOzjPHLrPt+8N6MB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA4G
-A1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYI
-KwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
-b20wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp
-Q2VydEdsb2JhbFJvb3RDQS5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2Ny
-bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA9BgNVHSAE
-NjA0MAsGCWCGSAGG/WwCATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgG
-BmeBDAECAzANBgkqhkiG9w0BAQwFAAOCAQEAR1mBf9QbH7Bx9phdGLqYR5iwfnYr
-6v8ai6wms0KNMeZK6BnQ79oU59cUkqGS8qcuLa/7Hfb7U7CKP/zYFgrpsC62pQsY
-kDUmotr2qLcy/JUjS8ZFucTP5Hzu5sn4kL1y45nDHQsFfGqXbbKrAjbYwrwsAZI/
-BKOLdRHHuSm8EdCGupK8JvllyDfNJvaGEwwEqonleLHBTnm8dqMLUeTF0J5q/hos
-Vq4GNiejcxwIfZMy0MJEGdqN9A57HSgDKwmKdsp33Id6rHtSJlWncg+d0ohP/rEh
-xRqhqjn1VtvChMQ1H3Dau0bwhr9kAMQ+959GG50jBbl9s08PqUU643QwmA==
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 08:3b:e0:56:90:42:46:b1:a1:75:6a:c9:59:91:c7:4a
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
- Validity
- Not Before: Nov 10 00:00:00 2006 GMT
- Not After : Nov 10 00:00:00 2031 GMT
- Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public-Key: (2048 bit)
- Modulus:
- 00:e2:3b:e1:11:72:de:a8:a4:d3:a3:57:aa:50:a2:
- 8f:0b:77:90:c9:a2:a5:ee:12:ce:96:5b:01:09:20:
- cc:01:93:a7:4e:30:b7:53:f7:43:c4:69:00:57:9d:
- e2:8d:22:dd:87:06:40:00:81:09:ce:ce:1b:83:bf:
- df:cd:3b:71:46:e2:d6:66:c7:05:b3:76:27:16:8f:
- 7b:9e:1e:95:7d:ee:b7:48:a3:08:da:d6:af:7a:0c:
- 39:06:65:7f:4a:5d:1f:bc:17:f8:ab:be:ee:28:d7:
- 74:7f:7a:78:99:59:85:68:6e:5c:23:32:4b:bf:4e:
- c0:e8:5a:6d:e3:70:bf:77:10:bf:fc:01:f6:85:d9:
- a8:44:10:58:32:a9:75:18:d5:d1:a2:be:47:e2:27:
- 6a:f4:9a:33:f8:49:08:60:8b:d4:5f:b4:3a:84:bf:
- a1:aa:4a:4c:7d:3e:cf:4f:5f:6c:76:5e:a0:4b:37:
- 91:9e:dc:22:e6:6d:ce:14:1a:8e:6a:cb:fe:cd:b3:
- 14:64:17:c7:5b:29:9e:32:bf:f2:ee:fa:d3:0b:42:
- d4:ab:b7:41:32:da:0c:d4:ef:f8:81:d5:bb:8d:58:
- 3f:b5:1b:e8:49:28:a2:70:da:31:04:dd:f7:b2:16:
- f2:4c:0a:4e:07:a8:ed:4a:3d:5e:b5:7f:a3:90:c3:
- af:27
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- 03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
- X509v3 Authority Key Identifier:
- keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
-
- Signature Algorithm: sha1WithRSAEncryption
- cb:9c:37:aa:48:13:12:0a:fa:dd:44:9c:4f:52:b0:f4:df:ae:
- 04:f5:79:79:08:a3:24:18:fc:4b:2b:84:c0:2d:b9:d5:c7:fe:
- f4:c1:1f:58:cb:b8:6d:9c:7a:74:e7:98:29:ab:11:b5:e3:70:
- a0:a1:cd:4c:88:99:93:8c:91:70:e2:ab:0f:1c:be:93:a9:ff:
- 63:d5:e4:07:60:d3:a3:bf:9d:5b:09:f1:d5:8e:e3:53:f4:8e:
- 63:fa:3f:a7:db:b4:66:df:62:66:d6:d1:6e:41:8d:f2:2d:b5:
- ea:77:4a:9f:9d:58:e2:2b:59:c0:40:23:ed:2d:28:82:45:3e:
- 79:54:92:26:98:e0:80:48:a8:37:ef:f0:d6:79:60:16:de:ac:
- e8:0e:cd:6e:ac:44:17:38:2f:49:da:e1:45:3e:2a:b9:36:53:
- cf:3a:50:06:f7:2e:e8:c4:57:49:6c:61:21:18:d5:04:ad:78:
- 3c:2c:3a:80:6b:a7:eb:af:15:14:e9:d8:89:c1:b9:38:6c:e2:
- 91:6c:8a:ff:64:b9:77:25:57:30:c0:1b:24:a3:e1:dc:e9:df:
- 47:7c:b5:b4:24:08:05:30:ec:2d:bd:0b:bf:45:bf:50:b9:a9:
- f3:eb:98:01:12:ad:c8:88:c6:98:34:5f:8d:0a:3c:c6:e9:d5:
- 95:95:6d:de
------BEGIN CERTIFICATE-----
-MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
-QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
-b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
-CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
-nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
-43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
-T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
-gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
-BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
-TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
-DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
-hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
-06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
-PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
-YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
-CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
------END CERTIFICATE-----
diff --git a/certs/E1.pem b/certs/E1.pem
deleted file mode 100644
index a62fc03..0000000
--- a/certs/E1.pem
+++ /dev/null
@@ -1,124 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- b3:bd:df:f8:a7:84:5b:bc:e9:03:a0:41:35:b3:4a:45
- Signature Algorithm: ecdsa-with-SHA384
- Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X2
- Validity
- Not Before: Sep 4 00:00:00 2020 GMT
- Not After : Sep 15 16:00:00 2025 GMT
- Subject: C = US, O = Let's Encrypt, CN = E1
- Subject Public Key Info:
- Public Key Algorithm: id-ecPublicKey
- Public-Key: (384 bit)
- pub:
- 04:24:5c:2d:a2:2a:fd:1c:4b:a6:5d:97:73:27:31:
- ac:b2:a0:69:62:ef:65:e8:a6:b0:f0:ac:4b:9f:ff:
- 1c:0b:70:0f:d3:98:2f:4d:fc:0f:00:9b:37:f0:74:
- 05:57:32:97:2e:05:ef:2a:43:25:a3:fb:6e:34:27:
- 13:f6:4f:7e:69:d3:02:99:5e:eb:24:47:92:c1:24:
- 9b:e6:b1:21:8f:c1:24:81:fc:68:cc:1f:69:ba:58:
- f5:19:22:f7:74:c6:16
- ASN1 OID: secp384r1
- NIST CURVE: P-384
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Client Authentication, TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- 5A:F3:ED:2B:FC:36:C2:37:79:B9:52:30:EA:54:6F:CF:55:CB:2E:AC
- X509v3 Authority Key Identifier:
- keyid:7C:42:96:AE:DE:4B:48:3B:FA:92:F8:9E:8C:CF:6D:8B:A9:72:37:95
-
- Authority Information Access:
- CA Issuers - URI:http://x2.i.lencr.org/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://x2.c.lencr.org/
-
- X509v3 Certificate Policies:
- Policy: 2.23.140.1.2.1
- Policy: 1.3.6.1.4.1.44947.1.1.1
-
- Signature Algorithm: ecdsa-with-SHA384
- 30:64:02:30:7b:74:d5:52:13:8d:61:fe:0d:ba:3f:03:00:9d:
- f3:d7:98:84:d9:57:2e:bd:e9:0f:9c:5c:48:04:21:f2:cb:b3:
- 60:72:8e:97:d6:12:4f:ca:44:f6:42:c9:d3:7b:86:a9:02:30:
- 5a:b1:b1:b4:ed:ea:60:99:20:b1:38:03:ca:3d:a0:26:b8:ee:
- 6e:2d:4a:f6:c6:66:1f:33:9a:db:92:4a:d5:f5:29:13:c6:70:
- 62:28:ba:23:8c:cf:3d:2f:cb:82:e9:7f
------BEGIN CERTIFICATE-----
-MIICxjCCAk2gAwIBAgIRALO93/inhFu86QOgQTWzSkUwCgYIKoZIzj0EAwMwTzEL
-MAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNo
-IEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDIwHhcNMjAwOTA0MDAwMDAwWhcN
-MjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3MgRW5j
-cnlwdDELMAkGA1UEAxMCRTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQkXC2iKv0c
-S6Zdl3MnMayyoGli72XoprDwrEuf/xwLcA/TmC9N/A8AmzfwdAVXMpcuBe8qQyWj
-+240JxP2T35p0wKZXuskR5LBJJvmsSGPwSSB/GjMH2m6WPUZIvd0xhajggEIMIIB
-BDAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMB
-MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFrz7Sv8NsI3eblSMOpUb89V
-yy6sMB8GA1UdIwQYMBaAFHxClq7eS0g7+pL4nozPbYupcjeVMDIGCCsGAQUFBwEB
-BCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL3gyLmkubGVuY3Iub3JnLzAnBgNVHR8E
-IDAeMBygGqAYhhZodHRwOi8veDIuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYG
-Z4EMAQIBMA0GCysGAQQBgt8TAQEBMAoGCCqGSM49BAMDA2cAMGQCMHt01VITjWH+
-Dbo/AwCd89eYhNlXLr3pD5xcSAQh8suzYHKOl9YST8pE9kLJ03uGqQIwWrGxtO3q
-YJkgsTgDyj2gJrjubi1K9sZmHzOa25JK1fUpE8ZwYii6I4zPPS/Lgul/
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 41:d2:9d:d1:72:ea:ee:a7:80:c1:2c:6c:e9:2f:87:52
- Signature Algorithm: ecdsa-with-SHA384
- Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X2
- Validity
- Not Before: Sep 4 00:00:00 2020 GMT
- Not After : Sep 17 16:00:00 2040 GMT
- Subject: C = US, O = Internet Security Research Group, CN = ISRG Root X2
- Subject Public Key Info:
- Public Key Algorithm: id-ecPublicKey
- Public-Key: (384 bit)
- pub:
- 04:cd:9b:d5:9f:80:83:0a:ec:09:4a:f3:16:4a:3e:
- 5c:cf:77:ac:de:67:05:0d:1d:07:b6:dc:16:fb:5a:
- 8b:14:db:e2:71:60:c4:ba:45:95:11:89:8e:ea:06:
- df:f7:2a:16:1c:a4:b9:c5:c5:32:e0:03:e0:1e:82:
- 18:38:8b:d7:45:d8:0a:6a:6e:e6:00:77:fb:02:51:
- 7d:22:d8:0a:6e:9a:5b:77:df:f0:fa:41:ec:39:dc:
- 75:ca:68:07:0c:1f:ea
- ASN1 OID: secp384r1
- NIST CURVE: P-384
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- 7C:42:96:AE:DE:4B:48:3B:FA:92:F8:9E:8C:CF:6D:8B:A9:72:37:95
- Signature Algorithm: ecdsa-with-SHA384
- 30:65:02:30:7b:79:4e:46:50:84:c2:44:87:46:1b:45:70:ff:
- 58:99:de:f4:fd:a4:d2:55:a6:20:2d:74:d6:34:bc:41:a3:50:
- 5f:01:27:56:b4:be:27:75:06:af:12:2e:75:98:8d:fc:02:31:
- 00:8b:f5:77:6c:d4:c8:65:aa:e0:0b:2c:ee:14:9d:27:37:a4:
- f9:53:a5:51:e4:29:83:d7:f8:90:31:5b:42:9f:0a:f5:fe:ae:
- 00:68:e7:8c:49:0f:b6:6f:5b:5b:15:f2:e7
------BEGIN CERTIFICATE-----
-MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
-CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
-R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
-MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
-ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
-EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
-+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
-ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
-AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
-zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
-tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
-/q4AaOeMSQ+2b1tbFfLn
------END CERTIFICATE-----
diff --git a/certs/GTS-CA-1C3.pem b/certs/GTS-CA-1C3.pem
deleted file mode 100644
index a8432d2..0000000
--- a/certs/GTS-CA-1C3.pem
+++ /dev/null
@@ -1,242 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 02:03:bc:53:59:6b:34:c7:18:f5:01:50:66
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C = US, O = Google Trust Services LLC, CN = GTS Root R1
- Validity
- Not Before: Aug 13 00:00:42 2020 GMT
- Not After : Sep 30 00:00:42 2027 GMT
- Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public-Key: (2048 bit)
- Modulus:
- 00:f5:88:df:e7:62:8c:1e:37:f8:37:42:90:7f:6c:
- 87:d0:fb:65:82:25:fd:e8:cb:6b:a4:ff:6d:e9:5a:
- 23:e2:99:f6:1c:e9:92:03:99:13:7c:09:0a:8a:fa:
- 42:d6:5e:56:24:aa:7a:33:84:1f:d1:e9:69:bb:b9:
- 74:ec:57:4c:66:68:93:77:37:55:53:fe:39:10:4d:
- b7:34:bb:5f:25:77:37:3b:17:94:ea:3c:e5:9d:d5:
- bc:c3:b4:43:eb:2e:a7:47:ef:b0:44:11:63:d8:b4:
- 41:85:dd:41:30:48:93:1b:bf:b7:f6:e0:45:02:21:
- e0:96:42:17:cf:d9:2b:65:56:34:07:26:04:0d:a8:
- fd:7d:ca:2e:ef:ea:48:7c:37:4d:3f:00:9f:83:df:
- ef:75:84:2e:79:57:5c:fc:57:6e:1a:96:ff:fc:8c:
- 9a:a6:99:be:25:d9:7f:96:2c:06:f7:11:2a:02:80:
- 80:eb:63:18:3c:50:49:87:e5:8a:ca:5f:19:2b:59:
- 96:81:00:a0:fb:51:db:ca:77:0b:0b:c9:96:4f:ef:
- 70:49:c7:5c:6d:20:fd:99:b4:b4:e2:ca:2e:77:fd:
- 2d:dc:0b:b6:6b:13:0c:8c:19:2b:17:96:98:b9:f0:
- 8b:f6:a0:27:bb:b6:e3:8d:51:8f:bd:ae:c7:9b:b1:
- 89:9d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- 8A:74:7F:AF:85:CD:EE:95:CD:3D:9C:D0:E2:46:14:F3:71:35:1D:27
- X509v3 Authority Key Identifier:
- keyid:E4:AF:2B:26:71:1A:2B:48:27:85:2F:52:66:2C:EF:F0:89:13:71:3E
-
- Authority Information Access:
- OCSP - URI:http://ocsp.pki.goog/gtsr1
- CA Issuers - URI:http://pki.goog/repo/certs/gtsr1.der
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.pki.goog/gtsr1/gtsr1.crl
-
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.11129.2.5.3
- CPS: https://pki.goog/repository/
- Policy: 2.23.140.1.2.1
- Policy: 2.23.140.1.2.2
-
- Signature Algorithm: sha256WithRSAEncryption
- 89:7d:ac:20:5c:0c:3c:be:9a:a8:57:95:1b:b4:ae:fa:ab:a5:
- 72:71:b4:36:95:fd:df:40:11:03:4c:c2:46:14:bb:14:24:ab:
- f0:50:71:22:db:ad:c4:6e:7f:cf:f1:6a:6f:c8:83:1b:d8:ce:
- 89:5f:87:6c:87:b8:a9:0c:a3:9b:a1:62:94:93:95:df:5b:ae:
- 66:19:0b:02:96:9e:fc:b5:e7:10:69:3e:7a:cb:46:49:5f:46:
- e1:41:b1:d7:98:4d:65:34:00:80:1a:3f:4f:9f:6c:7f:49:00:
- 81:53:41:a4:92:21:82:82:1a:f1:a3:44:5b:2a:50:12:13:4d:
- c1:53:36:f3:42:08:af:54:fa:8e:77:53:1b:64:38:27:17:09:
- bd:58:c9:1b:7c:39:2d:5b:f3:ce:d4:ed:97:db:14:03:bf:09:
- 53:24:1f:c2:0c:04:79:98:26:f2:61:f1:53:52:fd:42:8c:1b:
- 66:2b:3f:15:a1:bb:ff:f6:9b:e3:81:9a:01:06:71:89:35:28:
- 24:dd:e1:bd:eb:19:2d:e1:48:cb:3d:59:83:51:b4:74:c6:9d:
- 7c:c6:b1:86:5b:af:cc:34:c4:d3:cc:d4:81:11:95:00:a1:f4:
- 12:22:01:fa:b4:83:71:af:8c:b7:8c:73:24:ac:37:53:c2:00:
- 90:3f:11:fe:5c:ed:36:94:10:3b:bd:29:ae:e2:c7:3a:62:3b:
- 6c:63:d9:80:bf:59:71:ac:63:27:b9:4c:17:a0:da:f6:73:15:
- bf:2a:de:8f:f3:a5:6c:32:81:33:03:d0:86:51:71:99:34:ba:
- 93:8d:5d:b5:51:58:f7:b2:93:e8:01:f6:59:be:71:9b:fd:4d:
- 28:ce:cf:6d:c7:16:dc:f7:d1:d6:46:9b:a7:ca:6b:e9:77:0f:
- fd:a0:b6:1b:23:83:1d:10:1a:d9:09:00:84:e0:44:d3:a2:75:
- 23:b3:34:86:f6:20:b0:a4:5e:10:1d:e0:52:46:00:9d:b1:0f:
- 1f:21:70:51:f5:9a:dd:06:fc:55:f4:2b:0e:33:77:c3:4b:42:
- c2:f1:77:13:fc:73:80:94:eb:1f:bb:37:3f:ce:02:2a:66:b0:
- 73:1d:32:a5:32:6c:32:b0:8e:e0:c4:23:ff:5b:7d:4d:65:70:
- ac:2b:9b:3d:ce:db:e0:6d:8e:32:80:be:96:9f:92:63:bc:97:
- bb:5d:b9:f4:e1:71:5e:2a:e4:ef:03:22:b1:8a:65:3a:8f:c0:
- 93:65:d4:85:cd:0f:0f:5b:83:59:16:47:16:2d:9c:24:3a:c8:
- 80:a6:26:14:85:9b:f6:37:9b:ac:6f:f9:c5:c3:06:51:f3:e2:
- 7f:c5:b1:10:ba:51:f4:dd
------BEGIN CERTIFICATE-----
-MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw
-CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
-MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw
-MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
-Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp
-kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX
-lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm
-BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA
-gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL
-tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud
-DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T
-AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD
-VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG
-CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw
-AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt
-MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG
-A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br
-aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN
-AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ
-cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL
-RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U
-+o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr
-PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER
-lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs
-Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO
-z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG
-AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw
-juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl
-1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 6e:47:a9:c5:4b:47:0c:0d:ec:33:d0:89:b9:1c:f4:e1
- Signature Algorithm: sha384WithRSAEncryption
- Issuer: C = US, O = Google Trust Services LLC, CN = GTS Root R1
- Validity
- Not Before: Jun 22 00:00:00 2016 GMT
- Not After : Jun 22 00:00:00 2036 GMT
- Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public-Key: (4096 bit)
- Modulus:
- 00:b6:11:02:8b:1e:e3:a1:77:9b:3b:dc:bf:94:3e:
- b7:95:a7:40:3c:a1:fd:82:f9:7d:32:06:82:71:f6:
- f6:8c:7f:fb:e8:db:bc:6a:2e:97:97:a3:8c:4b:f9:
- 2b:f6:b1:f9:ce:84:1d:b1:f9:c5:97:de:ef:b9:f2:
- a3:e9:bc:12:89:5e:a7:aa:52:ab:f8:23:27:cb:a4:
- b1:9c:63:db:d7:99:7e:f0:0a:5e:eb:68:a6:f4:c6:
- 5a:47:0d:4d:10:33:e3:4e:b1:13:a3:c8:18:6c:4b:
- ec:fc:09:90:df:9d:64:29:25:23:07:a1:b4:d2:3d:
- 2e:60:e0:cf:d2:09:87:bb:cd:48:f0:4d:c2:c2:7a:
- 88:8a:bb:ba:cf:59:19:d6:af:8f:b0:07:b0:9e:31:
- f1:82:c1:c0:df:2e:a6:6d:6c:19:0e:b5:d8:7e:26:
- 1a:45:03:3d:b0:79:a4:94:28:ad:0f:7f:26:e5:a8:
- 08:fe:96:e8:3c:68:94:53:ee:83:3a:88:2b:15:96:
- 09:b2:e0:7a:8c:2e:75:d6:9c:eb:a7:56:64:8f:96:
- 4f:68:ae:3d:97:c2:84:8f:c0:bc:40:c0:0b:5c:bd:
- f6:87:b3:35:6c:ac:18:50:7f:84:e0:4c:cd:92:d3:
- 20:e9:33:bc:52:99:af:32:b5:29:b3:25:2a:b4:48:
- f9:72:e1:ca:64:f7:e6:82:10:8d:e8:9d:c2:8a:88:
- fa:38:66:8a:fc:63:f9:01:f9:78:fd:7b:5c:77:fa:
- 76:87:fa:ec:df:b1:0e:79:95:57:b4:bd:26:ef:d6:
- 01:d1:eb:16:0a:bb:8e:0b:b5:c5:c5:8a:55:ab:d3:
- ac:ea:91:4b:29:cc:19:a4:32:25:4e:2a:f1:65:44:
- d0:02:ce:aa:ce:49:b4:ea:9f:7c:83:b0:40:7b:e7:
- 43:ab:a7:6c:a3:8f:7d:89:81:fa:4c:a5:ff:d5:8e:
- c3:ce:4b:e0:b5:d8:b3:8e:45:cf:76:c0:ed:40:2b:
- fd:53:0f:b0:a7:d5:3b:0d:b1:8a:a2:03:de:31:ad:
- cc:77:ea:6f:7b:3e:d6:df:91:22:12:e6:be:fa:d8:
- 32:fc:10:63:14:51:72:de:5d:d6:16:93:bd:29:68:
- 33:ef:3a:66:ec:07:8a:26:df:13:d7:57:65:78:27:
- de:5e:49:14:00:a2:00:7f:9a:a8:21:b6:a9:b1:95:
- b0:a5:b9:0d:16:11:da:c7:6c:48:3c:40:e0:7e:0d:
- 5a:cd:56:3c:d1:97:05:b9:cb:4b:ed:39:4b:9c:c4:
- 3f:d2:55:13:6e:24:b0:d6:71:fa:f4:c1:ba:cc:ed:
- 1b:f5:fe:81:41:d8:00:98:3d:3a:c8:ae:7a:98:37:
- 18:05:95
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- E4:AF:2B:26:71:1A:2B:48:27:85:2F:52:66:2C:EF:F0:89:13:71:3E
- Signature Algorithm: sha384WithRSAEncryption
- 38:96:0a:ee:3d:b4:96:1e:5f:ef:9d:9c:0b:33:9f:2b:e0:ca:
- fd:d2:8e:0a:1f:41:74:a5:7c:aa:84:d4:e5:f2:1e:e6:37:52:
- 32:9c:0b:d1:61:1d:bf:28:c1:b6:44:29:35:75:77:98:b2:7c:
- d9:bd:74:ac:8a:68:e3:a9:31:09:29:01:60:73:e3:47:7c:53:
- a8:90:4a:27:ef:4b:d7:9f:93:e7:82:36:ce:9a:68:0c:82:e7:
- cf:d4:10:16:6f:5f:0e:99:5c:f6:1f:71:7d:ef:ef:7b:2f:7e:
- ea:36:d6:97:70:0b:15:ee:d7:5c:56:6a:33:a5:e3:49:38:0c:
- b8:7d:fb:8d:85:a4:b1:59:5e:f4:6a:e1:dd:a1:f6:64:44:ae:
- e6:51:83:21:66:c6:11:3e:f3:ce:47:ee:9c:28:1f:25:da:ff:
- ac:66:95:dd:35:0f:5c:ef:20:2c:62:fd:91:ba:a9:cc:fc:5a:
- 9c:93:81:83:29:97:4a:7c:5a:72:b4:39:d0:b7:77:cb:79:fd:
- 69:3a:92:37:ed:6e:38:65:46:7e:e9:60:bd:79:88:97:5f:38:
- 12:f4:ee:af:5b:82:c8:86:d5:e1:99:6d:8c:04:f2:76:ba:49:
- f6:6e:e9:6d:1e:5f:a0:ef:27:82:76:40:f8:a6:d3:58:5c:0f:
- 2c:42:da:42:c6:7b:88:34:c7:c1:d8:45:9b:c1:3e:c5:61:1d:
- d9:63:50:49:f6:34:85:6a:e0:18:c5:6e:47:ab:41:42:29:9b:
- f6:60:0d:d2:31:d3:63:98:23:93:5a:00:81:48:b4:ef:cd:8a:
- cd:c9:cf:99:ee:d9:9e:aa:36:e1:68:4b:71:49:14:36:28:3a:
- 3d:1d:ce:9a:8f:25:e6:80:71:61:2b:b5:7b:cc:f9:25:16:81:
- e1:31:5f:a1:a3:7e:16:a4:9c:16:6a:97:18:bd:76:72:a5:0b:
- 9e:1d:36:e6:2f:a1:2f:be:70:91:0f:a8:e6:da:f8:c4:92:40:
- 6c:25:7e:7b:b3:09:dc:b2:17:ad:80:44:f0:68:a5:8f:94:75:
- ff:74:5a:e8:a8:02:7c:0c:09:e2:a9:4b:0b:a0:85:0b:62:b9:
- ef:a1:31:92:fb:ef:f6:51:04:89:6c:e8:a9:74:a1:bb:17:b3:
- b5:fd:49:0f:7c:3c:ec:83:18:20:43:4e:d5:93:ba:b4:34:b1:
- 1f:16:36:1f:0c:e6:64:39:16:4c:dc:e0:fe:1d:c8:a9:62:3d:
- 40:ea:ca:c5:34:02:b4:ae:89:88:33:35:dc:2c:13:73:d8:27:
- f1:d0:72:ee:75:3b:22:de:98:68:66:5b:f1:c6:63:47:55:1c:
- ba:a5:08:51:75:a6:48:25
------BEGIN CERTIFICATE-----
-MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH
-MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
-QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy
-MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl
-cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB
-AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM
-f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX
-mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7
-zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P
-fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc
-vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4
-Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp
-zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO
-Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW
-k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+
-DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF
-lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
-HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW
-Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1
-d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z
-XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR
-gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3
-d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv
-J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg
-DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM
-+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy
-F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9
-SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws
-E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl
------END CERTIFICATE-----
diff --git a/certs/GTS-CA-1P5.pem b/certs/GTS-CA-1P5.pem
deleted file mode 100644
index 5be738d..0000000
--- a/certs/GTS-CA-1P5.pem
+++ /dev/null
@@ -1,238 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 02:03:bc:50:a3:27:53:f0:91:80:22:ed:f1
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=Google Trust Services LLC, CN=GTS Root R1
- Validity
- Not Before: Aug 13 00:00:42 2020 GMT
- Not After : Sep 30 00:00:42 2027 GMT
- Subject: C=US, O=Google Trust Services LLC, CN=GTS CA 1P5
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b3:82:f0:24:8c:bf:2d:87:af:b2:d9:a7:ae:fa:
- ca:ba:44:d6:5b:3e:fe:b2:f7:b2:65:16:dc:de:10:
- e8:4f:2d:10:58:5a:28:86:87:a1:ee:6a:b3:a0:d9:
- 75:4f:7f:a1:52:01:8b:55:a8:4a:5b:06:48:c8:36:
- 12:25:ab:89:f9:f2:23:5f:9d:60:65:f9:5c:da:be:
- 3a:e8:5c:6d:7d:9c:d0:84:18:85:30:cd:4e:9b:ec:
- 3c:d8:b3:e1:96:d4:f3:c5:0b:65:db:8f:b0:74:cb:
- f6:1e:f3:78:f1:ac:95:c5:dd:73:c3:31:88:81:af:
- 74:aa:6f:fd:0c:e3:05:95:f0:c5:10:4f:65:63:fa:
- a0:af:c6:18:3d:c5:a1:df:97:79:d7:05:89:b3:30:
- b0:74:ae:3d:92:10:6b:8c:15:77:dd:0b:04:57:fb:
- 81:03:dd:ea:22:34:d5:e5:56:b2:f0:c4:8d:41:b1:
- c3:02:db:62:ec:80:d0:ff:76:d4:86:e4:04:1a:b6:
- b6:0c:2b:62:71:7d:d9:af:d9:f1:5e:fa:c0:1e:ca:
- a0:19:5c:55:f0:80:d1:2a:0c:07:86:90:9f:35:e3:
- 28:2b:5b:ef:23:c8:a3:1d:a4:a3:3a:ee:fe:83:dc:
- 82:4c:25:b0:4d:c5:51:ad:9e:9b:d3:5b:84:c2:1a:
- 5a:e9
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- D5:FC:9E:0D:DF:1E:CA:DD:08:97:97:6E:2B:C5:5F:C5:2B:F5:EC:B8
- X509v3 Authority Key Identifier:
- E4:AF:2B:26:71:1A:2B:48:27:85:2F:52:66:2C:EF:F0:89:13:71:3E
- Authority Information Access:
- OCSP - URI:http://ocsp.pki.goog/gtsr1
- CA Issuers - URI:http://pki.goog/repo/certs/gtsr1.der
- X509v3 CRL Distribution Points:
- Full Name:
- URI:http://crl.pki.goog/gtsr1/gtsr1.crl
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.11129.2.5.3
- CPS: https://pki.goog/repository/
- Policy: 2.23.140.1.2.1
- Signature Algorithm: sha256WithRSAEncryption
- Signature Value:
- 6c:63:27:ee:23:df:e5:52:68:4d:81:66:91:85:df:7d:65:e5:
- 5b:37:31:08:26:b2:07:5d:9a:be:b1:ca:01:b9:ad:bf:9d:77:
- f6:51:1d:d7:98:c5:0b:49:a1:7b:a1:d7:d3:68:e5:44:0f:8b:
- ba:36:dd:42:82:77:d2:8d:dd:f5:3f:fb:eb:c8:07:98:93:ee:
- 5a:d0:b5:3d:de:4b:1c:2d:8c:4d:ec:7e:8c:7b:fe:4e:40:fd:
- f0:b4:b3:59:02:10:51:5c:e3:c0:2b:fd:b7:06:48:51:7e:09:
- 5e:3f:0f:dc:a7:fe:97:e7:79:c5:0e:44:89:78:c5:69:59:29:
- a0:9a:3a:48:36:29:a6:94:93:55:2d:b8:47:b5:e9:96:b5:9f:
- 07:cd:a6:ab:3e:32:8a:c0:86:83:c5:c1:41:c8:9f:2f:35:8e:
- 0d:c0:07:7a:e1:ac:c9:65:b5:cb:8a:a7:dd:71:d8:61:65:39:
- 84:ac:32:3e:f7:7a:36:f1:56:9f:57:a9:41:6d:5a:90:a7:db:
- 3a:ea:75:80:0c:63:0b:69:74:6f:07:4c:15:f3:37:28:a5:19:
- a4:6e:f5:f6:20:cd:63:b2:7e:c4:2b:09:75:89:da:d1:3c:2e:
- 72:4f:36:1a:a1:9e:44:d0:cd:9b:a6:23:08:3f:97:a1:a7:9e:
- 5a:a5:f7:09:94:ad:5d:76:5d:28:56:d1:1a:66:51:51:07:7b:
- de:3d:b0:c8:ef:30:7a:24:2d:be:b8:b3:86:f6:4b:f7:f0:b5:
- 4f:ff:ce:c6:f9:f6:3f:2a:27:08:0f:09:3e:23:5a:c7:e3:42:
- 2d:7a:36:e4:3d:98:96:60:39:98:ea:d1:db:63:2a:eb:78:09:
- b1:4e:21:b3:8e:b7:ce:3e:92:f1:95:5c:a4:39:d0:c0:2b:c8:
- 53:15:f5:d2:2f:82:cd:06:74:67:99:90:77:37:0a:97:2d:c5:
- 1c:1e:f4:d0:5b:e9:15:e3:ea:02:09:c8:13:d7:13:70:65:bf:
- fb:88:9b:5a:25:be:77:09:e1:a7:6a:4e:11:75:b9:1e:4d:f1:
- 00:1b:6a:66:79:8e:c3:6e:d8:6d:a2:22:a2:6d:05:fb:2c:f2:
- f1:50:e5:a0:d1:d8:9f:35:7d:fc:70:ab:59:2a:02:f1:be:b0:
- d3:f1:f8:cd:12:b9:6a:25:90:5b:e3:85:20:e6:f5:da:cb:40:
- 1c:19:34:20:03:61:77:ba:7f:48:0f:49:0b:29:eb:e7:61:64:
- c7:63:d1:47:eb:1c:e1:ee:94:46:ef:39:73:cc:ee:4f:2b:8d:
- dc:fb:58:a7:b3:65:20:99:95:b9:fb:55:6f:d7:96:6e:94:3d:
- f4:7a:92:8e:63:1d:df:6d
------BEGIN CERTIFICATE-----
-MIIFjDCCA3SgAwIBAgINAgO8UKMnU/CRgCLt8TANBgkqhkiG9w0BAQsFADBHMQsw
-CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
-MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw
-MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
-Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFQNTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBALOC8CSMvy2Hr7LZp676yrpE1ls+/rL3smUW3N4Q6E8tEFha
-KIaHoe5qs6DZdU9/oVIBi1WoSlsGSMg2EiWrifnyI1+dYGX5XNq+OuhcbX2c0IQY
-hTDNTpvsPNiz4ZbU88ULZduPsHTL9h7zePGslcXdc8MxiIGvdKpv/QzjBZXwxRBP
-ZWP6oK/GGD3Fod+XedcFibMwsHSuPZIQa4wVd90LBFf7gQPd6iI01eVWsvDEjUGx
-wwLbYuyA0P921IbkBBq2tgwrYnF92a/Z8V76wB7KoBlcVfCA0SoMB4aQnzXjKCtb
-7yPIox2kozru/oPcgkwlsE3FUa2em9NbhMIaWukCAwEAAaOCAXYwggFyMA4GA1Ud
-DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T
-AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU1fyeDd8eyt0Il5duK8VfxSv17LgwHwYD
-VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG
-CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw
-AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt
-MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsME0G
-A1UdIARGMEQwOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br
-aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAgEA
-bGMn7iPf5VJoTYFmkYXffWXlWzcxCCayB12avrHKAbmtv5139lEd15jFC0mhe6HX
-02jlRA+LujbdQoJ30o3d9T/768gHmJPuWtC1Pd5LHC2MTex+jHv+TkD98LSzWQIQ
-UVzjwCv9twZIUX4JXj8P3Kf+l+d5xQ5EiXjFaVkpoJo6SDYpppSTVS24R7XplrWf
-B82mqz4yisCGg8XBQcifLzWODcAHeuGsyWW1y4qn3XHYYWU5hKwyPvd6NvFWn1ep
-QW1akKfbOup1gAxjC2l0bwdMFfM3KKUZpG719iDNY7J+xCsJdYna0Twuck82GqGe
-RNDNm6YjCD+XoaeeWqX3CZStXXZdKFbRGmZRUQd73j2wyO8weiQtvrizhvZL9/C1
-T//Oxvn2PyonCA8JPiNax+NCLXo25D2YlmA5mOrR22Mq63gJsU4hs463zj6S8ZVc
-pDnQwCvIUxX10i+CzQZ0Z5mQdzcKly3FHB700FvpFePqAgnIE9cTcGW/+4ibWiW+
-dwnhp2pOEXW5Hk3xABtqZnmOw27YbaIiom0F+yzy8VDloNHYnzV9/HCrWSoC8b6w
-0/H4zRK5aiWQW+OFIOb12stAHBk0IANhd7p/SA9JCynr52Fkx2PRR+sc4e6URu85
-c8zuTyuN3PtYp7NlIJmVuftVb9eWbpQ99HqSjmMd320=
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 02:03:e5:93:6f:31:b0:13:49:88:6b:a2:17
- Signature Algorithm: sha384WithRSAEncryption
- Issuer: C=US, O=Google Trust Services LLC, CN=GTS Root R1
- Validity
- Not Before: Jun 22 00:00:00 2016 GMT
- Not After : Jun 22 00:00:00 2036 GMT
- Subject: C=US, O=Google Trust Services LLC, CN=GTS Root R1
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:b6:11:02:8b:1e:e3:a1:77:9b:3b:dc:bf:94:3e:
- b7:95:a7:40:3c:a1:fd:82:f9:7d:32:06:82:71:f6:
- f6:8c:7f:fb:e8:db:bc:6a:2e:97:97:a3:8c:4b:f9:
- 2b:f6:b1:f9:ce:84:1d:b1:f9:c5:97:de:ef:b9:f2:
- a3:e9:bc:12:89:5e:a7:aa:52:ab:f8:23:27:cb:a4:
- b1:9c:63:db:d7:99:7e:f0:0a:5e:eb:68:a6:f4:c6:
- 5a:47:0d:4d:10:33:e3:4e:b1:13:a3:c8:18:6c:4b:
- ec:fc:09:90:df:9d:64:29:25:23:07:a1:b4:d2:3d:
- 2e:60:e0:cf:d2:09:87:bb:cd:48:f0:4d:c2:c2:7a:
- 88:8a:bb:ba:cf:59:19:d6:af:8f:b0:07:b0:9e:31:
- f1:82:c1:c0:df:2e:a6:6d:6c:19:0e:b5:d8:7e:26:
- 1a:45:03:3d:b0:79:a4:94:28:ad:0f:7f:26:e5:a8:
- 08:fe:96:e8:3c:68:94:53:ee:83:3a:88:2b:15:96:
- 09:b2:e0:7a:8c:2e:75:d6:9c:eb:a7:56:64:8f:96:
- 4f:68:ae:3d:97:c2:84:8f:c0:bc:40:c0:0b:5c:bd:
- f6:87:b3:35:6c:ac:18:50:7f:84:e0:4c:cd:92:d3:
- 20:e9:33:bc:52:99:af:32:b5:29:b3:25:2a:b4:48:
- f9:72:e1:ca:64:f7:e6:82:10:8d:e8:9d:c2:8a:88:
- fa:38:66:8a:fc:63:f9:01:f9:78:fd:7b:5c:77:fa:
- 76:87:fa:ec:df:b1:0e:79:95:57:b4:bd:26:ef:d6:
- 01:d1:eb:16:0a:bb:8e:0b:b5:c5:c5:8a:55:ab:d3:
- ac:ea:91:4b:29:cc:19:a4:32:25:4e:2a:f1:65:44:
- d0:02:ce:aa:ce:49:b4:ea:9f:7c:83:b0:40:7b:e7:
- 43:ab:a7:6c:a3:8f:7d:89:81:fa:4c:a5:ff:d5:8e:
- c3:ce:4b:e0:b5:d8:b3:8e:45:cf:76:c0:ed:40:2b:
- fd:53:0f:b0:a7:d5:3b:0d:b1:8a:a2:03:de:31:ad:
- cc:77:ea:6f:7b:3e:d6:df:91:22:12:e6:be:fa:d8:
- 32:fc:10:63:14:51:72:de:5d:d6:16:93:bd:29:68:
- 33:ef:3a:66:ec:07:8a:26:df:13:d7:57:65:78:27:
- de:5e:49:14:00:a2:00:7f:9a:a8:21:b6:a9:b1:95:
- b0:a5:b9:0d:16:11:da:c7:6c:48:3c:40:e0:7e:0d:
- 5a:cd:56:3c:d1:97:05:b9:cb:4b:ed:39:4b:9c:c4:
- 3f:d2:55:13:6e:24:b0:d6:71:fa:f4:c1:ba:cc:ed:
- 1b:f5:fe:81:41:d8:00:98:3d:3a:c8:ae:7a:98:37:
- 18:05:95
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- E4:AF:2B:26:71:1A:2B:48:27:85:2F:52:66:2C:EF:F0:89:13:71:3E
- Signature Algorithm: sha384WithRSAEncryption
- Signature Value:
- 9f:aa:42:26:db:0b:9b:be:ff:1e:96:92:2e:3e:a2:65:4a:6a:
- 98:ba:22:cb:7d:c1:3a:d8:82:0a:06:c6:f6:a5:de:c0:4e:87:
- 66:79:a1:f9:a6:58:9c:aa:f9:b5:e6:60:e7:e0:e8:b1:1e:42:
- 41:33:0b:37:3d:ce:89:70:15:ca:b5:24:a8:cf:6b:b5:d2:40:
- 21:98:cf:22:34:cf:3b:c5:22:84:e0:c5:0e:8a:7c:5d:88:e4:
- 35:24:ce:9b:3e:1a:54:1e:6e:db:b2:87:a7:fc:f3:fa:81:55:
- 14:62:0a:59:a9:22:05:31:3e:82:d6:ee:db:57:34:bc:33:95:
- d3:17:1b:e8:27:a2:8b:7b:4e:26:1a:7a:5a:64:b6:d1:ac:37:
- f1:fd:a0:f3:38:ec:72:f0:11:75:9d:cb:34:52:8d:e6:76:6b:
- 17:c6:df:86:ab:27:8e:49:2b:75:66:81:10:21:a6:ea:3e:f4:
- ae:25:ff:7c:15:de:ce:8c:25:3f:ca:62:70:0a:f7:2f:09:66:
- 07:c8:3f:1c:fc:f0:db:45:30:df:62:88:c1:b5:0f:9d:c3:9f:
- 4a:de:59:59:47:c5:87:22:36:e6:82:a7:ed:0a:b9:e2:07:a0:
- 8d:7b:7a:4a:3c:71:d2:e2:03:a1:1f:32:07:dd:1b:e4:42:ce:
- 0c:00:45:61:80:b5:0b:20:59:29:78:bd:f9:55:cb:63:c5:3c:
- 4c:f4:b6:ff:db:6a:5f:31:6b:99:9e:2c:c1:6b:50:a4:d7:e6:
- 18:14:bd:85:3f:67:ab:46:9f:a0:ff:42:a7:3a:7f:5c:cb:5d:
- b0:70:1d:2b:34:f5:d4:76:09:0c:eb:78:4c:59:05:f3:33:42:
- c3:61:15:10:1b:77:4d:ce:22:8c:d4:85:f2:45:7d:b7:53:ea:
- ef:40:5a:94:0a:5c:20:5f:4e:40:5d:62:22:76:df:ff:ce:61:
- bd:8c:23:78:d2:37:02:e0:8e:de:d1:11:37:89:f6:bf:ed:49:
- 07:62:ae:92:ec:40:1a:af:14:09:d9:d0:4e:b2:a2:f7:be:ee:
- ee:d8:ff:dc:1a:2d:de:b8:36:71:e2:fc:79:b7:94:25:d1:48:
- 73:5b:a1:35:e7:b3:99:67:75:c1:19:3a:2b:47:4e:d3:42:8e:
- fd:31:c8:16:66:da:d2:0c:3c:db:b3:8e:c9:a1:0d:80:0f:7b:
- 16:77:14:bf:ff:db:09:94:b2:93:bc:20:58:15:e9:db:71:43:
- f3:de:10:c3:00:dc:a8:2a:95:b6:c2:d6:3f:90:6b:76:db:6c:
- fe:8c:bc:f2:70:35:0c:dc:99:19:35:dc:d7:c8:46:63:d5:36:
- 71:ae:57:fb:b7:82:6d:dc
------BEGIN CERTIFICATE-----
-MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
-CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
-MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
-MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
-Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA
-A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo
-27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w
-Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw
-TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl
-qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH
-szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8
-Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk
-MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
-wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p
-aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN
-VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID
-AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
-FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb
-C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe
-QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy
-h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4
-7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J
-ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef
-MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/
-Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
-6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ
-0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
-2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
-bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
------END CERTIFICATE-----
diff --git a/certs/GTS-Root-R1.pem b/certs/GTS-Root-R1.pem
new file mode 100644
index 0000000..a6095d2
--- /dev/null
+++ b/certs/GTS-Root-R1.pem
@@ -0,0 +1,38 @@
+# Issuer: CN=GTS Root R1 O=Google Trust Services LLC
+# Subject: CN=GTS Root R1 O=Google Trust Services LLC
+# Label: "GTS Root R1"
+# Serial: 159662320309726417404178440727
+# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40
+# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a
+# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf
+-----BEGIN CERTIFICATE-----
+MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo
+27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w
+Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw
+TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl
+qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH
+szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8
+Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk
+MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
+wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p
+aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN
+VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID
+AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb
+C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe
+QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy
+h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4
+7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J
+ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef
+MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/
+Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
+6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ
+0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
+2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
+bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
+-----END CERTIFICATE-----
diff --git a/certs/GTS-Root-R4.pem b/certs/GTS-Root-R4.pem
new file mode 100644
index 0000000..16a1c36
--- /dev/null
+++ b/certs/GTS-Root-R4.pem
@@ -0,0 +1,20 @@
+# Issuer: CN=GTS Root R4 O=Google Trust Services LLC
+# Subject: CN=GTS Root R4 O=Google Trust Services LLC
+# Label: "GTS Root R4"
+# Serial: 159662532700760215368942768210
+# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8
+# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47
+# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d
+-----BEGIN CERTIFICATE-----
+MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD
+VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
+A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
+WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
+IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi
+QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR
+HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D
+9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8
+p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD
+-----END CERTIFICATE-----
diff --git a/certs/GlobalSign-Atlas-R3-DV-TLS-CA-2022-Q3.pem b/certs/GlobalSign-Atlas-R3-DV-TLS-CA-2022-Q3.pem
deleted file mode 100644
index b514c11..0000000
--- a/certs/GlobalSign-Atlas-R3-DV-TLS-CA-2022-Q3.pem
+++ /dev/null
@@ -1,177 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 7c:2a:0c:21:3f:c6:55:53:45:c9:1f:19:1f:b8:4e:fa
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: OU = GlobalSign Root CA - R3, O = GlobalSign, CN = GlobalSign
- Validity
- Not Before: Apr 20 12:00:00 2022 GMT
- Not After : Apr 20 00:00:00 2025 GMT
- Subject: C = BE, O = GlobalSign nv-sa, CN = GlobalSign Atlas R3 DV TLS CA 2022 Q3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b8:a8:7a:66:3c:4e:66:9c:ce:37:a5:54:35:4d:
- 36:c7:99:d3:a8:27:36:f2:2f:c6:d5:18:3e:e9:09:
- dd:05:d6:d7:2c:34:32:7c:08:63:49:d1:10:37:e5:
- 78:5d:11:62:ce:6d:fb:2f:3f:37:94:db:8f:7b:30:
- e9:5e:2c:d9:55:3f:b2:db:b9:a0:b5:60:37:8b:a4:
- 06:32:35:50:a4:09:af:0a:45:ff:a8:1f:9b:65:8e:
- dd:4a:e0:40:a1:e3:63:37:58:90:dd:75:3b:fc:0e:
- 1c:82:40:98:bd:70:b1:c1:48:14:14:3c:04:4b:69:
- dd:d4:9c:01:a6:e9:21:e3:82:0a:fe:e4:aa:bf:34:
- a0:8c:cb:c9:79:6e:3e:5c:6a:52:9e:c4:ed:2b:c5:
- 69:fe:50:3c:93:9d:b5:ff:2d:28:a8:6c:06:6c:9d:
- c5:af:b2:59:fb:59:77:0d:74:7a:88:84:a4:d4:1d:
- d4:ba:20:06:cc:b5:1e:48:4e:74:21:15:86:75:c0:
- cc:5a:d1:05:cf:57:16:7a:13:17:ec:c2:4a:ae:d5:
- 1e:72:aa:22:5a:8c:9c:82:32:c4:10:e6:42:6e:21:
- 86:68:7c:80:23:30:35:d3:bd:b0:5e:0a:29:2b:f0:
- 14:b1:18:37:d9:59:25:c3:e7:38:d9:e9:d4:2d:36:
- 35:65
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- FA:91:39:63:9A:FB:AD:10:24:E5:BE:B5:B9:DA:AB:D9:C4:46:69:AB
- X509v3 Authority Key Identifier:
- 8F:F0:4B:7F:A8:2E:45:24:AE:4D:50:FA:63:9A:8B:DE:E2:DD:1B:BC
- Authority Information Access:
- OCSP - URI:http://ocsp2.globalsign.com/rootr3
- CA Issuers - URI:http://secure.globalsign.com/cacert/root-r3.crt
- X509v3 CRL Distribution Points:
- Full Name:
- URI:http://crl.globalsign.com/root-r3.crl
- X509v3 Certificate Policies:
- Policy: 2.23.140.1.2.1
- Policy: 1.3.6.1.4.1.4146.10.1.3
- Signature Algorithm: sha256WithRSAEncryption
- Signature Value:
- 14:33:2c:79:e5:3f:82:c6:70:3f:da:59:38:a7:bb:a2:76:ac:
- 61:18:05:68:57:d9:0d:fb:8a:46:bc:f1:a8:e8:0c:70:02:1d:
- c6:2f:97:ed:36:3e:9e:52:86:2f:5c:62:d8:d5:47:43:9a:73:
- d1:2b:25:87:9f:44:b4:14:eb:26:bc:21:47:74:20:bd:9f:a4:
- bf:b3:80:1d:4d:35:7d:cd:b9:b5:da:55:f2:90:50:c8:b2:17:
- 4e:0e:b4:61:88:29:5f:44:5d:03:7f:57:91:81:d0:eb:30:ae:
- d5:2a:ec:82:20:ce:4e:d2:b0:8b:95:02:61:73:d8:69:34:f4:
- ad:63:0e:5c:e4:20:1f:a9:7d:ed:8e:e5:1c:04:bb:22:9f:c7:
- a9:22:ca:99:3d:02:a7:67:e8:06:2d:fa:04:6b:bb:49:d2:6c:
- 99:57:63:6c:2d:c2:61:78:e1:20:b1:fb:f6:bf:e1:82:39:39:
- 3c:7b:ef:7d:1a:95:4a:b2:72:da:55:90:ae:ed:dd:e2:70:90:
- 7c:1a:ee:b5:32:5a:5d:cf:d6:fa:45:f2:9e:01:0c:31:2f:89:
- 84:fe:31:60:0f:fd:ee:a6:5b:84:d5:c7:18:e6:a4:f9:40:30:
- 29:18:1e:fe:fc:41:b5:b9:29:05:75:8b:62:1a:5b:22:2e:bf:
- e4:59:6c:b0
------BEGIN CERTIFICATE-----
-MIIEjzCCA3egAwIBAgIQfCoMIT/GVVNFyR8ZH7hO+jANBgkqhkiG9w0BAQsFADBM
-MSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xv
-YmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0yMjA0MjAxMjAwMDBaFw0y
-NTA0MjAwMDAwMDBaMFgxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWdu
-IG52LXNhMS4wLAYDVQQDEyVHbG9iYWxTaWduIEF0bGFzIFIzIERWIFRMUyBDQSAy
-MDIyIFEzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKh6ZjxOZpzO
-N6VUNU02x5nTqCc28i/G1Rg+6QndBdbXLDQyfAhjSdEQN+V4XRFizm37Lz83lNuP
-ezDpXizZVT+y27mgtWA3i6QGMjVQpAmvCkX/qB+bZY7dSuBAoeNjN1iQ3XU7/A4c
-gkCYvXCxwUgUFDwES2nd1JwBpukh44IK/uSqvzSgjMvJeW4+XGpSnsTtK8Vp/lA8
-k521/y0oqGwGbJ3Fr7JZ+1l3DXR6iISk1B3UuiAGzLUeSE50IRWGdcDMWtEFz1cW
-ehMX7MJKrtUecqoiWoycgjLEEOZCbiGGaHyAIzA1072wXgopK/AUsRg32Vklw+c4
-2enULTY1ZQIDAQABo4IBXzCCAVswDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQG
-CCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW
-BBT6kTljmvutECTlvrW52qvZxEZpqzAfBgNVHSMEGDAWgBSP8Et/qC5FJK5NUPpj
-move4t0bvDB7BggrBgEFBQcBAQRvMG0wLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3Nw
-Mi5nbG9iYWxzaWduLmNvbS9yb290cjMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9zZWN1
-cmUuZ2xvYmFsc2lnbi5jb20vY2FjZXJ0L3Jvb3QtcjMuY3J0MDYGA1UdHwQvMC0w
-K6ApoCeGJWh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5jb20vcm9vdC1yMy5jcmwwIQYD
-VR0gBBowGDAIBgZngQwBAgEwDAYKKwYBBAGgMgoBAzANBgkqhkiG9w0BAQsFAAOC
-AQEAFDMseeU/gsZwP9pZOKe7onasYRgFaFfZDfuKRrzxqOgMcAIdxi+X7TY+nlKG
-L1xi2NVHQ5pz0Sslh59EtBTrJrwhR3QgvZ+kv7OAHU01fc25tdpV8pBQyLIXTg60
-YYgpX0RdA39XkYHQ6zCu1SrsgiDOTtKwi5UCYXPYaTT0rWMOXOQgH6l97Y7lHAS7
-Ip/HqSLKmT0Cp2foBi36BGu7SdJsmVdjbC3CYXjhILH79r/hgjk5PHvvfRqVSrJy
-2lWQru3d4nCQfBrutTJaXc/W+kXyngEMMS+JhP4xYA/97qZbhNXHGOak+UAwKRge
-/vxBtbkpBXWLYhpbIi6/5FlssA==
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 04:00:00:00:00:01:21:58:53:08:a2
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: OU = GlobalSign Root CA - R3, O = GlobalSign, CN = GlobalSign
- Validity
- Not Before: Mar 18 10:00:00 2009 GMT
- Not After : Mar 18 10:00:00 2029 GMT
- Subject: OU = GlobalSign Root CA - R3, O = GlobalSign, CN = GlobalSign
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:cc:25:76:90:79:06:78:22:16:f5:c0:83:b6:84:
- ca:28:9e:fd:05:76:11:c5:ad:88:72:fc:46:02:43:
- c7:b2:8a:9d:04:5f:24:cb:2e:4b:e1:60:82:46:e1:
- 52:ab:0c:81:47:70:6c:dd:64:d1:eb:f5:2c:a3:0f:
- 82:3d:0c:2b:ae:97:d7:b6:14:86:10:79:bb:3b:13:
- 80:77:8c:08:e1:49:d2:6a:62:2f:1f:5e:fa:96:68:
- df:89:27:95:38:9f:06:d7:3e:c9:cb:26:59:0d:73:
- de:b0:c8:e9:26:0e:83:15:c6:ef:5b:8b:d2:04:60:
- ca:49:a6:28:f6:69:3b:f6:cb:c8:28:91:e5:9d:8a:
- 61:57:37:ac:74:14:dc:74:e0:3a:ee:72:2f:2e:9c:
- fb:d0:bb:bf:f5:3d:00:e1:06:33:e8:82:2b:ae:53:
- a6:3a:16:73:8c:dd:41:0e:20:3a:c0:b4:a7:a1:e9:
- b2:4f:90:2e:32:60:e9:57:cb:b9:04:92:68:68:e5:
- 38:26:60:75:b2:9f:77:ff:91:14:ef:ae:20:49:fc:
- ad:40:15:48:d1:02:31:61:19:5e:b8:97:ef:ad:77:
- b7:64:9a:7a:bf:5f:c1:13:ef:9b:62:fb:0d:6c:e0:
- 54:69:16:a9:03:da:6e:e9:83:93:71:76:c6:69:85:
- 82:17
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- 8F:F0:4B:7F:A8:2E:45:24:AE:4D:50:FA:63:9A:8B:DE:E2:DD:1B:BC
- Signature Algorithm: sha256WithRSAEncryption
- Signature Value:
- 4b:40:db:c0:50:aa:fe:c8:0c:ef:f7:96:54:45:49:bb:96:00:
- 09:41:ac:b3:13:86:86:28:07:33:ca:6b:e6:74:b9:ba:00:2d:
- ae:a4:0a:d3:f5:f1:f1:0f:8a:bf:73:67:4a:83:c7:44:7b:78:
- e0:af:6e:6c:6f:03:29:8e:33:39:45:c3:8e:e4:b9:57:6c:aa:
- fc:12:96:ec:53:c6:2d:e4:24:6c:b9:94:63:fb:dc:53:68:67:
- 56:3e:83:b8:cf:35:21:c3:c9:68:fe:ce:da:c2:53:aa:cc:90:
- 8a:e9:f0:5d:46:8c:95:dd:7a:58:28:1a:2f:1d:de:cd:00:37:
- 41:8f:ed:44:6d:d7:53:28:97:7e:f3:67:04:1e:15:d7:8a:96:
- b4:d3:de:4c:27:a4:4c:1b:73:73:76:f4:17:99:c2:1f:7a:0e:
- e3:2d:08:ad:0a:1c:2c:ff:3c:ab:55:0e:0f:91:7e:36:eb:c3:
- 57:49:be:e1:2e:2d:7c:60:8b:c3:41:51:13:23:9d:ce:f7:32:
- 6b:94:01:a8:99:e7:2c:33:1f:3a:3b:25:d2:86:40:ce:3b:2c:
- 86:78:c9:61:2f:14:ba:ee:db:55:6f:df:84:ee:05:09:4d:bd:
- 28:d8:72:ce:d3:62:50:65:1e:eb:92:97:83:31:d9:b3:b5:ca:
- 47:58:3f:5f
------BEGIN CERTIFICATE-----
-MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
-A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
-Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
-MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
-A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
-RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
-gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
-KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
-QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
-XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
-DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
-LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
-RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
-jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
-6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
-mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
-Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
-WD9f
------END CERTIFICATE-----
diff --git a/certs/Go-Daddy-Root-Certificate-Authority-G2.pem b/certs/Go-Daddy-Root-Certificate-Authority-G2.pem
new file mode 100644
index 0000000..c61f300
--- /dev/null
+++ b/certs/Go-Daddy-Root-Certificate-Authority-G2.pem
@@ -0,0 +1,30 @@
+# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
+# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
+# Label: "Go Daddy Root Certificate Authority - G2"
+# Serial: 0
+# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01
+# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b
+# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
+EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
+ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
+NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
+EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
+AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
+E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
+/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
+DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
+GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
+tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
+AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
+WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
+9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
+gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
+2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
+LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
+4uJEvlz36hz1
+-----END CERTIFICATE-----
diff --git a/certs/Go-Daddy-Secure-Certificate-Authority-G2.pem b/certs/Go-Daddy-Secure-Certificate-Authority-G2.pem
deleted file mode 100644
index 4faba90..0000000
--- a/certs/Go-Daddy-Secure-Certificate-Authority-G2.pem
+++ /dev/null
@@ -1,178 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 7 (0x7)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
- Validity
- Not Before: May 3 07:00:00 2011 GMT
- Not After : May 3 07:00:00 2031 GMT
- Subject: C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certs.godaddy.com/repository/, CN = Go Daddy Secure Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public-Key: (2048 bit)
- Modulus:
- 00:b9:e0:cb:10:d4:af:76:bd:d4:93:62:eb:30:64:
- b8:81:08:6c:c3:04:d9:62:17:8e:2f:ff:3e:65:cf:
- 8f:ce:62:e6:3c:52:1c:da:16:45:4b:55:ab:78:6b:
- 63:83:62:90:ce:0f:69:6c:99:c8:1a:14:8b:4c:cc:
- 45:33:ea:88:dc:9e:a3:af:2b:fe:80:61:9d:79:57:
- c4:cf:2e:f4:3f:30:3c:5d:47:fc:9a:16:bc:c3:37:
- 96:41:51:8e:11:4b:54:f8:28:be:d0:8c:be:f0:30:
- 38:1e:f3:b0:26:f8:66:47:63:6d:de:71:26:47:8f:
- 38:47:53:d1:46:1d:b4:e3:dc:00:ea:45:ac:bd:bc:
- 71:d9:aa:6f:00:db:db:cd:30:3a:79:4f:5f:4c:47:
- f8:1d:ef:5b:c2:c4:9d:60:3b:b1:b2:43:91:d8:a4:
- 33:4e:ea:b3:d6:27:4f:ad:25:8a:a5:c6:f4:d5:d0:
- a6:ae:74:05:64:57:88:b5:44:55:d4:2d:2a:3a:3e:
- f8:b8:bd:e9:32:0a:02:94:64:c4:16:3a:50:f1:4a:
- ae:e7:79:33:af:0c:20:07:7f:e8:df:04:39:c2:69:
- 02:6c:63:52:fa:77:c1:1b:c8:74:87:c8:b9:93:18:
- 50:54:35:4b:69:4e:bc:3b:d3:49:2e:1f:dc:c1:d2:
- 52:fb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE
- X509v3 Authority Key Identifier:
- keyid:3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
-
- Authority Information Access:
- OCSP - URI:http://ocsp.godaddy.com/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.godaddy.com/gdroot-g2.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://certs.godaddy.com/repository/
-
- Signature Algorithm: sha256WithRSAEncryption
- 08:7e:6c:93:10:c8:38:b8:96:a9:90:4b:ff:a1:5f:4f:04:ef:
- 6c:3e:9c:88:06:c9:50:8f:a6:73:f7:57:31:1b:be:bc:e4:2f:
- db:f8:ba:d3:5b:e0:b4:e7:e6:79:62:0e:0c:a2:d7:6a:63:73:
- 31:b5:f5:a8:48:a4:3b:08:2d:a2:5d:90:d7:b4:7c:25:4f:11:
- 56:30:c4:b6:44:9d:7b:2c:9d:e5:5e:e6:ef:0c:61:aa:bf:e4:
- 2a:1b:ee:84:9e:b8:83:7d:c1:43:ce:44:a7:13:70:0d:91:1f:
- f4:c8:13:ad:83:60:d9:d8:72:a8:73:24:1e:b5:ac:22:0e:ca:
- 17:89:62:58:44:1b:ab:89:25:01:00:0f:cd:c4:1b:62:db:51:
- b4:d3:0f:51:2a:9b:f4:bc:73:fc:76:ce:36:a4:cd:d9:d8:2c:
- ea:ae:9b:f5:2a:b2:90:d1:4d:75:18:8a:3f:8a:41:90:23:7d:
- 5b:4b:fe:a4:03:58:9b:46:b2:c3:60:60:83:f8:7d:50:41:ce:
- c2:a1:90:c3:bb:ef:02:2f:d2:15:54:ee:44:15:d9:0a:ae:a7:
- 8a:33:ed:b1:2d:76:36:26:dc:04:eb:9f:f7:61:1f:15:dc:87:
- 6f:ee:46:96:28:ad:a1:26:7d:0a:09:a7:2e:04:a3:8d:bc:f8:
- bc:04:30:01
------BEGIN CERTIFICATE-----
-MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
-EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
-ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3
-MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
-EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE
-CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD
-EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD
-BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv
-K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e
-cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY
-pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n
-eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB
-AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
-HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv
-9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
-b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n
-b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG
-CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv
-MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz
-91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2
-RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi
-DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11
-GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x
-LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 0 (0x0)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
- Validity
- Not Before: Sep 1 00:00:00 2009 GMT
- Not After : Dec 31 23:59:59 2037 GMT
- Subject: C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public-Key: (2048 bit)
- Modulus:
- 00:bf:71:62:08:f1:fa:59:34:f7:1b:c9:18:a3:f7:
- 80:49:58:e9:22:83:13:a6:c5:20:43:01:3b:84:f1:
- e6:85:49:9f:27:ea:f6:84:1b:4e:a0:b4:db:70:98:
- c7:32:01:b1:05:3e:07:4e:ee:f4:fa:4f:2f:59:30:
- 22:e7:ab:19:56:6b:e2:80:07:fc:f3:16:75:80:39:
- 51:7b:e5:f9:35:b6:74:4e:a9:8d:82:13:e4:b6:3f:
- a9:03:83:fa:a2:be:8a:15:6a:7f:de:0b:c3:b6:19:
- 14:05:ca:ea:c3:a8:04:94:3b:46:7c:32:0d:f3:00:
- 66:22:c8:8d:69:6d:36:8c:11:18:b7:d3:b2:1c:60:
- b4:38:fa:02:8c:ce:d3:dd:46:07:de:0a:3e:eb:5d:
- 7c:c8:7c:fb:b0:2b:53:a4:92:62:69:51:25:05:61:
- 1a:44:81:8c:2c:a9:43:96:23:df:ac:3a:81:9a:0e:
- 29:c5:1c:a9:e9:5d:1e:b6:9e:9e:30:0a:39:ce:f1:
- 88:80:fb:4b:5d:cc:32:ec:85:62:43:25:34:02:56:
- 27:01:91:b4:3b:70:2a:3f:6e:b1:e8:9c:88:01:7d:
- 9f:d4:f9:db:53:6d:60:9d:bf:2c:e7:58:ab:b8:5f:
- 46:fc:ce:c4:1b:03:3c:09:eb:49:31:5c:69:46:b3:
- e0:47
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
- Signature Algorithm: sha256WithRSAEncryption
- 99:db:5d:79:d5:f9:97:59:67:03:61:f1:7e:3b:06:31:75:2d:
- a1:20:8e:4f:65:87:b4:f7:a6:9c:bc:d8:e9:2f:d0:db:5a:ee:
- cf:74:8c:73:b4:38:42:da:05:7b:f8:02:75:b8:fd:a5:b1:d7:
- ae:f6:d7:de:13:cb:53:10:7e:8a:46:d1:97:fa:b7:2e:2b:11:
- ab:90:b0:27:80:f9:e8:9f:5a:e9:37:9f:ab:e4:df:6c:b3:85:
- 17:9d:3d:d9:24:4f:79:91:35:d6:5f:04:eb:80:83:ab:9a:02:
- 2d:b5:10:f4:d8:90:c7:04:73:40:ed:72:25:a0:a9:9f:ec:9e:
- ab:68:12:99:57:c6:8f:12:3a:09:a4:bd:44:fd:06:15:37:c1:
- 9b:e4:32:a3:ed:38:e8:d8:64:f3:2c:7e:14:fc:02:ea:9f:cd:
- ff:07:68:17:db:22:90:38:2d:7a:8d:d1:54:f1:69:e3:5f:33:
- ca:7a:3d:7b:0a:e3:ca:7f:5f:39:e5:e2:75:ba:c5:76:18:33:
- ce:2c:f0:2f:4c:ad:f7:b1:e7:ce:4f:a8:c4:9b:4a:54:06:c5:
- 7f:7d:d5:08:0f:e2:1c:fe:7e:17:b8:ac:5e:f6:d4:16:b2:43:
- 09:0c:4d:f6:a7:6b:b4:99:84:65:ca:7a:88:e2:e2:44:be:5c:
- f7:ea:1c:f5
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
-EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
-ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
-NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
-EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
-AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
-E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
-/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
-DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
-GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
-tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
-AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
-FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
-WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
-9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
-gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
-2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
-LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
-4uJEvlz36hz1
------END CERTIFICATE-----
diff --git a/certs/ISRG-Root-X1.pem b/certs/ISRG-Root-X1.pem
new file mode 100644
index 0000000..995c95d
--- /dev/null
+++ b/certs/ISRG-Root-X1.pem
@@ -0,0 +1,38 @@
+# Issuer: CN=ISRG Root X1 O=Internet Security Research Group
+# Subject: CN=ISRG Root X1 O=Internet Security Research Group
+# Label: "ISRG Root X1"
+# Serial: 172886928669790476064670243504169061120
+# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e
+# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8
+# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6
+-----BEGIN CERTIFICATE-----
+MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
+TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
+cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
+WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
+ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
+h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
+0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
+A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
+T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
+B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
+B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
+KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
+OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
+jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
+qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
+rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
+hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
+ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
+3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
+NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
+ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
+TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
+jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
+oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
+4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
+mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
+emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
+-----END CERTIFICATE-----
diff --git a/certs/ISRG-Root-X2.pem b/certs/ISRG-Root-X2.pem
new file mode 100644
index 0000000..9cca880
--- /dev/null
+++ b/certs/ISRG-Root-X2.pem
@@ -0,0 +1,21 @@
+# Issuer: CN=ISRG Root X2 O=Internet Security Research Group
+# Subject: CN=ISRG Root X2 O=Internet Security Research Group
+# Label: "ISRG Root X2"
+# Serial: 87493402998870891108772069816698636114
+# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5
+# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af
+# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70
+-----BEGIN CERTIFICATE-----
+MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
+CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
+R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
+MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
+ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
+EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
+ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
+zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
+tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
+/q4AaOeMSQ+2b1tbFfLn
+-----END CERTIFICATE-----
diff --git a/certs/Makefile b/certs/Makefile
new file mode 100644
index 0000000..3ccad6e
--- /dev/null
+++ b/certs/Makefile
@@ -0,0 +1,58 @@
+# Makefile to check certificates
+
+CURL = curl \
+ --capath /dev/null \
+ --connect-timeout 5 \
+ --output /dev/null \
+ --silent
+
+DOMAINS_DUAL = \
+ api.macvendors.com/GTS-Root-R4 \
+ api.telegram.org/Go-Daddy-Root-Certificate-Authority-G2 \
+ cloudflare-dns.com/DigiCert-Global-Root-G2 \
+ dns.google/GTS-Root-R4 \
+ dns.quad9.net/DigiCert-Global-Root-G3 \
+ git.eworm.de/ISRG-Root-X2 \
+ lists.blocklist.de/Certum-Trusted-Network-CA \
+ matrix.org/GTS-Root-R4 \
+ raw.githubusercontent.com/USERTrust-RSA-Certification-Authority \
+ rsc.eworm.de/ISRG-Root-X2 \
+ upgrade.mikrotik.com/ISRG-Root-X1
+DOMAINS_IPV4 = \
+ 1.1.1.1/DigiCert-Global-Root-G2 \
+ 8.8.8.8/GTS-Root-R1 \
+ 9.9.9.9/DigiCert-Global-Root-G3 \
+ api.mullvad.net/ISRG-Root-X1 \
+ ipv4.showipv6.de/ISRG-Root-X1 \
+ ipv4.tunnelbroker.net/Starfield-Root-Certificate-Authority-G2 \
+ mkcert.org/ISRG-Root-X1 \
+ ntfy.sh/ISRG-Root-X1 \
+ www.dshield.org/ISRG-Root-X1 \
+ www.spamhaus.org/GTS-Root-R4
+DOMAINS_IPV6 = \
+ [2606\:4700\:4700\:\:1111]/DigiCert-Global-Root-G2 \
+ [2001\:4860\:4860\:\:8888]/GTS-Root-R1 \
+ [2620\:fe\:\:9]/DigiCert-Global-Root-G3 \
+ ipv6.showipv6.de/ISRG-Root-X1
+
+.PHONY: $(DOMAINS_DUAL) $(DOMAINS_IPV4) $(DOMAINS_IPV6)
+
+all: $(DOMAINS_DUAL) $(DOMAINS_IPV4) $(DOMAINS_IPV6)
+
+$(DOMAINS_DUAL):
+ifndef NOIPV4
+ $(CURL) -4 --cacert $(notdir $@).pem https://$(dir $@)
+endif
+ifndef NOIPV6
+ $(CURL) -6 --cacert $(notdir $@).pem https://$(dir $@)
+endif
+
+$(DOMAINS_IPV4):
+ifndef NOIPV4
+ $(CURL) -4 --cacert $(notdir $@).pem https://$(dir $@)
+endif
+
+$(DOMAINS_IPV6):
+ifndef NOIPV6
+ $(CURL) -6 --cacert $(notdir $@).pem https://$(dir $@)
+endif
diff --git a/certs/R3.pem b/certs/R3.pem
deleted file mode 100644
index 837b709..0000000
--- a/certs/R3.pem
+++ /dev/null
@@ -1,237 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 91:2b:08:4a:cf:0c:18:a7:53:f6:d6:2e:25:a7:5f:5a
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X1
- Validity
- Not Before: Sep 4 00:00:00 2020 GMT
- Not After : Sep 15 16:00:00 2025 GMT
- Subject: C = US, O = Let's Encrypt, CN = R3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public-Key: (2048 bit)
- Modulus:
- 00:bb:02:15:28:cc:f6:a0:94:d3:0f:12:ec:8d:55:
- 92:c3:f8:82:f1:99:a6:7a:42:88:a7:5d:26:aa:b5:
- 2b:b9:c5:4c:b1:af:8e:6b:f9:75:c8:a3:d7:0f:47:
- 94:14:55:35:57:8c:9e:a8:a2:39:19:f5:82:3c:42:
- a9:4e:6e:f5:3b:c3:2e:db:8d:c0:b0:5c:f3:59:38:
- e7:ed:cf:69:f0:5a:0b:1b:be:c0:94:24:25:87:fa:
- 37:71:b3:13:e7:1c:ac:e1:9b:ef:db:e4:3b:45:52:
- 45:96:a9:c1:53:ce:34:c8:52:ee:b5:ae:ed:8f:de:
- 60:70:e2:a5:54:ab:b6:6d:0e:97:a5:40:34:6b:2b:
- d3:bc:66:eb:66:34:7c:fa:6b:8b:8f:57:29:99:f8:
- 30:17:5d:ba:72:6f:fb:81:c5:ad:d2:86:58:3d:17:
- c7:e7:09:bb:f1:2b:f7:86:dc:c1:da:71:5d:d4:46:
- e3:cc:ad:25:c1:88:bc:60:67:75:66:b3:f1:18:f7:
- a2:5c:e6:53:ff:3a:88:b6:47:a5:ff:13:18:ea:98:
- 09:77:3f:9d:53:f9:cf:01:e5:f5:a6:70:17:14:af:
- 63:a4:ff:99:b3:93:9d:dc:53:a7:06:fe:48:85:1d:
- a1:69:ae:25:75:bb:13:cc:52:03:f5:ed:51:a1:8b:
- db:15
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Client Authentication, TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- 14:2E:B3:17:B7:58:56:CB:AE:50:09:40:E6:1F:AF:9D:8B:14:C2:C6
- X509v3 Authority Key Identifier:
- keyid:79:B4:59:E6:7B:B6:E5:E4:01:73:80:08:88:C8:1A:58:F6:E9:9B:6E
-
- Authority Information Access:
- CA Issuers - URI:http://x1.i.lencr.org/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://x1.c.lencr.org/
-
- X509v3 Certificate Policies:
- Policy: 2.23.140.1.2.1
- Policy: 1.3.6.1.4.1.44947.1.1.1
-
- Signature Algorithm: sha256WithRSAEncryption
- 85:ca:4e:47:3e:a3:f7:85:44:85:bc:d5:67:78:b2:98:63:ad:
- 75:4d:1e:96:3d:33:65:72:54:2d:81:a0:ea:c3:ed:f8:20:bf:
- 5f:cc:b7:70:00:b7:6e:3b:f6:5e:94:de:e4:20:9f:a6:ef:8b:
- b2:03:e7:a2:b5:16:3c:91:ce:b4:ed:39:02:e7:7c:25:8a:47:
- e6:65:6e:3f:46:f4:d9:f0:ce:94:2b:ee:54:ce:12:bc:8c:27:
- 4b:b8:c1:98:2f:a2:af:cd:71:91:4a:08:b7:c8:b8:23:7b:04:
- 2d:08:f9:08:57:3e:83:d9:04:33:0a:47:21:78:09:82:27:c3:
- 2a:c8:9b:b9:ce:5c:f2:64:c8:c0:be:79:c0:4f:8e:6d:44:0c:
- 5e:92:bb:2e:f7:8b:10:e1:e8:1d:44:29:db:59:20:ed:63:b9:
- 21:f8:12:26:94:93:57:a0:1d:65:04:c1:0a:22:ae:10:0d:43:
- 97:a1:18:1f:7e:e0:e0:86:37:b5:5a:b1:bd:30:bf:87:6e:2b:
- 2a:ff:21:4e:1b:05:c3:f5:18:97:f0:5e:ac:c3:a5:b8:6a:f0:
- 2e:bc:3b:33:b9:ee:4b:de:cc:fc:e4:af:84:0b:86:3f:c0:55:
- 43:36:f6:68:e1:36:17:6a:8e:99:d1:ff:a5:40:a7:34:b7:c0:
- d0:63:39:35:39:75:6e:f2:ba:76:c8:93:02:e9:a9:4b:6c:17:
- ce:0c:02:d9:bd:81:fb:9f:b7:68:d4:06:65:b3:82:3d:77:53:
- f8:8e:79:03:ad:0a:31:07:75:2a:43:d8:55:97:72:c4:29:0e:
- f7:c4:5d:4e:c8:ae:46:84:30:d7:f2:85:5f:18:a1:79:bb:e7:
- 5e:70:8b:07:e1:86:93:c3:b9:8f:dc:61:71:25:2a:af:df:ed:
- 25:50:52:68:8b:92:dc:e5:d6:b5:e3:da:7d:d0:87:6c:84:21:
- 31:ae:82:f5:fb:b9:ab:c8:89:17:3d:e1:4c:e5:38:0e:f6:bd:
- 2b:bd:96:81:14:eb:d5:db:3d:20:a7:7e:59:d3:e2:f8:58:f9:
- 5b:b8:48:cd:fe:5c:4f:16:29:fe:1e:55:23:af:c8:11:b0:8d:
- ea:7c:93:90:17:2f:fd:ac:a2:09:47:46:3f:f0:e9:b0:b7:ff:
- 28:4d:68:32:d6:67:5e:1e:69:a3:93:b8:f5:9d:8b:2f:0b:d2:
- 52:43:a6:6f:32:57:65:4d:32:81:df:38:53:85:5d:7e:5d:66:
- 29:ea:b8:dd:e4:95:b5:cd:b5:56:12:42:cd:c4:4e:c6:25:38:
- 44:50:6d:ec:ce:00:55:18:fe:e9:49:64:d4:4e:ca:97:9c:b4:
- 5b:c0:73:a8:ab:b8:47:c2
------BEGIN CERTIFICATE-----
-MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
-TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
-cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
-WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
-RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
-R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
-sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
-NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
-Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
-/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
-AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
-Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
-FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
-AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
-Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
-gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
-PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
-ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
-CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
-lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
-avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
-yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
-yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
-hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
-HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
-MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
-nLRbwHOoq7hHwg==
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 82:10:cf:b0:d2:40:e3:59:44:63:e0:bb:63:82:8b:00
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X1
- Validity
- Not Before: Jun 4 11:04:38 2015 GMT
- Not After : Jun 4 11:04:38 2035 GMT
- Subject: C = US, O = Internet Security Research Group, CN = ISRG Root X1
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public-Key: (4096 bit)
- Modulus:
- 00:ad:e8:24:73:f4:14:37:f3:9b:9e:2b:57:28:1c:
- 87:be:dc:b7:df:38:90:8c:6e:3c:e6:57:a0:78:f7:
- 75:c2:a2:fe:f5:6a:6e:f6:00:4f:28:db:de:68:86:
- 6c:44:93:b6:b1:63:fd:14:12:6b:bf:1f:d2:ea:31:
- 9b:21:7e:d1:33:3c:ba:48:f5:dd:79:df:b3:b8:ff:
- 12:f1:21:9a:4b:c1:8a:86:71:69:4a:66:66:6c:8f:
- 7e:3c:70:bf:ad:29:22:06:f3:e4:c0:e6:80:ae:e2:
- 4b:8f:b7:99:7e:94:03:9f:d3:47:97:7c:99:48:23:
- 53:e8:38:ae:4f:0a:6f:83:2e:d1:49:57:8c:80:74:
- b6:da:2f:d0:38:8d:7b:03:70:21:1b:75:f2:30:3c:
- fa:8f:ae:dd:da:63:ab:eb:16:4f:c2:8e:11:4b:7e:
- cf:0b:e8:ff:b5:77:2e:f4:b2:7b:4a:e0:4c:12:25:
- 0c:70:8d:03:29:a0:e1:53:24:ec:13:d9:ee:19:bf:
- 10:b3:4a:8c:3f:89:a3:61:51:de:ac:87:07:94:f4:
- 63:71:ec:2e:e2:6f:5b:98:81:e1:89:5c:34:79:6c:
- 76:ef:3b:90:62:79:e6:db:a4:9a:2f:26:c5:d0:10:
- e1:0e:de:d9:10:8e:16:fb:b7:f7:a8:f7:c7:e5:02:
- 07:98:8f:36:08:95:e7:e2:37:96:0d:36:75:9e:fb:
- 0e:72:b1:1d:9b:bc:03:f9:49:05:d8:81:dd:05:b4:
- 2a:d6:41:e9:ac:01:76:95:0a:0f:d8:df:d5:bd:12:
- 1f:35:2f:28:17:6c:d2:98:c1:a8:09:64:77:6e:47:
- 37:ba:ce:ac:59:5e:68:9d:7f:72:d6:89:c5:06:41:
- 29:3e:59:3e:dd:26:f5:24:c9:11:a7:5a:a3:4c:40:
- 1f:46:a1:99:b5:a7:3a:51:6e:86:3b:9e:7d:72:a7:
- 12:05:78:59:ed:3e:51:78:15:0b:03:8f:8d:d0:2f:
- 05:b2:3e:7b:4a:1c:4b:73:05:12:fc:c6:ea:e0:50:
- 13:7c:43:93:74:b3:ca:74:e7:8e:1f:01:08:d0:30:
- d4:5b:71:36:b4:07:ba:c1:30:30:5c:48:b7:82:3b:
- 98:a6:7d:60:8a:a2:a3:29:82:cc:ba:bd:83:04:1b:
- a2:83:03:41:a1:d6:05:f1:1b:c2:b6:f0:a8:7c:86:
- 3b:46:a8:48:2a:88:dc:76:9a:76:bf:1f:6a:a5:3d:
- 19:8f:eb:38:f3:64:de:c8:2b:0d:0a:28:ff:f7:db:
- e2:15:42:d4:22:d0:27:5d:e1:79:fe:18:e7:70:88:
- ad:4e:e6:d9:8b:3a:c6:dd:27:51:6e:ff:bc:64:f5:
- 33:43:4f
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- 79:B4:59:E6:7B:B6:E5:E4:01:73:80:08:88:C8:1A:58:F6:E9:9B:6E
- Signature Algorithm: sha256WithRSAEncryption
- 55:1f:58:a9:bc:b2:a8:50:d0:0c:b1:d8:1a:69:20:27:29:08:
- ac:61:75:5c:8a:6e:f8:82:e5:69:2f:d5:f6:56:4b:b9:b8:73:
- 10:59:d3:21:97:7e:e7:4c:71:fb:b2:d2:60:ad:39:a8:0b:ea:
- 17:21:56:85:f1:50:0e:59:eb:ce:e0:59:e9:ba:c9:15:ef:86:
- 9d:8f:84:80:f6:e4:e9:91:90:dc:17:9b:62:1b:45:f0:66:95:
- d2:7c:6f:c2:ea:3b:ef:1f:cf:cb:d6:ae:27:f1:a9:b0:c8:ae:
- fd:7d:7e:9a:fa:22:04:eb:ff:d9:7f:ea:91:2b:22:b1:17:0e:
- 8f:f2:8a:34:5b:58:d8:fc:01:c9:54:b9:b8:26:cc:8a:88:33:
- 89:4c:2d:84:3c:82:df:ee:96:57:05:ba:2c:bb:f7:c4:b7:c7:
- 4e:3b:82:be:31:c8:22:73:73:92:d1:c2:80:a4:39:39:10:33:
- 23:82:4c:3c:9f:86:b2:55:98:1d:be:29:86:8c:22:9b:9e:e2:
- 6b:3b:57:3a:82:70:4d:dc:09:c7:89:cb:0a:07:4d:6c:e8:5d:
- 8e:c9:ef:ce:ab:c7:bb:b5:2b:4e:45:d6:4a:d0:26:cc:e5:72:
- ca:08:6a:a5:95:e3:15:a1:f7:a4:ed:c9:2c:5f:a5:fb:ff:ac:
- 28:02:2e:be:d7:7b:bb:e3:71:7b:90:16:d3:07:5e:46:53:7c:
- 37:07:42:8c:d3:c4:96:9c:d5:99:b5:2a:e0:95:1a:80:48:ae:
- 4c:39:07:ce:cc:47:a4:52:95:2b:ba:b8:fb:ad:d2:33:53:7d:
- e5:1d:4d:6d:d5:a1:b1:c7:42:6f:e6:40:27:35:5c:a3:28:b7:
- 07:8d:e7:8d:33:90:e7:23:9f:fb:50:9c:79:6c:46:d5:b4:15:
- b3:96:6e:7e:9b:0c:96:3a:b8:52:2d:3f:d6:5b:e1:fb:08:c2:
- 84:fe:24:a8:a3:89:da:ac:6a:e1:18:2a:b1:a8:43:61:5b:d3:
- 1f:dc:3b:8d:76:f2:2d:e8:8d:75:df:17:33:6c:3d:53:fb:7b:
- cb:41:5f:ff:dc:a2:d0:61:38:e1:96:b8:ac:5d:8b:37:d7:75:
- d5:33:c0:99:11:ae:9d:41:c1:72:75:84:be:02:41:42:5f:67:
- 24:48:94:d1:9b:27:be:07:3f:b9:b8:4f:81:74:51:e1:7a:b7:
- ed:9d:23:e2:be:e0:d5:28:04:13:3c:31:03:9e:dd:7a:6c:8f:
- c6:07:18:c6:7f:de:47:8e:3f:28:9e:04:06:cf:a5:54:34:77:
- bd:ec:89:9b:e9:17:43:df:5b:db:5f:fe:8e:1e:57:a2:cd:40:
- 9d:7e:62:22:da:de:18:27
------BEGIN CERTIFICATE-----
-MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
-TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
-cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
-WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
-ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
-MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
-h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
-0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
-A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
-T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
-B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
-B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
-KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
-OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
-jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
-qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
-rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
-hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
-ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
-3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
-NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
-ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
-TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
-jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
-oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
-4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
-mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
-emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
------END CERTIFICATE-----
diff --git a/certs/Starfield-Root-Certificate-Authority-G2.pem b/certs/Starfield-Root-Certificate-Authority-G2.pem
new file mode 100644
index 0000000..4e6774d
--- /dev/null
+++ b/certs/Starfield-Root-Certificate-Authority-G2.pem
@@ -0,0 +1,30 @@
+# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
+# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
+# Label: "Starfield Root Certificate Authority - G2"
+# Serial: 0
+# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96
+# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e
+# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5
+-----BEGIN CERTIFICATE-----
+MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
+ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
+MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
+b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
+aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
+Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
+nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
+HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
+Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
+dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
+HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
+CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
+sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
+4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
+8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
+pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
+mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
+-----END CERTIFICATE-----
diff --git a/certs/Starfield-Secure-Certificate-Authority-G2.pem b/certs/Starfield-Secure-Certificate-Authority-G2.pem
deleted file mode 100644
index 7772e6b..0000000
--- a/certs/Starfield-Secure-Certificate-Authority-G2.pem
+++ /dev/null
@@ -1,179 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 7 (0x7)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Root Certificate Authority - G2
- Validity
- Not Before: May 3 07:00:00 2011 GMT
- Not After : May 3 07:00:00 2031 GMT
- Subject: C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", OU = http://certs.starfieldtech.com/repository/, CN = Starfield Secure Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public-Key: (2048 bit)
- Modulus:
- 00:e5:90:66:4b:ec:f9:46:71:a9:20:83:be:e9:6c:
- bf:4a:c9:48:69:81:75:4e:6d:24:f6:cb:17:13:f8:
- b0:71:59:84:7a:6b:2b:85:a4:34:b5:16:e5:cb:cc:
- e9:41:70:2c:a4:2e:d6:fa:32:7d:e1:a8:de:94:10:
- ac:31:c1:c0:d8:6a:ff:59:27:ab:76:d6:fc:0b:74:
- 6b:b8:a7:ae:3f:c4:54:f4:b4:31:44:dd:93:56:8c:
- a4:4c:5e:9b:89:cb:24:83:9b:e2:57:7d:b7:d8:12:
- 1f:c9:85:6d:f4:d1:80:f1:50:9b:87:ae:d4:0b:10:
- 05:fb:27:ba:28:6d:17:e9:0e:d6:4d:b9:39:55:06:
- ff:0a:24:05:7e:2f:c6:1d:72:6c:d4:8b:29:8c:57:
- 7d:da:d9:eb:66:1a:d3:4f:a7:df:7f:52:c4:30:c5:
- a5:c9:0e:02:c5:53:bf:77:38:68:06:24:c3:66:c8:
- 37:7e:30:1e:45:71:23:35:ff:90:d8:2a:9d:8d:e7:
- b0:92:4d:3c:7f:2a:0a:93:dc:cd:16:46:65:f7:60:
- 84:8b:76:4b:91:27:73:14:92:e0:ea:ee:8f:16:ea:
- 8d:0e:3e:76:17:bf:7d:89:80:80:44:43:e7:2d:e0:
- 43:09:75:da:36:e8:ad:db:89:3a:f5:5d:12:8e:23:
- 04:83
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 25:45:81:68:50:26:38:3D:3B:2D:2C:BE:CD:6A:D9:B6:3D:B3:66:63
- X509v3 Authority Key Identifier:
- keyid:7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27
-
- Authority Information Access:
- OCSP - URI:http://ocsp.starfieldtech.com/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.starfieldtech.com/sfroot-g2.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://certs.starfieldtech.com/repository/
-
- Signature Algorithm: sha256WithRSAEncryption
- 56:65:ca:fe:f3:3f:0a:a8:93:8b:18:c7:de:43:69:13:34:20:
- be:4e:5f:78:a8:6b:9c:db:6a:4d:41:db:c1:13:ec:dc:31:00:
- 22:5e:f7:00:9e:0c:e0:34:65:34:f9:b1:3a:4e:48:c8:12:81:
- 88:5c:5b:3e:08:53:7a:f7:1a:64:df:b8:50:61:cc:53:51:40:
- 29:4b:c2:f4:ae:3a:5f:e4:ca:ad:26:cc:4e:61:43:e5:fd:57:
- a6:37:70:ce:43:2b:b0:94:c3:92:e9:e1:5f:aa:10:49:b7:69:
- e4:e0:d0:1f:64:a4:2b:cd:1f:6f:a0:f8:84:24:18:ce:79:3d:
- a9:91:bf:54:18:13:89:99:54:11:0d:55:c5:26:0b:79:4f:5a:
- 1c:6e:f9:63:db:14:80:a4:07:ab:fa:b2:a5:b9:88:dd:91:fe:
- 65:3b:a4:a3:79:be:89:4d:e1:d0:b0:f4:c8:17:0c:0a:96:14:
- 7c:09:b7:6c:e1:c2:d8:55:d4:18:a0:aa:41:69:70:24:a3:b9:
- ef:e9:5a:dc:3e:eb:94:4a:f0:b7:de:5f:0e:76:fa:fb:fb:69:
- 03:45:40:50:ee:72:0c:a4:12:86:81:cd:13:d1:4e:c4:3c:ca:
- 4e:0d:d2:26:f1:00:b7:b4:a6:a2:e1:6e:7a:81:fd:30:ac:7a:
- 1f:c7:59:7b
------BEGIN CERTIFICATE-----
-MIIFADCCA+igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
-HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
-ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAw
-MFoXDTMxMDUwMzA3MDAwMFowgcYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
-b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
-aG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydHMuc3RhcmZpZWxk
-dGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNVBAMTK1N0YXJmaWVsZCBTZWN1cmUg
-Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
-DwAwggEKAoIBAQDlkGZL7PlGcakgg77pbL9KyUhpgXVObST2yxcT+LBxWYR6ayuF
-pDS1FuXLzOlBcCykLtb6Mn3hqN6UEKwxwcDYav9ZJ6t21vwLdGu4p64/xFT0tDFE
-3ZNWjKRMXpuJyySDm+JXfbfYEh/JhW300YDxUJuHrtQLEAX7J7oobRfpDtZNuTlV
-Bv8KJAV+L8YdcmzUiymMV33a2etmGtNPp99/UsQwxaXJDgLFU793OGgGJMNmyDd+
-MB5FcSM1/5DYKp2N57CSTTx/KgqT3M0WRmX3YISLdkuRJ3MUkuDq7o8W6o0OPnYX
-v32JgIBEQ+ct4EMJddo26K3biTr1XRKOIwSDAgMBAAGjggEsMIIBKDAPBgNVHRMB
-Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUJUWBaFAmOD07LSy+
-zWrZtj2zZmMwHwYDVR0jBBgwFoAUfAwyH6fZMH/EfWijYqihzqsHWycwOgYIKwYB
-BQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNo
-LmNvbS8wOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0ZWNo
-LmNvbS9zZnJvb3QtZzIuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF
-BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv
-MA0GCSqGSIb3DQEBCwUAA4IBAQBWZcr+8z8KqJOLGMfeQ2kTNCC+Tl94qGuc22pN
-QdvBE+zcMQAiXvcAngzgNGU0+bE6TkjIEoGIXFs+CFN69xpk37hQYcxTUUApS8L0
-rjpf5MqtJsxOYUPl/VemN3DOQyuwlMOS6eFfqhBJt2nk4NAfZKQrzR9voPiEJBjO
-eT2pkb9UGBOJmVQRDVXFJgt5T1ocbvlj2xSApAer+rKluYjdkf5lO6Sjeb6JTeHQ
-sPTIFwwKlhR8Cbds4cLYVdQYoKpBaXAko7nv6VrcPuuUSvC33l8Odvr7+2kDRUBQ
-7nIMpBKGgc0T0U7EPMpODdIm8QC3tKai4W56gf0wrHofx1l7
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 0 (0x0)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Root Certificate Authority - G2
- Validity
- Not Before: Sep 1 00:00:00 2009 GMT
- Not After : Dec 31 23:59:59 2037 GMT
- Subject: C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Root Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public-Key: (2048 bit)
- Modulus:
- 00:bd:ed:c1:03:fc:f6:8f:fc:02:b1:6f:5b:9f:48:
- d9:9d:79:e2:a2:b7:03:61:56:18:c3:47:b6:d7:ca:
- 3d:35:2e:89:43:f7:a1:69:9b:de:8a:1a:fd:13:20:
- 9c:b4:49:77:32:29:56:fd:b9:ec:8c:dd:22:fa:72:
- dc:27:61:97:ee:f6:5a:84:ec:6e:19:b9:89:2c:dc:
- 84:5b:d5:74:fb:6b:5f:c5:89:a5:10:52:89:46:55:
- f4:b8:75:1c:e6:7f:e4:54:ae:4b:f8:55:72:57:02:
- 19:f8:17:71:59:eb:1e:28:07:74:c5:9d:48:be:6c:
- b4:f4:a4:b0:f3:64:37:79:92:c0:ec:46:5e:7f:e1:
- 6d:53:4c:62:af:cd:1f:0b:63:bb:3a:9d:fb:fc:79:
- 00:98:61:74:cf:26:82:40:63:f3:b2:72:6a:19:0d:
- 99:ca:d4:0e:75:cc:37:fb:8b:89:c1:59:f1:62:7f:
- 5f:b3:5f:65:30:f8:a7:b7:4d:76:5a:1e:76:5e:34:
- c0:e8:96:56:99:8a:b3:f0:7f:a4:cd:bd:dc:32:31:
- 7c:91:cf:e0:5f:11:f8:6b:aa:49:5c:d1:99:94:d1:
- a2:e3:63:5b:09:76:b5:56:62:e1:4b:74:1d:96:d4:
- 26:d4:08:04:59:d0:98:0e:0e:e6:de:fc:c3:ec:1f:
- 90:f1
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27
- Signature Algorithm: sha256WithRSAEncryption
- 11:59:fa:25:4f:03:6f:94:99:3b:9a:1f:82:85:39:d4:76:05:
- 94:5e:e1:28:93:6d:62:5d:09:c2:a0:a8:d4:b0:75:38:f1:34:
- 6a:9d:e4:9f:8a:86:26:51:e6:2c:d1:c6:2d:6e:95:20:4a:92:
- 01:ec:b8:8a:67:7b:31:e2:67:2e:8c:95:03:26:2e:43:9d:4a:
- 31:f6:0e:b5:0c:bb:b7:e2:37:7f:22:ba:00:a3:0e:7b:52:fb:
- 6b:bb:3b:c4:d3:79:51:4e:cd:90:f4:67:07:19:c8:3c:46:7a:
- 0d:01:7d:c5:58:e7:6d:e6:85:30:17:9a:24:c4:10:e0:04:f7:
- e0:f2:7f:d4:aa:0a:ff:42:1d:37:ed:94:e5:64:59:12:20:77:
- 38:d3:32:3e:38:81:75:96:73:fa:68:8f:b1:cb:ce:1f:c5:ec:
- fa:9c:7e:cf:7e:b1:f1:07:2d:b6:fc:bf:ca:a4:bf:d0:97:05:
- 4a:bc:ea:18:28:02:90:bd:54:78:09:21:71:d3:d1:7d:1d:d9:
- 16:b0:a9:61:3d:d0:0a:00:22:fc:c7:7b:cb:09:64:45:0b:3b:
- 40:81:f7:7d:7c:32:f5:98:ca:58:8e:7d:2a:ee:90:59:73:64:
- f9:36:74:5e:25:a1:f5:66:05:2e:7f:39:15:a9:2a:fb:50:8b:
- 8e:85:69:f4
------BEGIN CERTIFICATE-----
-MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
-HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
-ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
-MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
-b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
-aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
-Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
-nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
-HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
-Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
-dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
-HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
-BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
-CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
-sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
-4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
-8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
-pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
-mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
------END CERTIFICATE-----
diff --git a/certs/USERTrust-RSA-Certification-Authority.pem b/certs/USERTrust-RSA-Certification-Authority.pem
new file mode 100644
index 0000000..0fbeef6
--- /dev/null
+++ b/certs/USERTrust-RSA-Certification-Authority.pem
@@ -0,0 +1,41 @@
+# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
+# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
+# Label: "USERTrust RSA Certification Authority"
+# Serial: 2645093764781058787591871645665788717
+# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5
+# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e
+# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
+iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
+cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
+BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
+MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
+3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
+tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
+Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
+VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
+79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
+c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
+Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
+c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
+UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
+Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
+BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
+Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
+VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
+ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
+8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
+iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
+Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
+XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
+qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
+VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
+L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
+jjxDah2nGN59PRbxYvnKkKj9
+-----END CERTIFICATE-----
diff --git a/check-certificates.rsc b/check-certificates.rsc
index e9235f1..c10e33b 100644
--- a/check-certificates.rsc
+++ b/check-certificates.rsc
@@ -1,17 +1,19 @@
#!rsc by RouterOS
# RouterOS script: check-certificates
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, fetch
#
# check for certificate validity
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/check-certificates.md
+# https://rsc.eworm.de/doc/check-certificates.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global CertRenewTime;
@@ -32,7 +34,8 @@
:local CheckCertificatesDownloadImport do={
:local ScriptName [ :tostr $1 ];
- :local Name [ :tostr $2 ];
+ :local CertName [ :tostr $2 ];
+ :local FetchName [ :tostr $3 ];
:global CertRenewUrl;
:global CertRenewPass;
@@ -41,43 +44,51 @@
:global EscapeForRegEx;
:global FetchUserAgentStr;
:global LogPrint;
+ :global RmFile;
:global UrlEncode;
:global WaitForFile;
- :local Return false;
+ :foreach Type in={ "p12"; "pem" } do={
+ :local CertFileName ([ $UrlEncode $FetchName ] . "." . $Type);
+ $LogPrint debug $ScriptName ("Trying type '" . $Type . "' for '" . $CertName . \
+ "' (file '" . $CertFileName . "')...");
- :foreach Type in={ ".pem"; ".p12" } do={
- :local CertFileName ([ $UrlEncode $Name ] . $Type);
:do {
/tool/fetch check-certificate=yes-without-crl http-header-field=({ [ $FetchUserAgentStr $ScriptName ] }) \
($CertRenewUrl . $CertFileName) dst-path=$CertFileName as-value;
$WaitForFile $CertFileName;
:local DecryptionFailed true;
- :foreach PassPhrase in=$CertRenewPass do={
- :local Result [ /certificate/import file-name=$CertFileName passphrase=$PassPhrase as-value ];
- :if ($Result->"decryption-failures" = 0) do={
- :set DecryptionFailed false;
- }
+ :foreach I,PassPhrase in=$CertRenewPass do={
+ :do {
+ $LogPrint debug $ScriptName ("Trying " . $I . ". passphrase... ");
+ :local Result [ /certificate/import file-name=$CertFileName passphrase=$PassPhrase as-value ];
+ :if ($Result->"decryption-failures" = 0) do={
+ $LogPrint debug $ScriptName ("Success!");
+ :set DecryptionFailed false;
+ }
+ } on-error={ }
}
- /file/remove [ find where name=$CertFileName ];
+ $RmFile $CertFileName;
:if ($DecryptionFailed = true) do={
$LogPrint warning $ScriptName ("Decryption failed for certificate file '" . $CertFileName . "'.");
}
- :foreach CertInChain in=[ /certificate/find where name~("^" . [ $EscapeForRegEx $CertFileName ] . "_[0-9]+\$") \
- common-name!=$Name !(subject-alt-name~("(^|\\W)(DNS|IP):" . [ $EscapeForRegEx $Name ] . "(\\W|\$)")) !(common-name=[]) ] do={
+ :foreach CertInChain in=[ /certificate/find where common-name!=$CertName !private-key \
+ name~("^" . [ $EscapeForRegEx $CertFileName ] . "_[0-9]+\$") \
+ !(subject-alt-name~("(^|\\W)(DNS|IP):" . [ $EscapeForRegEx $CertName ] . "(\\W|\$)")) \
+ !(common-name=[]) ] do={
$CertificateNameByCN [ /certificate/get $CertInChain common-name ];
}
- :set Return true;
+ :return true;
} on-error={
$LogPrint debug $ScriptName ("Could not download certificate file '" . $CertFileName . "'.");
}
}
- :return $Return;
+ :return false;
}
:local FormatInfo do={
@@ -133,14 +144,15 @@
}
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
$WaitFullyConnected;
:foreach Cert in=[ /certificate/find where !revoked !ca !scep-url expires-after<$CertRenewTime ] do={
:local CertVal [ /certificate/get $Cert ];
- :local CertNew;
:local LastName;
+ :local FetchName;
:do {
:if ([ :len $CertRenewUrl ] = 0) do={
@@ -151,11 +163,17 @@
:local ImportSuccess false;
:set LastName ($CertVal->"common-name");
- :set ImportSuccess [ $CheckCertificatesDownloadImport $ScriptName $LastName ];
+ :set FetchName $LastName;
+ :set ImportSuccess [ $CheckCertificatesDownloadImport $ScriptName $LastName $FetchName ];
:foreach SAN in=($CertVal->"subject-alt-name") do={
:if ($ImportSuccess = false) do={
:set LastName [ :pick $SAN ([ :find $SAN ":" ] + 1) [ :len $SAN ] ];
- :set ImportSuccess [ $CheckCertificatesDownloadImport $ScriptName $LastName ];
+ :set FetchName $LastName;
+ :set ImportSuccess [ $CheckCertificatesDownloadImport $ScriptName $LastName $FetchName ];
+ :if ($ImportSuccess = false && [ :pick $LastName 0 2 ] = "*.") do={
+ :set FetchName ("star." . [ :pick $LastName 2 [ :len $LastName ] ]);
+ :set ImportSuccess [ $CheckCertificatesDownloadImport $ScriptName $LastName $FetchName ];
+ }
}
}
:if ($ImportSuccess = false) do={ :error false; }
@@ -166,7 +184,7 @@
} else={
$LogPrint debug $ScriptName ("Certificate '" . $CertVal->"name" . "' was not updated, but replaced.");
- :set CertNew [ /certificate/find where name~("^" . [ $EscapeForRegEx [ $UrlEncode $LastName ] ] . "\\.(p12|pem)_[0-9]+\$") \
+ :local CertNew [ /certificate/find where name~("^" . [ $EscapeForRegEx [ $UrlEncode $FetchName ] ] . "\\.(p12|pem)_[0-9]+\$") \
(common-name=($CertVal->"common-name") or subject-alt-name~("(^|\\W)(DNS|IP):" . [ $EscapeForRegEx $LastName ] . "(\\W|\$)")) \
fingerprint!=[ :tostr ($CertVal->"fingerprint") ] expires-after>$CertRenewTime ];
:local CertNewVal [ /certificate/get $CertNew ];
@@ -190,13 +208,13 @@
/certificate/remove $Cert;
/certificate/set $CertNew name=($CertVal->"name");
- :set CertNewVal;
+ :set Cert $CertNew;
:set CertVal [ /certificate/get $CertNew ];
}
$SendNotification2 ({ origin=$ScriptName; silent=true; \
subject=([ $SymbolForNotification "lock-with-ink-pen" ] . "Certificate renewed: " . ($CertVal->"name")); \
- message=("A certificate on " . $Identity . " has been renewed.\n\n" . [ $FormatInfo $CertNew ]) });
+ message=("A certificate on " . $Identity . " has been renewed.\n\n" . [ $FormatInfo $Cert ]) });
$LogPrint info $ScriptName ("The certificate '" . ($CertVal->"name") . "' has been renewed.");
} on-error={
$LogPrint debug $ScriptName ("Could not renew certificate '" . ($CertVal->"name") . "'.");
@@ -219,4 +237,6 @@
", it is invalid after " . ($CertVal->"invalid-after") . ".");
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/check-health.d/state.rsc b/check-health.d/state.rsc
new file mode 100644
index 0000000..2991935
--- /dev/null
+++ b/check-health.d/state.rsc
@@ -0,0 +1,48 @@
+#!rsc by RouterOS
+# RouterOS script: check-health.d/state
+# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.15
+#
+# check for RouterOS health state - state plugin
+# https://rsc.eworm.de/doc/check-health.md
+
+:global CheckHealthPlugins;
+
+:set ($CheckHealthPlugins->[ :jobname ]) do={
+ :local FuncName [ :tostr $0 ];
+
+ :global CheckHealthLast;
+ :global Identity;
+
+ :global LogPrint;
+ :global SendNotification2;
+ :global SymbolForNotification;
+
+ :if ([ :len [ /system/health/find where type="" name~"-state\$"] ] = 0) do={
+ $LogPrint debug $FuncName ("Your device does not provide any state health values.");
+ :return false;
+ }
+
+ :foreach State in=[ /system/health/find where type="" name~"-state\$" ] do={
+ :local Name [ /system/health/get $State name ];
+ :local Value [ /system/health/get $State value ];
+
+ :if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
+ :if ($CheckHealthLast->$Name = "ok" && \
+ $Value != "ok") do={
+ $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=$FuncName; \
+ subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \
+ message=("The device '" . $Name . "' on " . $Identity . " recovered!") });
+ }
+ }
+ :set ($CheckHealthLast->$Name) $Value;
+ }
+}
diff --git a/check-health.d/temperature.rsc b/check-health.d/temperature.rsc
new file mode 100644
index 0000000..a2f632d
--- /dev/null
+++ b/check-health.d/temperature.rsc
@@ -0,0 +1,74 @@
+#!rsc by RouterOS
+# RouterOS script: check-health.d/temperature
+# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.15
+#
+# check for RouterOS health state - temperature plugin
+# https://rsc.eworm.de/doc/check-health.md
+
+:global CheckHealthPlugins;
+
+:set ($CheckHealthPlugins->[ :jobname ]) do={
+ :local FuncName [ :tostr $0 ];
+
+ :global CheckHealthLast;
+ :global CheckHealthTemperature;
+ :global CheckHealthTemperatureDeviation;
+ :global CheckHealthTemperatureNotified;
+ :global Identity;
+
+ :global LogPrint;
+ :global SendNotification2;
+ :global SymbolForNotification;
+
+ :if ([ :len [ /system/health/find where type="C" ] ] = 0) do={
+ $LogPrint debug $FuncName ("Your device does not provide any voltage health values.");
+ :return false;
+ }
+
+ :local TempToNum do={
+ :global CharacterReplace;
+ :local T [ :toarray [ $CharacterReplace $1 "." "," ] ];
+ :return ($T->0 * 10 + $T->1);
+ }
+
+ :if ([ :typeof $CheckHealthTemperatureNotified ] != "array") do={
+ :set CheckHealthTemperatureNotified ({});
+ }
+
+ :foreach Temperature in=[ /system/health/find where type="C" ] do={
+ :local Name [ /system/health/get $Temperature name ];
+ :local Value [ /system/health/get $Temperature value ];
+
+ :if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
+ :if ([ :typeof ($CheckHealthTemperature->$Name) ] != "num" ) do={
+ $LogPrint info $FuncName ("No threshold given for " . $Name . ", assuming 50C.");
+ :set ($CheckHealthTemperature->$Name) 50;
+ }
+ :local Validate [ /system/health/get [ find where name=$Name ] value ];
+ :while ($Value != $Validate) do={
+ :set Value $Validate;
+ :set Validate [ /system/health/get [ find where name=$Name ] value ];
+ }
+ :if ($Value > $CheckHealthTemperature->$Name && \
+ $CheckHealthTemperatureNotified->$Name != true) do={
+ $SendNotification2 ({ origin=$FuncName; \
+ subject=([ $SymbolForNotification "fire" ] . "Health warning: " . $Name); \
+ message=("The " . $Name . " on " . $Identity . " is above threshold: " . \
+ $Value . "\C2\B0" . "C") });
+ :set ($CheckHealthTemperatureNotified->$Name) true;
+ }
+ :if ($Value <= ($CheckHealthTemperature->$Name - $CheckHealthTemperatureDeviation) && \
+ $CheckHealthTemperatureNotified->$Name = true) do={
+ $SendNotification2 ({ origin=$FuncName; \
+ subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \
+ message=("The " . $Name . " on " . $Identity . " dropped below threshold: " . \
+ $Value . "\C2\B0" . "C") });
+ :set ($CheckHealthTemperatureNotified->$Name) false;
+ }
+ }
+ :set ($CheckHealthLast->$Name) $Value;
+ }
+}
diff --git a/check-health.d/voltage.rsc b/check-health.d/voltage.rsc
new file mode 100644
index 0000000..9071c88
--- /dev/null
+++ b/check-health.d/voltage.rsc
@@ -0,0 +1,63 @@
+#!rsc by RouterOS
+# RouterOS script: check-health.d/voltage
+# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.15
+#
+# check for RouterOS health state - voltage plugin
+# https://rsc.eworm.de/doc/check-health.md
+
+:global CheckHealthPlugins;
+
+:set ($CheckHealthPlugins->[ :jobname ]) do={
+ :local FuncName [ :tostr $0 ];
+
+ :global CheckHealthLast;
+ :global CheckHealthVoltageLow;
+ :global CheckHealthVoltagePercent;
+ :global Identity;
+
+ :global FormatLine;
+ :global IfThenElse;
+ :global LogPrint;
+ :global SendNotification2;
+ :global SymbolForNotification;
+
+ :if ([ :len [ /system/health/find where type="V" ] ] = 0) do={
+ $LogPrint debug $FuncName ("Your device does not provide any voltage health values.");
+ :return false;
+ }
+
+ :foreach Voltage in=[ /system/health/find where type="V" ] do={
+ :local Name [ /system/health/get $Voltage name ];
+ :local Value [ /system/health/get $Voltage value ];
+
+ :if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
+ :local NumCurr [ $TempToNum $Value ];
+ :local NumLast [ $TempToNum ($CheckHealthLast->$Name) ];
+
+ :if ($NumLast * (100 + $CheckHealthVoltagePercent) < $NumCurr * 100 || \
+ $NumLast * 100 > $NumCurr * (100 + $CheckHealthVoltagePercent)) do={
+ $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" . \
+ [ $FormatLine "old value" ($CheckHealthLast->$Name . " V") 12 ] . "\n" . \
+ [ $FormatLine "new value" ($Value . " V") 12 ]) });
+ } else={
+ :if ($NumCurr <= $CheckHealthVoltageLow && $NumLast > $CheckHealthVoltageLow) do={
+ $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=$FuncName; \
+ subject=([ $SymbolForNotification "high-voltage-sign,chart-increasing" ] . "Health recovery: Low " . $Name); \
+ message=("The " . $Name . " on " . $Identity . " recovered to " . $Value . " V above hard limit.") });
+ }
+ }
+ }
+ :set ($CheckHealthLast->$Name) $Value;
+ }
+}
diff --git a/check-health.rsc b/check-health.rsc
index a769fa8..4cb9940 100644
--- a/check-health.rsc
+++ b/check-health.rsc
@@ -1,28 +1,24 @@
#!rsc by RouterOS
# RouterOS script: check-health
-# Copyright (c) 2019-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# check for RouterOS health state
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/check-health.md
+# https://rsc.eworm.de/doc/check-health.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global CheckHealthCPUUtilization;
:global CheckHealthCPUUtilizationNotified;
:global CheckHealthLast;
:global CheckHealthRAMUtilizationNotified;
- :global CheckHealthTemperature;
- :global CheckHealthTemperatureDeviation;
- :global CheckHealthTemperatureNotified;
- :global CheckHealthVoltageLow;
- :global CheckHealthVoltagePercent;
:global Identity;
:global FormatLine;
@@ -32,6 +28,7 @@
:global ScriptLock;
:global SendNotification2;
:global SymbolForNotification;
+ :global ValidateSyntax;
:local TempToNum do={
:global CharacterReplace;
@@ -40,6 +37,7 @@
}
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -76,103 +74,37 @@
:set CheckHealthRAMUtilizationNotified false;
}
- :if ([ :len [ /system/health/find ] ] = 0) do={
- $LogPrint debug $ScriptName ("Your device does not provide any health values.");
+ :local Plugins [ /system/script/find where name~"^check-health.d/." ];
+ :if ([ :len $Plugins ] = 0) do={
+ $LogPrint debug $ScriptName ("No plugins installed.");
+ :set ExitOK true;
:error true;
}
+ :global CheckHealthPlugins ({});
:if ([ :typeof $CheckHealthLast ] != "array") do={
:set CheckHealthLast ({});
}
- :if ([ :typeof $CheckHealthTemperatureNotified ] != "array") do={
- :set CheckHealthTemperatureNotified ({});
- }
-
-
- :foreach Voltage in=[ /system/health/find where type="V" ] do={
- :local Name [ /system/health/get $Voltage name ];
- :local Value [ /system/health/get $Voltage value ];
- :if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
- :local NumCurr [ $TempToNum $Value ];
- :local NumLast [ $TempToNum ($CheckHealthLast->$Name) ];
-
- :if ($NumLast * (100 + $CheckHealthVoltagePercent) < $NumCurr * 100 || \
- $NumLast * 100 > $NumCurr * (100 + $CheckHealthVoltagePercent)) do={
- $SendNotification2 ({ origin=$ScriptName; \
- 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" . \
- [ $FormatLine "old value" ($CheckHealthLast->$Name . " V") 12 ] . "\n" . \
- [ $FormatLine "new value" ($Value . " V") 12 ]) });
- } else={
- :if ($NumCurr <= $CheckHealthVoltageLow && $NumLast > $CheckHealthVoltageLow) do={
- $SendNotification2 ({ origin=$ScriptName; \
- 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; \
- subject=([ $SymbolForNotification "high-voltage-sign,chart-increasing" ] . "Health recovery: Low " . $Name); \
- message=("The " . $Name . " on " . $Identity . " recovered to " . $Value . " V above hard limit.") });
- }
+ :foreach Plugin in=$Plugins do={
+ :local PluginVal [ /system/script/get $Plugin ];
+ :if ([ $ValidateSyntax ($PluginVal->"source") ] = true) do={
+ :onerror Err {
+ /system/script/run $Plugin;
+ } do={
+ $LogPrint error $ScriptName ("Plugin '" . $ScriptVal->"name" . "' failed to run: " . $Err);
}
+ } else={
+ $LogPrint error $ScriptName ("Plugin '" . $ScriptVal->"name" . "' failed syntax validation, skipping.");
}
- :set ($CheckHealthLast->$Name) $Value;
}
- :foreach PSU in=[ /system/health/find where name~"^psu.*-state\$" ] do={
- :local Name [ /system/health/get $PSU name ];
- :local Value [ /system/health/get $PSU value ];
-
- :if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
- :if ($CheckHealthLast->$Name = "ok" && \
- $Value != "ok") do={
- $SendNotification2 ({ origin=$ScriptName; \
- subject=([ $SymbolForNotification "cross-mark" ] . "Health warning: " . $Name); \
- message=("The power supply unit '" . $Name . "' on " . $Identity . " failed!") });
- }
- :if ($CheckHealthLast->$Name != "ok" && \
- $Value = "ok") do={
- $SendNotification2 ({ origin=$ScriptName; \
- subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \
- message=("The power supply unit '" . $Name . "' on " . $Identity . " recovered!") });
- }
- }
- :set ($CheckHealthLast->$Name) $Value;
+ :foreach PluginName,Discard in=$CheckHealthPlugins do={
+ ($CheckHealthPlugins->$PluginName) \
+ ("\$CheckHealthPlugins->\"" . $PluginName . "\"");
}
- :foreach Temperature in=[ /system/health/find where type="C" ] do={
- :local Name [ /system/health/get $Temperature name ];
- :local Value [ /system/health/get $Temperature value ];
-
- :if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
- :if ([ :typeof ($CheckHealthTemperature->$Name) ] != "num" ) do={
- $LogPrint info $ScriptName ("No threshold given for " . $Name . ", assuming 50C.");
- :set ($CheckHealthTemperature->$Name) 50;
- }
- :local Validate [ /system/health/get [ find where name=$Name ] value ];
- :while ($Value != $Validate) do={
- :set Value $Validate;
- :set Validate [ /system/health/get [ find where name=$Name ] value ];
- }
- :if ($Value > $CheckHealthTemperature->$Name && \
- $CheckHealthTemperatureNotified->$Name != true) do={
- $SendNotification2 ({ origin=$ScriptName; \
- subject=([ $SymbolForNotification "fire" ] . "Health warning: " . $Name); \
- message=("The " . $Name . " on " . $Identity . " is above threshold: " . \
- $Value . "\C2\B0" . "C") });
- :set ($CheckHealthTemperatureNotified->$Name) true;
- }
- :if ($Value <= ($CheckHealthTemperature->$Name - $CheckHealthTemperatureDeviation) && \
- $CheckHealthTemperatureNotified->$Name = true) do={
- $SendNotification2 ({ origin=$ScriptName; \
- subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \
- message=("The " . $Name . " on " . $Identity . " dropped below threshold: " . \
- $Value . "\C2\B0" . "C") });
- :set ($CheckHealthTemperatureNotified->$Name) false;
- }
- }
- :set ($CheckHealthLast->$Name) $Value;
- }
-} on-error={ }
+ :set CheckHealthPlugins;
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/check-lte-firmware-upgrade.rsc b/check-lte-firmware-upgrade.rsc
index 3a25f83..9f4b656 100644
--- a/check-lte-firmware-upgrade.rsc
+++ b/check-lte-firmware-upgrade.rsc
@@ -1,17 +1,18 @@
#!rsc by RouterOS
# RouterOS script: check-lte-firmware-upgrade
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# check for LTE firmware upgrade, send notification
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/check-lte-firmware-upgrade.md
+# https://rsc.eworm.de/doc/check-lte-firmware-upgrade.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global SentLteFirmwareUpgradeNotification;
@@ -19,6 +20,7 @@
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -43,12 +45,12 @@
:local IntName [ /interface/lte/get $Interface name ];
:local Firmware;
:local Info;
- :do {
- :set Firmware [ /interface/lte/firmware-upgrade $Interface once as-value ];
+ :onerror Err {
+ :set Firmware [ /interface/lte/firmware-upgrade $Interface as-value ];
:set Info [ /interface/lte/monitor $Interface once as-value ];
- } on-error={
+ } do={
$LogPrint debug $ScriptName ("Could not get latest LTE firmware version for interface " . \
- $IntName . ".");
+ $IntName . ": " . $Err);
:return false;
}
@@ -100,4 +102,6 @@
:foreach Interface in=[ /interface/lte/find ] do={
$CheckInterface $ScriptName $Interface;
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/check-perpetual-license.rsc b/check-perpetual-license.rsc
new file mode 100644
index 0000000..c2f0dff
--- /dev/null
+++ b/check-perpetual-license.rsc
@@ -0,0 +1,78 @@
+#!rsc by RouterOS
+# RouterOS script: check-perpetual-license
+# Copyright (c) 2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.15
+#
+# check perpetual license on CHR
+# https://rsc.eworm.de/doc/check-perpetual-license.md
+
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
+ :local ScriptName [ :jobname ];
+
+ :global Identity;
+ :global SentCertificateNotification;
+
+ :global LogPrint;
+ :global ScriptLock;
+ :global SendNotification2;
+ :global SymbolForNotification;
+ :global WaitFullyConnected;
+
+ :if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
+ :error false;
+ }
+
+ $WaitFullyConnected;
+
+ :local License [ /system/license/get ];
+ :if ([ :typeof ($License->"deadline-at") ] != "str") do={
+ $LogPrint info $ScriptName ("This device does not have a perpetual license.");
+ :set ExitOK true;
+ :error true;
+ }
+
+ :if ([ :len ($License->"next-renewal-at") ] = 0 && ($License->"limited-upgrades") = true) do={
+ $LogPrint warning $ScriptName ("Your license expired on " . ($License->"deadline-at") . "!");
+ :if ($SentCertificateNotification != "expired") do={
+ $SendNotification2 ({ origin=$ScriptName; \
+ subject=([ $SymbolForNotification "warning-sign" ] . "License expired!"); \
+ message=("Your license expired on " . ($License->"deadline-at") . \
+ ", can no longer update RouterOS on " . $Identity . "...") });
+ :set SentCertificateNotification "expired";
+ }
+ :set ExitOK true;
+ :error true;
+ }
+
+ :if ([ :totime ($License->"deadline-at") ] - 3w < [ :timestamp ]) do={
+ $LogPrint warning $ScriptName ("Your license will expire on " . ($License->"deadline-at") . "!");
+ :if ($SentCertificateNotification != "warning") do={
+ $SendNotification2 ({ origin=$ScriptName; \
+ 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";
+ }
+ :set ExitOK true;
+ :error true;
+ }
+
+ :if ([ :typeof $SentCertificateNotification ] = "str" && \
+ [ :totime ($License->"deadline-at") ] - 4w > [ :timestamp ]) do={
+ $LogPrint info $ScriptName ("Your license was successfully renewed.");
+ $SendNotification2 ({ origin=$ScriptName; \
+ 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;
+ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/check-routeros-update.rsc b/check-routeros-update.rsc
index 6dca99a..8b80dde 100644
--- a/check-routeros-update.rsc
+++ b/check-routeros-update.rsc
@@ -1,17 +1,19 @@
#!rsc by RouterOS
# RouterOS script: check-routeros-update
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, fetch, scheduler
#
# check for RouterOS update, send notification and/or install
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/check-routeros-update.md
+# https://rsc.eworm.de/doc/check-routeros-update.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Identity;
@@ -26,6 +28,7 @@
:global EscapeForRegEx;
:global FetchUserAgentStr;
:global LogPrint;
+ :global RebootForUpdate;
:global ScriptFromTerminal;
:global ScriptLock;
:global SendNotification2;
@@ -34,38 +37,70 @@
:global WaitFullyConnected;
: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;
}
- :error "Waiting for system to reboot.";
+ $LogPrint info $ScriptName ("Waiting for system to reboot.");
}
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
+
+ :if ([ :len [ /system/scheduler/find where name="running-from-backup-partition" ] ] > 0) do={
+ $LogPrint warning $ScriptName ("Running from backup partition, refusing to act.");
+ :set ExitOK true;
+ :error false;
+ }
+
$WaitFullyConnected;
:if ([ :len [ /system/scheduler/find where name="_RebootForUpdate" ] ] > 0) do={
- :error "A reboot for update is already scheduled.";
+ :if ([ :typeof $RebootForUpdate ] = "nothing") do={
+ $LogPrint info $ScriptName ("Found a stale scheduler for reboot, removing.");
+ /system/scheduler/remove "_RebootForUpdate";
+ } else={
+ $LogPrint info $ScriptName ("A reboot for update is already scheduled.");
+ :set ExitOK true;
+ :error false;
+ }
}
$LogPrint debug $ScriptName ("Checking for updates...");
/system/package/update/check-for-updates without-paging as-value;
:local Update [ /system/package/update/get ];
- :if ([ $ScriptFromTerminal $ScriptName ] = true && ($Update->"installed-version") = ($Update->"latest-version")) do={
- $LogPrint info $ScriptName ("System is already up to date.");
+ :if (($Update->"installed-version") = ($Update->"latest-version")) do={
+ :if ([ $ScriptFromTerminal $ScriptName ] = true) do={
+ $LogPrint info $ScriptName ("System is already up to date.");
+ }
+ :set ExitOK true;
:error true;
}
+ :if ([ :len ($Update->"latest-version") ] = 0) do={
+ $LogPrint info $ScriptName ("Received an empty version string from server.");
+ :set ExitOK true;
+ :error false;
+ }
+
:local NumInstalled [ $VersionToNum ($Update->"installed-version") ];
:local NumLatest [ $VersionToNum ($Update->"latest-version") ];
+ :local BitMask [ $VersionToNum "255.255zero0" ];
+ :local NumInstalledFeature ($NumInstalled & $BitMask);
+ :local NumLatestFeature ($NumLatest & $BitMask);
:local Link ("https://mikrotik.com/download/changelogs/" . $Update->"channel" . "-release-tree");
- :if ($NumLatest < 117505792) do={
- $LogPrint info $ScriptName ("The version '" . ($Update->"latest-version") . "' is not a valid version.");
+ :if ($NumLatest < [ $VersionToNum "7.0" ]) do={
+ $LogPrint warning $ScriptName ("The version '" . ($Update->"latest-version") . "' is not a valid version.");
+ :set ExitOK true;
:error false;
}
@@ -77,16 +112,20 @@
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update: " . $Update->"latest-version"); \
message=("Installing ALL versions automatically, including " . $Update->"latest-version" . \
"... Updating on " . $Identity . "..."); link=$Link; silent=true });
- $DoUpdate;
+ $DoUpdate $ScriptName;
+ :set ExitOK true;
+ :error true;
}
- :if ($SafeUpdatePatch = true && ($NumInstalled & 0xffff0000) = ($NumLatest & 0xffff0000)) do={
+ :if ($SafeUpdatePatch = true && $NumInstalledFeature = $NumLatestFeature) do={
$LogPrint info $ScriptName ("Version " . $Update->"latest-version" . " is a patch release, updating...");
$SendNotification2 ({ origin=$ScriptName; \
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update: " . $Update->"latest-version"); \
message=("Version " . $Update->"latest-version" . " is a patch update for " . $Update->"channel" . \
", updating on " . $Identity . "..."); link=$Link; silent=true });
- $DoUpdate;
+ $DoUpdate $ScriptName;
+ :set ExitOK true;
+ :error true;
}
:if ($SafeUpdateNeighbor = true) do={
@@ -100,19 +139,21 @@
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update: " . $Update->"latest-version"); \
message=("Seen a neighbor (" . $Neighbor . ") running version " . $Update->"latest-version" . \
" from " . $Update->"channel" . ", updating on " . $Identity . "..."); link=$Link; silent=true });
- $DoUpdate;
+ $DoUpdate $ScriptName;
+ :set ExitOK true;
+ :error true;
}
}
:if ([ :len $SafeUpdateUrl ] > 0) do={
:local Result;
- :do {
+ :onerror Err {
:set Result [ /tool/fetch check-certificate=yes-without-crl \
($SafeUpdateUrl . $Update->"channel" . "?installed=" . $Update->"installed-version" . \
"&latest=" . $Update->"latest-version") http-header-field=({ [ $FetchUserAgentStr $ScriptName ] }) \
output=user as-value ];
- } on-error={
- $LogPrint warning $ScriptName ("Failed receiving safe version for " . $Update->"channel" . ".");
+ } do={
+ $LogPrint warning $ScriptName ("Failed receiving safe version for " . $Update->"channel" . ": " . $Err);
}
:if ($Result->"status" = "finished" && $Result->"data" = $Update->"latest-version") do={
$LogPrint info $ScriptName ("Version " . $Update->"latest-version" . " is considered safe, updating...");
@@ -120,14 +161,28 @@
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update: " . $Update->"latest-version"); \
message=("Version " . $Update->"latest-version" . " is considered safe for " . $Update->"channel" . \
", updating on " . $Identity . "..."); link=$Link; silent=true });
- $DoUpdate;
+ $DoUpdate $ScriptName;
+ :set ExitOK true;
+ :error true;
}
}
:if ([ $ScriptFromTerminal $ScriptName ] = true) do={
+ :if (($Update->"channel") = "testing" && $NumInstalledFeature < $NumLatestFeature) do={
+ :put ("This is a feature update in testing channel. Switch to channel 'stable'? [y/N]");
+ :if (([ /terminal/inkey timeout=60 ] % 32) = 25) do={
+ /system/package/update/set channel=stable;
+ $LogPrint info $ScriptName ("Switched to channel 'stable', please re-run!");
+ :set ExitOK true;
+ :error true;
+ }
+ }
+
:put ("Do you want to install RouterOS version " . $Update->"latest-version" . "? [y/N]");
:if (([ /terminal/inkey timeout=60 ] % 32) = 25) do={
- $DoUpdate;
+ $DoUpdate $ScriptName;
+ :set ExitOK true;
+ :error true;
} else={
:put "Canceled...";
}
@@ -136,6 +191,7 @@
:if ($SentRouterosUpdateNotification = $Update->"latest-version") do={
$LogPrint info $ScriptName ("Already sent the RouterOS update notification for version " . \
$Update->"latest-version" . ".");
+ :set ExitOK true;
:error true;
}
@@ -151,6 +207,7 @@
:if ($SentRouterosUpdateNotification = $Update->"latest-version") do={
$LogPrint info $ScriptName ("Already sent the RouterOS downgrade notification for version " . \
$Update->"latest-version" . ".");
+ :set ExitOK true;
:error true;
}
@@ -163,4 +220,6 @@
" is available for downgrade.");
:set SentRouterosUpdateNotification ($Update->"latest-version");
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/collect-wireless-mac.capsman.rsc b/collect-wireless-mac.capsman.rsc
index 74c0754..06b8d84 100644
--- a/collect-wireless-mac.capsman.rsc
+++ b/collect-wireless-mac.capsman.rsc
@@ -1,20 +1,21 @@
#!rsc by RouterOS
# RouterOS script: collect-wireless-mac.capsman
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=40
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# collect wireless mac adresses in access list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/collect-wireless-mac.md
+# https://rsc.eworm.de/doc/collect-wireless-mac.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Identity;
@@ -29,6 +30,7 @@
:global SymbolForNotification;
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -93,4 +95,6 @@
$LogPrint debug $ScriptName ("No mac address available... Ignoring.");
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/collect-wireless-mac.local.rsc b/collect-wireless-mac.local.rsc
index 8a60fea..6716582 100644
--- a/collect-wireless-mac.local.rsc
+++ b/collect-wireless-mac.local.rsc
@@ -1,20 +1,21 @@
#!rsc by RouterOS
# RouterOS script: collect-wireless-mac.local
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=40
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# collect wireless mac adresses in access list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/collect-wireless-mac.md
+# https://rsc.eworm.de/doc/collect-wireless-mac.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Identity;
@@ -29,6 +30,7 @@
:global SymbolForNotification;
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -94,4 +96,6 @@
$LogPrint debug $ScriptName ("No mac address available... Ignoring.");
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/collect-wireless-mac.template.rsc b/collect-wireless-mac.template.rsc
index c5cf74a..53e6b0a 100644
--- a/collect-wireless-mac.template.rsc
+++ b/collect-wireless-mac.template.rsc
@@ -1,21 +1,22 @@
#!rsc by RouterOS
# RouterOS script: collect-wireless-mac%TEMPL%
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=40
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# collect wireless mac adresses in access list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/collect-wireless-mac.md
+# https://rsc.eworm.de/doc/collect-wireless-mac.md
#
# !! This is just a template to generate the real script!
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Identity;
@@ -30,6 +31,7 @@
:global SymbolForNotification;
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -111,4 +113,6 @@
$LogPrint debug $ScriptName ("No mac address available... Ignoring.");
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/collect-wireless-mac.wifi.rsc b/collect-wireless-mac.wifi.rsc
index 12c3361..43ac851 100644
--- a/collect-wireless-mac.wifi.rsc
+++ b/collect-wireless-mac.wifi.rsc
@@ -1,20 +1,21 @@
#!rsc by RouterOS
# RouterOS script: collect-wireless-mac.wifi
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=40
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# collect wireless mac adresses in access list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/collect-wireless-mac.md
+# https://rsc.eworm.de/doc/collect-wireless-mac.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Identity;
@@ -29,6 +30,7 @@
:global SymbolForNotification;
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -93,4 +95,6 @@
$LogPrint debug $ScriptName ("No mac address available... Ignoring.");
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/contrib/checksums.sh b/contrib/checksums.sh
new file mode 100755
index 0000000..b472b49
--- /dev/null
+++ b/contrib/checksums.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# generate a checksums file as used by $ScriptInstallUpdate
+
+set -e
+
+md5sum $(find -name '*.rsc' | sort) | \
+ sed -e "s| \./||" -e 's|.rsc$||' | \
+ jq --raw-input --null-input '[ inputs | split (" ") | { (.[1]): (.[0]) }] | add' > 'checksums.json'
diff --git a/daily-psk.capsman.rsc b/daily-psk.capsman.rsc
index 64e8ce7..3ecd6b6 100644
--- a/daily-psk.capsman.rsc
+++ b/daily-psk.capsman.rsc
@@ -1,20 +1,21 @@
#!rsc by RouterOS
# RouterOS script: daily-psk.capsman
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# update daily PSK (pre shared key)
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/daily-psk.md
+# https://rsc.eworm.de/doc/daily-psk.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global DailyPskMatchComment;
@@ -31,6 +32,7 @@
:global WaitFullyConnected;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
$WaitFullyConnected;
@@ -68,7 +70,7 @@
:local Skip 0;
:if ($NewPsk != $OldPsk) do={
- $LogPrint info $ScriptName ("Updating daily PSK for " . $Ssid . " to " . $NewPsk . " (was " . $OldPsk . ")");
+ $LogPrint info $ScriptName ("Updating daily PSK for '" . $Ssid . "' to '" . $NewPsk . "' (was '" . $OldPsk . "')");
/caps-man/access-list/set $AccList private-passphrase=$NewPsk;
:if ([ :len [ /caps-man/actual-interface-configuration/find where configuration.ssid=$Ssid !disabled ] ] > 0) do={
@@ -80,13 +82,15 @@
$SendNotification2 ({ origin=$ScriptName; \
subject=([ $SymbolForNotification "calendar" ] . "daily PSK " . $Ssid); \
message=("This is the daily PSK on " . $Identity . ":\n\n" . \
- [ $FormatLine "SSID" $Ssid ] . "\n" . \
- [ $FormatLine "PSK" $NewPsk ] . "\n" . \
- [ $FormatLine "Date" $Date ] . "\n\n" . \
+ [ $FormatLine "SSID" $Ssid 8 ] . "\n" . \
+ [ $FormatLine "PSK" $NewPsk 8 ] . "\n" . \
+ [ $FormatLine "Date" $Date 8 ] . "\n\n" . \
"A client device specific rule must not exist!"); link=$Link });
:set ($Seen->$Ssid) 1;
}
}
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/daily-psk.local.rsc b/daily-psk.local.rsc
index 48e2b8d..d496350 100644
--- a/daily-psk.local.rsc
+++ b/daily-psk.local.rsc
@@ -1,20 +1,21 @@
#!rsc by RouterOS
# RouterOS script: daily-psk.local
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# update daily PSK (pre shared key)
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/daily-psk.md
+# https://rsc.eworm.de/doc/daily-psk.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global DailyPskMatchComment;
@@ -31,6 +32,7 @@
:global WaitFullyConnected;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
$WaitFullyConnected;
@@ -67,7 +69,7 @@
:local Skip 0;
:if ($NewPsk != $OldPsk) do={
- $LogPrint info $ScriptName ("Updating daily PSK for " . $Ssid . " to " . $NewPsk . " (was " . $OldPsk . ")");
+ $LogPrint info $ScriptName ("Updating daily PSK for '" . $Ssid . "' to '" . $NewPsk . "' (was '" . $OldPsk . "')");
/interface/wireless/access-list/set $AccList private-pre-shared-key=$NewPsk;
:if ([ :len [ /interface/wireless/find where name=$IntName !disabled ] ] = 1) do={
@@ -79,13 +81,15 @@
$SendNotification2 ({ origin=$ScriptName; \
subject=([ $SymbolForNotification "calendar" ] . "daily PSK " . $Ssid); \
message=("This is the daily PSK on " . $Identity . ":\n\n" . \
- [ $FormatLine "SSID" $Ssid ] . "\n" . \
- [ $FormatLine "PSK" $NewPsk ] . "\n" . \
- [ $FormatLine "Date" $Date ] . "\n\n" . \
+ [ $FormatLine "SSID" $Ssid 8 ] . "\n" . \
+ [ $FormatLine "PSK" $NewPsk 8 ] . "\n" . \
+ [ $FormatLine "Date" $Date 8 ] . "\n\n" . \
"A client device specific rule must not exist!"); link=$Link });
:set ($Seen->$Ssid) 1;
}
}
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/daily-psk.template.rsc b/daily-psk.template.rsc
index 5097b00..5a1df2f 100644
--- a/daily-psk.template.rsc
+++ b/daily-psk.template.rsc
@@ -1,21 +1,22 @@
#!rsc by RouterOS
# RouterOS script: daily-psk%TEMPL%
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# update daily PSK (pre shared key)
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/daily-psk.md
+# https://rsc.eworm.de/doc/daily-psk.md
#
# !! This is just a template to generate the real script!
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global DailyPskMatchComment;
@@ -32,6 +33,7 @@
:global WaitFullyConnected;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
$WaitFullyConnected;
@@ -79,13 +81,13 @@
:local Skip 0;
:if ($NewPsk != $OldPsk) do={
- $LogPrint info $ScriptName ("Updating daily PSK for " . $Ssid . " to " . $NewPsk . " (was " . $OldPsk . ")");
+ $LogPrint info $ScriptName ("Updating daily PSK for '" . $Ssid . "' to '" . $NewPsk . "' (was '" . $OldPsk . "')");
/caps-man/access-list/set $AccList private-passphrase=$NewPsk;
/interface/wifi/access-list/set $AccList passphrase=$NewPsk;
/interface/wireless/access-list/set $AccList private-pre-shared-key=$NewPsk;
:if ([ :len [ /caps-man/actual-interface-configuration/find where configuration.ssid=$Ssid !disabled ] ] > 0) do={
- :if ([ :len [ /interface/wifi/actual-configuration/find where configuration.ssid=$Ssid ] ] > 0) do={
+ :if ([ :len [ /interface/wifi/find where configuration.ssid=$Ssid !disabled ] ] > 0) do={
:if ([ :len [ /interface/wireless/find where name=$IntName !disabled ] ] = 1) do={
:if ($Seen->$Ssid = 1) do={
$LogPrint debug $ScriptName ("Already sent a mail for SSID " . $Ssid . ", skipping.");
@@ -95,13 +97,15 @@
$SendNotification2 ({ origin=$ScriptName; \
subject=([ $SymbolForNotification "calendar" ] . "daily PSK " . $Ssid); \
message=("This is the daily PSK on " . $Identity . ":\n\n" . \
- [ $FormatLine "SSID" $Ssid ] . "\n" . \
- [ $FormatLine "PSK" $NewPsk ] . "\n" . \
- [ $FormatLine "Date" $Date ] . "\n\n" . \
+ [ $FormatLine "SSID" $Ssid 8 ] . "\n" . \
+ [ $FormatLine "PSK" $NewPsk 8 ] . "\n" . \
+ [ $FormatLine "Date" $Date 8 ] . "\n\n" . \
"A client device specific rule must not exist!"); link=$Link });
:set ($Seen->$Ssid) 1;
}
}
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/daily-psk.wifi.rsc b/daily-psk.wifi.rsc
index 9d7f285..c441e58 100644
--- a/daily-psk.wifi.rsc
+++ b/daily-psk.wifi.rsc
@@ -1,20 +1,21 @@
#!rsc by RouterOS
# RouterOS script: daily-psk.wifi
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# update daily PSK (pre shared key)
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/daily-psk.md
+# https://rsc.eworm.de/doc/daily-psk.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global DailyPskMatchComment;
@@ -31,6 +32,7 @@
:global WaitFullyConnected;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
$WaitFullyConnected;
@@ -68,10 +70,10 @@
:local Skip 0;
:if ($NewPsk != $OldPsk) do={
- $LogPrint info $ScriptName ("Updating daily PSK for " . $Ssid . " to " . $NewPsk . " (was " . $OldPsk . ")");
+ $LogPrint info $ScriptName ("Updating daily PSK for '" . $Ssid . "' to '" . $NewPsk . "' (was '" . $OldPsk . "')");
/interface/wifi/access-list/set $AccList passphrase=$NewPsk;
- :if ([ :len [ /interface/wifi/actual-configuration/find where configuration.ssid=$Ssid ] ] > 0) do={
+ :if ([ :len [ /interface/wifi/find where configuration.ssid=$Ssid !disabled ] ] > 0) do={
:if ($Seen->$Ssid = 1) do={
$LogPrint debug $ScriptName ("Already sent a mail for SSID " . $Ssid . ", skipping.");
} else={
@@ -80,13 +82,15 @@
$SendNotification2 ({ origin=$ScriptName; \
subject=([ $SymbolForNotification "calendar" ] . "daily PSK " . $Ssid); \
message=("This is the daily PSK on " . $Identity . ":\n\n" . \
- [ $FormatLine "SSID" $Ssid ] . "\n" . \
- [ $FormatLine "PSK" $NewPsk ] . "\n" . \
- [ $FormatLine "Date" $Date ] . "\n\n" . \
+ [ $FormatLine "SSID" $Ssid 8 ] . "\n" . \
+ [ $FormatLine "PSK" $NewPsk 8 ] . "\n" . \
+ [ $FormatLine "Date" $Date 8 ] . "\n\n" . \
"A client device specific rule must not exist!"); link=$Link });
:set ($Seen->$Ssid) 1;
}
}
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/dhcp-lease-comment.capsman.rsc b/dhcp-lease-comment.capsman.rsc
index b7f3589..3615bb9 100644
--- a/dhcp-lease-comment.capsman.rsc
+++ b/dhcp-lease-comment.capsman.rsc
@@ -1,26 +1,28 @@
#!rsc by RouterOS
# RouterOS script: dhcp-lease-comment.capsman
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=60
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# update dhcp-server lease comment with infos from access-list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/dhcp-lease-comment.md
+# https://rsc.eworm.de/doc/dhcp-lease-comment.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global LogPrint;
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -36,4 +38,6 @@
/ip/dhcp-server/lease/set comment=$NewComment $Lease;
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/dhcp-lease-comment.local.rsc b/dhcp-lease-comment.local.rsc
index e35bbe7..9da5333 100644
--- a/dhcp-lease-comment.local.rsc
+++ b/dhcp-lease-comment.local.rsc
@@ -1,26 +1,28 @@
#!rsc by RouterOS
# RouterOS script: dhcp-lease-comment.local
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=60
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# update dhcp-server lease comment with infos from access-list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/dhcp-lease-comment.md
+# https://rsc.eworm.de/doc/dhcp-lease-comment.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global LogPrint;
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -36,4 +38,6 @@
/ip/dhcp-server/lease/set comment=$NewComment $Lease;
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/dhcp-lease-comment.template.rsc b/dhcp-lease-comment.template.rsc
index d4323ad..62cace1 100644
--- a/dhcp-lease-comment.template.rsc
+++ b/dhcp-lease-comment.template.rsc
@@ -1,27 +1,29 @@
#!rsc by RouterOS
# RouterOS script: dhcp-lease-comment%TEMPL%
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=60
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# update dhcp-server lease comment with infos from access-list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/dhcp-lease-comment.md
+# https://rsc.eworm.de/doc/dhcp-lease-comment.md
#
# !! This is just a template to generate the real script!
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global LogPrint;
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -41,4 +43,6 @@
/ip/dhcp-server/lease/set comment=$NewComment $Lease;
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/dhcp-lease-comment.wifi.rsc b/dhcp-lease-comment.wifi.rsc
index f67ce6e..667708c 100644
--- a/dhcp-lease-comment.wifi.rsc
+++ b/dhcp-lease-comment.wifi.rsc
@@ -1,26 +1,28 @@
#!rsc by RouterOS
# RouterOS script: dhcp-lease-comment.wifi
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=60
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# update dhcp-server lease comment with infos from access-list
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/dhcp-lease-comment.md
+# https://rsc.eworm.de/doc/dhcp-lease-comment.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global LogPrint;
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -36,4 +38,6 @@
/ip/dhcp-server/lease/set comment=$NewComment $Lease;
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/dhcp-to-dns.rsc b/dhcp-to-dns.rsc
index a3d41c9..a9c91e1 100644
--- a/dhcp-to-dns.rsc
+++ b/dhcp-to-dns.rsc
@@ -1,18 +1,19 @@
#!rsc by RouterOS
# RouterOS script: dhcp-to-dns
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=20
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.16
#
# check DHCP leases and add/remove/update DNS entries
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/dhcp-to-dns.md
+# https://rsc.eworm.de/doc/dhcp-to-dns.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Domain;
@@ -27,6 +28,7 @@
:global ScriptLock;
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -40,7 +42,7 @@
}
:local PlaceBefore ([ /ip/dns/static/find where (name=$CommentString or (comment=$CommentString and name=-)) type=NXDOMAIN disabled ]->0);
- :foreach DnsRecord in=[ /ip/dns/static/find where comment~("^" . $CommentPrefix . "\\b") (!type or type=A) ] do={
+ :foreach DnsRecord in=[ /ip/dns/static/find where comment~("^" . $CommentPrefix . "\\b") type=A ] do={
:local DnsRecordVal [ /ip/dns/static/get $DnsRecord ];
:local DnsRecordInfo [ $ParseKeyValueStore ($DnsRecordVal->"comment") ];
:local MacInServer ($DnsRecordInfo->"macaddress" . " in " . $DnsRecordInfo->"server");
@@ -83,7 +85,7 @@
:local FullCN ($HostName . "." . $NetDomain);
:local MacInServer ($LeaseVal->"active-mac-address" . " in " . $LeaseVal->"server");
- :local DnsRecord [ /ip/dns/static/find where comment=$Comment (!type or type=A) ];
+ :local DnsRecord [ /ip/dns/static/find where comment=$Comment type=A ];
:if ([ :len $DnsRecord ] > 0) do={
:local DnsRecordVal [ /ip/dns/static/get $DnsRecord ];
@@ -116,11 +118,13 @@
}
}
- :if ([ :len [ /ip/dns/static/find where name=$FullA (!type or type=A) ] ] > 1) do={
+ :if ([ :len [ /ip/dns/static/find where name=$FullA type=A ] ] > 1) do={
$LogPrintOnce warning $ScriptName ("The name '" . $FullA . "' appeared in more than one A record!");
}
} else={
$LogPrint debug $ScriptName ("No address available... Ignoring.");
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/doc/accesslist-duplicates.md b/doc/accesslist-duplicates.md
index a1f9198..e4d0c7f 100644
--- a/doc/accesslist-duplicates.md
+++ b/doc/accesslist-duplicates.md
@@ -4,7 +4,7 @@ Find and remove access list duplicates
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/backup-cloud.md b/doc/backup-cloud.md
index be6e06d..7d55d74 100644
--- a/doc/backup-cloud.md
+++ b/doc/backup-cloud.md
@@ -4,7 +4,7 @@ Upload backup to Mikrotik cloud
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -17,7 +17,7 @@ Description
-----------
This script uploads
-[binary backup to Mikrotik cloud](https://wiki.mikrotik.com/wiki/Manual:IP/Cloud#Backup).
+[binary backup to Mikrotik cloud ↗️](https://wiki.mikrotik.com/wiki/Manual:IP/Cloud#Backup).
> ⚠️ **Warning**: The used command can hit errors that a script can with
> workaround only. A notification *should* be sent anyway. But it can result
@@ -49,6 +49,7 @@ The configuration goes to `global-config-overlay`, these are the parameters:
Also notification settings are required for
[e-mail](mod/notification-email.md),
+[gotify](mod/notification-gotify.md),
[matrix](mod/notification-matrix.md),
[ntfy](mod/notification-ntfy.md) and/or
[telegram](mod/notification-telegram.md).
@@ -68,7 +69,7 @@ See also
--------
* [Send backup via e-mail](backup-email.md)
-* [Save configuration to fallback partition](doc/backup-partition.md)
+* [Save configuration to fallback partition](backup-partition.md)
* [Upload backup to server](backup-upload.md)
---
diff --git a/doc/backup-email.md b/doc/backup-email.md
index a506543..7b8bcfe 100644
--- a/doc/backup-email.md
+++ b/doc/backup-email.md
@@ -4,7 +4,7 @@ Send backup via e-mail
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -59,7 +59,7 @@ See also
--------
* [Upload backup to Mikrotik cloud](backup-cloud.md)
-* [Save configuration to fallback partition](doc/backup-partition.md)
+* [Save configuration to fallback partition](backup-partition.md)
* [Send notifications via e-mail](mod/notification-email.md)
* [Upload backup to server](backup-upload.md)
diff --git a/doc/backup-partition.md b/doc/backup-partition.md
index ba20657..50b8a09 100644
--- a/doc/backup-partition.md
+++ b/doc/backup-partition.md
@@ -4,7 +4,7 @@ Save configuration to fallback partition
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -17,7 +17,9 @@ Description
-----------
This script saves the current configuration to fallback
-[partition](https://wiki.mikrotik.com/wiki/Manual:Partitions).
+[partition ↗️](https://wiki.mikrotik.com/wiki/Manual:Partitions).
+It can also copy-over the RouterOS installation when run interactively
+or just before a feature update.
For this to work you need a device with sufficient flash storage that is
properly partitioned.
@@ -26,9 +28,9 @@ To make you aware of a possible issue a scheduler logging a warning is
added in the backup partition's configuration. You may want to use
[log-forward](log-forward.md) to be notified.
-> ⚠️ **Warning**: Only the configuration is saved to backup partition.
-> Every now and then you should copy your installation over for a recent
-> RouterOS version!
+> ⚠️ **Warning**: By default only the configuration is saved to backup
+> partition. Every now and then you should copy your installation over
+> for a recent RouterOS version! See below for options.
Requirements and installation
-----------------------------
@@ -37,6 +39,18 @@ Just install the script:
$ScriptInstallUpdate backup-partition;
+Configuration
+-------------
+
+The configuration goes to `global-config-overlay`, the only parameter is:
+
+* `BackupPartitionCopyBeforeFeatureUpdate`: copy-over the RouterOS
+ installation when a feature update is pending
+
+> ℹ️ **Info**: Copy relevant configuration from
+> [`global-config`](../global-config.rsc) (the one without `-overlay`) to
+> your local `global-config-overlay` and modify it to your specific needs.
+
Usage and invocation
--------------------
@@ -44,6 +58,9 @@ Just run the script:
/system/script/run backup-partition;
+When run interactively from terminal it supports to copy-over the RouterOS
+installation when versions differ.
+
Creating a scheduler may be an option:
/system/scheduler/add interval=1w name=backup-partition on-event="/system/script/run backup-partition;" start-time=09:30:00;
diff --git a/doc/backup-upload.md b/doc/backup-upload.md
index f524adb..b4012c8 100644
--- a/doc/backup-upload.md
+++ b/doc/backup-upload.md
@@ -4,7 +4,7 @@ Upload backup to server
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -55,6 +55,7 @@ The configuration goes to `global-config-overlay`, these are the parameters:
Also notification settings are required for
[e-mail](mod/notification-email.md),
+[gotify](mod/notification-gotify.md),
[matrix](mod/notification-matrix.md),
[ntfy](mod/notification-ntfy.md) and/or
[telegram](mod/notification-telegram.md).
@@ -85,7 +86,7 @@ See also
* [Upload backup to Mikrotik cloud](backup-cloud.md)
* [Send backup via e-mail](backup-email.md)
-* [Save configuration to fallback partition](doc/backup-partition.md)
+* [Save configuration to fallback partition](backup-partition.md)
---
[⬅️ Go back to main README](../README.md)
diff --git a/doc/capsman-download-packages.md b/doc/capsman-download-packages.md
index c68900e..5722227 100644
--- a/doc/capsman-download-packages.md
+++ b/doc/capsman-download-packages.md
@@ -4,7 +4,7 @@ Download packages for CAP upgrade from CAPsMAN
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/capsman-rolling-upgrade.md b/doc/capsman-rolling-upgrade.md
index 27d855f..d277db6 100644
--- a/doc/capsman-rolling-upgrade.md
+++ b/doc/capsman-rolling-upgrade.md
@@ -4,7 +4,7 @@ Run rolling CAP upgrades from CAPsMAN
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/certificate-renew-issued.md b/doc/certificate-renew-issued.md
index 91a1914..c4615b5 100644
--- a/doc/certificate-renew-issued.md
+++ b/doc/certificate-renew-issued.md
@@ -4,7 +4,7 @@ Renew locally issued certificates
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/check-certificates.md b/doc/check-certificates.md
index 636f719..a9426db 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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -51,6 +51,7 @@ subject alternative name (aka *Subject Alt Name* or *SAN*) can be used.
Also notification settings are required for
[e-mail](mod/notification-email.md),
+[gotify](mod/notification-gotify.md),
[matrix](mod/notification-matrix.md),
[ntfy](mod/notification-ntfy.md) and/or
[telegram](mod/notification-telegram.md).
diff --git a/doc/check-health.d/notification-08-psu-fail.avif b/doc/check-health.d/notification-08-state-fail.avif
index ad049ac..ad049ac 100644
--- a/doc/check-health.d/notification-08-psu-fail.avif
+++ b/doc/check-health.d/notification-08-state-fail.avif
Binary files differ
diff --git a/doc/check-health.d/notification-09-psu-ok.avif b/doc/check-health.d/notification-09-state-ok.avif
index 26f5a74..26f5a74 100644
--- a/doc/check-health.d/notification-09-psu-ok.avif
+++ b/doc/check-health.d/notification-09-state-ok.avif
Binary files differ
diff --git a/doc/check-health.md b/doc/check-health.md
index f94a0bf..33847e3 100644
--- a/doc/check-health.md
+++ b/doc/check-health.md
@@ -4,7 +4,7 @@ Notify about health state
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -17,22 +17,24 @@ Description
-----------
This script is run from scheduler periodically, sending notification on
-health related events:
+health related events. Monitoring CPU and RAM utilization (available
+processing and memory resources) works on all devices:
* high CPU utilization
* high RAM utilization (low available RAM)
+
+With additional plugins functionality can be extended, depending on
+sensors available in hardware:
+
* voltage jumps up or down more than configured threshold
* voltage drops below hard lower limit
+* fan failed or recovered
* power supply failed or recovered
* temperature is above or below threshold
-Note that bad initial state will not trigger an event.
-
-Monitoring CPU and RAM utilization (available processing and memory
-resources) works on all devices. Other than that only sensors available
-in hardware can be checked. See what your hardware supports:
-
- /system/health/print;
+> ⚠️ **Warning**: Note that bad initial state will not trigger an event! For
+> example rebooting a device that is already too hot will not trigger an
+> alert on high temperature.
### Sample notifications
@@ -57,8 +59,8 @@ in hardware can be checked. See what your hardware supports:
#### PSU state
-![check-health notification psu fail](check-health.d/notification-08-psu-fail.avif)
-![check-health notification psu ok](check-health.d/notification-09-psu-ok.avif)
+![check-health notification state fail](check-health.d/notification-08-state-fail.avif)
+![check-health notification state ok](check-health.d/notification-09-state-ok.avif)
Requirements and installation
-----------------------------
@@ -72,6 +74,30 @@ Just install the script and create a scheduler:
> precision of cpu utilization, escpecially on devices with limited
> resources. Thus an unusual interval is used here.
+### Plugins
+
+Additional plugins are available for sensors available in hardware. First
+check what your hardware supports:
+
+ /system/health/print;
+
+Then install the plugin for *fan* and *power supply unit* *state*:
+
+ $ScriptInstallUpdate check-health,check-health.d/state;
+
+... or *temperature*:
+
+ $ScriptInstallUpdate check-health,check-health.d/temperature;
+
+... or *voltage*:
+
+ $ScriptInstallUpdate check-health,check-health.d/voltage;
+
+You can also combine the commands and install all or a subset of plugins
+in one go:
+
+ $ScriptInstallUpdate check-health,check-health.d/state,check-health.d/temperature,check-health.d/voltage;
+
Configuration
-------------
@@ -87,6 +113,7 @@ The configuration goes to `global-config-overlay`, these are the parameters:
Also notification settings are required for
[e-mail](mod/notification-email.md),
+[gotify](mod/notification-gotify.md),
[matrix](mod/notification-matrix.md),
[ntfy](mod/notification-ntfy.md) and/or
[telegram](mod/notification-telegram.md).
diff --git a/doc/check-lte-firmware-upgrade.md b/doc/check-lte-firmware-upgrade.md
index 59a62c7..a0c441e 100644
--- a/doc/check-lte-firmware-upgrade.md
+++ b/doc/check-lte-firmware-upgrade.md
@@ -4,7 +4,7 @@ Notify on LTE firmware upgrade
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -44,7 +44,9 @@ Configuration
Also notification settings are required for
[e-mail](mod/notification-email.md),
-[matrix](mod/notification-matrix.md) and/or
+[gotify](mod/notification-gotify.md),
+[matrix](mod/notification-matrix.md),
+[ntfy](mod/notification-ntfy.md) and/or
[telegram](mod/notification-telegram.md).
See also
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
--- /dev/null
+++ b/doc/check-perpetual-license.d/notification.avif
Binary files differ
diff --git a/doc/check-perpetual-license.md b/doc/check-perpetual-license.md
new file mode 100644
index 0000000..0335fb5
--- /dev/null
+++ b/doc/check-perpetual-license.md
@@ -0,0 +1,71 @@
+Check perpetual license on CHR
+==============================
+
+[![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)
+
+[⬅️ Go back to main README](../README.md)
+
+> ℹ️ **Info**: This script can not be used on its own but requires the base
+> installation. See [main README](../README.md) for details.
+
+Description
+-----------
+
+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 notification
+
+![check-perpetual-license notification](check-perpetual-license.d/notification.avif)
+
+Requirements and installation
+-----------------------------
+
+Just install the script:
+
+ $ScriptInstallUpdate check-perpetual-license;
+
+And add a scheduler for automatic update notification:
+
+ /system/scheduler/add interval=1d name=check-perpetual-license on-event="/system/script/run check-perpetual-license;" start-time=startup;
+
+Configuration
+-------------
+
+No extra configuration is required for this script, but notification
+settings are required for
+[e-mail](mod/notification-email.md),
+[gotify](mod/notification-gotify.md),
+[matrix](mod/notification-matrix.md),
+[ntfy](mod/notification-ntfy.md) and/or
+[telegram](mod/notification-telegram.md).
+
+Usage and invocation
+--------------------
+
+Be notified when run from scheduler or run it manually:
+
+ /system/script/run check-perpetual-license;
+
+Tips & Tricks
+-------------
+
+The script checks for full connectivity before acting, so scheduling at
+startup is perfectly valid:
+
+ /system/scheduler/add name=check-perpetual-license@startup on-event="/system/script/run check-perpetual-license;" start-time=startup;
+
+See also
+--------
+
+* [Notify on RouterOS update](check-routeros-update.md)
+
+---
+[⬅️ Go back to main README](../README.md)
+[⬆️ Go back to top](#top)
diff --git a/doc/check-routeros-update.md b/doc/check-routeros-update.md
index f9d485c..a45e075 100644
--- a/doc/check-routeros-update.md
+++ b/doc/check-routeros-update.md
@@ -4,7 +4,7 @@ Notify on RouterOS update
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -30,8 +30,8 @@ automatically is supported.
> ⚠️ **Warning**: Installing updates is important from a security point
> 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/viewforum.php?f=21) before deploying
+> [changelog ↗️](https://mikrotik.com/download/changelogs/) and
+> [forum ↗️](https://forum.mikrotik.com/viewforum.php?f=21) before deploying
> to your production environment! Automatic updates should be handled
> with care!
@@ -73,6 +73,7 @@ The configuration goes to `global-config-overlay`, these are the parameters:
Also notification settings are required for
[e-mail](mod/notification-email.md),
+[gotify](mod/notification-gotify.md),
[matrix](mod/notification-matrix.md),
[ntfy](mod/notification-ntfy.md) and/or
[telegram](mod/notification-telegram.md).
@@ -99,6 +100,7 @@ startup is perfectly valid:
See also
--------
+* [Check perpetual license on CHR](check-perpetual-license.md)
* [Automatically upgrade firmware and reboot](firmware-upgrade-reboot.md)
* [Manage system update](packages-update.md)
diff --git a/doc/collect-wireless-mac.md b/doc/collect-wireless-mac.md
index 57032d8..2378fed 100644
--- a/doc/collect-wireless-mac.md
+++ b/doc/collect-wireless-mac.md
@@ -4,7 +4,7 @@ Collect MAC addresses in wireless access list
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -54,6 +54,7 @@ entries are to be added.
Also notification settings are required for
[e-mail](mod/notification-email.md),
+[gotify](mod/notification-gotify.md),
[matrix](mod/notification-matrix.md),
[ntfy](mod/notification-ntfy.md) and/or
[telegram](mod/notification-telegram.md).
diff --git a/doc/daily-psk.md b/doc/daily-psk.md
index 3894d52..118d768 100644
--- a/doc/daily-psk.md
+++ b/doc/daily-psk.md
@@ -4,7 +4,7 @@ Use wireless network with daily psk
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -79,6 +79,7 @@ For legacy local interface:
Also notification settings are required for
[e-mail](mod/notification-email.md),
+[gotify](mod/notification-gotify.md),
[trix](mod/notification-matrix.md),
[ntfy](mod/notification-ntfy.md) and/or
[telegram](mod/notification-telegram.md).
diff --git a/doc/dhcp-lease-comment.md b/doc/dhcp-lease-comment.md
index f95b124..b02f199 100644
--- a/doc/dhcp-lease-comment.md
+++ b/doc/dhcp-lease-comment.md
@@ -4,7 +4,7 @@ Comment DHCP leases with info from access list
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/dhcp-to-dns.md b/doc/dhcp-to-dns.md
index 13d5ef3..4211d85 100644
--- a/doc/dhcp-to-dns.md
+++ b/doc/dhcp-to-dns.md
@@ -4,7 +4,7 @@ Create DNS records for DHCP leases
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.16-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/doc/firmware-upgrade-reboot.md b/doc/firmware-upgrade-reboot.md
index bac17a7..54f1da0 100644
--- a/doc/firmware-upgrade-reboot.md
+++ b/doc/firmware-upgrade-reboot.md
@@ -4,7 +4,7 @@ Automatically upgrade firmware and reboot
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/fw-addr-lists.md b/doc/fw-addr-lists.md
index ac34c88..46b80c2 100644
--- a/doc/fw-addr-lists.md
+++ b/doc/fw-addr-lists.md
@@ -4,7 +4,7 @@ Download, import and update firewall address-lists
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.16-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)
@@ -18,10 +18,11 @@ Description
This script downloads, imports and updates firewall address-lists. Its main
purpose is to block attacking ip addresses, spam hosts, command-and-control
-servers and similar malicious entities. The default configuration contains
-lists from [abuse.ch](https://abuse.ch/) and
-[dshield.org](https://dshield.org/), and
-lists from [spamhaus.org](https://spamhaus.org/) are prepared.
+servers and similar malicious entities. The default configuration contains a
+[collective list by GitHub user @stamparm ↗️](https://github.com/stamparm/ipsum),
+lists from [dshield.org ↗️](https://dshield.org/) and
+[blocklist.de ↗️](https://www.blocklist.de/), and lists from
+[spamhaus.org ↗️](https://spamhaus.org/) are prepared.
The address-lists are updated in place, so after initial import you will not
see situation when the lists are not populated.
@@ -31,7 +32,10 @@ certificate is checked.
> ⚠️ **Warning**: The script does not limit the size of a list, but keep in
> mind that huge lists can exhaust your device's resources (RAM and CPU),
-> and may take a long time to process.
+> and may take a long time to process.
+> Even crashes for the complete scripting (and CLI) subsystem are possible.
+> This should be logged accordingly with warnings when global functions are
+> reloaded from scheduler.
Requirements and installation
-----------------------------
@@ -62,9 +66,8 @@ The configuration goes to `global-config-overlay`, these are the parameters:
> your local `global-config-overlay` and modify it to your specific needs.
Naming a certificate for a list makes the script verify the server
-certificate, so you should add that if possible. Some certificates are
-available in my repository and downloaded automatically. Import it manually
-(menu `/certificate/`) if missing.
+certificate, so you should add that if possible. You may want to find the
+[certificate name from browser](../CERTIFICATES.md).
Create firewall rules to process the packets that are related to addresses
from address-lists.
@@ -127,6 +130,11 @@ Drop packets in firewall's raw section:
> ⚠️ **Warning**: Just again... The order of firewall rules is important. Make
> sure they actually take effect as expected!
+See also
+--------
+
+* [Certificate name from browser](../CERTIFICATES.md)
+
---
[⬅️ Go back to main README](../README.md)
[⬆️ Go back to top](#top)
diff --git a/doc/global-wait.md b/doc/global-wait.md
index 4b42717..799cae7 100644
--- a/doc/global-wait.md
+++ b/doc/global-wait.md
@@ -4,7 +4,7 @@ Wait for global functions and modules
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/gps-track.md b/doc/gps-track.md
index 7006fb3..5e4878f 100644
--- a/doc/gps-track.md
+++ b/doc/gps-track.md
@@ -4,7 +4,7 @@ Send GPS position to server
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/hotspot-to-wpa.md b/doc/hotspot-to-wpa.md
index 275fe4d..a2e9748 100644
--- a/doc/hotspot-to-wpa.md
+++ b/doc/hotspot-to-wpa.md
@@ -4,7 +4,7 @@ Use WPA network with hotspot credentials
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/ip-addr-bridge.md b/doc/ip-addr-bridge.md
index 941a8ae..f9f98e3 100644
--- a/doc/ip-addr-bridge.md
+++ b/doc/ip-addr-bridge.md
@@ -4,7 +4,7 @@ Manage IP addresses with bridge status
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/ipsec-to-dns.md b/doc/ipsec-to-dns.md
index 0a91960..123656c 100644
--- a/doc/ipsec-to-dns.md
+++ b/doc/ipsec-to-dns.md
@@ -4,7 +4,7 @@ Create DNS records for IPSec peers
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/ipv6-update.md b/doc/ipv6-update.md
index 20265fe..1f009b1 100644
--- a/doc/ipv6-update.md
+++ b/doc/ipv6-update.md
@@ -4,7 +4,7 @@ Update configuration on IPv6 prefix change
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -45,13 +45,17 @@ Installing [ppp-on-up](ppp-on-up.md) may solve this.
Configuration
-------------
-An address list entry is updated with current prefix and can be used in
-firewall rules, comment has to be "`ipv6-pool-`" and actual pool name:
+As an address-list entry is mandatory a dynamic one is created automatically.
+It is updated with current prefix and can be used in firewall rules.
+
+Alternatively a static address-list entry can be used, where comment has to
+be "`ipv6-pool-`" and actual pool name. Use what ever list is desired, and
+create it with:
/ipv6/firewall/address-list/add address=2003:cf:2f0f:de00::/56 comment=ipv6-pool-isp list=extern;
-As this entry is mandatory it is created automatically if it does not exist,
-with the comment also set for list.
+If the dynamic entry exists already you need to remove it before creating
+the static one..
Address list entries for specific interfaces can be updated as well. The
interface needs to get its address from pool `isp` and the address list entry
diff --git a/doc/lease-script.md b/doc/lease-script.md
index 4d2f3bc..f83c383 100644
--- a/doc/lease-script.md
+++ b/doc/lease-script.md
@@ -4,7 +4,7 @@ Run other scripts on DHCP lease
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/leds-mode.md b/doc/leds-mode.md
index 90ea418..a194396 100644
--- a/doc/leds-mode.md
+++ b/doc/leds-mode.md
@@ -4,7 +4,7 @@ Manage LEDs dark mode
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/log-forward.md b/doc/log-forward.md
index 44409dc..f6086c8 100644
--- a/doc/log-forward.md
+++ b/doc/log-forward.md
@@ -4,7 +4,7 @@ Forward log messages via notification
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -22,15 +22,15 @@ server (see `/system/logging`). This has some limitation, however:
* does not work early after boot if network connectivity is not
yet established, or breaks intermittently
* lots of messages generate a flood of mails
-* Matrix and Telegram are not supported
+* Gotify, Matrix, Ntfy and Telegram are not supported
The script works around the limitations, for example it does:
* read from `/log`, including messages from early boot
* skip multi-repeated messages
* rate-limit itself to mitigate flooding
-* forward via notification (which includes *e-mail*, *Matrix* and *Telegram*
- when installed and configured, see below)
+* forward via notification (which includes *e-mail*, *Gotify*, *Matrix*,
+ *Ntfy* and *Telegram* when installed and configured, see below)
It is intended to be run periodically from scheduler, then collects new
log messages and forwards them via notification.
@@ -53,6 +53,12 @@ Just install the script:
Configuration
-------------
+The default configuration should provide reasonable presets, filtering
+*info*, and effectively forwarding *warning* and *error*.
+
+> 💡️ **Hint**: Please try with defaults first, especially if you are not
+> familiar with regular expressions!
+
The configuration goes to `global-config-overlay`, these are the parameters:
* `LogForwardFilter`: define topics *not* to be forwarded
@@ -66,7 +72,7 @@ The configuration goes to `global-config-overlay`, these are the parameters:
> your local `global-config-overlay` and modify it to your specific needs.
These patterns are matched as
-[regular expressions](https://wiki.mikrotik.com/wiki/Manual:Regular_Expressions).
+[regular expressions ↗️](https://wiki.mikrotik.com/wiki/Manual:Regular_Expressions).
To forward **all** (ignoring severity) log messages with topics `account`
(which includes user logins) and `dhcp` you need something like:
@@ -74,6 +80,7 @@ To forward **all** (ignoring severity) log messages with topics `account`
Also notification settings are required for
[e-mail](mod/notification-email.md),
+[gotify](mod/notification-gotify.md),
[matrix](mod/notification-matrix.md),
[ntfy](mod/notification-ntfy.md) and/or
[telegram](mod/notification-telegram.md).
diff --git a/doc/mod/bridge-port-to.md b/doc/mod/bridge-port-to.md
index 5c8bebc..629c526 100644
--- a/doc/mod/bridge-port-to.md
+++ b/doc/mod/bridge-port-to.md
@@ -4,7 +4,7 @@ Manage ports in bridge
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/mod/bridge-port-vlan.md b/doc/mod/bridge-port-vlan.md
index d23d5b5..cf29199 100644
--- a/doc/mod/bridge-port-vlan.md
+++ b/doc/mod/bridge-port-vlan.md
@@ -4,7 +4,7 @@ Manage VLANs on bridge ports
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/mod/inspectvar.md b/doc/mod/inspectvar.md
index d4e59b3..7daba15 100644
--- a/doc/mod/inspectvar.md
+++ b/doc/mod/inspectvar.md
@@ -4,7 +4,7 @@ Inspect variables
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/mod/ipcalc.md b/doc/mod/ipcalc.md
index cb655bc..c07853e 100644
--- a/doc/mod/ipcalc.md
+++ b/doc/mod/ipcalc.md
@@ -4,7 +4,7 @@ IP address calculation
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/mod/notification-email.md b/doc/mod/notification-email.md
index 2138e31..127bf96 100644
--- a/doc/mod/notification-email.md
+++ b/doc/mod/notification-email.md
@@ -4,7 +4,7 @@ Send notifications via e-mail
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -32,7 +32,7 @@ Configuration
-------------
Set up your device's
-[e-mail settings](https://wiki.mikrotik.com/wiki/Manual:Tools/email).
+[e-mail settings ↗️](https://wiki.mikrotik.com/wiki/Manual:Tools/email).
Also make sure the device has correct time configured, best is to set up
the ntp client.
@@ -79,6 +79,7 @@ function available:
See also
--------
+* [Send notifications via Gotify](notification-gotify.md)
* [Send notifications via Matrix](notification-matrix.md)
* [Send notifications via Ntfy](notification-ntfy.md)
* [Send notifications via Telegram](notification-telegram.md)
diff --git a/doc/mod/notification-gotify.d/appsetup.avif b/doc/mod/notification-gotify.d/appsetup.avif
new file mode 100644
index 0000000..58f57a8
--- /dev/null
+++ b/doc/mod/notification-gotify.d/appsetup.avif
Binary files differ
diff --git a/doc/mod/notification-gotify.md b/doc/mod/notification-gotify.md
new file mode 100644
index 0000000..6fce629
--- /dev/null
+++ b/doc/mod/notification-gotify.md
@@ -0,0 +1,97 @@
+Send notifications via Gotify
+===========================
+
+[![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)
+
+[⬅️ Go back to main README](../../README.md)
+
+> ℹ️️ **Info**: This module can not be used on its own but requires the base
+> installation. See [main README](../../README.md) for details.
+
+Description
+-----------
+
+This module adds support for sending notifications via
+[Gotify ↗️](https://gotify.net/). A queue is used to make sure
+notifications are not lost on failure but sent later.
+
+Requirements and installation
+-----------------------------
+
+Just install the module:
+
+ $ScriptInstallUpdate mod/notification-gotify;
+
+Also deploy the [Gotify server ↗️](https://github.com/gotify/server) and
+optionally install a Gotify client on your mobile device.
+
+Configuration
+-------------
+
+Follow the [Installation ↗️](https://gotify.net/docs/install) instructions
+and the [First Login ↗️](https://gotify.net/docs/first-login) setup. Once
+you have a user and account you can start creating apps. Each app is an
+independent notification feed for a device or application.
+
+![Create new app](notification-gotify.d/appsetup.avif)
+
+On creation apps are assigned a *Token* for authentification, you will need
+that in configuration.
+
+Edit `global-config-overlay`, add `GotifyServer` with your server address
+(just the address, no protocol - `https://` is assumed) and `GotifyToken`
+with the *Token* from your configured app on the Gotify server. Then reload
+the configuration.
+
+> ℹ️ **Info**: Copy relevant configuration from
+> [`global-config`](../../global-config.rsc) (the one without `-overlay`) to
+> your local `global-config-overlay` and modify it to your specific needs.
+
+For a custom service installing an additional certificate may be required.
+You may want to install that certificate manually, after finding the
+[certificate name from browser](../../CERTIFICATES.md).
+
+Usage and invocation
+--------------------
+
+There's nothing special to do. Every script or function sending a notification
+will now send it to your Gotify application feed.
+
+But of course you can use the function to send notifications directly. Give
+it a try:
+
+ $SendGotify "Subject..." "Body...";
+
+Alternatively this sends a notification with all available and configured
+methods:
+
+ $SendNotification "Subject..." "Body...";
+
+To use the functions in your own scripts you have to declare them first.
+Place this before you call them:
+
+ :global SendGotify;
+ :global SendNotification;
+
+In case there is a situation when the queue needs to be purged there is a
+function available:
+
+ $PurgeGotifyQueue;
+
+See also
+--------
+
+* [Certificate name from browser](../../CERTIFICATES.md)
+* [Send notifications via e-mail](notification-email.md)
+* [Send notifications via Matrix](notification-matrix.md)
+* [Send notifications via Ntfy](notification-ntfy.md)
+* [Send notifications via Telegram](notification-telegram.md)
+
+---
+[⬅️ Go back to main README](../../README.md)
+[⬆️ Go back to top](#top)
diff --git a/doc/mod/notification-matrix.md b/doc/mod/notification-matrix.md
index 92383be..da6d6de 100644
--- a/doc/mod/notification-matrix.md
+++ b/doc/mod/notification-matrix.md
@@ -4,7 +4,7 @@ Send notifications via Matrix
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -17,7 +17,7 @@ Description
-----------
This module adds support for sending notifications via
-[Matrix](https://matrix.org/) via client server api. A queue is used to
+[Matrix ↗️](https://matrix.org/) via client server api. A queue is used to
make sure notifications are not lost on failure but sent later.
Requirements and installation
@@ -46,8 +46,14 @@ The Matrix server is connected via encrypted https, and certificate
verification is applied. So make sure you have the certificate chain for
your server in device's certificate store.
-> ℹ️ **Info**: The *matrix.org* server uses a Cloudflare certificate. You can
-> install that with: `$CertificateAvailable "Cloudflare Inc ECC CA-3"`
+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";
+
+Replace the CA certificate name with what ever is needed for your server.
+You may want to find the
+[certificate name from browser](../../CERTIFICATES.md).
### From other device
@@ -123,7 +129,9 @@ function available:
See also
--------
+* [Certificate name from browser](../../CERTIFICATES.md)
* [Send notifications via e-mail](notification-email.md)
+* [Send notifications via Gotify](notification-gotify.md)
* [Send notifications via Ntfy](notification-ntfy.md)
* [Send notifications via Telegram](notification-telegram.md)
diff --git a/doc/mod/notification-ntfy.md b/doc/mod/notification-ntfy.md
index b2330a5..993501d 100644
--- a/doc/mod/notification-ntfy.md
+++ b/doc/mod/notification-ntfy.md
@@ -4,7 +4,7 @@ Send notifications via Ntfy
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -17,7 +17,7 @@ Description
-----------
This module adds support for sending notifications via
-[Ntfy](https://ntfy.sh/). A queue is used to make sure
+[Ntfy ↗️](https://ntfy.sh/). A queue is used to make sure
notifications are not lost on failure but sent later.
Requirements and installation
@@ -28,7 +28,7 @@ Just install the module:
$ScriptInstallUpdate mod/notification-ntfy;
Also install the Ntfy app on your mobile device or use the
-[web app](https://ntfy.sh/app) in a browser of your choice.
+[web app ↗️](https://ntfy.sh/app) in a browser of your choice.
Configuration
-------------
@@ -52,6 +52,12 @@ basic authentication. Configure `NtfyServerUser` and `NtfyServerPass` for this.
Even authentication via access token is possible, adding it as password with
a blank username.
+Also available is `NtfyServerToken` to add a bearer token for authentication.
+
+For a custom service installing an additional certificate may be required.
+You may want to install that certificate manually, after finding the
+[certificate name from browser](../../CERTIFICATES.md).
+
Usage and invocation
--------------------
@@ -82,7 +88,9 @@ function available:
See also
--------
+* [Certificate name from browser](../../CERTIFICATES.md)
* [Send notifications via e-mail](notification-email.md)
+* [Send notifications via Gotify](notification-gotify.md)
* [Send notifications via Matrix](notification-matrix.md)
* [Send notifications via Telegram](notification-telegram.md)
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
--- /dev/null
+++ b/doc/mod/notification-telegram.d/getchatid.avif
Binary files differ
diff --git a/doc/mod/notification-telegram.md b/doc/mod/notification-telegram.md
index 159fda9..804104f 100644
--- a/doc/mod/notification-telegram.md
+++ b/doc/mod/notification-telegram.md
@@ -4,7 +4,7 @@ Send notifications via Telegram
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -17,7 +17,7 @@ Description
-----------
This module adds support for sending notifications via
-[Telegram](https://telegram.org/) via bot api. A queue is used to make sure
+[Telegram ↗️](https://telegram.org/) via bot api. A queue is used to make sure
notifications are not lost on failure but sent later.
Requirements and installation
@@ -33,19 +33,26 @@ and create an account.
Configuration
-------------
-Open Telegram, then start a chat with [BotFather](https://t.me/BotFather) and
+Open Telegram, then start a chat with [BotFather ↗️](https://t.me/BotFather) and
create your own bot:
![create new bot](notification-telegram.d/newbot.avif)
-Now open a chat with your bot and start it by clicking the `START` button.
+Set that token from *BotFather* (use your own!) to `TelegramTokenId`, for
+now just temporarily:
-Open just another chat with [GetIDs Bot](https://t.me/getidsbot), again start
-with the `START` button. It will send you some information, including the
-`id`, just below `You`.
+ :set TelegramTokenId "5214364459:AAHLwf1o7ybbKDo6pY24Kd2bZ5rjCakDXTc";
+
+Now open a chat with your bot and start it by clicking the `START` button,
+then send your first message. Any text will do. On your device run
+`$GetTelegramChatId` to retrieve the chat id:
+
+ $GetTelegramChatId;
+
+![get chat id](notification-telegram.d/getchatid.avif)
Finally edit `global-config-overlay`, add `TelegramTokenId` with the token
-from *BotFather* and `TelegramChatId` with your id from *GetIDs Bot*. Then
+from *BotFather* and `TelegramChatId` with your retrieved chat id. Then
reload the configuration.
> ℹ️ **Info**: Copy relevant configuration from
@@ -54,9 +61,13 @@ reload the configuration.
### Notifications to a group
-Sending notifications to a group is possible as well. Add your bot and the
-*GetIDs Bot* to a group, then use the group's id (which starts with a dash)
-for `TelegramChatId`. Then remove *GetIDs Bot* from group.
+Sending notifications to a group is possible as well. Add your bot to a group
+and make it an admin (required for read access!) and send a message and run
+`$GetTelegramChatId` again. Then use that chat id (which starts with a dash)
+for `TelegramChatId`.
+
+Groups can enable the `Topics` feature. Use `TelegramThreadId` to send to a
+specific topic in a group.
Usage and invocation
--------------------
@@ -91,7 +102,7 @@ Tips & Tricks
### Set a profile photo
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.
+chat with [BotFather ↗️](https://t.me/BotFather) and set it there.
![set profile photo](notification-telegram.d/setuserpic.avif)
@@ -104,6 +115,7 @@ See also
* [Chat with your router and send commands via Telegram bot](../telegram-chat.md)
* [Send notifications via e-mail](notification-email.md)
+* [Send notifications via Gotify](notification-gotify.md)
* [Send notifications via Matrix](notification-matrix.md)
* [Send notifications via Ntfy](notification-ntfy.md)
diff --git a/doc/mod/scriptrunonce.md b/doc/mod/scriptrunonce.md
index c5fa891..955d12e 100644
--- a/doc/mod/scriptrunonce.md
+++ b/doc/mod/scriptrunonce.md
@@ -4,7 +4,7 @@ Download script and run it once
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/mod/ssh-keys-import.md b/doc/mod/ssh-keys-import.md
index db8e322..344f4bc 100644
--- a/doc/mod/ssh-keys-import.md
+++ b/doc/mod/ssh-keys-import.md
@@ -4,7 +4,7 @@ Import ssh keys for public key authentication
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.16-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)
@@ -34,12 +34,8 @@ Usage and invocation
Call the function `$SSHKeysImport` with key and user as parameter to
import that key:
- $SSHKeysImport "ssh-rsa AAAAB3Nza...QYZk8= user" admin;
-
-Starting with RouterOS *7.12beta1* support for keys of type `ed25519` has
-been added:
-
$SSHKeysImport "ssh-ed25519 AAAAC3Nza...ZVugJT user" admin;
+ $SSHKeysImport "ssh-rsa AAAAB3Nza...QYZk8= user" admin;
The third part of the key (`user` in this example) is inherited as
`key-owner` in RouterOS. Also the `MD5` fingerprint is recorded, this helps
diff --git a/doc/mode-button.md b/doc/mode-button.md
index 8734352..be15bc9 100644
--- a/doc/mode-button.md
+++ b/doc/mode-button.md
@@ -4,7 +4,7 @@ Mode button with multiple presses
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/netwatch-dns.md b/doc/netwatch-dns.md
index 443106f..0d94918 100644
--- a/doc/netwatch-dns.md
+++ b/doc/netwatch-dns.md
@@ -4,7 +4,7 @@ Manage DNS and DoH servers from netwatch
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.16-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)
@@ -53,18 +53,22 @@ Note that using a name in DoH url may introduce a chicken-and-egg issue!
Adding a static DNS record has the same result for the url, but always
resolves to the same address.
- /ip/dns/static/add name="dns.nextdns.io" address=199.247.16.158;
- /tool/netwatch/add comment="doh" host=199.247.16.158;
+ /ip/dns/static/add name="cloudflare-dns.com" address=1.1.1.1;
+ /tool/netwatch/add comment="doh" host=1.1.1.1;
Be aware that you have to keep the ip address in sync with real world
manually!
-Importing a certificate automatically is possible, at least if available in
-the repository (see `certs` sub directory).
+Importing a certificate automatically is possible. You may want to find the
+[certificate name from browser](../CERTIFICATES.md).
+
+ /tool/netwatch/add comment="doh, doh-cert=DigiCert Global Root G2" host=1.1.1.1;
+ /tool/netwatch/add comment="doh, doh-cert=DigiCert Global Root G3" host=9.9.9.9;
+ /tool/netwatch/add comment="doh, doh-cert=GTS Root R1" host=8.8.8.8;
- /tool/netwatch/add comment="doh, doh-cert=DigiCert Global G2 TLS RSA SHA256 2020 CA1" host=1.1.1.1;
- /tool/netwatch/add comment="doh, doh-cert=DigiCert TLS Hybrid ECC SHA384 2020 CA1" host=9.9.9.9;
- /tool/netwatch/add comment="doh, doh-cert=GTS CA 1C3" host=8.8.8.8;
+> ⚠️ **Warning**: Combining these techniques can cause some confusion and
+> troubles! Chances are that a service uses different certificates based
+> on indicated server name.
Sometimes using just one specific (possibly internal) DNS server may be
desired, with fallback in case it fails. This is possible as well:
@@ -87,6 +91,7 @@ Also this allows to update host address, see option `resolve`.
See also
--------
+* [Certificate name from browser](../CERTIFICATES.md)
* [Notify on host up and down](netwatch-notify.md)
---
diff --git a/doc/netwatch-notify.md b/doc/netwatch-notify.md
index 2db32bb..91c568f 100644
--- a/doc/netwatch-notify.md
+++ b/doc/netwatch-notify.md
@@ -4,7 +4,7 @@ Notify on host up and down
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -47,6 +47,7 @@ The hosts to be checked have to be added to netwatch with specific comment:
Also notification settings are required for
[e-mail](mod/notification-email.md),
+[gotify](mod/notification-gotify.md),
[matrix](mod/notification-matrix.md),
[ntfy](mod/notification-ntfy.md) and/or
[telegram](mod/notification-telegram.md).
@@ -66,9 +67,9 @@ notification is sent.
Getting the escaping right may be troublesome. Please consider adding a
script in `/system/script`, then running that from hook.
-### Count threshould
+### Count threshold
-The count threshould (default is 5 checks) is configurable as well:
+The count threshold (default is 5 checks) is configurable as well:
/tool/netwatch/add comment="notify, name=example.com, count=10" host=104.18.144.11;
@@ -81,19 +82,24 @@ suppress notification if the parent host is down:
/tool/netwatch/add comment="notify, name=example.com, parent=gateway" host=93.184.216.34;
Note that every configured parent in a chain increases the check count
-threshould by one.
+threshold by one.
### Update from DNS
The host address can be updated dynamically. Give extra parameter `resolve`
with a resolvable name:
- /tool/netwatch/add comment="notify, name=example.com, resolve=example.com";
+ /tool/netwatch/add comment="notify, name=example.com, resolve=example.com" host=0.0;
-This supports multiple A or AAAA records for a name just fine, even a CNAME
+This supports multiple A records for a name just fine, even a CNAME
to those. An update happens only if no more record with the configured host
address is found.
+The address family is preserved, so if you want AAAA records (for IPv6)
+use this:
+
+ /tool/netwatch/add comment="notify, name=example.com, resolve=example.com" host=::;
+
### No notification on host down
Also suppressing the notification on host down is possible with parameter
@@ -125,7 +131,7 @@ included verbatim into the notification.
It is possible to add a link in notification, that is added below the
formatted notification text.
- /tool/netwatch/add comment="notify, name=example.com, resolve=example.com, link=https://example.com/";
+ /tool/netwatch/add comment="notify, name=example.com, resolve=example.com, link=https://example.com/" host=0.0;
Tips & Tricks
-------------
diff --git a/doc/ospf-to-leds.md b/doc/ospf-to-leds.md
index 121f77b..3694d35 100644
--- a/doc/ospf-to-leds.md
+++ b/doc/ospf-to-leds.md
@@ -4,7 +4,7 @@ Visualize OSPF state via LEDs
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/packages-update.md b/doc/packages-update.md
index fae3896..a0a1795 100644
--- a/doc/packages-update.md
+++ b/doc/packages-update.md
@@ -4,7 +4,7 @@ Manage system update
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -46,8 +46,8 @@ Configuration
The configuration goes to `global-config-overlay`, this is the only parameter:
-* `PackagesUpdateDeferReboot`: defer the reboot for night (between 3 AM
- and 5 AM)
+* `PackagesUpdateDeferReboot`: defer the reboot for night (between 3 AM and
+ 5 AM), use a numerical value in days suffixed with a `d` to defer further
By modifying the scheduler's `start-time` you can force the reboot at
different time.
diff --git a/doc/ppp-on-up.md b/doc/ppp-on-up.md
index 21847c7..305afc1 100644
--- a/doc/ppp-on-up.md
+++ b/doc/ppp-on-up.md
@@ -4,7 +4,7 @@ Run scripts on ppp connection
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/sms-action.md b/doc/sms-action.md
index b4678af..b696c85 100644
--- a/doc/sms-action.md
+++ b/doc/sms-action.md
@@ -4,7 +4,7 @@ Act on received SMS
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/sms-forward.md b/doc/sms-forward.md
index 597410b..0c1317d 100644
--- a/doc/sms-forward.md
+++ b/doc/sms-forward.md
@@ -4,7 +4,7 @@ Forward received SMS
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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)
@@ -56,6 +56,7 @@ The configuration goes to `global-config-overlay`, this is the only parameter:
Notification settings are required for
[e-mail](mod/notification-email.md),
+[gotify](mod/notification-gotify.md),
[matrix](mod/notification-matrix.md),
[ntfy](mod/notification-ntfy.md) and/or
[telegram](mod/notification-telegram.md).
diff --git a/doc/super-mario-theme.md b/doc/super-mario-theme.md
index e4bae2e..c72f220 100644
--- a/doc/super-mario-theme.md
+++ b/doc/super-mario-theme.md
@@ -4,7 +4,7 @@ Play Super Mario theme
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/telegram-chat.md b/doc/telegram-chat.md
index eb4acf5..1e6f70f 100644
--- a/doc/telegram-chat.md
+++ b/doc/telegram-chat.md
@@ -4,7 +4,7 @@ Chat with your router and send commands via Telegram bot
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/unattended-lte-firmware-upgrade.md b/doc/unattended-lte-firmware-upgrade.md
index 6680447..cb96aa1 100644
--- a/doc/unattended-lte-firmware-upgrade.md
+++ b/doc/unattended-lte-firmware-upgrade.md
@@ -4,7 +4,7 @@ Install LTE firmware upgrade
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/update-gre-address.md b/doc/update-gre-address.md
index 80902b9..de9f622 100644
--- a/doc/update-gre-address.md
+++ b/doc/update-gre-address.md
@@ -4,7 +4,7 @@ Update GRE configuration with dynamic addresses
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/doc/update-tunnelbroker.md b/doc/update-tunnelbroker.md
index 2539e2f..ee0fe98 100644
--- a/doc/update-tunnelbroker.md
+++ b/doc/update-tunnelbroker.md
@@ -4,7 +4,7 @@ Update tunnelbroker configuration
[![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.13-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
+[![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/firmware-upgrade-reboot.rsc b/firmware-upgrade-reboot.rsc
index 169a2e0..e3ca55b 100644
--- a/firmware-upgrade-reboot.rsc
+++ b/firmware-upgrade-reboot.rsc
@@ -1,17 +1,18 @@
#!rsc by RouterOS
# RouterOS script: firmware-upgrade-reboot
-# Copyright (c) 2022-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2022-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# install firmware upgrade, and reboot
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/firmware-upgrade-reboot.md
+# https://rsc.eworm.de/doc/firmware-upgrade-reboot.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global LogPrint;
@@ -19,6 +20,7 @@
:global VersionToNum;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -26,10 +28,12 @@
:if ($RouterBoard->"current-firmware" = $RouterBoard->"upgrade-firmware") do={
$LogPrint info $ScriptName ("Current and upgrade firmware match with version " . \
$RouterBoard->"current-firmware" . ".");
+ :set ExitOK true;
:error true;
}
:if ([ $VersionToNum ($RouterBoard->"current-firmware") ] > [ $VersionToNum ($RouterBoard->"upgrade-firmware") ]) do={
$LogPrint info $ScriptName ("Different firmware version is available, but it is a downgrade. Ignoring.");
+ :set ExitOK true;
:error true;
}
@@ -51,4 +55,6 @@
$LogPrint info $ScriptName ("Firmware upgrade successful, rebooting.");
/system/reboot;
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/fw-addr-lists.rsc b/fw-addr-lists.rsc
index 007282c..0c45f7e 100644
--- a/fw-addr-lists.rsc
+++ b/fw-addr-lists.rsc
@@ -1,17 +1,18 @@
#!rsc by RouterOS
# RouterOS script: fw-addr-lists
-# Copyright (c) 2023-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2023-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.16
#
# download, import and update firewall address-lists
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/fw-addr-lists.md
+# https://rsc.eworm.de/doc/fw-addr-lists.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global FwAddrLists;
@@ -23,6 +24,7 @@
:global HumanReadableNum;
:global LogPrint;
:global LogPrintOnce;
+ :global LogPrintVerbose;
:global ScriptLock;
:global WaitFullyConnected;
@@ -35,11 +37,23 @@
}
}
+ :local GetBranch do={
+ :global EitherOr;
+ :return [ :pick [ :convert transform=md5 to=hex [ :pick $1 0 [ $EitherOr [ :find $1 "/" ] [ :len $1 ] ] ] ] 0 2 ];
+ }
+
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
$WaitFullyConnected;
+ :if ([ :len [ /log/find where topics=({"script"; "warning"}) \
+ message=("\$LogPrintOnce: The message is already in log, scripting subsystem may have crashed before!") ] ] > 0) do={
+ $LogPrintOnce warning $ScriptName ("Scripting subsystem may have crashed, possibly caused by us. Delaying!");
+ :delay 5m;
+ }
+
:local ListComment ("managed by " . $ScriptName);
:foreach FwListName,FwList in=$FwAddrLists do={
@@ -65,7 +79,7 @@
:for I from=1 to=5 do={
:if ($Data = false) do={
- :set Data [ $FetchHuge $ScriptName ($List->"url") $CheckCertificate ];
+ :set Data [ :tolf [ $FetchHuge $ScriptName ($List->"url") $CheckCertificate ] ];
:if ($Data = false) do={
:if ($I < 5) do={
$LogPrint debug $ScriptName ("Failed downloading for list '" . $FwListName . \
@@ -86,41 +100,56 @@
"B for list '" . $FwListName . "' from: " . $List->"url");
}
- :while ([ :len $Data ] != 0) do={
- :local Line [ :pick $Data 0 [ :find $Data "\n" ] ];
- :local Address ([ :pick $Line 0 [ $FindDelim $Line ] ] . ($List->"cidr"));
+ :foreach Line in=[ :deserialize $Data delimiter="\n" from=dsv options=dsv.plain ] do={
+ :set Line ($Line->0);
+ :local Address;
+ :if ([ :pick $Line 0 1 ] = "{") do={
+ :do {
+ :set Address [ :tostr ([ :deserialize from=json $Line ]->"cidr") ];
+ } on-error={ }
+ } else={
+ :set Address ([ :pick $Line 0 [ $FindDelim $Line ] ] . ($List->"cidr"));
+ }
:do {
+ :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={
- :set ($IPv4Addresses->$Address) $TimeOut;
+ :if ($Address ~ "/32\$") do={
+ :set Address [ :pick $Address 0 ([ :len $Address ] - 3) ];
+ }
+ :set ($IPv4Addresses->$Branch->$Address) $TimeOut;
:error true;
}
:if ($Address ~ "^[0-9a-zA-Z]*:[0-9a-zA-Z:\\.]+(/[0-9]{1,3})?\$") do={
- :set ($IPv6Addresses->$Address) $TimeOut;
+ :if ([ :typeof [ :find $Address "/" ] ] = "nil") do={
+ :set Address ($Address . "/128");
+ }
+ :set ($IPv6Addresses->$Branch->$Address) $TimeOut;
:error true;
}
:if ($Address ~ "^[\\.a-zA-Z0-9-]+\\.[a-zA-Z]{2,}\$") do={
- :set ($IPv4Addresses->$Address) $TimeOut;
- :set ($IPv6Addresses->$Address) $TimeOut;
+ :set ($IPv4Addresses->$Branch->$Address) $TimeOut;
+ :set ($IPv6Addresses->$Branch->$Address) $TimeOut;
:error true;
}
} on-error={ }
- :set Data [ :pick $Data ([ :len $Line ] + 1) [ :len $Data ] ];
}
}
:foreach Entry in=[ /ip/firewall/address-list/find where \
list=$FwListName comment=$ListComment ] do={
:local Address [ /ip/firewall/address-list/get $Entry address ];
- :if ([ :typeof ($IPv4Addresses->$Address) ] = "time") do={
- $LogPrint debug $ScriptName ("Renewing IPv4 address in list '" . $FwListName . \
- "' with " . ($IPv4Addresses->$Address) . ": " . $Address);
- /ip/firewall/address-list/set $Entry timeout=($IPv4Addresses->$Address);
- :set ($IPv4Addresses->$Address);
+ :local Branch [ $GetBranch $Address ];
+ :local TimeOut ($IPv4Addresses->$Branch->$Address);
+ :if ([ :typeof $TimeOut ] = "time") do={
+ $LogPrintVerbose debug $ScriptName ("Renewing IPv4 address " . $Address . \
+ " in list '" . $FwListName . "' with " . $TimeOut . ".");
+ /ip/firewall/address-list/set $Entry timeout=$TimeOut;
+ :set ($IPv4Addresses->$Branch->$Address);
:set CntRenew ($CntRenew + 1);
} else={
:if ($Failure = false) do={
- $LogPrint debug $ScriptName ("Removing IPv4 address from list '" . $FwListName . \
- "': " . $Address);
+ $LogPrintVerbose debug $ScriptName ("Removing IPv4 address " . $Address . \
+ " from list '" . $FwListName . ".");
/ip/firewall/address-list/remove $Entry;
:set CntRemove ($CntRemove + 1);
}
@@ -130,47 +159,53 @@
:foreach Entry in=[ /ipv6/firewall/address-list/find where \
list=$FwListName comment=$ListComment ] do={
:local Address [ /ipv6/firewall/address-list/get $Entry address ];
- :if ([ :typeof ($IPv6Addresses->$Address) ] = "time") do={
- $LogPrint debug $ScriptName ("Renewing IPv6 address in list '" . $FwListName . \
- "' with " . ($IPv6Addresses->$Address) . ": " . $Address);
- /ipv6/firewall/address-list/set $Entry timeout=($IPv6Addresses->$Address);
- :set ($IPv6Addresses->$Address);
+ :local Branch [ $GetBranch $Address ];
+ :local TimeOut ($IPv6Addresses->$Branch->$Address);
+ :if ([ :typeof $TimeOut ] = "time") do={
+ $LogPrintVerbose debug $ScriptName ("Renewing IPv6 address " . $Address . \
+ " in list '" . $FwListName . "' with " . $TimeOut . ".");
+ /ipv6/firewall/address-list/set $Entry timeout=$TimeOut;
+ :set ($IPv6Addresses->$Branch->$Address);
:set CntRenew ($CntRenew + 1);
} else={
:if ($Failure = false) do={
- $LogPrint debug $ScriptName ("Removing IPv6 address from list '" . $FwListName . \
- "': " . $Address);
+ $LogPrintVerbose debug $ScriptName ("Removing IPv6 address " . $Address . \
+ " from list '" . $FwListName .".");
/ipv6/firewall/address-list/remove $Entry;
:set CntRemove ($CntRemove + 1);
}
}
}
- :foreach Address,Timeout in=$IPv4Addresses do={
- $LogPrint debug $ScriptName ("Adding IPv4 address to list '" . $FwListName . \
- "' with " . $Timeout . ": " . $Address);
- :do {
- /ip/firewall/address-list/add list=$FwListName comment=$ListComment \
- address=$Address timeout=$Timeout;
- :set ($IPv4Addresses->$Address);
- :set CntAdd ($CntAdd + 1);
- } on-error={
- $LogPrint warning $ScriptName ("Failed to add IPv4 address to list '" . $FwListName . \
- "': " . $Address);
+ :foreach BranchName,Branch in=$IPv4Addresses do={
+ $LogPrintVerbose debug $ScriptName ("Handling branch: " . $BranchName);
+ :foreach Address,Timeout in=$Branch do={
+ $LogPrintVerbose debug $ScriptName ("Adding IPv4 address " . $Address . \
+ " to list '" . $FwListName . "' with " . $Timeout . ".");
+ :onerror Err {
+ /ip/firewall/address-list/add list=$FwListName comment=$ListComment \
+ address=$Address timeout=$Timeout;
+ :set CntAdd ($CntAdd + 1);
+ } do={
+ $LogPrint warning $ScriptName ("Failed to add IPv4 address " . $Address . \
+ " to list '" . $FwListName . "': " . $Err);
+ }
}
}
- :foreach Address,Timeout in=$IPv6Addresses do={
- $LogPrint debug $ScriptName ("Adding IPv6 address to list '" . $FwListName . \
- "' with " . $Timeout . ": " . $Address);
- :do {
- /ipv6/firewall/address-list/add list=$FwListName comment=$ListComment \
- address=$Address timeout=$Timeout;
- :set ($IPv6Addresses->$Address);
- :set CntAdd ($CntAdd + 1);
- } on-error={
- $LogPrint warning $ScriptName ("Failed to add IPv6 address to list '" . $FwListName . \
- "': " . $Address);
+ :foreach BranchName,Branch in=$IPv6Addresses do={
+ $LogPrintVerbose debug $ScriptName ("Handling branch: " . $BranchName);
+ :foreach Address,Timeout in=$Branch do={
+ $LogPrintVerbose debug $ScriptName ("Adding IPv6 address " . $Address . \
+ " to list '" . $FwListName . "' with " . $Timeout . ".");
+ :onerror Err {
+ /ipv6/firewall/address-list/add list=$FwListName comment=$ListComment \
+ address=$Address timeout=$Timeout;
+ :set CntAdd ($CntAdd + 1);
+ } do={
+ $LogPrint warning $ScriptName ("Failed to add IPv6 address " . $Address . \
+ " to list '" . $FwListName . "': " . $Err);
+ }
}
}
@@ -180,4 +215,6 @@
" - renewed: " . [ $HumanReadableNum $CntRenew 1000 ] . \
" - removed: " . [ $HumanReadableNum $CntRemove 1000 ]);
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/global-config-overlay.rsc b/global-config-overlay.rsc
index 9ffd90c..9afaceb 100644
--- a/global-config-overlay.rsc
+++ b/global-config-overlay.rsc
@@ -1,12 +1,12 @@
# Overlay for global configuration by RouterOS Scripts
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# global configuration, custom overlay
-# https://git.eworm.de/cgit/routeros-scripts/about/#editing-configuration
+# https://rsc.eworm.de/#editing-configuration
# Copy relevant configuration from global-config, paste and modify it here.
-# https://git.eworm.de/cgit/routeros-scripts/about/global-config.rsc
+# https://rsc.eworm.de/global-config.rsc
# End of global-config-overlay
diff --git a/global-config.rsc b/global-config.rsc
index 6a37c0c..86d528a 100644
--- a/global-config.rsc
+++ b/global-config.rsc
@@ -1,10 +1,16 @@
#!rsc by RouterOS
# RouterOS script: global-config
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# global configuration
-# https://git.eworm.de/cgit/routeros-scripts/about/
+# https://rsc.eworm.de/
+
+# Warning: Do *NOT* copy this line to overlay!
+:global GlobalConfigReady false;
+# || ... but
+# \||/ start
+# \/ here!
# Set this to 'true' to disable news and change notifications.
:global NoNewsAndChangesNotification false;
@@ -33,6 +39,8 @@
:global TelegramChatId "";
#:global TelegramTokenId "123456:ABCDEF-GHI";
#:global TelegramChatId "12345678";
+# Use this to send notifications to a specific topic in group.
+:global TelegramThreadId "";
# Using telegram-chat you have to define trusted chat ids (not group ids!)
# or user names. Groups allow to chat with devices simultaneously.
#:global TelegramChatIdsTrusted {
@@ -56,10 +64,17 @@
# install the module:
# $ScriptInstallUpdate mod/notification-ntfy
:global NtfyServer "ntfy.sh";
-:global NtfyServerUser [];
-:global NtfyServerPass [];
+:global NtfyServerUser "";
+:global NtfyServerPass "";
+:global NtfyServerToken "";
:global NtfyTopic "";
+# You can send Gotify notifications. Configure these settings and
+# install the module:
+# $ScriptInstallUpdate mod/notification-gotify
+:global GotifyServer "";
+:global GotifyToken "";
+
# It is possible to override e-mail, Telegram, Matrix and Ntfy setting
# for every script. This is done in arrays, where 'Override' is appended
# to the variable name, like this:
@@ -85,46 +100,50 @@
:global BackupUploadUrl "sftp://example.com/backup/";
:global BackupUploadUser "mikrotik";
:global BackupUploadPass "v3ry-s3cr3t";
+# Copy the RouterOS installation to backup partition before feature update.
+:global BackupPartitionCopyBeforeFeatureUpdate false;
# This defines the settings for firewall address-lists (fw-addr-lists).
+# Warning: Mind your device's resources - memory and processing!
:global FwAddrLists {
# "allow"={
-# { url="https://git.eworm.de/cgit/routeros-scripts/plain/fw-addr-lists.d/allow";
-# cert="E1"; timeout=1w };
+# { url="https://rsc.eworm.de/main/fw-addr-lists.d/allow";
+# cert="ISRG Root X2"; timeout=1w };
# };
"block"={
-# { url="https://git.eworm.de/cgit/routeros-scripts/plain/fw-addr-lists.d/block";
-# cert="E1" };
- { url="https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.txt";
- cert="GlobalSign Atlas R3 DV TLS CA 2022 Q3" };
- { url="https://sslbl.abuse.ch/blacklist/sslipblacklist.txt";
- cert="GlobalSign Atlas R3 DV TLS CA 2022 Q3" };
+# { url="https://rsc.eworm.de/main/fw-addr-lists.d/block";
+# cert="ISRG Root X2" };
+ { url="https://raw.githubusercontent.com/stamparm/ipsum/refs/heads/master/levels/4.txt";
+# # higher level (decrease the numerical value) for more addresses, and vice versa
+ cert="USERTrust RSA Certification Authority" };
{ url="https://www.dshield.org/block.txt"; cidr="/24";
- cert="R3" };
-# { url="https://www.spamhaus.org/drop/drop.txt";
-# cert="Cloudflare Inc ECC CA-3" };
-# { url="https://www.spamhaus.org/drop/edrop.txt";
-# cert="Cloudflare Inc ECC CA-3" };
+ cert="ISRG Root X1" };
+ { url="https://lists.blocklist.de/lists/strongips.txt";
+ cert="Certum Trusted Network CA" };
+# { url="https://www.spamhaus.org/drop/drop_v4.json";
+# cert="GTS Root R4" };
+# { url="https://www.spamhaus.org/drop/drop_v6.json";
+# cert="GTS Root R4" };
};
# "mikrotik"={
-# { url="https://git.eworm.de/cgit/routeros-scripts/plain/fw-addr-lists.d/mikrotik";
-# cert="E1"; timeout=1w };
+# { url="https://rsc.eworm.de/main/fw-addr-lists.d/mikrotik";
+# cert="ISRG Root X2"; timeout=1w };
# };
};
:global FwAddrListTimeOut 1d;
# This defines what log messages to filter or include by topic or message
-# text. Regular expressions are supported. Do *NOT* set an empty string,
-# that will filter or include everything!
+# text. Regular expressions are supported. An empty string has a special
+# meaning not to filter or include anything.
# These are filters, so excluding messages from forwarding.
:global LogForwardFilter "(debug|info|packet|raw)";
-:global LogForwardFilterMessage [];
+:global LogForwardFilterMessage "";
#:global LogForwardFilterMessage "message text";
#:global LogForwardFilterMessage "(message text|another text|...)";
# ... and another setting with reverse logic. This includes messages even
# if filtered above.
-:global LogForwardInclude [];
-:global LogForwardIncludeMessage [];
+:global LogForwardInclude "";
+:global LogForwardIncludeMessage "";
#:global LogForwardInclude "account";
#:global LogForwardIncludeMessage "message text";
@@ -182,7 +201,7 @@
# Run different commands with multiple mode-button presses.
:global ModeButton {
- 1="/system/script/run leds-toggle-mode;";
+ 1="/system/leds/settings/set all-leds-off=(({ \"never\"=\"immediate\"; \"immediate\"=\"never\" })->[ get all-leds-off ]);";
2=":global Identity; :global SendNotification; :global SymbolForNotification; \$SendNotification ([ \$SymbolForNotification \"earth\" ] . \"Hello...\") (\"Hello world, \" . \$Identity . \" calling!\");";
3="/system/shutdown;";
4="/system/reboot;";
@@ -212,14 +231,16 @@
:global GpsTrackUrl "https://example.com/index.php";
# This is the base url to fetch scripts from.
-:global ScriptUpdatesBaseUrl "https://git.eworm.de/cgit/routeros-scripts/plain/";
+:global ScriptUpdatesBaseUrl "https://rsc.eworm.de/main/";
# alternative urls - main: stable code - next: currently in development
+#:global ScriptUpdatesBaseUrl "https://rsc.eworm.de/next/";
+#:global ScriptUpdatesBaseUrl "https://git.eworm.de/cgit/routeros-scripts/plain/";
#:global ScriptUpdatesBaseUrl "https://raw.githubusercontent.com/eworm-de/routeros-scripts/main/";
#:global ScriptUpdatesBaseUrl "https://raw.githubusercontent.com/eworm-de/routeros-scripts/next/";
#:global ScriptUpdatesBaseUrl "https://gitlab.com/eworm-de/routeros-scripts/raw/main/";
#:global ScriptUpdatesBaseUrl "https://gitlab.com/eworm-de/routeros-scripts/raw/next/";
:global ScriptUpdatesUrlSuffix "";
-# use next branch with default url (git.eworm.de)
+# use next branch with my git url (git.eworm.de)
#:global ScriptUpdatesUrlSuffix "?h=next";
# Use this for defaults with $ScriptRunOnce
@@ -231,7 +252,7 @@
# This project is developed in private spare time and usage is free of charge
# for you. If you like the scripts and think this is of value for you or your
# business please consider a donation:
-# https://git.eworm.de/cgit/routeros-scripts/about/#donate
+# https://rsc.eworm.de/#donate
# Enable this to silence donation hint.
:global IDonate false;
@@ -249,14 +270,20 @@
"cert2-cn"="4n0th3r-s3cr3t";
};
+# /\ Warning: Do *NOT* copy
+# /\7\ the code below to overlay!
+# /_()_\ Things *will* break!
+#
# load custom settings from overlay and snippets
-# Warning: Do *NOT* copy this code to overlay!
:foreach Script in=([ /system/script/find where name="global-config-overlay" ], \
[ /system/script/find where name~"^global-config-overlay.d/" ]) do={
- :do {
+ :onerror Err {
/system/script/run $Script;
- } on-error={
+ } do={
:log error ("Loading configuration from overlay or snippet " . \
- [ /system/script/get $Script name ] . " failed!");
+ [ /system/script/get $Script name ] . " failed: " . $Err);
}
}
+
+# signal we are ready
+:set GlobalConfigReady true;
diff --git a/global-functions.rsc b/global-functions.rsc
index b1833b1..829cbf2 100644
--- a/global-functions.rsc
+++ b/global-functions.rsc
@@ -1,18 +1,21 @@
#!rsc by RouterOS
# RouterOS script: global-functions
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, fetch, scheduler
#
# global functions
-# https://git.eworm.de/cgit/routeros-scripts/about/
+# https://rsc.eworm.de/
:local ScriptName [ :jobname ];
-# expected configuration version
-:global ExpectedConfigVersion 127;
+# Git commit id & info, expected configuration version
+:global CommitId "unknown";
+:global CommitInfo "unknown";
+:global ExpectedConfigVersion 138;
# global variables not to be changed by user
:global GlobalFunctionsReady false;
@@ -32,8 +35,11 @@
:global DownloadPackage;
:global EitherOr;
:global EscapeForRegEx;
+:global ExitError;
:global FetchHuge;
:global FetchUserAgentStr;
+:global FileExists;
+:global FileGet;
:global FormatLine;
:global FormatMultiLines;
:global GetMacVendor;
@@ -51,6 +57,7 @@
:global IsTimeSync;
:global LogPrint;
:global LogPrintOnce;
+:global LogPrintVerbose;
:global MAX;
:global MIN;
:global MkDir;
@@ -61,6 +68,8 @@
:global ProtocolStrip;
:global RandomDelay;
:global RequiredRouterOS;
+:global RmDir;
+:global RmFile;
:global ScriptFromTerminal;
:global ScriptInstallUpdate;
:global ScriptLock;
@@ -107,6 +116,16 @@
"is configured to download certificate CRLs to system!");
}
+ :if ([ :len $CommonName ] = 0) do={
+ $LogPrint warning $0 ("No CommonName given!");
+ :return false;
+ }
+
+ :if (([ /certificate/settings/get ]->"builtin-trust-anchors") = "trusted" && \
+ [[ :parse (":return [ :len [ /certificate/builtin/find where common-name=\"" . $CommonName . "\" ] ]") ]] > 0) do={
+ :return true;
+ }
+
:if ([ :len [ /certificate/find where common-name=$CommonName ] ] = 0) do={
$LogPrint info $0 ("Certificate with CommonName '" . $CommonName . "' not available.");
:if ([ $CertificateDownload $CommonName ] = false) do={
@@ -135,42 +154,75 @@
:global ScriptUpdatesBaseUrl;
:global ScriptUpdatesUrlSuffix;
+ :global CertificateAvailable;
:global CertificateNameByCN;
:global CleanName;
:global FetchUserAgentStr;
:global LogPrint;
+ :global RmFile;
:global WaitForFile;
$LogPrint info $0 ("Downloading and importing certificate with " . \
"CommonName '" . $CommonName . "'.");
+ :local FileName ([ $CleanName $CommonName ] . ".pem");
:do {
- :local FileName ([ $CleanName $CommonName ] . ".pem");
/tool/fetch check-certificate=yes-without-crl http-header-field=({ [ $FetchUserAgentStr $0 ] }) \
($ScriptUpdatesBaseUrl . "certs/" . $FileName . $ScriptUpdatesUrlSuffix) \
dst-path=$FileName as-value;
$WaitForFile $FileName;
- /certificate/import file-name=$FileName passphrase="" as-value;
- :delay 1s;
- /file/remove [ find where name=$FileName ];
-
- :foreach Cert in=[ /certificate/find where name~("^" . $FileName . "_[0-9]+\$") ] do={
- $CertificateNameByCN [ /certificate/get $Cert common-name ];
- }
} on-error={
- $LogPrint warning $0 ("Failed importing certificate with CommonName '" . $CommonName . "'!");
+ $LogPrint warning $0 ("Failed downloading certificate with CommonName '" . $CommonName . \
+ "' from repository! Trying fallback to mkcert.org...");
+ :do {
+ :if ([ :len [ /certificate/find where common-name="ISRG Root X1" ] ] = 0) do={
+ $LogPrint error $0 ("Required certificate is not available.");
+ :return false;
+ }
+ /tool/fetch check-certificate=yes-without-crl http-header-field=({ [ $FetchUserAgentStr $0 ] }) \
+ "https://mkcert.org/generate/" http-data=[ :serialize to=json ({ $CommonName }) ] \
+ dst-path=$FileName as-value;
+ $WaitForFile $FileName;
+ :if ([ /file/get $FileName size ] = 0) do={
+ $RmFile $FileName;
+ :error false;
+ }
+ } on-error={
+ $LogPrint warning $0 ("Failed downloading certificate with CommonName '" . $CommonName . "'!");
+ :return false;
+ }
+ }
+
+ /certificate/import file-name=$FileName passphrase="" as-value;
+ :delay 1s;
+ $RmFile $FileName;
+
+ :if ([ :len [ /certificate/find where common-name=$CommonName ] ] = 0) do={
+ /certificate/remove [ find where name~("^" . $FileName . "_[0-9]+\$") ];
+ $LogPrint warning $0 ("Certificate with CommonName '" . $CommonName . "' still unavailable!");
:return false;
}
+
+ :foreach Cert in=[ /certificate/find where name~("^" . $FileName . "_[0-9]+\$") ] do={
+ $CertificateNameByCN [ /certificate/get $Cert common-name ];
+ }
:return true;
}
# name a certificate by its common-name
:set CertificateNameByCN do={
- :local CommonName [ :tostr $1 ];
+ :local Match [ :tostr $1 ];
:global CleanName;
+ :global LogPrint;
- :local Cert [ /certificate/find where common-name=$CommonName ];
+ :local Cert ([ /certificate/find where (common-name=$Match or fingerprint=$Match or name=$Match) ]->0);
+ :if ([ :len $Cert ] = 0) do={
+ $LogPrint warning $0 ("No matching certificate found.");
+ :return false;
+ }
+ :local CommonName [ /certificate/get $Cert common-name ];
/certificate/set $Cert name=[ $CleanName $CommonName ];
+ :return true;
}
# multiply given character(s)
@@ -229,7 +281,7 @@
:for I from=0 to=([ :len $Input ] - 1) do={
:local Char [ :pick $Input $I ];
- :if ([ :typeof [ find "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-" $Char ] ] = "nil") do={
+ :if ([ :typeof [ find "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" $Char ] ] = "nil") do={
:do {
:if ([ :len $Return ] = 0) do={
:error true;
@@ -249,6 +301,8 @@
# get readable device info
:set DeviceInfo do={
+ :global CommitId;
+ :global CommitInfo;
:global ExpectedConfigVersion;
:global Identity;
@@ -270,16 +324,19 @@
([ $FormatLine "Location" ($Snmp->"location") ] . "\n") ] . \
[ $IfThenElse ([ :len ($Snmp->"contact") ] > 0) \
([ $FormatLine "Contact" ($Snmp->"contact") ] . "\n") ] . \
- [ $FormatLine "Board name" ($Resource->"board-name") ] . "\n" . \
- [ $FormatLine "Architecture" ($Resource->"architecture-name") ] . "\n" . \
+ "Hardware:\n" . \
+ [ $FormatLine " Board" ($Resource->"board-name") ] . "\n" . \
+ [ $FormatLine " Arch" ($Resource->"architecture-name") ] . "\n" . \
[ $IfThenElse ($RouterBoard->"routerboard" = true) \
- ([ $FormatLine "Model" ($RouterBoard->"model") ] . \
+ ([ $FormatLine " Model" ($RouterBoard->"model") ] . \
[ $IfThenElse ([ :len ($RouterBoard->"revision") ] > 0) \
(" " . $RouterBoard->"revision") ] . "\n" . \
- [ $FormatLine "Serial number" ($RouterBoard->"serial-number") ] . "\n") ] . \
- [ $IfThenElse ([ :len ($License->"level") ] > 0) \
- ([ $FormatLine "License" ($License->"level") ] . "\n") ] . \
+ [ $FormatLine " Serial" ($RouterBoard->"serial-number") ] . "\n") ] . \
+ [ $IfThenElse ([ :len ($License->"nlevel") ] > 0) \
+ ([ $FormatLine " License" ("level " . ($License->"nlevel")) ] . "\n") ] . \
"RouterOS:\n" . \
+ [ $IfThenElse ([ :len ($License->"level") ] > 0) \
+ ([ $FormatLine " License" ("level " . ($License->"level")) ] . "\n") ] . \
[ $FormatLine " Channel" ($Update->"channel") ] . "\n" . \
[ $FormatLine " Installed" ($Update->"installed-version") ] . "\n" . \
[ $IfThenElse ([ :typeof ($Update->"latest-version") ] != "nothing" && \
@@ -289,16 +346,14 @@
$RouterBoard->"current-firmware" != $RouterBoard->"upgrade-firmware") \
([ $FormatLine " Firmware" ($RouterBoard->"current-firmware") ] . "\n") ] . \
"RouterOS-Scripts:\n" . \
+ [ $IfThenElse ($CommitId != "unknown") \
+ ([ $FormatLine " Commit" ($CommitInfo . "/" . [ :pick $CommitId 0 8 ]) ] . "\n") ] . \
[ $FormatLine " Version" $ExpectedConfigVersion ]);
}
# convert line endings, DOS -> UNIX
:set Dos2Unix do={
- :local Input [ :tostr $1 ];
-
- :global CharacterReplace;
-
- :return [ $CharacterReplace $Input ("\r\n") ("\n") ];
+ :return [ :tolf [ :tostr $1 ] ];
}
# download package from upgrade server
@@ -310,8 +365,10 @@
:global CertificateAvailable;
:global CleanFilePath;
+ :global FileExists;
:global LogPrint;
:global MkDir;
+ :global RmFile;
:global WaitForFile;
:if ([ :len $PkgName ] = 0) do={ :return false; }
@@ -329,12 +386,12 @@
:return false;
}
- :if ([ :len [ /file/find where name=$PkgDest type="package" ] ] > 0) do={
+ :if ([ $FileExists $PkgDest "package" ] = true) do={
$LogPrint info $0 ("Package file " . $PkgName . " already exists.");
:return true;
}
- :if ([ $CertificateAvailable "R3" ] = false) do={
+ :if ([ $CertificateAvailable "ISRG Root X1" ] = false) do={
$LogPrint error $0 ("Downloading required certificate failed.");
:return false;
}
@@ -342,25 +399,22 @@
:local Url ("https://upgrade.mikrotik.com/routeros/" . $PkgVer . "/" . $PkgFile);
$LogPrint info $0 ("Downloading package file '" . $PkgName . "'...");
$LogPrint debug $0 ("... from url: " . $Url);
- :local Retry 3;
- :while ($Retry > 0) do={
- :do {
- /tool/fetch check-certificate=yes-without-crl $Url dst-path=$PkgDest;
- $WaitForFile $PkgDest;
- :if ([ /file/get [ find where name=$PkgDest ] type ] = "package") do={
- :return true;
- }
- } on-error={
- $LogPrint debug $0 ("Downloading package file failed.");
- }
+ :onerror Err {
+ /tool/fetch check-certificate=yes-without-crl $Url dst-path=$PkgDest;
+ $WaitForFile $PkgDest;
+ } do={
+ $LogPrint warning $0 ("Downloading package file '" . $PkgName . "' failed: " . $Err);
+ :return false;
+ }
- /file/remove [ find where name=$PkgDest ];
- :set Retry ($Retry - 1);
+ :if ([ $FileExists $PkgDest "package" ] = false) do={
+ $LogPrint warning $0 ("Downloaded file is not a package, removing.");
+ $RmFile $PkgDest;
+ :return false;
}
- $LogPrint warning $0 ("Downloading package file '" . $PkgName . "' failed.");
- :return false;
+ :return true;
}
# return either first (if "true") or second
@@ -373,6 +427,7 @@
:if ([ :typeof $1 ] = "time") do={
:return [ $IfThenElse ($1 > 0s) $1 $2 ];
}
+ # this works for boolean values, literal ones with parentheses
:return [ $IfThenElse ([ :len [ :tostr $1 ] ] > 0) $1 $2 ];
}
@@ -398,11 +453,27 @@
:return $Return;
}
+# simple macro to print error message on unintentional error
+:set ExitError do={
+ :local ExitOK [ :tostr $1 ];
+ :local Name [ :tostr $2 ];
+ :local Error [ :tostr $3 ];
+
+ :global IfThenElse;
+ :global LogPrint;
+
+ :if ($ExitOK = "false") do={
+ $LogPrint error $Name ([ $IfThenElse ([ :pick $Name 0 1 ] = "\$") \
+ "Function" "Script" ] . " '" . $Name . "' exited with error" . \
+ [ $IfThenElse (!($Error ~ "^(|true|false)\$")) (": " . $Error) "." ]);
+ }
+}
+
# fetch huge data to file, read in chunks
:set FetchHuge do={
- :local ScriptName [ :tostr $1 ];
- :local Url [ :tostr $2 ];
- :local CheckCert [ :tobool $3 ];
+ :local ScriptName [ :tostr $1 ];
+ :local Url [ :tostr $2 ];
+ :local CheckCert [ :tostr $3 ];
:global CleanName;
:global FetchUserAgentStr;
@@ -410,9 +481,11 @@
:global IfThenElse;
:global LogPrint;
:global MkDir;
+ :global RmDir;
+ :global RmFile;
:global WaitForFile;
- :set CheckCert [ $IfThenElse ($CheckCert = false) "no" "yes-without-crl" ];
+ :set CheckCert [ $IfThenElse ($CheckCert = "false") "no" "yes-without-crl" ];
:local DirName ("tmpfs/" . [ $CleanName $ScriptName ]);
:if ([ $MkDir $DirName ] = false) do={
@@ -421,15 +494,15 @@
}
:local FileName ($DirName . "/" . [ $CleanName $0 ] . "-" . [ $GetRandom20CharAlNum ]);
- :do {
+ :onerror Err {
/tool/fetch check-certificate=$CheckCert $Url dst-path=$FileName \
http-header-field=({ [ $FetchUserAgentStr $ScriptName ] }) as-value;
- } on-error={
+ } do={
:if ([ $WaitForFile $FileName 500ms ] = true) do={
- /file/remove $FileName;
+ $RmFile $FileName;
}
- $LogPrint debug $0 ("Failed downloading from: " . $Url);
- /file/remove $DirName;
+ $LogPrint debug $0 ("Failed downloading from " . $Url . " - " . $Err);
+ $RmDir $DirName;
:return false;
}
$WaitForFile $FileName;
@@ -437,11 +510,15 @@
:local FileSize [ /file/get $FileName size ];
:local Return "";
:local VarSize 0;
- :while ($VarSize < $FileSize) do={
+ :while ($VarSize != $FileSize) do={
:set Return ($Return . ([ /file/read offset=$VarSize chunk-size=32768 file=$FileName as-value ]->"data"));
+ :set FileSize [ /file/get $FileName size ];
:set VarSize [ :len $Return ];
+ :if ($VarSize > $FileSize) do={
+ :delay 100ms;
+ }
}
- /file/remove $DirName;
+ $RmDir $DirName;
:return $Return;
}
@@ -455,6 +532,47 @@
$Resource->"architecture-name" . " " . $Caller . "/Fetch (https://rsc.eworm.de/)");
}
+# check for existence of file, optionally with type
+:set FileExists do={
+ :local FileName [ :tostr $1 ];
+ :local Type [ :tostr $2 ];
+
+ :global FileGet;
+
+ :local FileVal [ $FileGet $FileName ];
+ :if ($FileVal = false) do={
+ :return false;
+ }
+
+ :if ([ :len ($FileVal->"size") ] = 0) do={
+ :return false;
+ }
+
+ :if ([ :len $Type ] = 0 || $FileVal->"type" = $Type) do={
+ :return true;
+ }
+
+ :return false;
+}
+
+# get file properties in array, or false on error
+:set FileGet do={
+ :local FileName [ :tostr $1 ];
+
+ :global WaitForFile;
+
+ :if ([ $WaitForFile $FileName 0s ] = false) do={
+ :return false;
+ }
+
+ :local FileVal false;
+ :do {
+ :set FileVal [ /file/get $FileName ];
+ } on-error={ }
+
+ :return $FileVal;
+}
+
# format a line for output
:set FormatLine do={
:local Key [ :tostr $1 ];
@@ -509,7 +627,7 @@
}
:do {
- :if ([ $CertificateAvailable "GTS CA 1P5" ] = false) do={
+ :if ([ $CertificateAvailable "GTS Root R4" ] = false) do={
$LogPrint warning $0 ("Downloading required certificate failed.");
:error false;
}
@@ -517,12 +635,12 @@
("https://api.macvendors.com/" . [ :pick $Mac 0 8 ]) output=user as-value ]->"data");
:return $Vendor;
} on-error={
- :do {
+ :onerror Err {
/tool/fetch check-certificate=yes-without-crl ("https://api.macvendors.com/") \
output=none as-value;
$LogPrint debug $0 ("The mac vendor is not known in database.");
- } on-error={
- $LogPrint warning $0 ("Failed getting mac vendor.");
+ } do={
+ $LogPrint warning $0 ("Failed getting mac vendor: " . $Err);
}
:return "unknown vendor";
}
@@ -685,10 +803,10 @@
:return true;
}
+ :local Uptime [ /system/resource/get uptime ];
:if ([ :typeof $IsTimeSyncResetNtp ] = "nothing") do={
- :set IsTimeSyncResetNtp 0s;
+ :set IsTimeSyncResetNtp $Uptime;
}
- :local Uptime [ /system/resource/get uptime ];
:if ($Uptime - $IsTimeSyncResetNtp < 3m) do={
:return false;
}
@@ -786,6 +904,9 @@
:return true;
}
+# The function $LogPrintVerbose is declared, but has no code, intentionally.
+# https://rsc.eworm.de/DEBUG.md#verbose-output
+
# get max value
:set MAX do={
:if ($1 > $2) do={ :return $1; }
@@ -803,24 +924,31 @@
:local Path [ :tostr $1 ];
:global CleanFilePath;
+ :global FileGet;
:global LogPrint;
+ :global RmDir;
:global WaitForFile;
:local MkTmpfs do={
:global LogPrint;
:global WaitForFile;
- :if ([ :len [ /disk/find where slot=tmpfs type=tmpfs ] ] = 1) do={
+ :local TmpFs [ /disk/find where slot=tmpfs type=tmpfs ];
+ :if ([ :len $TmpFs ] = 1) do={
+ :if ([ /disk/get $TmpFs disabled ] = true) do={
+ $LogPrint info $0 ("The tmpfs is disabled, enabling.");
+ /disk/enable $TmpFs;
+ }
:return true;
}
$LogPrint info $0 ("Creating disk of type tmpfs.");
- /file/remove [ find where name="tmpfs" type="directory" ];
- :do {
+ $RmDir "tmpfs";
+ :onerror Err {
/disk/add slot=tmpfs type=tmpfs tmpfs-max-size=([ /system/resource/get total-memory ] / 3);
$WaitForFile "tmpfs";
- } on-error={
- $LogPrint warning $0 ("Creating disk of type tmpfs failed!");
+ } do={
+ $LogPrint warning $0 ("Creating disk of type tmpfs failed: " . $Err);
:return false;
}
:return true;
@@ -832,7 +960,11 @@
:return true;
}
- :if ([ :len [ /file/find where name=$Path type="directory" ] ] = 1) do={
+ $LogPrint debug $0 ("Making directory: " . $Path);
+
+ :local PathVal [ $FileGet $Path ];
+ :if ($PathVal->"type" = "directory") do={
+ $LogPrint debug $0 ("... which already exists.");
:return true;
}
@@ -842,13 +974,11 @@
}
}
- :do {
- :local File ($Path . "/file");
- /file/add name=$File;
- $WaitForFile $File;
- /file/remove $File;
- } on-error={
- $LogPrint warning $0 ("Making directory '" . $Path . "' failed!");
+ :onerror Err {
+ /file/add type="directory" name=$Path;
+ $WaitForFile $Path;
+ } do={
+ $LogPrint warning $0 ("Making directory '" . $Path . "' failed: " . $Err);
:return false;
}
@@ -872,14 +1002,24 @@
# parse key value store
:set ParseKeyValueStore do={
:local Source $1;
+
+ :if ([ :pick $Source 0 1 ] = "{") do={
+ :do {
+ :return [ :deserialize from=json $Source ];
+ } on-error={ }
+ }
+
:if ([ :typeof $Source ] != "array") do={
:set Source [ :tostr $1 ];
}
:local Result ({});
:foreach KeyValue in=[ :toarray $Source ] do={
:if ([ :find $KeyValue "=" ]) do={
- :set ($Result->[ :pick $KeyValue 0 [ :find $KeyValue "=" ] ]) \
- [ :pick $KeyValue ([ :find $KeyValue "=" ] + 1) [ :len $KeyValue ] ];
+ :local Key [ :pick $KeyValue 0 [ :find $KeyValue "=" ] ];
+ :local Value [ :pick $KeyValue ([ :find $KeyValue "=" ] + 1) [ :len $KeyValue ] ];
+ :if ($Value="true") do={ :set Value true; }
+ :if ($Value="false") do={ :set Value false; }
+ :set ($Result->$Key) $Value;
} else={
:set ($Result->$KeyValue) true;
}
@@ -889,11 +1029,7 @@
# print lines with trailing carriage return
:set PrettyPrint do={
- :local Input [ :tostr $1 ];
-
- :global Unix2Dos;
-
- :put [ $Unix2Dos $Input ];
+ :put [ :tocrlf [ :tostr $1 ] ];
}
# strip protocol from from url string
@@ -948,6 +1084,64 @@
:return true;
}
+# remove directory
+:set RmDir do={
+ :local DirName [ :tostr $1 ];
+
+ :global FileGet;
+ :global LogPrint;
+
+ $LogPrint debug $0 ("Removing directory: ". $DirName);
+
+ :local DirVal [ $FileGet $DirName ];
+ :if ($DirVal = false) do={
+ $LogPrint debug $0 ("... which does not exist.");
+ :return true;
+ }
+
+ :if ($DirVal->"type" != "directory") do={
+ $LogPrint error $0 ("Directory '" . $DirName . "' is not a directory.");
+ :return false;
+ }
+
+ :onerror Err {
+ /file/remove $DirName;
+ } do={
+ $LogPrint error $0 ("Removing directory '" . $DirName . "' failed: " . $Err);
+ :return false;
+ }
+ :return true;
+}
+
+# remove file
+:set RmFile do={
+ :local FileName [ :tostr $1 ];
+
+ :global FileGet;
+ :global LogPrint;
+
+ $LogPrint debug $0 ("Removing file: ". $FileName);
+
+ :local FileVal [ $FileGet $FileName ];
+ :if ($FileVal = false) do={
+ $LogPrint debug $0 ("... which does not exist.");
+ :return true;
+ }
+
+ :if ($FileVal->"type" = "directory" || $FileVal->"type" = "disk") do={
+ $LogPrint error $0 ("File '" . $FileName . "' is not a file.");
+ :return false;
+ }
+
+ :onerror Err {
+ /file/remove $FileName;
+ } do={
+ $LogPrint error $0 ("Removing file '" . $FileName . "' failed: " . $Err);
+ :return false;
+ }
+ :return true;
+}
+
# check if script is run from terminal
:set ScriptFromTerminal do={
:local Script [ :tostr $1 ];
@@ -975,15 +1169,20 @@
}
# install new scripts, update existing scripts
-:set ScriptInstallUpdate do={
+:set ScriptInstallUpdate do={ :onerror Err {
:local Scripts [ :toarray $1 ];
:local NewComment [ :tostr $2 ];
+ :global CommitId;
+ :global CommitInfo;
:global ExpectedConfigVersion;
+ :global GlobalConfigReady;
+ :global GlobalFunctionsReady;
:global Identity;
:global IDonate;
:global NoNewsAndChangesNotification;
:global ScriptUpdatesBaseUrl;
+ :global ScriptUpdatesCRLF;
:global ScriptUpdatesUrlSuffix;
:global CertificateAvailable;
@@ -999,7 +1198,7 @@
:global SymbolForNotification;
:global ValidateSyntax;
- :if ([ $CertificateAvailable "E1" ] = false) do={
+ :if ([ $CertificateAvailable "ISRG Root X2" ] = false) do={
$LogPrint warning $0 ("Downloading certificate failed, trying without.");
}
@@ -1010,9 +1209,18 @@
}
}
+ :local CommitIdBefore $CommitId;
:local ExpectedConfigVersionBefore $ExpectedConfigVersion;
- :local ReloadGlobalFunctions false;
- :local ReloadGlobalConfig false;
+ :local ReloadGlobal false;
+ :local DeviceMode [ /system/device-mode/get ];
+
+ :local CheckSums ({});
+ :do {
+ :local Url ($ScriptUpdatesBaseUrl . "checksums.json" . $ScriptUpdatesUrlSuffix);
+ $LogPrint debug $0 ("Fetching checksums from url: " . $Url);
+ :set CheckSums [ :deserialize from=json ([ /tool/fetch check-certificate=yes-without-crl \
+ http-header-field=({ [ $FetchUserAgentStr $0 ] }) $Url output=user as-value ]->"data") ];
+ } on-error={ }
:foreach Script in=[ /system/script/find where source~"^#!rsc by RouterOS\r?\n" ] do={
:local ScriptVal [ /system/script/get $Script ];
@@ -1027,8 +1235,26 @@
}
}
- :if (!($ScriptInfo->"ignore" = true)) do={
- :do {
+ :do {
+ :if ($ScriptInfo->"ignore" = true) do={
+ $LogPrint debug $0 ("Ignoring script '" . $ScriptVal->"name" . "', as requested.");
+ :error true;
+ }
+
+ :local CheckSum ($CheckSums->($ScriptVal->"name"));
+ :if ([ :len ($ScriptInfo->"base-url") ] = 0 && [ :len ($ScriptInfo->"url-suffix") ] = 0 && \
+ [ :convert transform=md5 to=hex [ :tolf ($ScriptVal->"source") ] ] = $CheckSum) do={
+ $LogPrint debug $0 ("Checksum for script '" . $ScriptVal->"name" . "' matches, ignoring.");
+ :error true;
+ }
+
+ :if ([ :len ($ScriptInfo->"certificate") ] > 0) do={
+ :if ([ $CertificateAvailable ($ScriptInfo->"certificate") ] = false) do={
+ $LogPrint warning $0 ("Downloading certificate failed, trying without.");
+ }
+ }
+
+ :onerror Err {
:local BaseUrl [ $EitherOr ($ScriptInfo->"base-url") $ScriptUpdatesBaseUrl ];
:local UrlSuffix [ $EitherOr ($ScriptInfo->"url-suffix") $ScriptUpdatesUrlSuffix ];
:local Url ($BaseUrl . $ScriptVal->"name" . ".rsc" . $UrlSuffix);
@@ -1036,70 +1262,86 @@
:local Result [ /tool/fetch check-certificate=yes-without-crl \
http-header-field=({ [ $FetchUserAgentStr $0 ] }) $Url output=user as-value ];
:if ($Result->"status" = "finished") do={
- :set SourceNew ($Result->"data");
+ :set SourceNew [ :tolf ($Result->"data") ];
}
- } on-error={
+ } do={
+ $LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . "': " . $Err);
:if ($ScriptVal->"source" = "#!rsc by RouterOS\n") do={
- $LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . \
- "', removing dummy. Typo on installation?");
+ $LogPrint warning $0 ("Removing dummy. Typo on installation?");
/system/script/remove $Script;
- } else={
- $LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . "'!");
}
+ :error false;
}
- }
- :if ([ :len $SourceNew ] > 0) do={
- :if ($SourceNew != $ScriptVal->"source") do={
- :if ([ :pick $SourceNew 0 18 ] = "#!rsc by RouterOS\n") do={
- :local Required ([ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires RouterOS, ") ] ]->"version");
- :if ([ $RequiredRouterOS $0 [ $EitherOr $Required "0.0" ] false ] = true) do={
- :if ([ $ValidateSyntax $SourceNew ] = true) do={
- $LogPrint info $0 ("Updating script: " . $ScriptVal->"name");
- /system/script/set owner=($ScriptVal->"name") source=$SourceNew $Script;
- :if ($ScriptVal->"name" = "global-config") do={
- :set ReloadGlobalConfig true;
- }
- :if ($ScriptVal->"name" = "global-functions" || $ScriptVal->"name" ~ ("^mod/.")) do={
- :set ReloadGlobalFunctions true;
- }
- } else={
- $LogPrint warning $0 ("Syntax validation for script '" . $ScriptVal->"name" . \
- "' failed! Ignoring!");
- }
- } else={
- $LogPrintOnce warning $0 ("The script '" . $ScriptVal->"name" . "' requires RouterOS " . \
- $Required . ", which is not met by your installation. Ignoring!");
- }
- } else={
- $LogPrint warning $0 ("Looks like new script '" . $ScriptVal->"name" . \
+ :if ([ :len $SourceNew ] = 0) do={
+ $LogPrint debug $0 ("No update for script '" . $ScriptVal->"name" . "'.");
+ :error false;
+ }
+
+ :local SourceCRLF [ :tocrlf $SourceNew ];
+ :if ($SourceNew = $ScriptVal->"source" || $SourceCRLF = $ScriptVal->"source") do={
+ $LogPrint debug $0 ("Script '" . $ScriptVal->"name" . "' did not change.");
+ :error false;
+ }
+
+ :if ([ :pick $SourceNew 0 18 ] != "#!rsc by RouterOS\n") do={
+ $LogPrint warning $0 ("Looks like new script '" . $ScriptVal->"name" . \
"' is not valid (missing shebang). Ignoring!");
+ :error false;
+ }
+
+ :local RequiredROS ([ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires RouterOS, ") ] ]->"version");
+ :if ([ $RequiredRouterOS $0 [ $EitherOr $RequiredROS "0.0" ] false ] = false) do={
+ $LogPrintOnce warning $0 ("The script '" . $ScriptVal->"name" . "' requires RouterOS " . \
+ $RequiredROS . ", which is not met by your installation. Ignoring!");
+ :error false;
+ }
+
+ :local RequiredDM [ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires device-mode, ") ] ];
+ :local MissingDM ({});
+ :foreach Feature,Value in=$RequiredDM do={
+ :if ([ :typeof ($DeviceMode->$Feature) ] = "bool" && ($DeviceMode->$Feature) = false) do={
+ :set MissingDM ($MissingDM, $Feature);
}
- } else={
- $LogPrint debug $0 ("Script '" . $ScriptVal->"name" . "' did not change.");
}
- } else={
- $LogPrint debug $0 ("No update for script '" . $ScriptVal->"name" . "'.");
- }
+ :if ([ :len $MissingDM ] > 0) do={
+ $LogPrintOnce warning $0 ("The script '" . $ScriptVal->"name" . "' requires disabled " . \
+ "device-mode features (" . [ :tostr $MissingDM ] . "). Ignoring!");
+ :error false;
+ }
+
+ :if ([ $ValidateSyntax $SourceNew ] = false) do={
+ $LogPrint warning $0 ("Syntax validation for script '" . $ScriptVal->"name" . "' failed! Ignoring!");
+ :error false;
+ }
+
+ $LogPrint info $0 ("Updating script: " . $ScriptVal->"name");
+ /system/script/set owner=($ScriptVal->"name") \
+ source=[ $IfThenElse ($ScriptUpdatesCRLF = true) $SourceCRLF $SourceNew ] $Script;
+ :if ($ScriptVal->"name" = "global-config" || \
+ $ScriptVal->"name" = "global-functions" || \
+ $ScriptVal->"name" ~ ("^mod/.")) do={
+ :set ReloadGlobal true;
+ }
+ } on-error={ }
}
- :if ($ReloadGlobalFunctions = true) do={
- $LogPrint info $0 ("Reloading global functions.");
- :do {
+ :if ($ReloadGlobal = true) do={
+ $LogPrint info $0 ("Reloading global configuration and functions.");
+ :set GlobalConfigReady false;
+ :set GlobalFunctionsReady false;
+ :delay 1s;
+
+ :onerror Err {
+ /system/script/run global-config;
/system/script/run global-functions;
- } on-error={
- $LogPrint error $0 ("Reloading global functions failed!");
+ } do={
+ $LogPrint error $0 ("Reloading global configuration and functions failed! " . $Err);
}
}
- :if ($ReloadGlobalConfig = true) do={
- $LogPrint info $0 ("Reloading global configuration.");
- :do {
- /system/script/run global-config;
- } on-error={
- $LogPrint error $0 ("Reloading global configuration failed!" . \
- " Syntax error or missing overlay?");
- }
+ :if ($CommitId != "unknown" && $CommitIdBefore != $CommitId) do={
+ $LogPrint info $0 ("Updated to commit: " . $CommitInfo . "/" . [ :pick $CommitId 0 8 ]);
}
:if ($ExpectedConfigVersionBefore > $ExpectedConfigVersion) do={
@@ -1113,7 +1355,7 @@
:global GlobalConfigMigration;
:local ChangeLogCode;
- :do {
+ :onerror Err {
:local Url ($ScriptUpdatesBaseUrl . "news-and-changes.rsc" . $ScriptUpdatesUrlSuffix);
$LogPrint debug $0 ("Fetching news, changes and migration: " . $Url);
:local Result [ /tool/fetch check-certificate=yes-without-crl \
@@ -1121,16 +1363,16 @@
:if ($Result->"status" = "finished") do={
:set ChangeLogCode ($Result->"data");
}
- } on-error={
- $LogPrint warning $0 ("Failed fetching news, changes and migration!");
+ } do={
+ $LogPrint warning $0 ("Failed fetching news, changes and migration: " . $Err);
}
:if ([ :len $ChangeLogCode ] > 0) do={
:if ([ $ValidateSyntax $ChangeLogCode ] = true) do={
- :do {
+ :onerror Err {
[ :parse $ChangeLogCode ];
- } on-error={
- $LogPrint warning $0 ("The changelog failed to run!");
+ } do={
+ $LogPrint warning $0 ("The changelog failed to run: " . $Err);
}
} else={
$LogPrint warning $0 ("The changelog failed syntax validation!");
@@ -1140,18 +1382,24 @@
:if ([ :len $GlobalConfigMigration ] > 0) do={
:for I from=($ExpectedConfigVersionBefore + 1) to=$ExpectedConfigVersion do={
:local Migration ($GlobalConfigMigration->[ :tostr $I ]);
- :if ([ :typeof $Migration ] = "str") do={
- :if ([ $ValidateSyntax $Migration ] = true) do={
- $LogPrint info $0 ("Applying migration for change " . $I . ": " . $Migration);
- :do {
- [ :parse $Migration ];
- } on-error={
- $LogPrint warning $0 ("Migration code for change " . $I . " failed to run!");
- }
- } else={
+ :do {
+ :if ([ :typeof $Migration ] != "str") do={
+ $LogPrint debug $0 ("Migration code for change " . $I . " is not available.");
+ :error false;
+ }
+
+ :if ([ $ValidateSyntax $Migration ] = false) do={
$LogPrint warning $0 ("Migration code for change " . $I . " failed syntax validation!");
+ :error false;
}
- }
+
+ $LogPrint info $0 ("Applying migration for change " . $I . ": " . $Migration);
+ :onerror Err {
+ [ :parse $Migration ];
+ } do={
+ $LogPrint warning $0 ("Migration code for change " . $I . " failed to run: " . $Err);
+ }
+ } on-error={ }
}
}
@@ -1191,12 +1439,14 @@
:set GlobalConfigChanges;
:set GlobalConfigMigration;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# lock script against multiple invocation
:set ScriptLock do={
- :local Script [ :tostr $1 ];
- :local WaitMax ([ :tonum $3 ] * 10);
+ :local Script [ :tostr $1 ];
+ :local WaitMax [ :totime $2 ];
:global GetRandom20CharAlNum;
:global IfThenElse;
@@ -1285,6 +1535,10 @@
:set ($ScriptLockOrder->$Script) ({});
}
+ :if ([ :typeof $WaitMax ] = "nil" ) do={
+ :set WaitMax 0s;
+ }
+
:if ([ :len [ /system/script/find where name=$Script ] ] = 0) do={
$LogPrint error $0 ("A script named '" . $Script . "' does not exist!");
:error false;
@@ -1304,12 +1558,13 @@
:local MyTicket [ $GetRandom20CharAlNum 6 ];
$AddTicket $Script $MyTicket;
- :local WaitCount 0;
- :while ($WaitMax > $WaitCount && \
+ :local WaitInterval ($WaitMax / 20);
+ :local WaitTime $WaitMax;
+ :while ($WaitTime > 0 && \
([ $IsFirstTicket $Script $MyTicket ] = false || \
[ $TicketCount $Script ] < [ $JobCount $Script ])) do={
- :set WaitCount ($WaitCount + 1);
- :delay 100ms;
+ :set WaitTime ($WaitTime - $WaitInterval);
+ :delay $WaitInterval;
}
:if ([ $IsFirstTicket $Script $MyTicket ] = true && \
@@ -1321,16 +1576,18 @@
$RemoveTicket $Script $MyTicket;
$LogPrint debug $0 ("Script '" . $Script . "' started more than once" . \
- [ $IfThenElse ($WaitCount > 0) " and timed out waiting for lock" "" ] . "...");
+ [ $IfThenElse ($WaitTime < $WaitMax) " and timed out waiting for lock" "" ] . "...");
:return false;
}
# send notification via NotificationFunctions - expects at least two string arguments
-:set SendNotification do={
+:set SendNotification do={ :onerror Err {
:global SendNotification2;
$SendNotification2 ({ origin=$0; subject=$1; message=$2; link=$3; silent=$4 });
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via NotificationFunctions - expects one array argument
:set SendNotification2 do={
@@ -1414,12 +1671,7 @@
# convert line endings, UNIX -> DOS
:set Unix2Dos do={
- :local Input [ :tostr $1 ];
-
- :global CharacterReplace;
-
- :return [ $CharacterReplace [ $CharacterReplace $Input \
- ("\n") ("\r\n") ] ("\r\r\n") ("\r\n") ];
+ :return [ :tocrlf [ :tostr $1 ] ];
}
# url encoding
@@ -1453,9 +1705,12 @@
:set ValidateSyntax do={
:local Code [ :tostr $1 ];
- :do {
+ :global LogPrint;
+
+ :onerror Err {
[ :parse (":local Validate do={\n" . $Code . "\n}") ];
- } on-error={
+ } do={
+ $LogPrint debug $0 ("Valdation failed: " . $Err);
:return false;
}
:return true;
@@ -1470,7 +1725,7 @@
:global CharacterReplace;
:set Input [ $CharacterReplace $Input "." "," ];
- :foreach I in={ "alpha"; "beta"; "rc" } do={
+ :foreach I in={ "zero"; "alpha"; "beta"; "rc" } do={
:set Input [ $CharacterReplace $Input $I ("," . $I . ",") ];
}
@@ -1481,6 +1736,7 @@
:set Return ($Return + 0xff00);
:set Multi ($Multi / 0x100);
} else={
+ :if ($Value = "zero") do={ }
:if ($Value = "alpha") do={ :set Return ($Return + 0x3f00); }
:if ($Value = "beta") do={ :set Return ($Return + 0x5f00); }
:if ($Value = "rc") do={ :set Return ($Return + 0x7f00); }
@@ -1521,17 +1777,28 @@
:global MAX;
:set FileName [ $CleanFilePath $FileName ];
- :local I 1;
- :local Delay ([ $MAX [ $EitherOr $WaitTime 2s ] 100ms ] / 10);
+ :local Delay ([ $MAX [ $EitherOr $WaitTime 2s ] 100ms ] / 9);
- :while ([ :len [ /file/find where name=$FileName ] ] = 0) do={
- :if ($I >= 10) do={
- :return false;
- }
+ :do {
+ :retry {
+ :if ([ :len [ /file/find where name=$FileName ] ] = 0) do={
+ :error false;
+ }
+ } delay=$Delay max=10;
+ } on-error={
+ :return false;
+ }
+
+ :while ([ :len [ /file/find where name=$FileName ] ] > 0) do={
+ :do {
+ /file/get $FileName;
+ :return true;
+ } on-error={ }
:delay $Delay;
- :set I ($I + 1);
+ :set Delay ($Delay * 3 / 2);
}
- :return true;
+
+ :return false;
}
# wait to be fully connected (default route is reachable, time is sync, DNS resolves)
@@ -1558,10 +1825,10 @@
:foreach Script in=[ /system/script/find where name ~ "^mod/." ] do={
:local ScriptVal [ /system/script/get $Script ];
:if ([ $ValidateSyntax ($ScriptVal->"source") ] = true) do={
- :do {
+ :onerror Err {
/system/script/run $Script;
- } on-error={
- $LogPrint error $0 ("Module '" . $ScriptVal->"name" . "' failed to run.");
+ } do={
+ $LogPrint error $0 ("Module '" . $ScriptVal->"name" . "' failed to run: " . $Err);
}
} else={
$LogPrint error $0 ("Module '" . $ScriptVal->"name" . "' failed syntax validation, skipping.");
diff --git a/global-wait.rsc b/global-wait.rsc
index 239f575..23b5629 100644
--- a/global-wait.rsc
+++ b/global-wait.rsc
@@ -1,12 +1,13 @@
#!rsc by RouterOS
# RouterOS script: global-wait
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# wait for global-functions to finish
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/global-wait.md
+# https://rsc.eworm.de/doc/global-wait.md
+:global GlobalConfigReady;
:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
+:while ($GlobalConfigReady != true || $GlobalFunctionsReady != true) do={ :delay 500ms; }
diff --git a/gps-track.rsc b/gps-track.rsc
index e2a4e16..6a090bf 100644
--- a/gps-track.rsc
+++ b/gps-track.rsc
@@ -1,17 +1,19 @@
#!rsc by RouterOS
# RouterOS script: gps-track
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, fetch
#
# track gps data by sending json data to http server
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/gps-track.md
+# https://rsc.eworm.de/doc/gps-track.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global GpsTrackUrl;
@@ -23,6 +25,7 @@
:global WaitFullyConnected;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
$WaitFullyConnected;
@@ -31,7 +34,7 @@
:local Gps [ /system/gps/monitor once as-value ];
:if ($Gps->"valid" = true) do={
- :do {
+ :onerror Err {
/tool/fetch check-certificate=yes-without-crl output=none http-method=post \
http-header-field=({ [ $FetchUserAgentStr $ScriptName ]; "Content-Type: application/json" }) \
http-data=[ :serialize to=json { "identity"=$Identity; \
@@ -39,10 +42,12 @@
$LogPrint debug $ScriptName ("Sending GPS data in " . $CoordinateFormat . " format: " . \
"lat: " . ($Gps->"latitude") . " " . \
"lon: " . ($Gps->"longitude"));
- } on-error={
- $LogPrint warning $ScriptName ("Failed sending GPS data!");
+ } do={
+ $LogPrint warning $ScriptName ("Failed sending GPS data: " . $Err);
}
} else={
$LogPrint debug $ScriptName ("GPS data not valid.");
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/hotspot-to-wpa-cleanup.capsman.rsc b/hotspot-to-wpa-cleanup.capsman.rsc
index 8f55d71..e4ac967 100644
--- a/hotspot-to-wpa-cleanup.capsman.rsc
+++ b/hotspot-to-wpa-cleanup.capsman.rsc
@@ -1,20 +1,22 @@
#!rsc by RouterOS
# RouterOS script: hotspot-to-wpa-cleanup.capsman
-# Copyright (c) 2021-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2021-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=80
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, hotspot
#
# manage and clean up private WPA passphrase after hotspot login
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/hotspot-to-wpa.md
+# https://rsc.eworm.de/doc/hotspot-to-wpa.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global EitherOr;
@@ -23,6 +25,7 @@
:global ScriptLock;
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -50,7 +53,7 @@
}
:foreach Client in=[ /caps-man/access-list/find where comment~"^hotspot-to-wpa:" \
- !(comment~[ /system/clock/get date ]) ] do={
+ !(comment~[ /system/clock/get date ]) mac-address ] do={
:local ClientVal [ /caps-man/access-list/get $Client ];
:if ([ :len [ /ip/dhcp-server/lease/find where !dynamic comment~"^hotspot-to-wpa:" \
mac-address=($ClientVal->"mac-address") ] ] = 0) do={
@@ -61,8 +64,9 @@
}
:foreach Server,Timeout in=$DHCPServers do={
+ :local TimeoutExtra ($Timeout + [ /system/clock/get time ]);
:foreach Lease in=[ /ip/dhcp-server/lease/find where !dynamic status="waiting" \
- server=$Server last-seen>$Timeout comment~"^hotspot-to-wpa:" ] do={
+ server=$Server last-seen>$TimeoutExtra comment~"^hotspot-to-wpa:" ] do={
:local LeaseVal [ /ip/dhcp-server/lease/get $Lease ];
$LogPrint info $ScriptName ("Client with mac address " . ($LeaseVal->"mac-address") . \
" was not seen for " . ($LeaseVal->"last-seen") . ", removing.");
@@ -71,4 +75,6 @@
/ip/dhcp-server/lease/remove $Lease;
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/hotspot-to-wpa-cleanup.template.rsc b/hotspot-to-wpa-cleanup.template.rsc
index 7ac996c..d51e1d0 100644
--- a/hotspot-to-wpa-cleanup.template.rsc
+++ b/hotspot-to-wpa-cleanup.template.rsc
@@ -1,21 +1,23 @@
#!rsc by RouterOS
# RouterOS script: hotspot-to-wpa-cleanup%TEMPL%
-# Copyright (c) 2021-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2021-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=80
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, hotspot
#
# manage and clean up private WPA passphrase after hotspot login
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/hotspot-to-wpa.md
+# https://rsc.eworm.de/doc/hotspot-to-wpa.md
#
# !! This is just a template to generate the real script!
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global EitherOr;
@@ -24,6 +26,7 @@
:global ScriptLock;
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -54,7 +57,7 @@
:foreach Client in=[ /caps-man/access-list/find where comment~"^hotspot-to-wpa:" \
:foreach Client in=[ /interface/wifi/access-list/find where comment~"^hotspot-to-wpa:" \
- !(comment~[ /system/clock/get date ]) ] do={
+ !(comment~[ /system/clock/get date ]) mac-address ] do={
:local ClientVal [ /caps-man/access-list/get $Client ];
:local ClientVal [ /interface/wifi/access-list/get $Client ];
:if ([ :len [ /ip/dhcp-server/lease/find where !dynamic comment~"^hotspot-to-wpa:" \
@@ -67,8 +70,9 @@
}
:foreach Server,Timeout in=$DHCPServers do={
+ :local TimeoutExtra ($Timeout + [ /system/clock/get time ]);
:foreach Lease in=[ /ip/dhcp-server/lease/find where !dynamic status="waiting" \
- server=$Server last-seen>$Timeout comment~"^hotspot-to-wpa:" ] do={
+ server=$Server last-seen>$TimeoutExtra comment~"^hotspot-to-wpa:" ] do={
:local LeaseVal [ /ip/dhcp-server/lease/get $Lease ];
$LogPrint info $ScriptName ("Client with mac address " . ($LeaseVal->"mac-address") . \
" was not seen for " . ($LeaseVal->"last-seen") . ", removing.");
@@ -78,4 +82,6 @@
/ip/dhcp-server/lease/remove $Lease;
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/hotspot-to-wpa-cleanup.wifi.rsc b/hotspot-to-wpa-cleanup.wifi.rsc
index 39c9f25..8bb2631 100644
--- a/hotspot-to-wpa-cleanup.wifi.rsc
+++ b/hotspot-to-wpa-cleanup.wifi.rsc
@@ -1,20 +1,22 @@
#!rsc by RouterOS
# RouterOS script: hotspot-to-wpa-cleanup.wifi
-# Copyright (c) 2021-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2021-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=80
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, hotspot
#
# manage and clean up private WPA passphrase after hotspot login
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/hotspot-to-wpa.md
+# https://rsc.eworm.de/doc/hotspot-to-wpa.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global EitherOr;
@@ -23,6 +25,7 @@
:global ScriptLock;
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -50,7 +53,7 @@
}
:foreach Client in=[ /interface/wifi/access-list/find where comment~"^hotspot-to-wpa:" \
- !(comment~[ /system/clock/get date ]) ] do={
+ !(comment~[ /system/clock/get date ]) mac-address ] do={
:local ClientVal [ /interface/wifi/access-list/get $Client ];
:if ([ :len [ /ip/dhcp-server/lease/find where !dynamic comment~"^hotspot-to-wpa:" \
mac-address=($ClientVal->"mac-address") ] ] = 0) do={
@@ -61,8 +64,9 @@
}
:foreach Server,Timeout in=$DHCPServers do={
+ :local TimeoutExtra ($Timeout + [ /system/clock/get time ]);
:foreach Lease in=[ /ip/dhcp-server/lease/find where !dynamic status="waiting" \
- server=$Server last-seen>$Timeout comment~"^hotspot-to-wpa:" ] do={
+ server=$Server last-seen>$TimeoutExtra comment~"^hotspot-to-wpa:" ] do={
:local LeaseVal [ /ip/dhcp-server/lease/get $Lease ];
$LogPrint info $ScriptName ("Client with mac address " . ($LeaseVal->"mac-address") . \
" was not seen for " . ($LeaseVal->"last-seen") . ", removing.");
@@ -71,4 +75,6 @@
/ip/dhcp-server/lease/remove $Lease;
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/hotspot-to-wpa.capsman.rsc b/hotspot-to-wpa.capsman.rsc
index 113c95d..8977cee 100644
--- a/hotspot-to-wpa.capsman.rsc
+++ b/hotspot-to-wpa.capsman.rsc
@@ -1,19 +1,21 @@
#!rsc by RouterOS
# RouterOS script: hotspot-to-wpa.capsman
-# Copyright (c) 2019-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, hotspot
#
# add private WPA passphrase after hotspot login
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/hotspot-to-wpa.md
+# https://rsc.eworm.de/doc/hotspot-to-wpa.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global EitherOr;
@@ -25,11 +27,13 @@
:local UserName $username;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
:if ([ :typeof $MacAddress ] = "nothing" || [ :typeof $UserName ] = "nothing") do={
$LogPrint error $ScriptName ("This script is supposed to run from hotspot on login.");
+ :set ExitOK true;
:error false;
}
@@ -57,6 +61,7 @@
:if ($Template->"action" = "reject") do={
$LogPrint info $ScriptName ("Ignoring login for hotspot '" . $Hotspot . "'.");
+ :set ExitOK true;
:error true;
}
@@ -95,4 +100,6 @@
:delay 2s;
/caps-man/access-list/set $Entry action=accept;
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/hotspot-to-wpa.template.rsc b/hotspot-to-wpa.template.rsc
index 10f0c7e..c5d977d 100644
--- a/hotspot-to-wpa.template.rsc
+++ b/hotspot-to-wpa.template.rsc
@@ -1,20 +1,22 @@
#!rsc by RouterOS
# RouterOS script: hotspot-to-wpa%TEMPL%
-# Copyright (c) 2019-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, hotspot
#
# add private WPA passphrase after hotspot login
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/hotspot-to-wpa.md
+# https://rsc.eworm.de/doc/hotspot-to-wpa.md
#
# !! This is just a template to generate the real script!
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global EitherOr;
@@ -26,11 +28,13 @@
:local UserName $username;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
:if ([ :typeof $MacAddress ] = "nothing" || [ :typeof $UserName ] = "nothing") do={
$LogPrint error $ScriptName ("This script is supposed to run from hotspot on login.");
+ :set ExitOK true;
:error false;
}
@@ -64,6 +68,7 @@
:if ($Template->"action" = "reject") do={
$LogPrint info $ScriptName ("Ignoring login for hotspot '" . $Hotspot . "'.");
+ :set ExitOK true;
:error true;
}
@@ -115,4 +120,6 @@
:delay 2s;
/caps-man/access-list/set $Entry action=accept;
/interface/wifi/access-list/set $Entry action=accept;
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/hotspot-to-wpa.wifi.rsc b/hotspot-to-wpa.wifi.rsc
index dbf50e0..6a97e46 100644
--- a/hotspot-to-wpa.wifi.rsc
+++ b/hotspot-to-wpa.wifi.rsc
@@ -1,19 +1,21 @@
#!rsc by RouterOS
# RouterOS script: hotspot-to-wpa.wifi
-# Copyright (c) 2019-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, hotspot
#
# add private WPA passphrase after hotspot login
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/hotspot-to-wpa.md
+# https://rsc.eworm.de/doc/hotspot-to-wpa.md
#
# !! Do not edit this file, it is generated from template!
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global EitherOr;
@@ -25,11 +27,13 @@
:local UserName $username;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
:if ([ :typeof $MacAddress ] = "nothing" || [ :typeof $UserName ] = "nothing") do={
$LogPrint error $ScriptName ("This script is supposed to run from hotspot on login.");
+ :set ExitOK true;
:error false;
}
@@ -57,6 +61,7 @@
:if ($Template->"action" = "reject") do={
$LogPrint info $ScriptName ("Ignoring login for hotspot '" . $Hotspot . "'.");
+ :set ExitOK true;
:error true;
}
@@ -92,4 +97,6 @@
:delay 2s;
/interface/wifi/access-list/set $Entry action=accept;
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/ip-addr-bridge.rsc b/ip-addr-bridge.rsc
index 758cd46..68ff4a4 100644
--- a/ip-addr-bridge.rsc
+++ b/ip-addr-bridge.rsc
@@ -1,10 +1,10 @@
#!rsc by RouterOS
# RouterOS script: ip-addr-bridge
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# enable or disable ip addresses based on bridge port state
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/ip-addr-bridge.md
+# https://rsc.eworm.de/doc/ip-addr-bridge.md
:foreach Bridge in=[ /interface/bridge/find ] do={
:local BrName [ /interface/bridge/get $Bridge name ];
diff --git a/ipsec-to-dns.rsc b/ipsec-to-dns.rsc
index 8894eee..1b5ed13 100644
--- a/ipsec-to-dns.rsc
+++ b/ipsec-to-dns.rsc
@@ -1,17 +1,19 @@
#!rsc by RouterOS
# RouterOS script: ipsec-to-dns
-# Copyright (c) 2021-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2021-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, ipsec
#
# and add/remove/update DNS entries from IPSec mode-config
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/ipsec-to-dns.md
+# https://rsc.eworm.de/doc/ipsec-to-dns.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Domain;
@@ -26,6 +28,7 @@
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -76,4 +79,6 @@
/ip/dns/static/add name=$Fqdn address=($PeerVal->"dynamic-address") ttl=$Ttl comment=$Comment place-before=$PlaceBefore;
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/ipv6-update.rsc b/ipv6-update.rsc
index ec9a03a..580a426 100644
--- a/ipv6-update.rsc
+++ b/ipv6-update.rsc
@@ -1,38 +1,56 @@
#!rsc by RouterOS
# RouterOS script: ipv6-update
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# update firewall and dns settings on IPv6 prefix change
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/ipv6-update.md
+# https://rsc.eworm.de/doc/ipv6-update.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global LogPrint;
:global ParseKeyValueStore;
:global ScriptLock;
+ :local NaAddress $"na-address";
+ :local NaValid $"na-valid";
:local PdPrefix $"pd-prefix";
+ :local PdValid $"pd-valid";
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
+ :error false;
+ }
+
+ :if ([ :typeof $NaAddress ] = "str") do={
+ $LogPrint info $ScriptName ("An address (" . $NaAddress . ") was acquired, not a prefix. Ignoring.");
+ :set ExitOK true;
:error false;
}
- :if ([ :typeof $PdPrefix ] = "nothing") do={
+ :if ([ :typeof $PdPrefix ] = "nothing" || [ :typeof $PdValid ] = "nothing") do={
$LogPrint error $ScriptName ("This script is supposed to run from ipv6 dhcp-client.");
+ :set ExitOK true;
+ :error false;
+ }
+
+ :if ($PdValid != 1) do={
+ $LogPrint info $ScriptName ("The prefix " . $PdPrefix . " is no longer valid. Ignoring.");
+ :set ExitOK true;
:error false;
}
:local Pool [ /ipv6/pool/get [ find where prefix=$PdPrefix ] name ];
:if ([ :len [ /ipv6/firewall/address-list/find where comment=("ipv6-pool-" . $Pool) ] ] = 0) do={
- /ipv6/firewall/address-list/add list=("ipv6-pool-" . $Pool) address=:: comment=("ipv6-pool-" . $Pool);
- $LogPrint warning $ScriptName ("Added ipv6 address list entry for ipv6-pool-" . $Pool);
+ /ipv6/firewall/address-list/add list=("ipv6-pool-" . $Pool) address=:: comment=("ipv6-pool-" . $Pool) dynamic=yes;
+ $LogPrint warning $ScriptName ("Added dynamic ipv6 address list entry for ipv6-pool-" . $Pool);
}
:local AddrList [ /ipv6/firewall/address-list/find where comment=("ipv6-pool-" . $Pool) ];
:local OldPrefix [ /ipv6/firewall/address-list/get ($AddrList->0) address ];
@@ -84,4 +102,6 @@
}
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/lease-script.rsc b/lease-script.rsc
index a9d4b68..ab44956 100644
--- a/lease-script.rsc
+++ b/lease-script.rsc
@@ -1,17 +1,18 @@
#!rsc by RouterOS
# RouterOS script: lease-script
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# run scripts on DHCP lease
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/lease-script.md
+# https://rsc.eworm.de/doc/lease-script.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Grep;
@@ -25,6 +26,7 @@
[ :typeof $leaseServerName ] = "nothing" || \
[ :typeof $leaseBound ] = "nothing") do={
$LogPrint error $ScriptName ("This script is supposed to run from ip dhcp-server.");
+ :set ExitOK true;
:error false;
}
@@ -32,11 +34,13 @@
"de" "" ] . "assigned lease " . $leaseActIP . " to " . $leaseActMAC);
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
+ :set ExitOK true;
:error false;
}
:if ([ :len [ /system/script/job/find where script=$ScriptName ] ] > 1) do={
$LogPrint debug $ScriptName ("More invocations are waiting, exiting early.");
+ :set ExitOK true;
:error true;
}
@@ -49,11 +53,13 @@
}
:foreach Order,Script in=$RunOrder do={
- :do {
+ :onerror Err {
$LogPrint debug $ScriptName ("Running script with order " . $Order . ": " . $Script);
/system/script/run $Script;
- } on-error={
- $LogPrint warning $ScriptName ("Running script '" . $Script . "' failed!");
+ } do={
+ $LogPrint warning $ScriptName ("Running script '" . $Script . "' failed: " . $Err);
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/leds-day-mode.rsc b/leds-day-mode.rsc
index b7c6b5b..7344fde 100644
--- a/leds-day-mode.rsc
+++ b/leds-day-mode.rsc
@@ -1,9 +1,9 @@
#!rsc by RouterOS
# RouterOS script: leds-day-mode
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# enable LEDs
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/leds-mode.md
+# https://rsc.eworm.de/doc/leds-mode.md
/system/leds/settings/set all-leds-off=never;
diff --git a/leds-night-mode.rsc b/leds-night-mode.rsc
index fb7c7a2..8bd028e 100644
--- a/leds-night-mode.rsc
+++ b/leds-night-mode.rsc
@@ -1,9 +1,9 @@
#!rsc by RouterOS
# RouterOS script: leds-night-mode
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# disable LEDs
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/leds-mode.md
+# https://rsc.eworm.de/doc/leds-mode.md
/system/leds/settings/set all-leds-off=immediate;
diff --git a/leds-toggle-mode.rsc b/leds-toggle-mode.rsc
index 136c9d1..b55e351 100644
--- a/leds-toggle-mode.rsc
+++ b/leds-toggle-mode.rsc
@@ -1,13 +1,9 @@
#!rsc by RouterOS
# RouterOS script: leds-toggle-mode
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# toggle LEDs mode
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/leds-mode.md
+# https://rsc.eworm.de/doc/leds-mode.md
-:if ([ /system/leds/settings/get all-leds-off ] = "never") do={
- /system/leds/settings/set all-leds-off=immediate;
-} else={
- /system/leds/settings/set all-leds-off=never;
-}
+/system/leds/settings/set all-leds-off=(({ "never"="immediate"; "immediate"="never" })->[ get all-leds-off ]);
diff --git a/log-forward.rsc b/log-forward.rsc
index 7abcb4d..be7eff7 100644
--- a/log-forward.rsc
+++ b/log-forward.rsc
@@ -1,17 +1,18 @@
#!rsc by RouterOS
# RouterOS script: log-forward
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# forward log messages via notification
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/log-forward.md
+# https://rsc.eworm.de/doc/log-forward.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Identity;
@@ -33,6 +34,7 @@
:global SymbolForNotification;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -43,6 +45,7 @@
:if ($LogForwardRateLimit > 30) do={
:set LogForwardRateLimit ($LogForwardRateLimit - 1);
$LogPrint info $ScriptName ("Rate limit in action, not forwarding logs, if any!");
+ :set ExitOK true;
:error false;
}
@@ -54,6 +57,11 @@
:local MessageVal;
:local MessageDups ({});
+ :set LogForwardFilter [ $EitherOr $LogForwardFilter [] ];
+ :set LogForwardFilterMessage [ $EitherOr $LogForwardFilterMessage [] ];
+ :set LogForwardInclude [ $EitherOr $LogForwardInclude [] ];
+ :set LogForwardIncludeMessage [ $EitherOr $LogForwardIncludeMessage [] ];
+
:local LogForwardFilterLogForwardingCached [ $EitherOr [ $LogForwardFilterLogForwarding ] ("\$^") ];
:foreach Message in=[ /log/find where (!(message="") and \
!(message~$LogForwardFilterLogForwardingCached) and \
@@ -94,9 +102,12 @@
[ $IfThenElse ($Duplicates = true) (" Multi-repeated messages have been skipped.") ] . \
[ $IfThenElse ($LogForwardRateLimit > 30) ("\nRate limit in action, delaying forwarding.") ] . \
"\n" . $Messages) });
-
- :set LogForwardLast ($MessageVal->".id");
} else={
:set LogForwardRateLimit [ $MAX 0 ($LogForwardRateLimit - 1) ];
}
-} on-error={ }
+
+ :local LogAll [ /log/find ];
+ :set LogForwardLast ($LogAll->([ :len $LogAll ] - 1) );
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/logo.avif b/logo.avif
index 399a2f5..956fea8 100644
--- a/logo.avif
+++ b/logo.avif
Binary files differ
diff --git a/logo.png b/logo.png
index d97b75d..7bec10e 100644
--- a/logo.png
+++ b/logo.png
Binary files differ
diff --git a/mod/bridge-port-to.rsc b/mod/bridge-port-to.rsc
index 000532a..93eedce 100644
--- a/mod/bridge-port-to.rsc
+++ b/mod/bridge-port-to.rsc
@@ -1,16 +1,16 @@
#!rsc by RouterOS
# RouterOS script: mod/bridge-port-to
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# reset bridge ports to default bridge
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/bridge-port-to.md
+# https://rsc.eworm.de/doc/mod/bridge-port-to.md
:global BridgePortTo;
-:set BridgePortTo do={
+:set BridgePortTo do={ :onerror Err {
:local BridgePortTo [ :tostr $1 ];
:global IfThenElse;
@@ -65,4 +65,6 @@
$LogPrint info $0 ("Re-enabling interfaces...");
/interface/ethernet/enable $InterfaceReEnable;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
diff --git a/mod/bridge-port-vlan.rsc b/mod/bridge-port-vlan.rsc
index 760e8a6..6deee99 100644
--- a/mod/bridge-port-vlan.rsc
+++ b/mod/bridge-port-vlan.rsc
@@ -1,16 +1,16 @@
#!rsc by RouterOS
# RouterOS script: mod/bridge-port-vlan
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# manage VLANs on bridge ports
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/bridge-port-vlan.md
+# https://rsc.eworm.de/doc/mod/bridge-port-vlan.md
:global BridgePortVlan;
-:global BridgePortVlan do={
+:global BridgePortVlan do={ :onerror Err {
:local ConfigTo [ :tostr $1 ];
:global IfThenElse;
@@ -74,4 +74,6 @@
$LogPrint info $0 ("Re-enabling interfaces...");
/interface/ethernet/enable $InterfaceReEnable;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
diff --git a/mod/inspectvar.rsc b/mod/inspectvar.rsc
index 5adca0a..fc1b366 100644
--- a/mod/inspectvar.rsc
+++ b/mod/inspectvar.rsc
@@ -1,29 +1,31 @@
#!rsc by RouterOS
# RouterOS script: mod/inspectvar
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# inspect variables
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/inspectvar.md
+# https://rsc.eworm.de/doc/mod/inspectvar.md
:global InspectVar;
:global InspectVarReturn;
# inspect variable and print on terminal
-:set InspectVar do={
+:set InspectVar do={ :onerror Err {
:global InspectVarReturn;
- :global PrettyPrint;
- $PrettyPrint [ $InspectVarReturn $1 ];
-}
+ :put [ :tocrlf [ $InspectVarReturn $1 ] ];
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# inspect variable and return formatted string
:set InspectVarReturn do={
:local Input $1;
:local Level (0 + [ :tonum $2 ]);
+ :global CharacterReplace;
:global IfThenElse;
:global InspectVarReturn;
@@ -32,14 +34,13 @@
:local Value [ :tostr $2 ];
:local Level [ :tonum $3 ];
- :local Indent "";
- :for I from=1 to=$Level step=1 do={
- :set Indent ($Indent . " ");
- }
- :return ($Indent . "-" . $Prefix . "-> " . $Value);
+ :global CharacterMultiply;
+
+ :return ([ $CharacterMultiply " " $Level ] . "-" . $Prefix . "-> " . $Value);
}
:local TypeOf [ :typeof $Input ];
+ :local Len [ :len $Input ];
:local Return [ $IndentReturn "type" $TypeOf $Level ];
:if ($TypeOf = "array") do={
@@ -49,6 +50,16 @@
[ $InspectVarReturn $Value ($Level + 2) ]);
}
} else={
+ :if ($TypeOf = "str") do={
+ :set $Return ($Return . "\n" . \
+ [ $IndentReturn "len" $Len $Level ]);
+ :if ([ :typeof [ :find $Input ("\r") ] ] = "num") do={
+ :set Input [ $CharacterReplace $Input ("\r") "" ];
+ }
+ :if ([ :typeof [ :find $Input ("\n") ] ] = "num") do={
+ :set Input [ $CharacterReplace $Input ("\n") " " ];
+ }
+ }
:if ($TypeOf != "nothing") do={
:set $Return ($Return . "\n" . \
[ $IndentReturn "value" [ $IfThenElse ([ :len $Input ] > 80) \
diff --git a/mod/ipcalc.rsc b/mod/ipcalc.rsc
index 128ca54..eacff6d 100644
--- a/mod/ipcalc.rsc
+++ b/mod/ipcalc.rsc
@@ -1,34 +1,35 @@
#!rsc by RouterOS
# RouterOS script: mod/ipcalc
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# ip address calculation
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/ipcalc.md
+# https://rsc.eworm.de/doc/mod/ipcalc.md
:global IPCalc;
:global IPCalcReturn;
# print netmask, network, min host, max host and broadcast
-:set IPCalc do={
+:set IPCalc do={ :onerror Err {
:local Input [ :tostr $1 ];
:global FormatLine;
:global IPCalcReturn;
- :global PrettyPrint;
:local Values [ $IPCalcReturn $1 ];
- $PrettyPrint ( \
+ :put [ :tocrlf ( \
[ $FormatLine "Address" ($Values->"address") ] . "\n" . \
[ $FormatLine "Netmask" ($Values->"netmask") ] . "\n" . \
[ $FormatLine "Network" ($Values->"network") ] . "\n" . \
[ $FormatLine "HostMin" ($Values->"hostmin") ] . "\n" . \
[ $FormatLine "HostMax" ($Values->"hostmax") ] . "\n" . \
- [ $FormatLine "Broadcast" ($Values->"broadcast") ]);
-}
+ [ $FormatLine "Broadcast" ($Values->"broadcast") ]) ];
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# calculate and return netmask, network, min host, max host and broadcast
:set IPCalcReturn do={
diff --git a/mod/notification-email.rsc b/mod/notification-email.rsc
index df2e81a..ad9762a 100644
--- a/mod/notification-email.rsc
+++ b/mod/notification-email.rsc
@@ -1,12 +1,13 @@
#!rsc by RouterOS
# RouterOS script: mod/notification-email
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, email, scheduler
#
# send notifications via e-mail
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/notification-email.md
+# https://rsc.eworm.de/doc/mod/notification-email.md
:global EMailGenerateFrom;
:global FlushEmailQueue;
@@ -34,20 +35,39 @@
}
# flush e-mail queue
-:set FlushEmailQueue do={
+:set FlushEmailQueue do={ :onerror Err {
:global EmailQueue;
:global EitherOr;
:global EMailGenerateFrom;
+ :global FileExists;
:global IsDNSResolving;
:global IsTimeSync;
:global LogPrint;
+ :global RmFile;
:local AllDone true;
:local QueueLen [ :len $EmailQueue ];
:local Scheduler [ /system/scheduler/find where name="_FlushEmailQueue" ];
- :if ([ :len $Scheduler ] > 0 && [ /system/scheduler/get $Scheduler interval ] < 1m) do={
+ :if ([ :len $Scheduler ] > 0 && $QueueLen = 0) do={
+ $LogPrint warning $0 ("Flushing E-Mail messages from scheduler, but queue is empty.");
+ /system/scheduler/remove $Scheduler;
+ :return false;
+ }
+
+ :if ($QueueLen = 0) do={
+ :return true;
+ }
+
+ :if ([ :len $Scheduler ] < 0) do={
+ /system/scheduler/add name="_FlushEmailQueue" interval=1m start-time=startup \
+ comment="Doing initial checks..." on-event=(":global FlushEmailQueue; \$FlushEmailQueue;");
+ :set Scheduler [ /system/scheduler/find where name="_FlushEmailQueue" ];
+ }
+
+ :local SchedVal [ /system/scheduler/get $Scheduler ];
+ :if (($SchedVal->"interval") < 1m) do={
/system/scheduler/set interval=1m comment="Doing initial checks..." $Scheduler;
}
@@ -67,53 +87,64 @@
:return false;
}
- :if ([ :len $Scheduler ] > 0 && $QueueLen = 0) do={
- $LogPrint warning $0 ("Flushing E-Mail messages from scheduler, but queue is empty.");
- }
-
- /system/scheduler/set interval=([ $EitherOr $QueueLen 1 ] . "m") comment="Sending..." $Scheduler;
+ /system/scheduler/set interval=($QueueLen . "m") comment="Sending..." $Scheduler;
:foreach Id,Message in=$EmailQueue do={
:if ([ :typeof $Message ] = "array" ) do={
- :local Attach ({});
:while ([ /tool/e-mail/get last-status ] = "in-progress") do={ :delay 1s; }
- :foreach File in=[ :toarray [ $EitherOr ($Message->"attach") "" ] ] do={
- :if ([ :len [ /file/find where name=$File ] ] = 1) do={
- :set Attach ($Attach, $File);
- } else={
- $LogPrint warning $0 ("File '" . $File . "' does not exist, can not attach.");
+ :onerror Err {
+ :local Attach ({});
+ :foreach File in=[ :toarray [ $EitherOr ($Message->"attach") "" ] ] do={
+ :if ([ $FileExists $File ] = true) do={
+ :set Attach ($Attach, $File);
+ } else={
+ $LogPrint warning $0 ("File '" . $File . "' does not exist, can not attach.");
+ }
}
- }
- /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;
- :local Status [ /tool/e-mail/get last-status ];
- :if ($Status = "succeeded") do={
- :set ($EmailQueue->$Id);
- :set Wait false;
- :if (($Message->"remove-attach") = true) do={
- :foreach File in=$Attach do={
- /file/remove $File;
+ /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;
+ :local Status [ /tool/e-mail/get last-status ];
+ :if ($Status = "succeeded") do={
+ :set ($EmailQueue->$Id);
+ :set Wait false;
+ :if (($Message->"remove-attach") = true) do={
+ :foreach File in=$Attach do={
+ $RmFile $File;
+ }
}
}
- }
- :if ($Status = "failed") do={
- :set AllDone false;
- :set Wait false;
- }
- } while=($Wait = true);
+ :if ($Status = "failed") do={
+ :set AllDone false;
+ :set Wait false;
+ }
+ } while=($Wait = true);
+ } do={
+ $LogPrint warning $0 ("Sending queued mail failed: " . $Err);
+ :set AllDone false;
+ }
}
}
:if ($AllDone = true && $QueueLen = [ :len $EmailQueue ]) do={
/system/scheduler/remove $Scheduler;
:set EmailQueue;
- } else={
- /system/scheduler/set interval=1m comment="Waiting for retry..." $Scheduler;
+ :return true;
}
-}
+
+ :if ([ :len [ /system/scheduler/find where name="_FlushEmailQueue" ] ] = 0 && \
+ [ :typeof $EmailQueue ] = "nothing") do={
+ $LogPrint info $0 ("Queue was purged? Exiting.");
+ :return false;
+ }
+
+ /system/scheduler/set interval=(($SchedVal->"run-count") . "m") \
+ comment="Waiting for retry..." $Scheduler;
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# generate filter for log-forward
:set LogForwardFilterLogForwarding do={
@@ -152,6 +183,7 @@
:global IfThenElse;
:global NotificationEMailSignature;
:global NotificationEMailSubject;
+ :global SymbolForNotification;
:local To [ $EitherOr ($EmailGeneralToOverride->($Notification->"origin")) $EmailGeneralTo ];
:local Cc [ $EitherOr ($EmailGeneralCcOverride->($Notification->"origin")) $EmailGeneralCc ];
@@ -164,13 +196,23 @@
:if ([ :typeof $EmailQueue ] = "nothing") do={
:set EmailQueue ({});
}
+ :local Truncated false;
+ :local Body ($Notification->"message");
+ :if ([ :len $Body ] > 62000) do={
+ :set Body ([ :pick $Body 0 62000 ] . "...");
+ :set Truncated true;
+ }
:local Signature [ $EitherOr [ $NotificationEMailSignature ] [ /system/note/get note ] ];
+ :set Body ($Body . "\n" . \
+ [ $IfThenElse ([ :len ($Notification->"link") ] > 0) \
+ ("\n" . [ $SymbolForNotification "link" ] . ($Notification->"link")) ] . \
+ [ $IfThenElse ($Truncated = true) ("\n" . [ $SymbolForNotification "scissors" ] . \
+ "The message was too long and has been truncated!") ] . \
+ [ $IfThenElse ([ :len $Signature ] > 0) ("\n-- \n" . $Signature) "" ]);
:set ($EmailQueue->[ :len $EmailQueue ]) {
to=$To; cc=$Cc;
subject=[ $NotificationEMailSubject ($Notification->"subject") ];
- body=(($Notification->"message") . \
- [ $IfThenElse ([ :len ($Notification->"link") ] > 0) ("\n\n" . ($Notification->"link")) "" ] . \
- [ $IfThenElse ([ :len $Signature ] > 0) ("\n-- \n" . $Signature) "" ]); \
+ body=$Body; \
attach=($Notification->"attach"); remove-attach=($Notification->"remove-attach") };
:if ([ :len [ /system/scheduler/find where name="_FlushEmailQueue" ] ] = 0) do={
/system/scheduler/add name="_FlushEmailQueue" interval=1s start-time=startup \
@@ -224,11 +266,13 @@
}
# send notification via e-mail - expects at least two string arguments
-:set SendEMail do={
+:set SendEMail do={ :onerror Err {
:global SendEMail2;
$SendEMail2 ({ origin=$0; subject=$1; message=$2; link=$3 });
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via e-mail - expects one array argument
:set SendEMail2 do={
diff --git a/mod/notification-gotify.rsc b/mod/notification-gotify.rsc
new file mode 100644
index 0000000..d8eafbe
--- /dev/null
+++ b/mod/notification-gotify.rsc
@@ -0,0 +1,139 @@
+#!rsc by RouterOS
+# RouterOS script: mod/notification-gotify
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# Leonardo David Monteiro <leo@cub3.xyz>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.15
+# requires device-mode, fetch, scheduler
+#
+# send notifications via Gotify (gotify.net)
+# https://rsc.eworm.de/doc/mod/notification-gotify.md
+
+:global FlushGotifyQueue;
+:global NotificationFunctions;
+:global PurgeGotifyQueue;
+:global SendGotify;
+:global SendGotify2;
+
+# flush Gotify queue
+:set FlushGotifyQueue do={ :onerror Err {
+ :global GotifyQueue;
+
+ :global IsFullyConnected;
+ :global LogPrint;
+
+ :if ([ $IsFullyConnected ] = false) do={
+ $LogPrint debug $0 ("System is not fully connected, not flushing.");
+ :return false;
+ }
+
+ :local AllDone true;
+ :local QueueLen [ :len $GotifyQueue ];
+
+ :if ([ :len [ /system/scheduler/find where name="_FlushGotifyQueue" ] ] > 0 && $QueueLen = 0) do={
+ $LogPrint warning $0 ("Flushing Gotify messages from scheduler, but queue is empty.");
+ }
+
+ :foreach Id,Message in=$GotifyQueue do={
+ :if ([ :typeof $Message ] = "array" ) do={
+ :onerror Err {
+ /tool/fetch check-certificate=yes-without-crl output=none http-method=post \
+ http-header-field=($Message->"headers") http-data=[ :serialize to=json ($Message->"message") ] \
+ ($Message->"url") as-value;
+ :set ($GotifyQueue->$Id);
+ } do={
+ $LogPrint debug $0 ("Sending queued Gotify message failed: " . $Err);
+ :set AllDone false;
+ }
+ }
+ }
+
+ :if ($AllDone = true && $QueueLen = [ :len $GotifyQueue ]) do={
+ /system/scheduler/remove [ find where name="_FlushGotifyQueue" ];
+ :set GotifyQueue;
+ }
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
+
+# send notification via Gotify - expects one array argument
+:set ($NotificationFunctions->"gotify") do={
+ :local Notification $1;
+
+ :global Identity;
+ :global IdentityExtra;
+ :global GotifyQueue;
+ :global GotifyServer;
+ :global GotifyServerOverride;
+ :global GotifyToken;
+ :global GotifyTokenOverride;
+
+ :global EitherOr;
+ :global FetchUserAgentStr;
+ :global IfThenElse;
+ :global LogPrint;
+ :global SymbolForNotification;
+
+ :local Server [ $EitherOr ($GotifyServerOverride->($Notification->"origin")) $GotifyServer ];
+ :local Token [ $EitherOr ($GotifyTokenOverride->($Notification->"origin")) $GotifyToken ];
+
+ :if ([ :len $Token ] = 0) do={
+ :return false;
+ }
+
+ :local Url ("https://" . $Server . "/message");
+ :local Headers ({ [ $FetchUserAgentStr ($Notification->"origin") ]; \
+ ("X-Gotify-Key: " . $Token); "Content-Type: application/json" });
+ :local Message ({
+ "title"=("[" . $IdentityExtra . $Identity . "] " . ($Notification->"subject")); \
+ "message"=(($Notification->"message") . "\n" . [ $IfThenElse ([ :len ($Notification->"link") ] > 0) \
+ ("\n" . [ $SymbolForNotification "link" ] . ($Notification->"link")) ]); \
+ "priority"=[ :tonum [ $IfThenElse ($Notification->"silent") 2 5 ] ] });
+
+ :onerror Err {
+ /tool/fetch check-certificate=yes-without-crl output=none http-method=post \
+ http-header-field=$Headers http-data=[ :serialize to=json $Message ] $Url as-value;
+ } do={
+ $LogPrint info $0 ("Failed sending Gotify notification: " . $Err . " - Queuing...");
+
+ :if ([ :typeof $GotifyQueue ] = "nothing") do={
+ :set GotifyQueue ({});
+ }
+ :set ($Message->"message") (($Notification->"message") . "\n" . \
+ [ $SymbolForNotification "alarm-clock" ] . "This message was queued since " . \
+ [ /system/clock/get date ] . " " . [ /system/clock/get time ] . " and may be obsolete.");
+ :set ($GotifyQueue->[ :len $GotifyQueue ]) \
+ { url=$Url; headers=$Headers; message=$Message };
+ :if ([ :len [ /system/scheduler/find where name="_FlushGotifyQueue" ] ] = 0) do={
+ /system/scheduler/add name="_FlushGotifyQueue" interval=1m start-time=startup \
+ on-event=(":global FlushGotifyQueue; \$FlushGotifyQueue;");
+ }
+ }
+}
+
+# purge the Gotify queue
+:set PurgeGotifyQueue do={
+ :global GotifyQueue;
+
+ /system/scheduler/remove [ find where name="_FlushGotifyQueue" ];
+ :set GotifyQueue;
+}
+
+# send notification via Gotify - expects at least two string arguments
+:set SendGotify do={ :onerror Err {
+ :global SendGotify2;
+
+ $SendGotify2 ({ origin=$0; subject=$1; message=$2; link=$3; silent=$4 });
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
+
+# send notification via Gotify - expects one array argument
+:set SendGotify2 do={
+ :local Notification $1;
+
+ :global NotificationFunctions;
+
+ ($NotificationFunctions->"gotify") ("\$NotificationFunctions->\"gotify\"") $Notification;
+}
diff --git a/mod/notification-matrix.rsc b/mod/notification-matrix.rsc
index 196633a..e9b42a0 100644
--- a/mod/notification-matrix.rsc
+++ b/mod/notification-matrix.rsc
@@ -1,13 +1,14 @@
#!rsc by RouterOS
# RouterOS script: mod/notification-matrix
-# Copyright (c) 2013-2024 Michael Gisbers <michael@gisbers.de>
+# Copyright (c) 2013-2025 Michael Gisbers <michael@gisbers.de>
# Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, fetch, scheduler
#
# send notifications via Matrix
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/notification-matrix.md
+# https://rsc.eworm.de/doc/mod/notification-matrix.md
:global FlushMatrixQueue;
:global NotificationFunctions;
@@ -18,7 +19,7 @@
:global SetupMatrixJoinRoom;
# flush Matrix queue
-:set FlushMatrixQueue do={
+:set FlushMatrixQueue do={ :onerror Err {
:global MatrixQueue;
:global IsFullyConnected;
@@ -38,7 +39,7 @@
:foreach Id,Message in=$MatrixQueue do={
:if ([ :typeof $Message ] = "array" ) do={
- :do {
+ :onerror Err {
/tool/fetch check-certificate=yes-without-crl output=none \
http-header-field=($Message->"headers") http-method=post \
http-data=[ :serialize to=json { "msgtype"="m.text"; "body"=($Message->"plain");
@@ -46,8 +47,8 @@
("https://" . $Message->"homeserver" . "/_matrix/client/r0/rooms/" . $Message->"room" . \
"/send/m.room.message?access_token=" . $Message->"accesstoken") as-value;
:set ($MatrixQueue->$Id);
- } on-error={
- $LogPrint debug $0 ("Sending queued Matrix message failed.");
+ } do={
+ $LogPrint debug $0 ("Sending queued Matrix message failed: " . $Err);
:set AllDone false;
}
}
@@ -57,7 +58,9 @@
/system/scheduler/remove [ find where name="_FlushMatrixQueue" ];
:set MatrixQueue;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via Matrix - expects one array argument
:set ($NotificationFunctions->"matrix") do={
@@ -126,15 +129,15 @@
[ $PrepareText $Label ] . "</a>");
}
- :do {
+ :onerror Err {
/tool/fetch check-certificate=yes-without-crl output=none \
http-header-field=$Headers http-method=post \
http-data=[ :serialize to=json { "msgtype"="m.text"; "body"=$Plain;
"format"="org.matrix.custom.html"; "formatted_body"=$Formatted } ] \
("https://" . $HomeServer . "/_matrix/client/r0/rooms/" . $Room . \
"/send/m.room.message?access_token=" . $AccessToken) as-value;
- } on-error={
- $LogPrint info $0 ("Failed sending Matrix notification! Queuing...");
+ } do={
+ $LogPrint info $0 ("Failed sending Matrix notification: " . $Err . " - Queuing...");
:if ([ :typeof $MatrixQueue ] = "nothing") do={
:set MatrixQueue ({});
@@ -164,11 +167,13 @@
}
# send notification via Matrix - expects at least two string arguments
-:set SendMatrix do={
+:set SendMatrix do={ :onerror Err {
:global SendMatrix2;
$SendMatrix2 ({ origin=$0; subject=$1; message=$2; link=$3 });
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via Matrix - expects one array argument
:set SendMatrix2 do={
@@ -191,14 +196,14 @@
:global MatrixHomeServer;
:local Domain [ :pick $User ([ :find $User ":" ] + 1) [ :len $User] ];
- :do {
+ :onerror Err {
:local Data ([ /tool/fetch check-certificate=yes-without-crl output=user \
http-header-field=({ [ $FetchUserAgentStr $0 ] }) \
("https://" . $Domain . "/.well-known/matrix/client") as-value ]->"data");
:set MatrixHomeServer ([ :deserialize from=json value=$Data ]->"m.homeserver"->"base_url");
$LogPrint debug $0 ("Home server is: " . $MatrixHomeServer);
- } on-error={
- $LogPrint error $0 ("Failed getting home server!");
+ } do={
+ $LogPrint error $0 ("Failed getting home server: " . $Err);
:return false;
}
@@ -206,27 +211,27 @@
:set MatrixHomeServer [ :pick $MatrixHomeServer 8 [ :len $MatrixHomeServer ] ];
}
- :do {
+ :onerror Err {
:local Data ([ /tool/fetch check-certificate=yes-without-crl output=user \
http-header-field=({ [ $FetchUserAgentStr $0 ] }) http-method=post \
http-data=[ :serialize to=json { "type"="m.login.password"; "user"=$User; "password"=$Pass } ] \
("https://" . $MatrixHomeServer . "/_matrix/client/r0/login") as-value ]->"data");
:set MatrixAccessToken ([ :deserialize from=json value=$Data ]->"access_token");
$LogPrint debug $0 ("Access token is: " . $MatrixAccessToken);
- } on-error={
- $LogPrint error $0 ("Failed logging in (and getting access token)!");
+ } do={
+ $LogPrint error $0 ("Failed logging in (and getting access token): " . $Err);
:return false;
}
- :do {
+ :onerror Err {
/system/script/remove [ find where name="global-config-overlay.d/mod/notification-matrix" ];
/system/script/add name="global-config-overlay.d/mod/notification-matrix" source=( \
"# configuration snippet: mod/notification-matrix\n\n" . \
":global MatrixHomeServer \"" . $MatrixHomeServer . "\";\n" . \
":global MatrixAccessToken \"" . $MatrixAccessToken . "\";\n");
$LogPrint info $0 ("Added configuration snippet. Now create and join a room, please!");
- } on-error={
- $LogPrint error $0 ("Failed adding configuration snippet!");
+ } do={
+ $LogPrint error $0 ("Failed adding configuration snippet: " . $Err);
:return false;
}
}
@@ -243,24 +248,24 @@
:global MatrixHomeServer;
:global MatrixRoom;
- :do {
+ :onerror Err {
/tool/fetch check-certificate=yes-without-crl output=none \
http-header-field=({ [ $FetchUserAgentStr $0 ] }) http-method=post http-data="" \
("https://" . $MatrixHomeServer . "/_matrix/client/r0/rooms/" . [ $UrlEncode $MatrixRoom ] . \
"/join?access_token=" . [ $UrlEncode $MatrixAccessToken ]) as-value;
$LogPrint debug $0 ("Joined the room.");
- } on-error={
- $LogPrint error $0 ("Failed joining the room!");
+ } do={
+ $LogPrint error $0 ("Failed joining the room: " . $Err);
:return false;
}
- :do {
+ :onerror Err {
:local Snippet [ /system/script/find where name="global-config-overlay.d/mod/notification-matrix" ];
/system/script/set $Snippet source=([ get $Snippet source ] . \
":global MatrixRoom \"" . $MatrixRoom . "\";\n");
$LogPrint info $0 ("Appended configuration to configuration snippet. Please review!");
- } on-error={
- $LogPrint error $0 ("Failed appending configuration to snippet!");
+ } do={
+ $LogPrint error $0 ("Failed appending configuration to snippet: " . $Err);
:return false;
}
}
diff --git a/mod/notification-ntfy.rsc b/mod/notification-ntfy.rsc
index 4413f07..7114020 100644
--- a/mod/notification-ntfy.rsc
+++ b/mod/notification-ntfy.rsc
@@ -1,12 +1,13 @@
#!rsc by RouterOS
# RouterOS script: mod/notification-ntfy
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, fetch, scheduler
#
# send notifications via Ntfy (ntfy.sh)
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/notification-ntfy.md
+# https://rsc.eworm.de/doc/mod/notification-ntfy.md
:global FlushNtfyQueue;
:global NotificationFunctions;
@@ -15,9 +16,8 @@
:global SendNtfy2;
# flush ntfy queue
-:set FlushNtfyQueue do={
+:set FlushNtfyQueue do={ :onerror Err {
:global NtfyQueue;
- :global NtfyMessageIDs;
:global IsFullyConnected;
:global LogPrint;
@@ -36,13 +36,13 @@
:foreach Id,Message in=$NtfyQueue do={
:if ([ :typeof $Message ] = "array" ) do={
- :do {
+ :onerror Err {
/tool/fetch check-certificate=yes-without-crl output=none http-method=post \
http-header-field=($Message->"headers") http-data=($Message->"text") \
- ($Message->"url") user=($Message->"user") password=($Message->"pass") as-value;
+ ($Message->"url") as-value;
:set ($NtfyQueue->$Id);
- } on-error={
- $LogPrint debug $0 ("Sending queued Ntfy message failed.");
+ } do={
+ $LogPrint debug $0 ("Sending queued Ntfy message failed: " . $Err);
:set AllDone false;
}
}
@@ -52,7 +52,9 @@
/system/scheduler/remove [ find where name="_FlushNtfyQueue" ];
:set NtfyQueue;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via ntfy - expects one array argument
:set ($NotificationFunctions->"ntfy") do={
@@ -65,6 +67,8 @@
:global NtfyServerOverride;
:global NtfyServerPass;
:global NtfyServerPassOverride;
+ :global NtfyServerToken;
+ :global NtfyServerTokenOverride;
:global NtfyServerUser;
:global NtfyServerUserOverride;
:global NtfyTopic;
@@ -81,32 +85,39 @@
:local Server [ $EitherOr ($NtfyServerOverride->($Notification->"origin")) $NtfyServer ];
:local User [ $EitherOr ($NtfyServerUserOverride->($Notification->"origin")) $NtfyServerUser ];
:local Pass [ $EitherOr ($NtfyServerPassOverride->($Notification->"origin")) $NtfyServerPass ];
+ :local Token [ $EitherOr ($NtfyServerTokenOverride->($Notification->"origin")) $NtfyServerToken ];
:local Topic [ $EitherOr ($NtfyTopicOverride->($Notification->"origin")) $NtfyTopic ];
:if ([ :len $Topic ] = 0) do={
:return false;
}
- :local Url ("https://" . $NtfyServer . "/" . [ $UrlEncode $NtfyTopic ]);
+ :local Url ("https://" . $Server . "/" . [ $UrlEncode $Topic ]);
:local Headers ({ [ $FetchUserAgentStr ($Notification->"origin") ]; \
("Priority: " . [ $IfThenElse ($Notification->"silent") "low" "default" ]); \
("Title: " . "[" . $IdentityExtra . $Identity . "] " . ($Notification->"subject")) });
+ :if ([ :len $User ] > 0 || [ :len $Pass ] > 0) do={
+ :set Headers ($Headers, ("Authorization: Basic " . [ :convert to=base64 ($User . ":" . $Pass) ]));
+ }
+ :if ([ :len $Token ] > 0) do={
+ :set Headers ($Headers, ("Authorization: Bearer " . $Token));
+ }
:local Text (($Notification->"message") . "\n");
:if ([ :len ($Notification->"link") ] > 0) do={
:set Text ($Text . "\n" . [ $SymbolForNotification "link" ] . ($Notification->"link"));
}
- :do {
- :if ($NtfyServer = "ntfy.sh") do={
- :if ([ $CertificateAvailable "R3" ] = false) do={
+ :onerror Err {
+ :if ($Server = "ntfy.sh") do={
+ :if ([ $CertificateAvailable "ISRG Root X1" ] = false) do={
$LogPrint warning $0 ("Downloading required certificate failed.");
:error false;
}
}
/tool/fetch check-certificate=yes-without-crl output=none http-method=post \
- http-header-field=$Headers http-data=$Text $Url user=$User password=$Pass as-value;
- } on-error={
- $LogPrint info $0 ("Failed sending ntfy notification! Queuing...");
+ http-header-field=$Headers http-data=$Text $Url as-value;
+ } do={
+ $LogPrint info $0 ("Failed sending ntfy notification: " . $Err . " - Queuing...");
:if ([ :typeof $NtfyQueue ] = "nothing") do={
:set NtfyQueue ({});
@@ -115,7 +126,7 @@
"This message was queued since " . [ /system/clock/get date ] . " " . \
[ /system/clock/get time ] . " and may be obsolete.");
:set ($NtfyQueue->[ :len $NtfyQueue ]) \
- { url=$Url; user=$User; pass=$Pass; headers=$Headers; text=$Text };
+ { url=$Url; headers=$Headers; text=$Text };
:if ([ :len [ /system/scheduler/find where name="_FlushNtfyQueue" ] ] = 0) do={
/system/scheduler/add name="_FlushNtfyQueue" interval=1m start-time=startup \
on-event=(":global FlushNtfyQueue; \$FlushNtfyQueue;");
@@ -132,11 +143,13 @@
}
# send notification via ntfy - expects at least two string arguments
-:set SendNtfy do={
+:set SendNtfy do={ :onerror Err {
:global SendNtfy2;
$SendNtfy2 ({ origin=$0; subject=$1; message=$2; link=$3; silent=$4 });
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via ntfy - expects one array argument
:set SendNtfy2 do={
diff --git a/mod/notification-telegram.rsc b/mod/notification-telegram.rsc
index 9a628ce..2eb90e1 100644
--- a/mod/notification-telegram.rsc
+++ b/mod/notification-telegram.rsc
@@ -1,27 +1,28 @@
#!rsc by RouterOS
# RouterOS script: mod/notification-telegram
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, fetch, scheduler
#
# send notifications via Telegram
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/notification-telegram.md
+# https://rsc.eworm.de/doc/mod/notification-telegram.md
:global FlushTelegramQueue;
+:global GetTelegramChatId;
:global NotificationFunctions;
:global PurgeTelegramQueue;
:global SendTelegram;
:global SendTelegram2;
# flush telegram queue
-:set FlushTelegramQueue do={
+:set FlushTelegramQueue do={ :onerror Err {
:global TelegramQueue;
:global TelegramMessageIDs;
:global IsFullyConnected;
:global LogPrint;
- :global UrlEncode;
:if ([ $IsFullyConnected ] = false) do={
$LogPrint debug $0 ("System is not fully connected, not flushing.");
@@ -37,16 +38,14 @@
:foreach Id,Message in=$TelegramQueue do={
:if ([ :typeof $Message ] = "array" ) do={
- :do {
+ :onerror Err {
:local Data ([ /tool/fetch check-certificate=yes-without-crl output=user http-method=post \
("https://api.telegram.org/bot" . ($Message->"tokenid") . "/sendMessage") \
- http-data=("chat_id=" . ($Message->"chatid") . "&disable_notification=" . ($Message->"silent") . \
- "&reply_to_message_id=" . ($Message->"replyto") . "&disable_web_page_preview=true" . \
- "&parse_mode=MarkdownV2&text=" . [ $UrlEncode ($Message->"text") ]) as-value ]->"data");
+ http-data=($Message->"http-data") as-value ]->"data");
:set ($TelegramQueue->$Id);
:set ($TelegramMessageIDs->[ :tostr ([ :deserialize from=json value=$Data ]->"result"->"message_id") ]) 1;
- } on-error={
- $LogPrint debug $0 ("Sending queued Telegram message failed.");
+ } do={
+ $LogPrint debug $0 ("Sending queued Telegram message failed: " . $Err);
:set AllDone false;
}
}
@@ -56,7 +55,48 @@
/system/scheduler/remove [ find where name="_FlushTelegramQueue" ];
:set TelegramQueue;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
+
+# get the chat id
+:set GetTelegramChatId do={ :onerror Err {
+ :global TelegramTokenId;
+
+ :global CertificateAvailable;
+ :global LogPrint;
+
+ :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" ] = false) do={
+ $LogPrint warning $0 ("Downloading required certificate failed.");
+ :return false;
+ }
+
+ :local Data;
+ :onerror Err {
+ :set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \
+ ("https://api.telegram.org/bot" . $TelegramTokenId . "/getUpdates?offset=0" . \
+ "&allowed_updates=%5B%22message%22%5D") as-value ]->"data");
+ } do={
+ $LogPrint warning $0 ("Fetching data failed: " . $Err);
+ :return false;
+ }
+
+ :local JSON [ :deserialize from=json value=$Data ];
+ :local Count [ :len ($JSON->"result") ];
+
+ :if ($Count = 0) do={
+ $LogPrint info $0 ("No message received.");
+ :return false;
+ }
+
+ :local Message ($JSON->"result"->($Count - 1)->"message");
+ $LogPrint info $0 ("The chat id is: " . ($Message->"chat"->"id"));
+ :if (($Message->"is_topic_message") = true) do={
+ $LogPrint info $0 ("The thread id is: " . ($Message->"message_thread_id"));
+ }
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via telegram - expects one array argument
:set ($NotificationFunctions->"telegram") do={
@@ -68,6 +108,8 @@
:global TelegramChatIdOverride;
:global TelegramMessageIDs;
:global TelegramQueue;
+ :global TelegramThreadId;
+ :global TelegramThreadIdOverride;
:global TelegramTokenId;
:global TelegramTokenIdOverride;
@@ -108,6 +150,9 @@
:local ChatId [ $EitherOr ($Notification->"chatid") \
[ $EitherOr ($TelegramChatIdOverride->($Notification->"origin")) $TelegramChatId ] ];
+ :local ThreadId [ $EitherOr ($Notification->"threadid") \
+ [ $EitherOr ($TelegramThreadIdOverride->($Notification->"origin")) \
+ [ $IfThenElse ([ :len ($TelegramChatIdOverride->($Notification->"origin")) ] = 0) $TelegramThreadId ] ] ];
:local TokenId [ $EitherOr ($TelegramTokenIdOverride->($Notification->"origin")) $TelegramTokenId ];
:if ([ :len $TokenId ] = 0 || [ :len $ChatId ] = 0) do={
@@ -142,19 +187,20 @@
(($LenSum - [ :len $Text ]) * 100 / $LenSum) . "%_!") "plain" "_" ]);
}
- :do {
- :if ([ $CertificateAvailable "Go Daddy Secure Certificate Authority - G2" ] = false) do={
+ :local HTTPData ("chat_id=" . $ChatId . "&disable_notification=" . ($Notification->"silent") . \
+ "&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" ] = false) do={
$LogPrint warning $0 ("Downloading required certificate failed.");
:error false;
}
:local Data ([ /tool/fetch check-certificate=yes-without-crl output=user http-method=post \
("https://api.telegram.org/bot" . $TokenId . "/sendMessage") \
- http-data=("chat_id=" . $ChatId . "&disable_notification=" . ($Notification->"silent") . \
- "&reply_to_message_id=" . ($Notification->"replyto") . "&disable_web_page_preview=true" . \
- "&parse_mode=MarkdownV2&text=" . [ $UrlEncode $Text ]) as-value ]->"data");
+ http-data=($HTTPData . "&text=" . [ $UrlEncode $Text ]) as-value ]->"data");
:set ($TelegramMessageIDs->[ :tostr ([ :deserialize from=json value=$Data ]->"result"->"message_id") ]) 1;
- } on-error={
- $LogPrint info $0 ("Failed sending Telegram notification! Queuing...");
+ } do={
+ $LogPrint info $0 ("Failed sending Telegram notification: " . $Err . " - Queuing...");
:if ([ :typeof $TelegramQueue ] = "nothing") do={
:set TelegramQueue ({});
@@ -162,8 +208,8 @@
:set Text ($Text . "\n" . [ $SymbolForNotification "alarm-clock" ] . \
[ $EscapeMD ("This message was queued since _" . [ /system/clock/get date ] . \
" " . [ /system/clock/get time ] . "_ and may be obsolete.") "plain" "_" ]);
- :set ($TelegramQueue->[ :len $TelegramQueue ]) { chatid=$ChatId; tokenid=$TokenId;
- text=$Text; silent=($Notification->"silent"); replyto=($Notification->"replyto") };
+ :set ($TelegramQueue->[ :len $TelegramQueue ]) { tokenid=$TokenId;
+ http-data=($HTTPData . "&text=" . [ $UrlEncode $Text ]) };
:if ([ :len [ /system/scheduler/find where name="_FlushTelegramQueue" ] ] = 0) do={
/system/scheduler/add name="_FlushTelegramQueue" interval=1m start-time=startup \
on-event=(":global FlushTelegramQueue; \$FlushTelegramQueue;");
@@ -180,11 +226,13 @@
}
# send notification via telegram - expects at least two string arguments
-:set SendTelegram do={
+:set SendTelegram do={ :onerror Err {
:global SendTelegram2;
$SendTelegram2 ({ origin=$0; subject=$1; message=$2; link=$3; silent=$4 });
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via telegram - expects one array argument
:set SendTelegram2 do={
diff --git a/mod/scriptrunonce.rsc b/mod/scriptrunonce.rsc
index c3972a0..1d6aaf1 100644
--- a/mod/scriptrunonce.rsc
+++ b/mod/scriptrunonce.rsc
@@ -1,22 +1,23 @@
#!rsc by RouterOS
# RouterOS script: mod/scriptrunonece
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# download script and run it once
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/scriptrunonce.md
+# https://rsc.eworm.de/doc/mod/scriptrunonce.md
:global ScriptRunOnce;
# fetch and run script(s) once
-:set ScriptRunOnce do={
+:set ScriptRunOnce do={ :onerror Err {
:local Scripts [ :toarray $1 ];
:global ScriptRunOnceBaseUrl;
:global ScriptRunOnceUrlSuffix;
+ :global FetchHuge;
:global LogPrint;
:global ValidateSyntax;
@@ -29,24 +30,27 @@
:set Script ($ScriptRunOnceBaseUrl . $Script . ".rsc" . $ScriptRunOnceUrlSuffix);
}
- :local Source;
- :do {
- :set Source ([ /tool/fetch check-certificate=yes-without-crl $Script output=user as-value ]->"data");
- } on-error={
+ :local Source [ $FetchHuge $0 $Script true ];
+ :if ($Source = false) do={
$LogPrint warning $0 ("Failed fetching script '" . $Script . "'!");
+ :return false;
}
- :if ([ :len $Source ] > 0) do={
- :if ([ $ValidateSyntax $Source ] = true) do={
- :do {
- $LogPrint info $0 ("Running script '" . $Script . "' now.");
- [ :parse $Source ];
- } on-error={
- $LogPrint warning $0 ("The script '" . $Script . "' failed to run!");
- }
- } else={
- $LogPrint warning $0 ("The script '" . $Script . "' failed syntax validation!");
- }
+ :if ([ $ValidateSyntax $Source ] = false) do={
+ $LogPrint warning $0 ("The script '" . $Script . "' failed syntax validation!");
+ :return false;
+ }
+
+ :onerror Err {
+ $LogPrint info $0 ("Running script '" . $Script . "' now.");
+ [ :parse $Source ];
+ } do={
+ $LogPrint warning $0 ("The script '" . $Script . "' failed to run: " . $Err);
+ :return false;
}
+
+ :return true;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
diff --git a/mod/ssh-keys-import.rsc b/mod/ssh-keys-import.rsc
index 6272a93..7bdc95d 100644
--- a/mod/ssh-keys-import.rsc
+++ b/mod/ssh-keys-import.rsc
@@ -1,25 +1,25 @@
#!rsc by RouterOS
# RouterOS script: mod/ssh-keys-import
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.16
#
# import ssh keys for public key authentication
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/ssh-keys-import.md
+# https://rsc.eworm.de/doc/mod/ssh-keys-import.md
:global SSHKeysImport;
:global SSHKeysImportFile;
# import single key passed as string
-:set SSHKeysImport do={
+:set SSHKeysImport do={ :onerror Err {
:local Key [ :tostr $1 ];
:local User [ :tostr $2 ];
- :global CharacterReplace;
:global GetRandom20CharAlNum;
:global LogPrint;
:global MkDir;
+ :global RmDir;
:global WaitForFile;
:if ([ :len $Key ] = 0 || [ :len $User ] = 0) do={
@@ -32,7 +32,7 @@
:return false;
}
- :local KeyVal [ :toarray [ $CharacterReplace $Key " " "," ] ];
+ :local KeyVal ([ :deserialize $Key delimiter=" " from=dsv options=dsv.plain ]->0);
:if (!($KeyVal->0 = "ssh-ed25519" || $KeyVal->0 = "ssh-rsa")) do={
$LogPrint warning $0 ("SSH key of type '" . $KeyVal->0 . "' is not supported.");
:return false;
@@ -55,25 +55,27 @@
/file/add name=$FileName contents=($Key . ", md5=" . $FingerPrintMD5);
$WaitForFile $FileName;
- :do {
+ :onerror Err {
/user/ssh-keys/import public-key-file=$FileName user=$User;
$LogPrint info $0 ("Imported ssh public key (" . $KeyVal->2 . ", " . $KeyVal->0 . ", " . \
"MD5:" . $FingerPrintMD5 . ") for user '" . $User . "'.");
- /file/remove "tmpfs/ssh-keys-import";
- } on-error={
- $LogPrint warning $0 ("Failed importing key.");
- /file/remove "tmpfs/ssh-keys-import";
+ $RmDir "tmpfs/ssh-keys-import";
+ } do={
+ $LogPrint warning $0 ("Failed importing key: " . $Err);
+ $RmDir "tmpfs/ssh-keys-import";
:return false;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# import keys from a file
-:set SSHKeysImportFile do={
+:set SSHKeysImportFile do={ :onerror Err {
:local FileName [ :tostr $1 ];
:local User [ :tostr $2 ];
- :global CharacterReplace;
:global EitherOr;
+ :global FileExists;
:global LogPrint;
:global ParseKeyValueStore;
:global SSHKeysImport;
@@ -83,32 +85,28 @@
:return false;
}
- :local File [ /file/find where name=$FileName ];
- :if ([ :len $File ] = 0) do={
+ :if ([ $FileExists $FileName ] = true) do={
$LogPrint warning $0 ("File '" . $FileName . "' does not exist.");
:return false;
}
- :local Keys ([ /file/get $FileName contents ] . "\n");
+ :local Keys [ :tolf [ /file/get $FileName contents ] ];
- :do {
+ :foreach KeyVal in=[ :deserialize $Keys delimiter=" " from=dsv options=dsv.plain ] do={
:local Continue false;
- :local Line [ :pick $Keys 0 [ :find $Keys "\n" ] ];
- :set Keys [ :pick $Keys ([ :find $Keys "\n" ] + 1) [ :len $Keys ] ];
- :local KeyVal [ :toarray [ $CharacterReplace $Line " " "," ] ];
:if ($KeyVal->0 = "ssh-ed25519" || $KeyVal->0 = "ssh-rsa") do={
- :do {
- $SSHKeysImport $Line $User;
- } on-error={
+ :if ([ $SSHKeysImport ($KeyVal->0 . " " . $KeyVal->1 . " " . $KeyVal->2) $User ] = false) do={
$LogPrint warning $0 ("Failed importing key for user '" . $User . "'.");
}
:set Continue true;
}
:if ($Continue = false && $KeyVal->0 = "#") do={
- :set User [ $EitherOr ([ $ParseKeyValueStore [ :pick $Line 2 [ :len $Line ] ] ]->"user") $User ];
+ :set User [ $EitherOr ([ $ParseKeyValueStore ($KeyVal->1) ]->"user") $User ];
:set Continue true;
}
:if ($Continue = false && [ :len ($KeyVal->0) ] > 0) do={
$LogPrint warning $0 ("SSH key of type '" . $KeyVal->0 . "' is not supported.");
}
- } while=([ :len $Keys ] > 0);
-}
+ }
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
diff --git a/mode-button.rsc b/mode-button.rsc
index 4994f6b..d82f899 100644
--- a/mode-button.rsc
+++ b/mode-button.rsc
@@ -1,17 +1,19 @@
#!rsc by RouterOS
# RouterOS script: mode-button
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, scheduler
#
# act on multiple mode and reset button presses
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mode-button.md
+# https://rsc.eworm.de/doc/mode-button.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global ModeButton;
@@ -24,7 +26,9 @@
:if ([ :len $Scheduler ] = 0) do={
$LogPrint info $ScriptName ("Creating scheduler _ModeButtonScheduler, counting presses...");
- :global ModeButtonScheduler do={
+ :global ModeButtonScheduler do={ :onerror Err {
+ :local FuncName $0;
+
:global ModeButton;
:global LogPrint;
@@ -36,7 +40,8 @@
:global IfThenElse;
- :local LED [ /system/leds/find where leds=$ModeButtonLED type~"^(on|off)\$" interface=[] ];
+ :local LED [ /system/leds/find where leds=$ModeButtonLED \
+ !disabled type~"^(on|off)\$" interface=[] ];
:if ([ :len $LED ] = 0) do={
:return false;
}
@@ -52,7 +57,7 @@
:if ([ :len $Code ] > 0) do={
:if ([ $ValidateSyntax $Code ] = true) do={
- $LogPrint info $ScriptName ("Acting on " . $Count . " mode-button presses: " . $Code);
+ $LogPrint info $FuncName ("Acting on " . $Count . " mode-button presses: " . $Code);
:for I from=1 to=$Count do={
$LEDInvert;
@@ -64,18 +69,28 @@
:delay 200ms;
}
- [ :parse $Code ];
+ :onerror Err {
+ [ :parse $Code ];
+ } do={
+ $LogPrint warning $FuncName \
+ ("The code for " . $Count . " mode-button presses failed with runtime error: " . $Err);
+ }
} else={
- $LogPrint warning $ScriptName ("The code for " . $Count . " mode-button presses failed syntax validation!");
+ $LogPrint warning $FuncName \
+ ("The code for " . $Count . " mode-button presses failed syntax validation!");
}
} else={
- $LogPrint info $ScriptName ("No action defined for " . $Count . " mode-button presses.");
+ $LogPrint info $FuncName ("No action defined for " . $Count . " mode-button presses.");
}
- }
+ } do={
+ :global ExitError; $ExitError false $0 $Err;
+ } }
/system/scheduler/add name="_ModeButtonScheduler" \
on-event=":global ModeButtonScheduler; \$ModeButtonScheduler;" interval=3s;
} else={
$LogPrint debug $ScriptName ("Updating scheduler _ModeButtonScheduler...");
/system/scheduler/set $Scheduler start-time=[ /system/clock/get time ];
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/netwatch-dns.rsc b/netwatch-dns.rsc
index 09365ba..9e2f9bc 100644
--- a/netwatch-dns.rsc
+++ b/netwatch-dns.rsc
@@ -1,32 +1,39 @@
#!rsc by RouterOS
# RouterOS script: netwatch-dns
-# Copyright (c) 2022-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2022-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.16
+# requires device-mode, fetch
#
# monitor and manage dns/doh with netwatch
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/netwatch-dns.md
+# https://rsc.eworm.de/doc/netwatch-dns.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global CertificateAvailable;
:global EitherOr;
+ :global IsDNSResolving;
+ :global IsTimeSync;
:global LogPrint;
+ :global LogPrintOnce;
:global ParseKeyValueStore;
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
:local SettleTime (5m30s - [ /system/resource/get uptime ]);
:if ($SettleTime > 0s) do={
$LogPrint info $ScriptName ("System just booted, giving netwatch " . $SettleTime . " to settle.");
+ :set ExitOK true;
:error true;
}
@@ -67,11 +74,17 @@
:local DohCurrent [ /ip/dns/get use-doh-server ];
:local DohServers ({});
+ :if ([ :len $DohCurrent ] > 0 && [ $IsDNSResolving ] = false && [ $IsTimeSync ] = false) do={
+ $LogPrint info $ScriptName ("Time is not sync, disabling DoH: " . $DohCurrent);
+ /ip/dns/set use-doh-server="";
+ :set DohCurrent "";
+ }
+
:foreach Host in=[ /tool/netwatch/find where comment~"\\bdoh\\b" status="up" ] do={
:local HostVal [ /tool/netwatch/get $Host ];
:local HostInfo [ $ParseKeyValueStore ($HostVal->"comment") ];
:local HostName [ /ip/dns/static/find where name address=($HostVal->"host") \
- (!type or type="A" or type="AAAA") !disabled !dynamic ];
+ (type="A" or type="AAAA") !disabled !dynamic ];
:if ([ :len $HostName ] > 0) do={
:set HostName [ /ip/dns/static/get ($HostName->0) name ];
}
@@ -83,6 +96,7 @@
:if ($DohCurrent = $HostInfo->"doh-url") do={
$LogPrint debug $ScriptName ("Current DoH server is still up: " . $DohCurrent);
+ :set ExitOK true;
:error true;
}
@@ -104,22 +118,28 @@
}
:local Data false;
- :do {
- :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");
- } on-error={
- $LogPrint warning $ScriptName ("Request to DoH server failed (network or certificate issue): " . \
- ($DohServer->"doh-url"));
+ :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;
+ } do={
+ $LogPrint warning $ScriptName ("Request to DoH server " . ($DohServer->"doh-url") . \
+ " failed: " . $Err);
}
:if ($Data != false) do={
:if ([ :typeof [ :find $Data "doh-check-OK" ] ] = "num") do={
/ip/dns/set use-doh-server=($DohServer->"doh-url") verify-doh-cert=yes;
+ :if ([ /certificate/settings/get crl-use ] = true) do={
+ $LogPrintOnce warning $ScriptName ("Configured to use CRL, that can cause severe issue!");
+ }
/ip/dns/cache/flush;
$LogPrint info $ScriptName ("Setting DoH server: " . ($DohServer->"doh-url"));
+ :set ExitOK true;
:error true;
} else={
$LogPrint warning $ScriptName ("Received unexpected response from DoH server: " . \
@@ -127,4 +147,6 @@
}
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc
index 17682f0..00f03cd 100644
--- a/netwatch-notify.rsc
+++ b/netwatch-notify.rsc
@@ -1,17 +1,18 @@
#!rsc by RouterOS
# RouterOS script: netwatch-notify
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# monitor netwatch and send notifications
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/netwatch-notify.md
+# https://rsc.eworm.de/doc/netwatch-notify.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global NetwatchNotify;
@@ -37,10 +38,10 @@
:global ValidateSyntax;
:if ([ $ValidateSyntax $Hook ] = true) do={
- :do {
+ onerror Err {
[ :parse $Hook ];
- } on-error={
- $LogPrint warning $ScriptName ("The " . $State . "-hook for " . $Type . " '" . $Name . "' failed to run.");
+ } do={
+ $LogPrint warning $ScriptName ("The " . $State . "-hook for " . $Type . " '" . $Name . "' failed to run: " . $Err);
:return ("The hook failed to run.");
}
} else={
@@ -60,21 +61,26 @@
:global GetRandom20CharAlNum;
:local FwAddrList ($ScriptName . "-" . [ $GetRandom20CharAlNum ]);
- /ip/firewall/address-list/add address=$Name list=$FwAddrList dynamic=yes timeout=1s;
- :delay 20ms;
- :if ([ :len [ /ip/firewall/address-list/find where list=$FwAddrList address=$Expected ] ] > 0) do={
- :return true;
+ :if ([ :typeof [ :toip $Expected ] ] = "ip") do={
+ /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;
+ }
}
- /ipv6/firewall/address-list/add address=$Name list=$FwAddrList dynamic=yes timeout=1s;
- :delay 20ms;
- :if ([ :len [ /ipv6/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=10s;
+ :delay 20ms;
+ :if ([ :len [ /ipv6/firewall/address-list/find where list=$FwAddrList address=$Expected ] ] > 0) do={
+ :return true;
+ }
}
:return false;
}
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -101,8 +107,9 @@
:if ([ :typeof ($HostInfo->"resolve") ] = "str") do={
:if ([ $IsDNSResolving ] = true) do={
- :do {
- :local Resolve [ :resolve ($HostInfo->"resolve") ];
+ :onerror Err {
+ :local Resolve [ :resolve type=[ $IfThenElse ([ :typeof ($HostVal->"host") ] = "ip") \
+ "ipv4" "ipv6" ] ($HostInfo->"resolve") ];
:if ($Resolve != $HostVal->"host") do={
:if ([ $ResolveExpected $ScriptName ($HostInfo->"resolve") ($HostVal->"host") ] = false) do={
$LogPrint info $ScriptName ("Name '" . $HostInfo->"resolve" . [ $IfThenElse \
@@ -114,13 +121,13 @@
:set ($HostVal->"status") "unknown";
}
}
- } on-error={
+ } do={
:set ($Metric->"resolve-failcnt") ($Metric->"resolve-failcnt" + 1);
:if ($Metric->"resolve-failcnt" = 3) do={
$LogPrint [ $IfThenElse ($HostInfo->"no-resolve-fail" != true) warning debug ] \
$ScriptName ("Resolving name '" . $HostInfo->"resolve" . [ $IfThenElse \
($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \
- $HostInfo->"name") "" ] . "' failed.");
+ $HostInfo->"name") "" ] . "' failed: " . $Err);
}
}
}
@@ -217,4 +224,6 @@
"since"=($Metric->"since") };
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/news-and-changes.rsc b/news-and-changes.rsc
index 8ddeb91..dbfb1b9 100644
--- a/news-and-changes.rsc
+++ b/news-and-changes.rsc
@@ -1,6 +1,6 @@
# News, changes and migration by RouterOS Scripts
-# Copyright (c) 2019-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
:global IDonate;
@@ -52,12 +52,25 @@
125=("April's Fool! " . [ $SymbolForNotification "smiley-partying-face" ] . "Well, you missed it... - no charge nor fees. (Anyway... Donations are much appreciated, " . [ $SymbolForNotification "smiley-smiling-face" ] . "thanks!)");
126="Made 'telegram-chat' capable of handling large command output. Telegram messages still limit the size, so it is truncated now.";
127="Added support for authentication to Ntfy notification module.";
+ 128="Added another list from blocklist.de to default configuration for 'fw-addr-lists'.";
+ 129="Extended 'backup-partition' to support RouterOS copy-over - interactively or before feature update.";
+ 130="Dropped intermediate certificates, depending on just root certificates now.";
+ 131="Enhanced certificate download to fallback to mkcert.org, so all (commonly trusted) root certificates are available now.";
+ 132="Split off plugins from 'check-health', so the script works on all devices to monitor CPU and RAM. The supported plugins for sensors in hardware are installed automatically.";
+ 133="Updated the default configuration for 'fw-addr-lists', deprecated lists were removed, a collective list was added.";
+ 134="Enhanced 'mod/notification-telegram' and 'telegram-chat' to support topics in groups.";
+ 135="Introduced helper function '\$GetTelegramChatId' for 'mod/notification-telegram' which helps retrieve information.";
+ 136="Introduced script 'check-perpetual-license' to check for license state on CHR.";
+ 137="Added support to send notifications via Gotify (gotify.net).";
+ 138="RouterOS 7.19 is suffering an issue with certificate store. Fixing trust state for all certificates...";
};
# Migration steps to be applied on script updates
:global GlobalConfigMigration {
97=":local Rec [ /ip/dns/static/find where comment~\"^managed by dhcp-to-dns for \" ]; :if ([ :len \$Rec ] > 0) do={ /ip/dns/static/remove \$Rec; /system/script/run dhcp-to-dns; }";
- 100=":global ScriptInstallUpdate; :if ([ :len [ /system/script/find where name=\"ssh-keys-import\" source~\"^#!rsc by RouterOS\\n\" ] ] > 0) do={ /system/script/set name=\"mod/ssh-keys-import\" ssh-keys-import; \$ScriptInstallUpdate; }";
+ 100=":global ScriptInstallUpdate; :if ([ :len [ /system/script/find where name=\"ssh-keys-import\" source~\"^#!rsc by RouterOS\\r?\\n\" ] ] > 0) do={ /system/script/set name=\"mod/ssh-keys-import\" ssh-keys-import; \$ScriptInstallUpdate; }";
104=":global CharacterReplace; :global ScriptInstallUpdate; :foreach Script in={ \"capsman-download-packages\"; \"capsman-rolling-upgrade\"; \"hotspot-to-wpa\"; \"hotspot-to-wpa-cleanup\" } do={ /system/script/set name=(\$Script . \".capsman\") [ find where name=\$Script ]; :foreach Scheduler in=[ /system/scheduler/find where on-event~(\$Script . \"([^-.]|\\\$)\") ] do={ /system/scheduler/set \$Scheduler on-event=[ \$CharacterReplace [ get \$Scheduler on-event ] \$Script (\$Script . \".capsman\") ]; }; }; /ip/hotspot/user/profile/set on-login=\"hotspot-to-wpa.capsman\" [ find where on-login=\"hotspot-to-wpa\" ]; \$ScriptInstallUpdate;";
111=":local Rec [ /ip/dns/static/find where comment~\"^managed by dhcp-to-dns for \" ]; :if ([ :len \$Rec ] > 0) do={ /ip/dns/static/remove \$Rec; /system/script/run dhcp-to-dns; }";
+ 132=":if ([ :len [ /system/script/find where name=\"check-health\" ] ] > 0) do={ :local Code \":local Install \\\"check-health\\\"; :if ([ :len [ /system/health/find where type=\\\"\\\" name~\\\"-state\\\\\\\$\\\" ] ] > 0) do={ :set Install (\\\$Install . \\\",check-health.d/state\\\"); }; :if ([ :len [ /system/health/find where type=\\\"C\\\" ] ] > 0) do={ :set Install (\\\$Install . \\\",check-health.d/temperature\\\"); }; :if ([ :len [ /system/health/find where type=\\\"V\\\" ] ] > 0) do={ :set Install (\\\$Install . \\\",check-health.d/voltage\\\"); }; :global ScriptInstallUpdate; \\\$ScriptInstallUpdate \\\$Install;\"; :global ValidateSyntax; :if ([ \$ValidateSyntax \$Code ] = true) do={ :do { [ :parse \$Code ]; } on-error={ }; }; }";
+ 138="/certificate/set trusted=yes [ find where trusted=yes ];";
};
diff --git a/ospf-to-leds.rsc b/ospf-to-leds.rsc
index 0932815..26f8aa3 100644
--- a/ospf-to-leds.rsc
+++ b/ospf-to-leds.rsc
@@ -1,17 +1,18 @@
#!rsc by RouterOS
# RouterOS script: ospf-to-leds
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# visualize ospf instance state via leds
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/ospf-to-leds.md
+# https://rsc.eworm.de/doc/ospf-to-leds.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global LogPrint;
@@ -19,6 +20,7 @@
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -42,4 +44,6 @@
/system/leds/set type=off [ find where leds=$LED ];
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/packages-update.rsc b/packages-update.rsc
index 0208b1e..d3140f2 100644
--- a/packages-update.rsc
+++ b/packages-update.rsc
@@ -1,19 +1,25 @@
#!rsc by RouterOS
# RouterOS script: packages-update
-# Copyright (c) 2019-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, scheduler
#
# download packages and reboot for installation
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/packages-update.md
+# https://rsc.eworm.de/doc/packages-update.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
+ :global BackupRandomDelay;
+ :global PackagesUpdateDeferReboot;
+ :global PackagesUpdateBackupFailure;
+
:global DownloadPackage;
:global Grep;
:global LogPrint;
@@ -22,29 +28,39 @@
:global ScriptLock;
:global VersionToNum;
- :global PackagesUpdateDeferReboot;
- :global PackagesUpdateBackupFailure;
-
:local Schedule do={
:local ScriptName [ :tostr $1 ];
+ :global PackagesUpdateDeferReboot;
+
:global GetRandomNumber;
+ :global IfThenElse;
:global LogPrint;
:global RebootForUpdate do={
/system/reboot;
}
+ :local Interval [ $IfThenElse ([ :totime $PackagesUpdateDeferReboot ] >= 1d) \
+ $PackagesUpdateDeferReboot 1d ];
:local StartTime [ :tostr [ :totime (10800 + [ $GetRandomNumber 7200 ]) ] ];
- /system/scheduler/add name="_RebootForUpdate" start-time=$StartTime interval=1d \
+ /system/scheduler/add name="_RebootForUpdate" start-time=$StartTime interval=$Interval \
on-event=("/system/scheduler/remove \"_RebootForUpdate\"; " . \
":global RebootForUpdate; \$RebootForUpdate;");
$LogPrint info $ScriptName ("Scheduled reboot for update at " . $StartTime . \
- " local time (" . [ /system/clock/get time-zone-name ] . ").");
+ " local time (" . [ /system/clock/get time-zone-name ] . ")" . \
+ [ $IfThenElse ($Interval > 1d) (" deferred by " . $Interval) ] . ".");
:return true;
}
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
+ :error false;
+ }
+
+ :if ([ :len [ /system/scheduler/find where name="running-from-backup-partition" ] ] > 0) do={
+ $LogPrint warning $ScriptName ("Running from backup partition, refusing to act.");
+ :set ExitOK true;
:error false;
}
@@ -52,40 +68,16 @@
:if ([ :typeof ($Update->"latest-version") ] = "nothing") do={
$LogPrint warning $ScriptName ("Latest version is not known.");
+ :set ExitOK true;
:error false;
}
:if ($Update->"installed-version" = $Update->"latest-version") do={
$LogPrint info $ScriptName ("Version " . $Update->"latest-version" . " is already installed.");
+ :set ExitOK true;
:error true;
}
- :local NumInstalled [ $VersionToNum ($Update->"installed-version") ];
- :local NumLatest [ $VersionToNum ($Update->"latest-version") ];
-
- :local DoDowngrade false;
- :if ($NumInstalled > $NumLatest) do={
- :if ([ $ScriptFromTerminal $ScriptName ] = true) do={
- :put "Latest version is older than installed one. Want to downgrade? [y/N]";
- :if (([ /terminal/inkey timeout=60 ] % 32) = 25) do={
- :set DoDowngrade true;
- } else={
- :put "Canceled...";
- }
- } else={
- $LogPrint warning $ScriptName ("Not installing downgrade automatically.");
- :error false;
- }
- }
-
- :foreach Package in=[ /system/package/find where !bundle ] do={
- :local PkgName [ /system/package/get $Package name ];
- :if ([ $DownloadPackage $PkgName ($Update->"latest-version") ] = false) do={
- $LogPrint error $ScriptName ("Download for package " . $PkgName . " failed, update aborted.");
- :error false;
- }
- }
-
:local RunOrder ({});
:foreach Script in=[ /system/script/find where source~("\n# provides: backup-script\\b") ] do={
:local ScriptVal [ /system/script/get $Script ];
@@ -94,7 +86,9 @@
:set ($RunOrder->($Store->"order" . "-" . $ScriptVal->"name")) ($ScriptVal->"name");
}
+ :local BackupRandomDelayBefore $BackupRandomDelay;
:foreach Order,Script in=$RunOrder do={
+ :set BackupRandomDelay 0;
:set PackagesUpdateBackupFailure false;
:do {
$LogPrint info $ScriptName ("Running backup script " . $Script . " before update.");
@@ -102,6 +96,7 @@
} on-error={
:set PackagesUpdateBackupFailure true;
}
+ :set BackupRandomDelay $BackupRandomDelayBefore;
:if ($PackagesUpdateBackupFailure = true) do={
$LogPrint warning $ScriptName ("Running backup script " . $Script . " before update failed!");
@@ -111,15 +106,45 @@
$LogPrint info $ScriptName ("User requested to continue anyway.");
} else={
$LogPrint info $ScriptName ("Canceled update...");
+ :set ExitOK true;
:error false;
}
} else={
$LogPrint warning $ScriptName ("Canceled non-interactive update.");
+ :set ExitOK true;
:error false;
}
}
}
+ :local NumInstalled [ $VersionToNum ($Update->"installed-version") ];
+ :local NumLatest [ $VersionToNum ($Update->"latest-version") ];
+
+ :local DoDowngrade false;
+ :if ($NumInstalled > $NumLatest) do={
+ :if ([ $ScriptFromTerminal $ScriptName ] = true) do={
+ :put "Latest version is older than installed one. Want to downgrade? [y/N]";
+ :if (([ /terminal/inkey timeout=60 ] % 32) = 25) do={
+ :set DoDowngrade true;
+ } else={
+ :put "Canceled...";
+ }
+ } else={
+ $LogPrint warning $ScriptName ("Not installing downgrade automatically.");
+ :set ExitOK true;
+ :error false;
+ }
+ }
+
+ :foreach Package in=[ /system/package/find where !bundle !available ] do={
+ :local PkgName [ /system/package/get $Package name ];
+ :if ([ $DownloadPackage $PkgName ($Update->"latest-version") ] = false) do={
+ $LogPrint error $ScriptName ("Download for package " . $PkgName . " failed, update aborted.");
+ :set ExitOK true;
+ :error false;
+ }
+ }
+
:if ($DoDowngrade = true) do={
$LogPrint info $ScriptName ("Rebooting for downgrade.");
:delay 1s;
@@ -130,11 +155,13 @@
:put "Do you want to (s)chedule reboot or (r)eboot now? [s/R]";
:if (([ /terminal/inkey timeout=60 ] % 32) = 19) do={
$Schedule $ScriptName;
+ :set ExitOK true;
:error true;
}
} else={
- :if ($PackagesUpdateDeferReboot = true) do={
+ :if ($PackagesUpdateDeferReboot = true || [ :totime $PackagesUpdateDeferReboot ] >= 1d) do={
$Schedule $ScriptName;
+ :set ExitOK true;
:error true;
}
}
@@ -142,4 +169,6 @@
$LogPrint info $ScriptName ("Rebooting for update.");
:delay 1s;
/system/reboot;
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/ppp-on-up.rsc b/ppp-on-up.rsc
index 4ed92c5..f16d73f 100644
--- a/ppp-on-up.rsc
+++ b/ppp-on-up.rsc
@@ -1,17 +1,18 @@
#!rsc by RouterOS
# RouterOS script: ppp-on-up
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# run scripts on ppp up
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/ppp-on-up.md
+# https://rsc.eworm.de/doc/ppp-on-up.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global LogPrint;
@@ -20,15 +21,16 @@
:if ([ :typeof $Interface ] = "nothing") do={
$LogPrint error $ScriptName ("This script is supposed to run from ppp on-up script hook.");
+ :set ExitOK true;
:error false;
}
:local IntName [ /interface/get $Interface name ];
$LogPrint info $ScriptName ("PPP interface " . $IntName . " is up.");
- /ipv6/dhcp-client/release [ find where interface=$IntName !disabled ];
+ /ipv6/dhcp-client/release [ find where interface=$IntName !disabled bound ];
- :foreach Script in=[ /system/script/find where source~("\n# provides: ppp-on-up\n") ] do={
+ :foreach Script in=[ /system/script/find where source~("\n# provides: ppp-on-up\r?\n") ] do={
:local ScriptName [ /system/script/get $Script name ];
:do {
$LogPrint debug $ScriptName ("Running script: " . $ScriptName);
@@ -37,4 +39,6 @@
$LogPrint warning $ScriptName ("Running script '" . $ScriptName . "' failed!");
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/sms-action.rsc b/sms-action.rsc
index 70bfb28..47e1922 100644
--- a/sms-action.rsc
+++ b/sms-action.rsc
@@ -1,17 +1,18 @@
#!rsc by RouterOS
# RouterOS script: sms-action
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# run action on received SMS
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/sms-action.md
+# https://rsc.eworm.de/doc/sms-action.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global SmsAction;
@@ -23,6 +24,7 @@
:if ([ :typeof $Action ] = "nothing") do={
$LogPrint error $ScriptName ("This script is supposed to run from SMS hook with action=...");
+ :set ExitOK true;
:error false;
}
@@ -34,4 +36,6 @@
} else={
$LogPrint warning $ScriptName ("The code for action '" . $Action . "' failed syntax validation!");
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/sms-forward.rsc b/sms-forward.rsc
index 477d11e..feb640e 100644
--- a/sms-forward.rsc
+++ b/sms-forward.rsc
@@ -1,18 +1,19 @@
#!rsc by RouterOS
# RouterOS script: sms-forward
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# Anatoly Bubenkov <bubenkoff@gmail.com>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# forward SMS to e-mail
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/sms-forward.md
+# https://rsc.eworm.de/doc/sms-forward.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Identity;
@@ -28,11 +29,13 @@
:global WaitFullyConnected;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
:if ([ /tool/sms/get receive-enabled ] = false) do={
$LogPrintOnce warning $ScriptName ("Receiving of SMS is not enabled.");
+ :set ExitOK true;
:error false;
}
@@ -42,6 +45,7 @@
:if ([ /interface/lte/get ($Settings->"port") running ] != true) do={
$LogPrint info $ScriptName ("The LTE interface is not in running state, skipping.");
+ :set ExitOK true;
:error true;
}
@@ -57,7 +61,12 @@
:if ($Phone = $Settings->"allowed-number" && \
($SmsVal->"message")~("^:cmd " . $Settings->"secret" . " script ")) do={
$LogPrint debug $ScriptName ("Removing SMS, which started a script.");
- /tool/sms/inbox/remove $Sms;
+ :onerror Err {
+ /tool/sms/inbox/remove $Sms;
+ :delay 50ms;
+ } do={
+ $LogPrint warning $ScriptName ("Failed to remove message: " . $Err);
+ }
} else={
:set Messages ($Messages . "\n\nOn " . $SmsVal->"timestamp" . \
" type " . $SmsVal->"type" . ":\n" . $SmsVal->"message");
@@ -65,12 +74,12 @@
:if ($Phone~($Hook->"allowed-number") && ($SmsVal->"message")~($Hook->"match")) do={
:if ([ $ValidateSyntax ($Hook->"command") ] = true) do={
$LogPrint info $ScriptName ("Running hook '" . $Hook->"match" . "': " . $Hook->"command");
- :do {
+ :onerror Err {
:local Command [ :parse ($Hook->"command") ];
$Command Phone=$Phone Message=($SmsVal->"message");
:set Messages ($Messages . "\n\nRan hook '" . $Hook->"match" . "':\n" . $Hook->"command");
- } on-error={
- $LogPrint warning $ScriptName ("The code for hook '" . $Hook->"match" . "' failed to run!");
+ } do={
+ $LogPrint warning $ScriptName ("The code for hook '" . $Hook->"match" . "' failed to run: " . $Err);
}
} else={
$LogPrint warning $ScriptName ("The code for hook '" . $Hook->"match" . "' failed syntax validation!");
@@ -88,8 +97,15 @@
message=("Received " . [ $IfThenElse ($Count = 1) "this message" ("these " . $Count . " messages") ] . \
" by " . $Identity . " from " . $Phone . ":" . $Messages) });
:foreach Sms in=$Delete do={
- /tool/sms/inbox/remove $Sms;
+ :onerror Err {
+ /tool/sms/inbox/remove $Sms;
+ :delay 50ms;
+ } do={
+ $LogPrint warning $ScriptName ("Failed to remove message: " . $Err);
+ }
}
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/super-mario-theme.rsc b/super-mario-theme.rsc
index 63308b0..726c526 100644
--- a/super-mario-theme.rsc
+++ b/super-mario-theme.rsc
@@ -1,10 +1,10 @@
#!rsc by RouterOS
# RouterOS script: super-mario-theme
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
# play Super Mario theme
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/super-mario-theme.md
+# https://rsc.eworm.de/doc/super-mario-theme.md
:local Beeps {
{ 660; 100 }; 150; { 660; 100 }; 300; { 660; 100 }; 300;
diff --git a/telegram-chat.rsc b/telegram-chat.rsc
index f8dcd42..7f7b7a7 100644
--- a/telegram-chat.rsc
+++ b/telegram-chat.rsc
@@ -1,17 +1,19 @@
#!rsc by RouterOS
# RouterOS script: telegram-chat
-# Copyright (c) 2023-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2023-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, fetch
#
# use Telegram to chat with your Router and send commands
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/telegram-chat.md
+# https://rsc.eworm.de/doc/telegram-chat.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Identity;
@@ -28,13 +30,16 @@
:global CertificateAvailable;
:global EitherOr;
:global EscapeForRegEx;
+ :global FileExists;
:global GetRandom20CharAlNum;
:global IfThenElse;
:global LogPrint;
+ :global LogPrintVerbose;
:global MAX;
:global MIN;
:global MkDir;
:global RandomDelay;
+ :global RmDir;
:global ScriptLock;
:global SendTelegram2;
:global SymbolForNotification;
@@ -43,6 +48,7 @@
:global WaitFullyConnected;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -55,8 +61,9 @@
:set TelegramRandomDelay 0;
}
- :if ([ $CertificateAvailable "Go Daddy Secure Certificate Authority - G2" ] = false) do={
+ :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" ] = false) do={
$LogPrint warning $ScriptName ("Downloading required certificate failed.");
+ :set ExitOK true;
:error false;
}
@@ -65,14 +72,14 @@
:local Data false;
:for I from=1 to=4 do={
:if ($Data = false) do={
- :do {
+ :onerror Err {
:set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \
("https://api.telegram.org/bot" . $TelegramTokenId . "/getUpdates?offset=" . \
$TelegramChatOffset->0 . "&allowed_updates=%5B%22message%22%5D") as-value ]->"data");
:set TelegramRandomDelay [ $MAX 0 ($TelegramRandomDelay - 1) ];
- } on-error={
+ } do={
:if ($I < 4) do={
- $LogPrint debug $ScriptName ("Fetch failed, " . $I . ". try.");
+ $LogPrint debug $ScriptName ("Fetch failed, " . $I . ". try: " . $Err);
:set TelegramRandomDelay [ $MIN 15 ($TelegramRandomDelay + 5) ];
:delay (($I * $I) . "s");
}
@@ -82,6 +89,7 @@
:if ($Data = false) do={
$LogPrint warning $ScriptName ("Failed getting updates.");
+ :set ExitOK true;
:error false;
}
@@ -90,31 +98,39 @@
:local Uptime [ /system/resource/get uptime ];
:foreach Update in=($JSON->"result") do={
:set UpdateID ($Update->"update_id");
+ $LogPrintVerbose debug $ScriptName ("Update " . $UpdateID . ": " . [ :serialize to=json $Update ]);
+
:local Message ($Update->"message");
- :local IsReply [ :len ($Message->"reply_to_message") ];
+ :local IsAnyReply ([ :typeof ($Message->"reply_to_message") ] = "array");
:local IsMyReply ($TelegramMessageIDs->[ :tostr ($Message->"reply_to_message"->"message_id") ]);
:if (($IsMyReply = 1 || $TelegramChatOffset->0 > 0 || $Uptime > 5m) && $UpdateID >= $TelegramChatOffset->2) do={
:local Trusted false;
:local Chat ($Message->"chat");
:local From ($Message->"from");
+ :local Command ($Message->"text");
+ :local ThreadId [ $IfThenElse ($Message->"is_topic_message") ($Message->"message_thread_id") "" ];
:foreach IdsTrusted in=($TelegramChatId, $TelegramChatIdsTrusted) do={
- :if ($From->"id" = $IdsTrusted || $From->"username" = $IdsTrusted) do={
+ :if ($From->"id" = $IdsTrusted || \
+ $From->"username" = $IdsTrusted || \
+ $Chat->"id" = $IdsTrusted) do={
:set Trusted true;
}
}
:if ($Trusted = true) do={
:local Done false;
- :if ($Message->"text" = "?") do={
+ :if ($Command = "?") do={
$LogPrint info $ScriptName ("Sending notice for update " . $UpdateID . ".");
- $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=true; replyto=($Message->"message_id"); \
+ $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=true; \
+ replyto=($Message->"message_id"); threadid=$ThreadId; \
subject=([ $SymbolForNotification "speech-balloon" ] . "Telegram Chat"); \
- message=("Online" . [ $IfThenElse $TelegramChatActive " (and active!)" ] . ", awaiting your commands!") });
+ message=([ $IfThenElse ([ :len ($From->"first_name") ] > 0) ("Hello " . ($From->"first_name") . "!\n\n") ] . \
+ "Online" . [ $IfThenElse $TelegramChatActive " (and active!)" ] . ", awaiting your commands!") });
:set Done true;
}
- :if ($Done = false && [ :pick ($Message->"text") 0 1 ] = "!") do={
- :if ($Message->"text" ~ ("^! *(" . [ $EscapeForRegEx $Identity ] . "|@" . $TelegramChatGroups . ")\$")) do={
+ :if ($Done = false && [ :pick $Command 0 1 ] = "!") do={
+ :if ($Command ~ ("^! *(" . [ $EscapeForRegEx $Identity ] . "|@" . $TelegramChatGroups . ")\$")) do={
:set TelegramChatActive true;
} else={
:set TelegramChatActive false;
@@ -123,36 +139,40 @@
" from update " . $UpdateID . "!");
:set Done true;
}
- :if ($Done = false && ($IsMyReply = 1 || ($IsReply = 0 && $TelegramChatActive = true)) && [ :len ($Message->"text") ] > 0) do={
- :if ([ $ValidateSyntax ($Message->"text") ] = true) do={
+ :if ($Done = false && ($IsMyReply = 1 || ($IsAnyReply = false && \
+ $TelegramChatActive = true)) && [ :len $Command ] > 0) do={
+ :if ([ $ValidateSyntax $Command ] = true) do={
:local State "";
:local File ("tmpfs/telegram-chat/" . [ $GetRandom20CharAlNum 6 ]);
:if ([ $MkDir "tmpfs/telegram-chat" ] = false) do={
$LogPrint error $ScriptName ("Failed creating directory!");
+ :set ExitOK true;
:error false;
}
- $LogPrint info $ScriptName ("Running command from update " . $UpdateID . ": " . $Message->"text");
- :execute script=(":do {\n" . $Message->"text" . "\n} on-error={ /file/add name=\"" . $File . ".failed\" };" . \
+ $LogPrint info $ScriptName ("Running command from update " . $UpdateID . ": " . $Command);
+ :execute script=(":do {\n" . $Command . "\n} on-error={ /file/add name=\"" . $File . ".failed\" };" . \
"/file/add name=\"" . $File . ".done\"") file=($File . "\00");
:if ([ $WaitForFile ($File . ".done") [ $EitherOr $TelegramChatRunTime 20s ] ] = false) do={
:set State ([ $SymbolForNotification "warning-sign" ] . "The command did not finish, still running in background.\n\n");
}
- :if ([ :len [ /file/find where name=($File . ".failed") ] ] > 0) do={
+ :if ([ $FileExists ($File . ".failed") ] = true) do={
:set State ([ $SymbolForNotification "cross-mark" ] . "The command failed with an error!\n\n");
}
:local Content ([ /file/read chunk-size=32768 file=$File as-value ]->"data");
- $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=true; replyto=($Message->"message_id"); \
+ $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=true; \
+ replyto=($Message->"message_id"); threadid=$ThreadId; \
subject=([ $SymbolForNotification "speech-balloon" ] . "Telegram Chat"); \
- message=([ $SymbolForNotification "gear" ] . "Command:\n" . $Message->"text" . "\n\n" . \
+ message=([ $SymbolForNotification "gear" ] . "Command:\n" . $Command . "\n\n" . \
$State . [ $IfThenElse ([ :len $Content ] > 0) \
([ $SymbolForNotification "memo" ] . "Output:\n" . $Content) \
([ $SymbolForNotification "memo" ] . "No output.") ]) });
- /file/remove "tmpfs/telegram-chat";
+ $RmDir "tmpfs/telegram-chat";
} else={
$LogPrint info $ScriptName ("The command from update " . $UpdateID . " failed syntax validation!");
- $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=false; replyto=($Message->"message_id"); \
+ $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=false; \
+ replyto=($Message->"message_id"); threadid=$ThreadId; \
subject=([ $SymbolForNotification "speech-balloon" ] . "Telegram Chat"); \
- message=([ $SymbolForNotification "gear" ] . "Command:\n" . $Message->"text" . "\n\n" . \
+ message=([ $SymbolForNotification "gear" ] . "Command:\n" . $Command . "\n\n" . \
[ $SymbolForNotification "cross-mark" ] . "The command failed syntax validation!") });
}
}
@@ -160,9 +180,10 @@
:local MessageText ("Received a message from untrusted contact " . \
[ $IfThenElse ([ :len ($From->"username") ] = 0) "without username" ("'" . $From->"username" . "'") ] . \
" (ID " . $From->"id" . ") in update " . $UpdateID . "!");
- :if ($Message->"text" ~ ("^! *" . [ $EscapeForRegEx $Identity ] . "\$")) do={
+ :if ($Command ~ ("^! *" . [ $EscapeForRegEx $Identity ] . "\$")) do={
$LogPrint warning $ScriptName $MessageText;
- $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=false; replyto=($Message->"message_id"); \
+ $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=false; \
+ replyto=($Message->"message_id"); threadid=$ThreadId; \
subject=([ $SymbolForNotification "speech-balloon" ] . "Telegram Chat"); \
message=("You are not trusted.") });
} else={
@@ -175,4 +196,6 @@
}
:set TelegramChatOffset ([ :pick $TelegramChatOffset 1 3 ], \
[ $IfThenElse ($UpdateID >= $TelegramChatOffset->2) ($UpdateID + 1) ($TelegramChatOffset->2) ]);
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/unattended-lte-firmware-upgrade.rsc b/unattended-lte-firmware-upgrade.rsc
index 904f952..237c2d8 100644
--- a/unattended-lte-firmware-upgrade.rsc
+++ b/unattended-lte-firmware-upgrade.rsc
@@ -1,18 +1,21 @@
#!rsc by RouterOS
# RouterOS script: unattended-lte-firmware-upgrade
-# Copyright (c) 2018-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.15
+# requires device-mode, scheduler
#
# schedule unattended lte firmware upgrade
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/unattended-lte-firmware-upgrade.md
+# https://rsc.eworm.de/doc/unattended-lte-firmware-upgrade.md
:foreach Interface in=[ /interface/lte/find where running ] do={
:local Firmware;
:local IntName [ /interface/lte/get $Interface name ];
- :do {
- :set Firmware [ /interface/lte/firmware-upgrade $Interface once as-value ];
- } on-error={
- :log debug ("Could not get latest LTE firmware version for interface " . $IntName . ".");
+ :onerror Err {
+ :set Firmware [ /interface/lte/firmware-upgrade $Interface as-value ];
+ } do={
+ :log debug ("Could not get latest LTE firmware version for interface " . $IntName . ": " . $Err);
}
:if ([ :typeof $Firmware ] = "array") do={
@@ -24,17 +27,17 @@
:set LTEFirmwareUpgrade;
/system/scheduler/remove ($1 . "-firmware-upgrade");
- :do {
+ :onerror Err {
/interface/lte/firmware-upgrade $1 upgrade=yes;
:log info ("LTE firmware upgrade on '" . $1 . "' finished, waiting for reset.");
:delay 240s;
- :local Firmware [ /interface/lte/firmware-upgrade $1 once as-value ];
- :if (($Firmware->"installed") != ($Firmware->"latest")) do={
- :log warning ("LTE firmware versions still differ. Resetting again...");
- /interface/lte/at-chat $1 input="AT+RESET";
+ :local Firmware [ /interface/lte/firmware-upgrade $1 as-value ];
+ :if ([ :len ($Firmware->"latest") ] > 0 && \
+ ($Firmware->"installed") != ($Firmware->"latest")) do={
+ :log warning ("LTE firmware versions still differ. Upgrade failed anyway?");
}
- } on-error={
- :log error ("LTE firmware upgrade on '" . $1 . "' failed.");
+ } do={
+ :log error ("LTE firmware upgrade on '" . $1 . "' failed: " . $Err);
}
}
diff --git a/update-gre-address.rsc b/update-gre-address.rsc
index 76d0c81..dd7d63e 100644
--- a/update-gre-address.rsc
+++ b/update-gre-address.rsc
@@ -1,18 +1,19 @@
#!rsc by RouterOS
# RouterOS script: update-gre-address
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
#
# update gre interface remote address with dynamic address from
# ipsec remote peer
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/update-gre-address.md
+# https://rsc.eworm.de/doc/update-gre-address.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global CharacterReplace;
@@ -20,6 +21,7 @@
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
@@ -39,4 +41,6 @@
}
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/update-tunnelbroker.rsc b/update-tunnelbroker.rsc
index 364dc08..9057e1e 100644
--- a/update-tunnelbroker.rsc
+++ b/update-tunnelbroker.rsc
@@ -1,19 +1,21 @@
#!rsc by RouterOS
# RouterOS script: update-tunnelbroker
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
# provides: ppp-on-up
-# requires RouterOS, version=7.13
+# requires RouterOS, version=7.15
+# requires device-mode, fetch
#
# update local address of tunnelbroker interface
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/update-tunnelbroker.md
+# https://rsc.eworm.de/doc/update-tunnelbroker.md
-:global GlobalFunctionsReady;
-:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
-
-:do {
+:local ExitOK false;
+:onerror Err {
+ :global GlobalConfigReady; :global GlobalFunctionsReady;
+ :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+ do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global CertificateAvailable;
@@ -22,11 +24,13 @@
:global ScriptLock;
:if ([ $ScriptLock $ScriptName ] = false) do={
+ :set ExitOK true;
:error false;
}
- :if ([ $CertificateAvailable "Starfield Secure Certificate Authority - G2" ] = false) do={
+ :if ([ $CertificateAvailable "Starfield Root Certificate Authority - G2" ] = false) do={
$LogPrint error $ScriptName ("Downloading required certificate failed.");
+ :set ExitOK true;
:error false;
}
@@ -37,12 +41,12 @@
:for I from=2 to=0 do={
:if ($Data = false) do={
- :do {
+ :onerror Err {
:set Data ([ /tool/fetch check-certificate=yes-without-crl \
("https://ipv4.tunnelbroker.net/nic/update?hostname=" . $Comment->"id") \
user=($Comment->"user") password=($Comment->"pass") output=user as-value ]->"data");
- } on-error={
- $LogPrint debug $ScriptName ("Failed downloading, " . $I . " retries pending.");
+ } do={
+ $LogPrint debug $ScriptName ("Failed downloading: " . $Err . " - " . $I . " retries pending.");
:delay 2s;
}
}
@@ -50,6 +54,7 @@
:if (!($Data ~ "^(good|nochg) ")) do={
$LogPrint error $ScriptName ("Failed sending the local address to tunnelbroker or unexpected response!");
+ :set ExitOK true;
:error false;
}
@@ -64,4 +69,6 @@
/interface/6to4/set $Interface local-address=$PublicAddress;
}
}
-} on-error={ }
+} do={
+ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}