Compare commits

..

No commits in common. "main" and "change-139" have entirely different histories.

56 changed files with 228 additions and 444 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before After
Before After

View file

@ -32,13 +32,13 @@ is to use a desktop browser to get that information. This demonstration uses
[Mozilla Firefox ↗️](https://www.mozilla.org/firefox/). [Mozilla Firefox ↗️](https://www.mozilla.org/firefox/).
Let's assume we want to make sure the certificate for Let's assume we want to make sure the certificate for
[rsc.eworm.de](https://rsc.eworm.de/) is available. Open that page in the [git.eworm.de](https://git.eworm.de/) is available. Open that page in the
browser, then click the *shield* icon in addressbar, followed by browser, then click the *lock* icon in addressbar, followed by "*Connection
"*Connection secure*". secure*".
![screenshot: dialog A](CERTIFICATES.d/01-dialog-A.avif) ![screenshot: dialog A](CERTIFICATES.d/01-dialog-A.avif)
The dialog will change, click "*More site information*". The dialog will change, click "*More information*".
![screenshot: dialog B](CERTIFICATES.d/02-dialog-B.avif) ![screenshot: dialog B](CERTIFICATES.d/02-dialog-B.avif)

View file

@ -18,9 +18,9 @@ Run the complete base installation:
{ {
:local BaseUrl "https://rsc.eworm.de/main/"; :local BaseUrl "https://rsc.eworm.de/main/";
:local CertCommonName "ISRG Root X2"; :local CertCommonName "Root YE";
:local CertFileName "ISRG-Root-X2.pem"; :local CertFileName "Root-YE.pem";
:local CertFingerprint "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470"; :local CertFingerprint "e14ffcad5b0025731006caa43a121a22d8e9700f4fb9cf852f02a708aa5d5666";
:local CertSettings [ /certificate/settings/get ]; :local CertSettings [ /certificate/settings/get ];
:if (!((($CertSettings->"builtin-trust-anchors") = "trusted" || \ :if (!((($CertSettings->"builtin-trust-anchors") = "trusted" || \

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Before After
Before After

View file

@ -126,18 +126,18 @@ If you intend to download the scripts from a
different location (for example from github.com) install the corresponding different location (for example from github.com) install the corresponding
certificate chain. certificate chain.
/tool/fetch "https://rsc.eworm.de/main/certs/ISRG-Root-X2.pem" dst-path="isrg-root-x2.pem"; /tool/fetch "https://rsc.eworm.de/main/certs/Root-YE.pem" dst-path="root-ye.pem";
![screenshot: download certs](README.d/01-download-certs.avif) ![screenshot: download certs](README.d/01-download-certs.avif)
> **Info**: Note that the command above does *not* verify server > **Info**: Note that the command above does *not* verify server
> certificate, so if you want to be safe download with your workstations's > certificate, so if you want to be safe download with your workstations's
> browser from CA's website and transfer the file to your MikroTik device: > browser from CA's website and transfer the file to your MikroTik device:
> *Let's Encrypt* / *ISRG* [ISRG Root X2 ↗️](https://letsencrypt.org/certs/isrg-root-x2.pem) > *Let's Encrypt* / *ISRG* [Root YE ↗️](https://letsencrypt.org/certs/gen-y/root-ye.pem)
Then we import the certificate. Then we import the certificate.
/certificate/import file-name="isrg-root-x2.pem" passphrase=""; /certificate/import file-name="root-ye.pem" passphrase="";
Do not worry that the command is not shown - that happens because it contains Do not worry that the command is not shown - that happens because it contains
a sensitive property, the passphrase. a sensitive property, the passphrase.
@ -145,11 +145,11 @@ a sensitive property, the passphrase.
![screenshot: import certs](README.d/02-import-certs.avif) ![screenshot: import certs](README.d/02-import-certs.avif)
For basic verification we rename the certificate and print it by For basic verification we rename the certificate and print it by
fingerprint. Make sure exactly this one certificate ("*ISRG-Root-X2*") fingerprint. Make sure exactly this one certificate ("*Root-YE*")
is shown. is shown.
/certificate/set name="ISRG-Root-X2" [ find where common-name="ISRG Root X2" ]; /certificate/set name="Root-YE" [ find where common-name="Root YE" ];
/certificate/print proplist=name,fingerprint where fingerprint="69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470"; /certificate/print proplist=name,fingerprint where fingerprint="e14ffcad5b0025731006caa43a121a22d8e9700f4fb9cf852f02a708aa5d5666";
![screenshot: check certs](README.d/03-check-certs.avif) ![screenshot: check certs](README.d/03-check-certs.avif)
@ -258,8 +258,8 @@ Some events can run a script. If you want your DHCP hostnames to be available
in DNS use `dhcp-to-dns` with the events from dhcp server. For a regular in DNS use `dhcp-to-dns` with the events from dhcp server. For a regular
cleanup add a scheduler entry. cleanup add a scheduler entry.
$ScriptInstallUpdate dhcp-to-dns,dhcpv4-server-lease; $ScriptInstallUpdate dhcp-to-dns,lease-script;
/ip/dhcp-server/set lease-script="dhcpv4-server-lease" [ find ]; /ip/dhcp-server/set lease-script=lease-script [ find ];
/system/scheduler/add name="dhcp-to-dns" interval=5m start-time=startup on-event="/system/script/run dhcp-to-dns;"; /system/scheduler/add name="dhcp-to-dns" interval=5m start-time=startup on-event="/system/script/run dhcp-to-dns;";
![screenshot: setup lease script](README.d/12-setup-lease-script.avif) ![screenshot: setup lease script](README.d/12-setup-lease-script.avif)
@ -286,8 +286,6 @@ Available scripts
* [Use wireless network with daily psk](doc/daily-psk.md) (`daily-psk`) * [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`) * [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`) * [Create DNS records for DHCP leases](doc/dhcp-to-dns.md) (`dhcp-to-dns`)
* [Run other scripts on IPv4 DHCP server lease](doc/dhcpv4-server-lease.md) (`dhcpv4-server-lease`)
* [Run other scripts on IPv6 DHCP client lease](doc/dhcpv6-client-lease.md) (`dhcpv6-client-lease`)
* [Automatically upgrade firmware and reboot](doc/firmware-upgrade-reboot.md) (`firmware-upgrade-reboot`) * [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`) * [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`) * [Wait for global functions und modules](doc/global-wait.md) (`global-wait`)
@ -296,6 +294,7 @@ Available scripts
* [Create DNS records for IPSec peers](doc/ipsec-to-dns.md) (`ipsec-to-dns`) * [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`) * [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`) * [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`) * [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`) * [Forward log messages via notification](doc/log-forward.md) (`log-forward`)
* [Mode button with multiple presses](doc/mode-button.md) (`mode-button`) * [Mode button with multiple presses](doc/mode-button.md) (`mode-button`)

View file

@ -16,7 +16,6 @@
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ]; :local ScriptName [ :jobname ];
:global BackupFileNameDate;
:global BackupPassword; :global BackupPassword;
:global BackupRandomDelay; :global BackupRandomDelay;
:global BackupSendBinary; :global BackupSendBinary;
@ -74,9 +73,7 @@
# filename based on identity # filename based on identity
:local DirName ("tmpfs/" . $ScriptName); :local DirName ("tmpfs/" . $ScriptName);
:local Clock [ /system/clock/get ]; :local FileName [ $CleanName ($Identity . "." . $Domain) ];
:local FileName [ $CleanName ($Identity . "." . $Domain . [ $IfThenElse \
($BackupFileNameDate = true) ("-" . $Clock->"date" . "-" . $Clock->"time") "" ] ) ];
:local FilePath ($DirName . "/" . $FileName); :local FilePath ($DirName . "/" . $FileName);
:local BackupFile "none"; :local BackupFile "none";
:local ExportFile "none"; :local ExportFile "none";

View file

@ -17,7 +17,6 @@
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ]; :local ScriptName [ :jobname ];
:global BackupFileNameDate;
:global BackupPassword; :global BackupPassword;
:global BackupRandomDelay; :global BackupRandomDelay;
:global BackupSendBinary; :global BackupSendBinary;
@ -73,9 +72,7 @@
# filename based on identity # filename based on identity
:local DirName ("tmpfs/" . $ScriptName); :local DirName ("tmpfs/" . $ScriptName);
:local Clock [ /system/clock/get ]; :local FileName [ $CleanName ($Identity . "." . $Domain) ];
:local FileName [ $CleanName ($Identity . "." . $Domain . [ $IfThenElse \
($BackupFileNameDate = true) ("-" . $Clock->"date" . "-" . $Clock->"time") "" ] ) ];
:local FilePath ($DirName . "/" . $FileName); :local FilePath ($DirName . "/" . $FileName);
:local BackupFile "none"; :local BackupFile "none";
:local ExportFile "none"; :local ExportFile "none";

View file

@ -12,12 +12,12 @@ DOMAINS_DUAL = \
cloudflare-dns.com/SSL-com-Root-Certification-Authority-ECC \ cloudflare-dns.com/SSL-com-Root-Certification-Authority-ECC \
dns.google/GTS-Root-RX \ dns.google/GTS-Root-RX \
dns.quad9.net/DigiCert-Global-Root-G3 \ dns.quad9.net/DigiCert-Global-Root-G3 \
git.eworm.de/ISRG-Root-X2 \ git.eworm.de/Root-YE \
gitlab.com/USERTrust-RSA-Certification-Authority \ gitlab.com/USERTrust-RSA-Certification-Authority \
lists.blocklist.de/GTS-Root-R4 \ lists.blocklist.de/GTS-Root-R4 \
matrix.org/GTS-Root-R4 \ matrix.org/GTS-Root-R4 \
raw.githubusercontent.com/ISRG-Root-X1 \ raw.githubusercontent.com/USERTrust-RSA-Certification-Authority \
rsc.eworm.de/ISRG-Root-X2 \ rsc.eworm.de/Root-YE \
upgrade.mikrotik.com/ISRG-Root-X1 upgrade.mikrotik.com/ISRG-Root-X1
DOMAINS_IPV4 = \ DOMAINS_IPV4 = \
1.1.1.1/SSL-com-Root-Certification-Authority-ECC \ 1.1.1.1/SSL-com-Root-Certification-Authority-ECC \

View file

@ -60,8 +60,8 @@
http-header-field=({ [ $FetchUserAgentStr $ScriptName ] }) \ http-header-field=({ [ $FetchUserAgentStr $ScriptName ] }) \
($CertRenewUrl . $CertFileName) dst-path=$CertFileName as-value; ($CertRenewUrl . $CertFileName) dst-path=$CertFileName as-value;
} do={ } do={
:if (!($Err ~ "[Ss]tatus 404")) do={ :if ($Err != "Fetch failed with status 404") do={
$LogPrint warning $0 ("Failed fetching certificate by '" . $FetchName . "': " . $Err); $LogPrint warning $0 ("Failed fetching certificate: " . $Err);
} }
:error false; :error false;
} }
@ -164,8 +164,7 @@
} }
$WaitFullyConnected; $WaitFullyConnected;
:foreach Cert in=[ /certificate/find where !revoked !scep-url expires-after<$CertRenewTime \ :foreach Cert in=[ /certificate/find where !revoked !ca !scep-url expires-after<$CertRenewTime ] do={
!ca (common-name or subject-alt-name) ] do={
:local CertVal [ /certificate/get $Cert ]; :local CertVal [ /certificate/get $Cert ];
:local LastName; :local LastName;
:local FetchName; :local FetchName;
@ -178,11 +177,9 @@
$LogPrint info $ScriptName ("Attempting to renew certificate '" . ($CertVal->"name") . "'."); $LogPrint info $ScriptName ("Attempting to renew certificate '" . ($CertVal->"name") . "'.");
:local ImportSuccess false; :local ImportSuccess false;
:if ([ :len ($CertVal->"common-name") ] > 0) do={ :set LastName ($CertVal->"common-name");
:set LastName ($CertVal->"common-name"); :set FetchName $LastName;
:set FetchName $LastName; :set ImportSuccess [ $CheckCertificatesDownloadImport $ScriptName $LastName $FetchName ];
:set ImportSuccess [ $CheckCertificatesDownloadImport $ScriptName $LastName $FetchName ];
}
:foreach SAN in=($CertVal->"subject-alt-name") do={ :foreach SAN in=($CertVal->"subject-alt-name") do={
:if ($ImportSuccess = false) do={ :if ($ImportSuccess = false) do={
:set LastName [ :pick $SAN ([ :find $SAN ":" ] + 1) [ :len $SAN ] ]; :set LastName [ :pick $SAN ([ :find $SAN ":" ] + 1) [ :len $SAN ] ];
@ -245,8 +242,8 @@
} }
} }
:foreach Cert in=[ /certificate/find where !revoked !scep-url expires-after<$CertWarnTime \ :foreach Cert in=[ /certificate/find where !revoked !scep-url !(expires-after=[]) \
!(expires-after=[]) !(fingerprint=[]) ] do={ expires-after<$CertWarnTime !(fingerprint=[]) ] do={
:local CertVal [ /certificate/get $Cert ]; :local CertVal [ /certificate/get $Cert ];
:if ([ :len [ /certificate/scep-server/find where ca-cert=($CertVal->"ca") ] ] > 0) do={ :if ([ :len [ /certificate/scep-server/find where ca-cert=($CertVal->"ca") ] ] > 0) do={

View file

@ -3,7 +3,7 @@
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=40 # provides: lease-script, order=40
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# #
# collect wireless mac adresses in access list # collect wireless mac adresses in access list

View file

@ -3,7 +3,7 @@
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=40 # provides: lease-script, order=40
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# #
# collect wireless mac adresses in access list # collect wireless mac adresses in access list

View file

@ -3,7 +3,7 @@
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=40 # provides: lease-script, order=40
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# #
# collect wireless mac adresses in access list # collect wireless mac adresses in access list

View file

@ -3,7 +3,7 @@
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=40 # provides: lease-script, order=40
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# #
# collect wireless mac adresses in access list # collect wireless mac adresses in access list

View file

@ -13,9 +13,7 @@ sed \
markdown -f toc,idanchor "${1}" | sed \ markdown -f toc,idanchor "${1}" | sed \
-e 's/href="\([-_\./[:alnum:]]*\)\.md\(#[-[:alnum:]]*\)\?"/href="\1.html\2"/g' \ -e 's/href="\([-_\./[:alnum:]]*\)\.md\(#[-[:alnum:]]*\)\?"/href="\1.html\2"/g' \
-e '/<h[1234] /s| id="\(.*\)">| id="\L\1">|' \ -e '/<h[1234] /s| id="\(.*\)">| id="\L\1">|' \
-e '/<h[1234] /s|--26-amp-3b-||g' \ -e '/<h[1234] /s|-2[1789cd]-||g' -e '/<h[1234] /s|--26-amp-3b-||g' \
-e '/<h[1234] /s|-2[1789cd]-||g' \
-e '/<h[1234] /s|-3[f]-||g' \
-e '/^<pre>/s|pre|pre class="code" onclick="CopyToClipboard(this)"|g' \ -e '/^<pre>/s|pre|pre class="code" onclick="CopyToClipboard(this)"|g' \
-e '/The above link may be broken on code hosting sites/s|blockquote|blockquote style="display: none;"|' -e '/The above link may be broken on code hosting sites/s|blockquote|blockquote style="display: none;"|'

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Before After
Before After

View file

@ -45,7 +45,7 @@ logo and download it.</p>
<p><img src="logo-color.d/browser-03.avif" alt="Screenshot Browser 03"></p> <p><img src="logo-color.d/browser-03.avif" alt="Screenshot Browser 03"></p>
<p>(This example is with <p>(This example is with
<a href="https://www.mozilla.org/firefox/">Mozilla Firefox ↗️</a>. The workflow <a href="https://www.mozilla.org/de/firefox/new/">Firefox</a>. The workflow
for other browsers may differ.)</p> for other browsers may differ.)</p>
<p>See how to <p>See how to

View file

@ -91,14 +91,6 @@ Notes
/save dhcp-to-dns Create DNS records for DHCP leases with [dhcp-to-dns](https://rsc.eworm.de/doc/dhcp-to-dns.md). /save dhcp-to-dns Create DNS records for DHCP leases with [dhcp-to-dns](https://rsc.eworm.de/doc/dhcp-to-dns.md).
#### dhcpv4-server-lease
/save dhcpv4-server-lease Run other scripts on IPv4 DHCP server lease with [dhcpv4-server-lease](https://rsc.eworm.de/doc/dhcpv4-server-lease.md).
#### dhcpv6-client-lease
/save dhcpv6-client-lease Run other scripts on IPv6 DHCP client lease with [dhcpv6-client-lease](https://rsc.eworm.de/doc/dhcpv6-client-lease.md).
#### firmware-upgrade-reboot #### firmware-upgrade-reboot
/save firmware-upgrade-reboot Automatically upgrade firmware and reboot with [firmware-upgrade-reboot](https://rsc.eworm.de/doc/firmware-upgrade-reboot.md). /save firmware-upgrade-reboot Automatically upgrade firmware and reboot with [firmware-upgrade-reboot](https://rsc.eworm.de/doc/firmware-upgrade-reboot.md).
@ -131,6 +123,10 @@ Notes
/save ip-addr-bridge Manage IP addresses with [ip-addr-bridge](https://rsc.eworm.de/doc/ip-addr-bridge.md). /save ip-addr-bridge Manage IP addresses with [ip-addr-bridge](https://rsc.eworm.de/doc/ip-addr-bridge.md).
#### lease-script
/save lease-script Run other scripts on DHCP lease with [lease-script](https://rsc.eworm.de/doc/lease-script.md).
#### leds-mode #### leds-mode
/save leds-mode Manage LEDs dark mode with [leds-mode](https://rsc.eworm.de/doc/leds-mode.md). /save leds-mode Manage LEDs dark mode with [leds-mode](https://rsc.eworm.de/doc/leds-mode.md).

View file

@ -3,7 +3,7 @@
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=60 # provides: lease-script, order=60
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# #
# update dhcp-server lease comment with infos from access-list # update dhcp-server lease comment with infos from access-list

View file

@ -3,7 +3,7 @@
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=60 # provides: lease-script, order=60
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# #
# update dhcp-server lease comment with infos from access-list # update dhcp-server lease comment with infos from access-list

View file

@ -3,7 +3,7 @@
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=60 # provides: lease-script, order=60
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# #
# update dhcp-server lease comment with infos from access-list # update dhcp-server lease comment with infos from access-list

View file

@ -3,7 +3,7 @@
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=60 # provides: lease-script, order=60
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# #
# update dhcp-server lease comment with infos from access-list # update dhcp-server lease comment with infos from access-list

View file

@ -3,7 +3,7 @@
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=20 # provides: lease-script, order=20
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# #
# check DHCP leases and add/remove/update DNS entries # check DHCP leases and add/remove/update DNS entries
@ -51,6 +51,7 @@
active-address=($DnsRecordVal->"address") server=($DnsRecordInfo->"server") status=bound ] ] > 0) do={ active-address=($DnsRecordVal->"address") server=($DnsRecordInfo->"server") status=bound ] ] > 0) do={
$LogPrint debug $ScriptName ("Lease for " . $MacInServer . " (" . $DnsRecordVal->"name" . ") still exists. Not deleting record."); $LogPrint debug $ScriptName ("Lease for " . $MacInServer . " (" . $DnsRecordVal->"name" . ") still exists. Not deleting record.");
} else={ } else={
:local Found false;
$LogPrint info $ScriptName ("Lease expired for " . $MacInServer . ", deleting record (" . $DnsRecordVal->"name" . ")."); $LogPrint info $ScriptName ("Lease expired for " . $MacInServer . ", deleting record (" . $DnsRecordVal->"name" . ").");
/ip/dns/static/remove $DnsRecord; /ip/dns/static/remove $DnsRecord;
/ip/dns/static/remove [ find where type=CNAME comment=($DnsRecordVal->"comment") ]; /ip/dns/static/remove [ find where type=CNAME comment=($DnsRecordVal->"comment") ];

View file

@ -1,65 +0,0 @@
#!rsc by RouterOS
# RouterOS script: dhcpv4-server-lease
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.19
#
# run scripts on IPv4 DHCP server lease
# https://rsc.eworm.de/doc/dhcpv4-server-lease.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 Grep;
:global IfThenElse;
:global LogPrint;
:global ParseKeyValueStore;
:global ScriptLock;
:if ([ :typeof $leaseActIP ] = "nothing" || \
[ :typeof $leaseActMAC ] = "nothing" || \
[ :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;
}
$LogPrint debug $ScriptName ("DHCP Server " . $leaseServerName . " " . [ $IfThenElse ($leaseBound = 0) \
"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;
}
:local RunOrder ({});
:foreach Script in=[ /system/script/find where source~("\n# provides: dhcpv4-server-lease\\b") ] do={
:local ScriptVal [ /system/script/get $Script ];
:local Store [ $ParseKeyValueStore [ $Grep ($ScriptVal->"source") ("\23 provides: dhcpv4-server-lease, ") ] ];
:set ($RunOrder->($Store->"order" . "-" . $ScriptVal->"name")) ($ScriptVal->"name");
}
:foreach Order,Script in=$RunOrder do={
:onerror Err {
$LogPrint debug $ScriptName ("Running script with order " . $Order . ": " . $Script);
/system/script/run $Script;
} do={
$LogPrint warning $ScriptName ("Running script '" . $Script . "' failed: " . $Err);
}
}
} do={
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
}

View file

@ -1,63 +0,0 @@
#!rsc by RouterOS
# RouterOS script: dhcpv6-client-lease
# Copyright (c) 2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.19
#
# run scripts on IPv6 DHCP client lease
# https://rsc.eworm.de/doc/dhcpv6-client-lease.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 Grep;
:global LogPrint;
:global ParseKeyValueStore;
:global ScriptLock;
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
:set ExitOK true;
:error false;
}
:if (([ :typeof $"na-address" ] = "nothing" || [ :typeof $"na-valid" ] = "nothing") && \
([ :typeof $"pd-prefix" ] = "nothing" || [ :typeof $"pd-valid" ] = "nothing")) do={
$LogPrint error $ScriptName ("This script is supposed to run from ipv6 dhcp-client.");
:set ExitOK true;
:error false;
}
:global DHCPv6ClientLeaseVars {
"na-address"=$"na-address";
"na-valid"=$"na-valid";
"pd-prefix"=$"pd-prefix";
"pd-valid"=$"pd-valid";
"options"=$"options" };
:local RunOrder ({});
:foreach Script in=[ /system/script/find where source~("\n# provides: dhcpv6-client-lease\\b") ] do={
:local ScriptVal [ /system/script/get $Script ];
:local Store [ $ParseKeyValueStore [ $Grep ($ScriptVal->"source") ("\23 provides: dhcpv6-client-lease, ") ] ];
:set ($RunOrder->($Store->"order" . "-" . $ScriptVal->"name")) ($ScriptVal->"name");
}
:foreach Order,Script in=$RunOrder do={
:onerror Err {
$LogPrint debug $ScriptName ("Running script with order " . $Order . ": " . $Script);
/system/script/run $Script;
} do={
$LogPrint warning $ScriptName ("Running script '" . $Script . "' failed: " . $Err);
}
}
:set DHCPv6ClientLeaseVars;
} do={
:global DHCPv6ClientLeaseVars; :set DHCPv6ClientLeaseVars;
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
}

View file

@ -34,7 +34,6 @@ Configuration
The configuration goes to `global-config-overlay`, these are the parameters: The configuration goes to `global-config-overlay`, these are the parameters:
* `BackupFileNameDate`: whether to add date & time in filenames
* `BackupSendBinary`: whether to send binary backup * `BackupSendBinary`: whether to send binary backup
* `BackupSendExport`: whether to send configuration export * `BackupSendExport`: whether to send configuration export
* `BackupSendGlobalConfig`: whether to send `global-config-overlay` * `BackupSendGlobalConfig`: whether to send `global-config-overlay`

View file

@ -40,7 +40,6 @@ Configuration
The configuration goes to `global-config-overlay`, these are the parameters: The configuration goes to `global-config-overlay`, these are the parameters:
* `BackupFileNameDate`: whether to add date & time in filenames
* `BackupSendBinary`: whether to send binary backup * `BackupSendBinary`: whether to send binary backup
* `BackupSendExport`: whether to send configuration export * `BackupSendExport`: whether to send configuration export
* `BackupSendGlobalConfig`: whether to send `global-config-overlay` * `BackupSendGlobalConfig`: whether to send `global-config-overlay`

View file

@ -85,7 +85,7 @@ Given you have a certificate on you server, you can use `check-certificates`
for the initial import. Just create a *dummy* certificate with short lifetime for the initial import. Just create a *dummy* certificate with short lifetime
that matches criteria to be renewed: that matches criteria to be renewed:
/certificate/add name="example.com" common-name="example.com" subject-alt-name="DNS:example.com" days-valid=1; /certificate/add name=example.com common-name=example.com days-valid=1;
/certificate/sign example.com; /certificate/sign example.com;
/system/script/run check-certificates; /system/script/run check-certificates;

View file

@ -64,14 +64,14 @@ Usage and invocation
Run this script from a dhcp server as lease-script to collect the MAC Run this script from a dhcp server as lease-script to collect the MAC
address when a new address is leased. You may want to use address when a new address is leased. You may want to use
[dhcpv4-server-lease](dhcpv4-server-lease.md). [lease-script](lease-script.md).
See also See also
-------- --------
* [Comment DHCP leases with info from access list](dhcp-lease-comment.md) * [Comment DHCP leases with info from access list](dhcp-lease-comment.md)
* [Create DNS records for DHCP leases](dhcp-to-dns.md) * [Create DNS records for DHCP leases](dhcp-to-dns.md)
* [Run other scripts on IPv4 DHCP server lease](dhcpv4-server-lease.md) * [Run other scripts on DHCP lease](lease-script.md)
--- ---
[⬅️ Go back to main README](../README.md) [⬅️ Go back to main README](../README.md)

View file

@ -50,14 +50,14 @@ Usage and invocation
Run this script from a dhcp server as lease-script to update the comment Run this script from a dhcp server as lease-script to update the comment
just after a new address is leased. You may want to use just after a new address is leased. You may want to use
[dhcpv4-server-lease](dhcpv4-server-lease.md). [lease-script](lease-script.md).
See also See also
-------- --------
* [Collect MAC addresses in wireless access list](collect-wireless-mac.md) * [Collect MAC addresses in wireless access list](collect-wireless-mac.md)
* [Create DNS records for DHCP leases](dhcp-to-dns.md) * [Create DNS records for DHCP leases](dhcp-to-dns.md)
* [Run other scripts on IPv4 DHCP server lease](dhcpv4-server-lease.md) * [Run other scripts on DHCP lease](lease-script.md)
--- ---
[⬅️ Go back to main README](../README.md) [⬅️ Go back to main README](../README.md)

View file

@ -28,7 +28,7 @@ Just install the script:
$ScriptInstallUpdate dhcp-to-dns; $ScriptInstallUpdate dhcp-to-dns;
Then run it from dhcp server as lease script. You may want to use Then run it from dhcp server as lease script. You may want to use
[dhcpv4-server-lease](dhcpv4-server-lease.md). [lease-script](lease-script.md).
A scheduler cares about cleanup: A scheduler cares about cleanup:
@ -80,30 +80,13 @@ Note this information can be configured in wireless access list with
then due to script execution order. Decrease the scheduler interval to then due to script execution order. Decrease the scheduler interval to
reduce the effect. reduce the effect.
Frequently asked questions
--------------------------
### Is it possible to have the hostname in reverse lookup?
It used to be like that in the beginning. But there are way too many special
cases... Devices without hostname, devices with same hostname, devices
switching from one network to another, devices with same hostname in
different network, ...
Fixing one broke another. It never really worked without problems. So
finally the code ended with what we have now.
I know about that side effect and limitation with reverse lookup, but
there's really no (easy) way to get that right without mac address. The
reverse lookup will always give a name based on mac address.
See also See also
-------- --------
* [Collect MAC addresses in wireless access list](collect-wireless-mac.md) * [Collect MAC addresses in wireless access list](collect-wireless-mac.md)
* [Comment DHCP leases with info from access list](dhcp-lease-comment.md) * [Comment DHCP leases with info from access list](dhcp-lease-comment.md)
* [Run other scripts on IPv4 DHCP server lease](dhcpv4-server-lease.md)
* [Create DNS records for IPSec peers](ipsec-to-dns.md) * [Create DNS records for IPSec peers](ipsec-to-dns.md)
* [Run other scripts on DHCP lease](lease-script.md)
--- ---
[⬅️ Go back to main README](../README.md) [⬅️ Go back to main README](../README.md)

View file

@ -1,54 +0,0 @@
Run other scripts on IPv4 DHCP server 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.19-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts)
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
[⬅️ 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
-----------
This script is supposed to run from IPv4 DHCP server as lease script. On a
DHCP lease it runs each script containing the following line, where `##` is
a decimal number for ordering:
# provides: dhcpv4-server-lease, order=##
Currently it runs if available, in order:
* [dhcp-to-dns](dhcp-to-dns.md)
* [collect-wireless-mac](collect-wireless-mac.md)
* [dhcp-lease-comment](dhcp-lease-comment.md)
* `hotspot-to-wpa-cleanup`, which is an optional cleanup script
of [hotspot-to-wpa](hotspot-to-wpa.md)
Requirements and installation
-----------------------------
Just install the script:
$ScriptInstallUpdate dhcpv4-server-lease;
... and add it as `lease-script` to your dhcp server:
/ip/dhcp-server/set lease-script="dhcpv4-server-lease" [ find ];
See also
--------
* [Collect MAC addresses in wireless access list](collect-wireless-mac.md)
* [Comment DHCP leases with info from access list](dhcp-lease-comment.md)
* [Create DNS records for DHCP leases](dhcp-to-dns.md)
* [Use WPA network with hotspot credentials](hotspot-to-wpa.md)
---
[⬅️ Go back to main README](../README.md)
[⬆️ Go back to top](#top)

View file

@ -1,65 +0,0 @@
Run other scripts on IPv6 DHCP client 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.19-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts)
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
[⬅️ 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
-----------
This script is supposed to run from IPv6 DHCP client as lease script. On a
DHCP leasse it runs each script containing the following line, where `##` is
a decimal number for ordering:
# provides: dhcpv6-client-lease, order=##
The lease script is started with some variables injected, but these are not
available in child scripts. However this script makes these variables
available with a global variable. This code is required in child script:
:global EitherOr;
:global DHCPv6ClientLeaseVars;
:local NaAddress [ $EitherOr $"na-address" ($DHCPv6ClientLeaseVars->"na-address") ];
:local NaValid [ $EitherOr $"na-valid" ($DHCPv6ClientLeaseVars->"na-valid") ];
:local PdPrefix [ $EitherOr $"pd-prefix" ($DHCPv6ClientLeaseVars->"pd-prefix") ];
:local PdValid [ $EitherOr $"pd-valid" ($DHCPv6ClientLeaseVars->"pd-valid") ];
:local Options [ $EitherOr $"options" ($DHCPv6ClientLeaseVars->"options") ];
The values are available under different name then, use `$PdPrefix` instead
of `$"pd-prefix"`, and so on. The resulting script supports both, being a
lease script itself or being run as child.
Currently it runs if available, in order:
* [ipv6-update](ipv6-update.md)
Requirements and installation
-----------------------------
Just install the script:
$ScriptInstallUpdate dhcpv6-client-lease;
... and add it as `lease-script` to your dhcp client:
/ipv6/dhcp-client/set lease-script="dhcpv6-client-lease" [ find ];
See also
--------
* [Update configuration on IPv6 prefix change](ipv6-update.md)
---
[⬅️ Go back to main README](../README.md)
[⬆️ Go back to top](#top)

View file

@ -49,24 +49,24 @@ and add a scheduler.
For `wifi`: For `wifi`:
$ScriptInstallUpdate hotspot-to-wpa-cleanup.wifi,dhcpv4-server-lease; $ScriptInstallUpdate hotspot-to-wpa-cleanup.wifi,lease-script;
/system/scheduler/add interval=1d name="hotspot-to-wpa-cleanup" on-event="/system/script/run hotspot-to-wpa-cleanup.wifi;" start-time=startup; /system/scheduler/add interval=1d name=hotspot-to-wpa-cleanup on-event="/system/script/run hotspot-to-wpa-cleanup.wifi;" start-time=startup;
For legacy CAPsMAN: For legacy CAPsMAN:
$ScriptInstallUpdate hotspot-to-wpa-cleanup.capsman,dhcpv4-server-lease; $ScriptInstallUpdate hotspot-to-wpa-cleanup.capsman,lease-script;
/system/scheduler/add interval=1d name="hotspot-to-wpa-cleanup" on-event="/system/script/run hotspot-to-wpa-cleanup.capsman;" start-time=startup; /system/scheduler/add interval=1d name=hotspot-to-wpa-cleanup on-event="/system/script/run hotspot-to-wpa-cleanup.capsman;" start-time=startup;
And add the lease script and matcher comment to your wpa interfaces' dhcp And add the lease script and matcher comment to your wpa interfaces' dhcp
server. You can add more information to the comment, separated by comma. In server. You can add more information to the comment, separated by comma. In
this example the server is called `hotspot-to-wpa`. this example the server is called `hotspot-to-wpa`.
/ip/dhcp-server/set lease-script="dhcpv4-server-lease" comment="hotspot-to-wpa=wpa" hotspot-to-wpa; /ip/dhcp-server/set lease-script=lease-script comment="hotspot-to-wpa=wpa" hotspot-to-wpa;
You can specify the timeout after which a device is removed from leases and You can specify the timeout after which a device is removed from leases and
access-list. The default is four weeks. access-list. The default is four weeks.
/ip/dhcp-server/set lease-script="dhcpv4-server-lease" comment="hotspot-to-wpa=wpa, timeout=2w" hotspot-to-wpa; /ip/dhcp-server/set lease-script=lease-script comment="hotspot-to-wpa=wpa, timeout=2w" hotspot-to-wpa;
Configuration Configuration
------------- -------------
@ -117,7 +117,7 @@ passphrase from hotspot credentials.
See also See also
-------- --------
* [Run other scripts on IPv4 DHCP server lease](dhcpv4-server-lease.md) * [Run other scripts on DHCP lease](lease-script.md)
--- ---
[⬅️ Go back to main README](../README.md) [⬅️ Go back to main README](../README.md)

View file

@ -55,7 +55,7 @@ create it with:
/ipv6/firewall/address-list/add address=2003:cf:2f0f:de00::/56 comment=ipv6-pool-isp list=extern; /ipv6/firewall/address-list/add address=2003:cf:2f0f:de00::/56 comment=ipv6-pool-isp list=extern;
If the dynamic entry exists already you need to remove it before creating If the dynamic entry exists already you need to remove it before creating
the static one. the static one..
Address list entries for specific interfaces can be updated as well. The 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 interface needs to get its address from pool `isp` and the address list entry
@ -77,7 +77,6 @@ start with "`ipv6-pool-`" and actual pool name, followed by a comma,
See also See also
-------- --------
* [Run other scripts on IPv6 DHCP client lease](dhcpv6-client-lease.md)
* [Run scripts on ppp connection](ppp-on-up.md) * [Run scripts on ppp connection](ppp-on-up.md)
--- ---

View file

@ -1 +1,54 @@
This script has been renamed. Please see [dhcpv4-server-lease](dhcpv4-server-lease.md). 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.19-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts)
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
[⬅️ 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
-----------
This script is supposed to run from dhcp server as lease script. On a dhcp
lease it runs each script containing the following line, where `##` is a
decimal number for ordering:
# provides: lease-script, order=##
Currently it runs if available, in order:
* [dhcp-to-dns](dhcp-to-dns.md)
* [collect-wireless-mac](collect-wireless-mac.md)
* [dhcp-lease-comment](dhcp-lease-comment.md)
* `hotspot-to-wpa-cleanup`, which is an optional cleanup script
of [hotspot-to-wpa](hotspot-to-wpa.md)
Requirements and installation
-----------------------------
Just install the script:
$ScriptInstallUpdate lease-script;
... and add it as `lease-script` to your dhcp server:
/ip/dhcp-server/set lease-script=lease-script [ find ];
See also
--------
* [Collect MAC addresses in wireless access list](collect-wireless-mac.md)
* [Comment DHCP leases with info from access list](dhcp-lease-comment.md)
* [Create DNS records for DHCP leases](dhcp-to-dns.md)
* [Use WPA network with hotspot credentials](hotspot-to-wpa.md)
---
[⬅️ Go back to main README](../README.md)
[⬆️ Go back to top](#top)

View file

@ -37,9 +37,7 @@ Also make sure the device has correct time configured, best is to set up
the ntp client. the ntp client.
Then edit `global-config-overlay`, add `EmailGeneralTo` with a valid Then edit `global-config-overlay`, add `EmailGeneralTo` with a valid
recipient address. Optionally add `EmailServerCertificate` and add the CA recipient address. Finally reload the configuration.
certificate name if you have certificate verification enabled. Finally
reload the configuration.
> **Info**: Copy relevant configuration from > **Info**: Copy relevant configuration from
> [`global-config`](../../global-config.rsc) (the one without `-overlay`) to > [`global-config`](../../global-config.rsc) (the one without `-overlay`) to

View file

@ -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 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 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) [![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.21-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![required RouterOS version](https://img.shields.io/badge/RouterOS-7.19-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![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) [![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)
@ -38,8 +38,9 @@ import that key:
$SSHKeysImport "ssh-rsa AAAAB3Nza...QYZk8= user" admin; $SSHKeysImport "ssh-rsa AAAAB3Nza...QYZk8= user" admin;
The third part of the key (`user` in this example) is inherited as The third part of the key (`user` in this example) is inherited as
`info` in RouterOS. Also the `MD5` fingerprint is recorded, this helps `info` in RouterOS (or `key-owner` with RouterOS 7.20.x and before). Also
to audit and verify the available keys. the `MD5` fingerprint is recorded, this helps to audit and verify the
available keys.
> **Info**: Use `ssh-keygen` to show a fingerprint of an existing public > **Info**: Use `ssh-keygen` to show a fingerprint of an existing public
> key file: `ssh-keygen -l -E md5 -f ~/.ssh/id_ed25519.pub` > key file: `ssh-keygen -l -E md5 -f ~/.ssh/id_ed25519.pub`

View file

@ -36,7 +36,6 @@ Just install the script:
See also See also
-------- --------
* [Run other scripts on IPv6 DHCP client lease](dhcpv6-client-lease.md)
* [Update configuration on IPv6 prefix change](ipv6-update.md) * [Update configuration on IPv6 prefix change](ipv6-update.md)
* [Update tunnelbroker configuration](update-tunnelbroker.md) * [Update tunnelbroker configuration](update-tunnelbroker.md)

View file

@ -31,8 +31,6 @@
:global EmailGeneralCc ""; :global EmailGeneralCc "";
#:global EmailGeneralTo "mail@example.com"; #:global EmailGeneralTo "mail@example.com";
#:global EmailGeneralCc "another@example.com,third@example.com"; #:global EmailGeneralCc "another@example.com,third@example.com";
# Add the CA certificate name here for verification.
:global EmailServerCertificate "";
# You can send Telegram notifications. Register a bot # You can send Telegram notifications. Register a bot
# and add the token and chat ids here, then install the module: # and add the token and chat ids here, then install the module:
@ -90,9 +88,7 @@
# Toggle this to disable color output in terminal/cli. # Toggle this to disable color output in terminal/cli.
:global TerminalColorOutput true; :global TerminalColorOutput true;
# This defines whether to add date & time in filenames, what backups to generate, # This defines what backups to generate and what password to use.
# the password to use, and what random delay (between 0 and given seconds) to apply.
:global BackupFileNameDate false;
:global BackupSendBinary false; :global BackupSendBinary false;
:global BackupSendExport true; :global BackupSendExport true;
:global BackupSendGlobalConfig true; :global BackupSendGlobalConfig true;
@ -119,7 +115,7 @@
# cert="Root YE" }; # cert="Root YE" };
{ url="https://raw.githubusercontent.com/stamparm/ipsum/refs/heads/master/levels/4.txt"; { 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 # # higher level (decrease the numerical value) for more addresses, and vice versa
cert="ISRG Root X1" }; cert="USERTrust RSA Certification Authority" };
{ url="https://www.dshield.org/block.txt"; cidr="/24"; { url="https://www.dshield.org/block.txt"; cidr="/24";
cert="GTS Root R4" }; cert="GTS Root R4" };
{ url="https://lists.blocklist.de/lists/strongips.txt"; { url="https://lists.blocklist.de/lists/strongips.txt";

View file

@ -15,7 +15,7 @@
# Git commit id & info, expected configuration version # Git commit id & info, expected configuration version
:global CommitId "unknown"; :global CommitId "unknown";
:global CommitInfo "unknown"; :global CommitInfo "unknown";
:global ExpectedConfigVersion 143; :global ExpectedConfigVersion 139;
# global variables not to be changed by user # global variables not to be changed by user
:global GlobalFunctionsReady false; :global GlobalFunctionsReady false;
@ -111,13 +111,11 @@
:local UseFor [ :tostr $2 ]; :local UseFor [ :tostr $2 ];
:global CertificateDownload; :global CertificateDownload;
:global EitherOr;
:global LogPrint; :global LogPrint;
:global ParseKeyValueStore; :global ParseKeyValueStore;
:if ([ :len $UseFor ] = 0) do={ :set UseFor [ $EitherOr $UseFor "undefined" ];
$LogPrint warning $0 ("The intended use is undefined!");
:set UseFor "undefined";
}
:if ([ /system/resource/get free-hdd-space ] < 8388608 && \ :if ([ /system/resource/get free-hdd-space ] < 8388608 && \
[ /certificate/settings/get crl-download ] = true && \ [ /certificate/settings/get crl-download ] = true && \
@ -191,12 +189,7 @@
$LogPrint warning $0 ("Failed downloading certificate with CommonName '" . $CommonName . \ $LogPrint warning $0 ("Failed downloading certificate with CommonName '" . $CommonName . \
"' from repository! Trying fallback to mkcert.org..."); "' from repository! Trying fallback to mkcert.org...");
:do { :do {
:local CertSettings [ /certificate/settings/get ]; :if ([ :len [ /certificate/find where common-name="ISRG Root X1" ] ] = 0) do={
:if ([ :len [ /certificate/find where common-name="ISRG Root X1" ] ] = 0 && \
!((($CertSettings->"builtin-trust-anchors") = "trusted" || \
($CertSettings->"builtin-trust-store") ~ "fetch" || \
($CertSettings->"builtin-trust-store") = "all") && \
[ :len [ /certificate/builtin/find where common-name="ISRG Root X1" ] ] > 0)) do={
$LogPrint error $0 ("Required certificate is not available."); $LogPrint error $0 ("Required certificate is not available.");
:return false; :return false;
} }
@ -310,7 +303,7 @@
:for I from=0 to=([ :len $Input ] - 1) do={ :for I from=0 to=([ :len $Input ] - 1) do={
:local Char [ :pick $Input $I ]; :local Char [ :pick $Input $I ];
:if ([ :typeof [ :find "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" $Char ] ] = "nil") do={ :if ([ :typeof [ find "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" $Char ] ] = "nil") do={
:do { :do {
:if ([ :len $Return ] = 0) do={ :if ([ :len $Return ] = 0) do={
:error true; :error true;
@ -812,15 +805,10 @@
# check if DNS is resolving # check if DNS is resolving
:set IsDNSResolving do={ :set IsDNSResolving do={
:do { :do {
:local I 1; :resolve "low-ttl.eworm.de";
:retry {
:set I ($I ^ 1);
:resolve ("low-ttl.eworm." . ({ "de"; "net" }->$I));
} delay=50ms max=6;
} on-error={ } on-error={
:return false; :return false;
} }
:return true; :return true;
} }
@ -1205,12 +1193,10 @@
} }
:onerror Err { :onerror Err {
/file/remove [ find where name=$DirName ]; /file/remove $DirName;
} do={ } do={
:if (!($Err ~ "no such item")) do={ $LogPrint error $0 ("Removing directory '" . $DirName . "' failed: " . $Err);
$LogPrint error $0 ("Removing directory '" . $DirName . "' failed: " . $Err); :return false;
:return false;
}
} }
:return true; :return true;
} }
@ -1236,12 +1222,10 @@
} }
:onerror Err { :onerror Err {
/file/remove [ find where name=$FileName ]; /file/remove $FileName;
} do={ } do={
:if (!($Err ~ "no such item")) do={ $LogPrint error $0 ("Removing file '" . $FileName . "' failed: " . $Err);
$LogPrint error $0 ("Removing file '" . $FileName . "' failed: " . $Err); :return false;
:return false;
}
} }
:return true; :return true;
} }
@ -1301,15 +1285,12 @@
:global SymbolForNotification; :global SymbolForNotification;
:global ValidateSyntax; :global ValidateSyntax;
:if ([ $CertificateAvailable "ISRG Root X2" "fetch" ] = false || \ :if ([ $CertificateAvailable "Root YE" "fetch" ] = false) do={
[ $CertificateAvailable "Root YE" "fetch" ] = false) do={
$LogPrint warning $0 ("Downloading certificate failed, trying without."); $LogPrint warning $0 ("Downloading certificate failed, trying without.");
} }
:foreach Script in=$Scripts do={ :foreach Script in=$Scripts do={
:if ([ :len [ /system/script/find where name=$Script ] ] > 0) do={ :if ([ :len [ /system/script/find where name=$Script ] ] = 0) do={
$LogPrint warning $0 ("Requested to add script '" . $Script . "', but that exists already!");
} else={
$LogPrint info $0 ("Adding new script: " . $Script); $LogPrint info $0 ("Adding new script: " . $Script);
/system/script/add name=$Script owner=$Script source="#!rsc by RouterOS\n" comment=$NewComment; /system/script/add name=$Script owner=$Script source="#!rsc by RouterOS\n" comment=$NewComment;
} }

View file

@ -3,7 +3,7 @@
# Copyright (c) 2021-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2021-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=80 # provides: lease-script, order=80
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# requires device-mode, hotspot # requires device-mode, hotspot
# #

View file

@ -3,7 +3,7 @@
# Copyright (c) 2021-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2021-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=80 # provides: lease-script, order=80
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# requires device-mode, hotspot # requires device-mode, hotspot
# #

View file

@ -3,7 +3,7 @@
# Copyright (c) 2021-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2021-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# provides: dhcpv4-server-lease, order=80 # provides: lease-script, order=80
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# requires device-mode, hotspot # requires device-mode, hotspot
# #

View file

@ -4,7 +4,6 @@
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# requires RouterOS, version=7.19 # requires RouterOS, version=7.19
# provides: dhcpv6-client-lease, order=40
# #
# update firewall and dns settings on IPv6 prefix change # update firewall and dns settings on IPv6 prefix change
# https://rsc.eworm.de/doc/ipv6-update.md # https://rsc.eworm.de/doc/ipv6-update.md
@ -16,19 +15,16 @@
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ]; :local ScriptName [ :jobname ];
:global EitherOr;
:global LogPrint; :global LogPrint;
:global ParseKeyValueStore; :global ParseKeyValueStore;
:global ScriptLock; :global ScriptLock;
:global DHCPv6ClientLeaseVars; :local NaAddress $"na-address";
:local NaValid $"na-valid";
:local PdPrefix $"pd-prefix";
:local PdValid $"pd-valid";
:local NaAddress [ $EitherOr $"na-address" ($DHCPv6ClientLeaseVars->"na-address") ]; :if ([ $ScriptLock $ScriptName ] = false) do={
:local NaValid [ $EitherOr $"na-valid" ($DHCPv6ClientLeaseVars->"na-valid") ];
:local PdPrefix [ $EitherOr $"pd-prefix" ($DHCPv6ClientLeaseVars->"pd-prefix") ];
:local PdValid [ $EitherOr $"pd-valid" ($DHCPv6ClientLeaseVars->"pd-valid") ];
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
:set ExitOK true; :set ExitOK true;
:error false; :error false;
} }
@ -54,7 +50,7 @@
:local Pool [ /ipv6/pool/get [ find where prefix=$PdPrefix ] name ]; :local Pool [ /ipv6/pool/get [ find where prefix=$PdPrefix ] name ];
:if ([ :len [ /ipv6/firewall/address-list/find where comment=("ipv6-pool-" . $Pool) ] ] = 0) do={ :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) dynamic=yes; /ipv6/firewall/address-list/add list=("ipv6-pool-" . $Pool) address=:: comment=("ipv6-pool-" . $Pool) dynamic=yes;
$LogPrint info $ScriptName ("Added dynamic ipv6 address list entry for ipv6-pool-" . $Pool); $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 AddrList [ /ipv6/firewall/address-list/find where comment=("ipv6-pool-" . $Pool) ];
:local OldPrefix [ /ipv6/firewall/address-list/get ($AddrList->0) address ]; :local OldPrefix [ /ipv6/firewall/address-list/get ($AddrList->0) address ];

View file

@ -1,3 +1,65 @@
#!rsc by RouterOS #!rsc by RouterOS
# RouterOS script: lease-script
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
# #
# dummy for migration # requires RouterOS, version=7.19
#
# run scripts on DHCP lease
# https://rsc.eworm.de/doc/lease-script.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 Grep;
:global IfThenElse;
:global LogPrint;
:global ParseKeyValueStore;
:global ScriptLock;
:if ([ :typeof $leaseActIP ] = "nothing" || \
[ :typeof $leaseActMAC ] = "nothing" || \
[ :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;
}
$LogPrint debug $ScriptName ("DHCP Server " . $leaseServerName . " " . [ $IfThenElse ($leaseBound = 0) \
"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;
}
:local RunOrder ({});
:foreach Script in=[ /system/script/find where source~("\n# provides: lease-script\\b") ] do={
:local ScriptVal [ /system/script/get $Script ];
:local Store [ $ParseKeyValueStore [ $Grep ($ScriptVal->"source") ("\23 provides: lease-script, ") ] ];
:set ($RunOrder->($Store->"order" . "-" . $ScriptVal->"name")) ($ScriptVal->"name");
}
:foreach Order,Script in=$RunOrder do={
:onerror Err {
$LogPrint debug $ScriptName ("Running script with order " . $Order . ": " . $Script);
/system/script/run $Script;
} do={
$LogPrint warning $ScriptName ("Running script '" . $Script . "' failed: " . $Err);
}
}
} do={
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
}

View file

@ -37,9 +37,7 @@
# flush e-mail queue # flush e-mail queue
:set FlushEmailQueue do={ :onerror Err { :set FlushEmailQueue do={ :onerror Err {
:global EmailQueue; :global EmailQueue;
:global EmailServerCertificate;
:global CertificateAvailable;
:global EitherOr; :global EitherOr;
:global EMailGenerateFrom; :global EMailGenerateFrom;
:global FileExists; :global FileExists;
@ -50,10 +48,11 @@
:local AllDone true; :local AllDone true;
:local QueueLen [ :len $EmailQueue ]; :local QueueLen [ :len $EmailQueue ];
:local Scheduler [ /system/scheduler/find where name="_FlushEmailQueue" ];
:if ([ :len [ /system/scheduler/find where name="_FlushEmailQueue" ] ] > 0 && $QueueLen = 0) do={ :if ([ :len $Scheduler ] > 0 && $QueueLen = 0) do={
$LogPrint warning $0 ("Flushing E-Mail messages from scheduler, but queue is empty."); $LogPrint warning $0 ("Flushing E-Mail messages from scheduler, but queue is empty.");
/system/scheduler/remove [ find where name="_FlushEmailQueue" ]; /system/scheduler/remove $Scheduler;
:return false; :return false;
} }
@ -61,19 +60,15 @@
:return true; :return true;
} }
:if ([ :len [ /system/scheduler/find where name="_FlushEmailQueue" ] ] < 0) do={ :if ([ :len $Scheduler ] < 0) do={
/system/scheduler/add name="_FlushEmailQueue" interval=1m start-time=startup \ /system/scheduler/add name="_FlushEmailQueue" interval=1m start-time=startup \
comment="Doing initial checks..." on-event=(":global FlushEmailQueue; \$FlushEmailQueue;"); comment="Doing initial checks..." on-event=(":global FlushEmailQueue; \$FlushEmailQueue;");
:set Scheduler [ /system/scheduler/find where name="_FlushEmailQueue" ];
} }
:do { :local SchedVal [ /system/scheduler/get $Scheduler ];
:if (([ /system/scheduler/get [ find where name="_FlushEmailQueue" ] ]->"interval") < 1m) do={ :if (($SchedVal->"interval") < 1m) do={
/system/scheduler/set interval=1m comment="Doing initial checks..." \ /system/scheduler/set interval=1m comment="Doing initial checks..." $Scheduler;
[ find where name="_FlushEmailQueue" ];
}
} on-error={
$LogPrint debug $0 ("The scheduler is gone, aborting.");
:return false;
} }
:if ([ /tool/e-mail/get last-status ] = "in-progress") do={ :if ([ /tool/e-mail/get last-status ] = "in-progress") do={
@ -92,16 +87,7 @@
:return false; :return false;
} }
:if (([ /tool/e-mail/get ]->"certificate-verification") ~ "^yes" && \ /system/scheduler/set interval=($QueueLen . "m") comment="Sending..." $Scheduler;
[ :len $EmailServerCertificate ] > 0) do={
:if ([ $CertificateAvailable $EmailServerCertificate "email" ] = false) do={
$LogPrint warning $0 ("Downloading required certificate failed.");
:return false;
}
}
/system/scheduler/set interval=($QueueLen . "m") comment="Sending..." \
[ find where name="_FlushEmailQueue" ];
:foreach Id,Message in=$EmailQueue do={ :foreach Id,Message in=$EmailQueue do={
:if ([ :typeof $Message ] = "array" ) do={ :if ([ :typeof $Message ] = "array" ) do={
@ -157,8 +143,8 @@
:return false; :return false;
} }
/system/scheduler/set interval=(([ get [ find where name="_FlushEmailQueue" ] ]->"run-count") . "m") \ /system/scheduler/set interval=(($SchedVal->"run-count") . "m") \
comment="Waiting for retry..." [ find where name="_FlushEmailQueue" ]; comment="Waiting for retry..." $Scheduler;
} do={ } do={
:global ExitOnError; $ExitOnError $0 $Err; :global ExitOnError; $ExitOnError $0 $Err;
} } } }

View file

@ -3,7 +3,7 @@
# Copyright (c) 2020-2026 Christian Hesse <mail@eworm.de> # Copyright (c) 2020-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md # https://rsc.eworm.de/COPYING.md
# #
# requires RouterOS, version=7.21 # requires RouterOS, version=7.19
# #
# import ssh keys for public key authentication # import ssh keys for public key authentication
# https://rsc.eworm.de/doc/mod/ssh-keys-import.md # https://rsc.eworm.de/doc/mod/ssh-keys-import.md
@ -40,8 +40,9 @@
:local FingerPrintMD5 [ :convert from=base64 transform=md5 to=hex ($KeyVal->1) ]; :local FingerPrintMD5 [ :convert from=base64 transform=md5 to=hex ($KeyVal->1) ];
:local RegEx ("\\bmd5=" . $FingerPrintMD5 . "\\b");
:if ([ :len [ /user/ssh-keys/find where user=$User \ :if ([ :len [ /user/ssh-keys/find where user=$User \
info~("\\bmd5=" . $FingerPrintMD5 . "\\b") ] ] > 0) do={ (key-owner~$RegEx or info~$RegEx) ] ] > 0) do={
$LogPrint warning $0 ("The ssh public key (MD5:" . $FingerPrintMD5 . \ $LogPrint warning $0 ("The ssh public key (MD5:" . $FingerPrintMD5 . \
") is already available for user '" . $User . "'."); ") is already available for user '" . $User . "'.");
:return false; :return false;

View file

@ -115,15 +115,13 @@
:local Data false; :local Data false;
:onerror Err { :onerror Err {
:local I 1;
:retry { :retry {
:set I ($I ^ 1);
:set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \ :set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \
http-header-field=({ "accept: application/dns-message" }) \ http-header-field=({ "accept: application/dns-message" }) \
url=(($DohServer->"doh-url") . "?dns=" . [ :convert to=base64 ([ :rndstr length=2 ] . \ url=(($DohServer->"doh-url") . "?dns=" . [ :convert to=base64 ([ :rndstr length=2 ] . \
"\01\00" . "\00\01" . "\00\00" . "\00\00" . "\00\00" . "\09doh-check\05eworm" . \ "\01\00" . "\00\01" . "\00\00" . "\00\00" . "\00\00" . "\09doh-check\05eworm\02de\00" . \
({ "\02de"; "\03net" }->$I) . "\00" . "\00\10" . "\00\01") ]) as-value ]->"data"); "\00\10" . "\00\01") ]) as-value ]->"data");
} delay=500ms max=6; } delay=1s max=3;
} do={ } do={
$LogPrint warning $ScriptName ("Request to DoH server " . ($DohServer->"doh-url") . \ $LogPrint warning $ScriptName ("Request to DoH server " . ($DohServer->"doh-url") . \
" failed: " . $Err); " failed: " . $Err);

View file

@ -64,19 +64,14 @@
137="Added support to send notifications via Gotify (gotify.net)."; 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..."; 138="RouterOS 7.19 is suffering an issue with certificate store. Fixing trust state for all certificates...";
139="Certificate Authorities will reduce the leaf certificate validity times soon. Thus the defaults for renewal and warning in 'check-certificates' were decreased."; 139="Certificate Authorities will reduce the leaf certificate validity times soon. Thus the defaults for renewal and warning in 'check-certificates' were decreased.";
140="The scripts 'lease-script' was renamed to 'dhcpv4-server-lease', configuration was updated automatically.";
141="Introduced script 'dhcpv6-client-lease' to run several scripts on IPv6 DHCP client lease.";
142="Added a setting for 'mod/notification-email' to check availability of certificate chain.";
143="Made backup scripts 'backup-email' and 'backup-upload' support date & time in filenames.";
}; };
# Migration steps to be applied on script updates # Migration steps to be applied on script updates
:global GlobalConfigMigration { :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; };"; 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\\r?\\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;"; 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; };"; 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={ }; }; };"; 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 ];"; 138="/certificate/set trusted=yes [ find where trusted=yes ];";
140=":if ([ :len [ /system/script/find where name=\"lease-script\" ] ] > 0) do={ /system/script/set name=\"dhcpv4-server-lease\" \"lease-script\"; :global ScriptInstallUpdate; \$ScriptInstallUpdate; /ip/dhcp-server/set lease-script=\"dhcpv4-server-lease\" [ find where lease-script=\"lease-script\" ]; };";
}; };