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/).
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
browser, then click the *shield* icon in addressbar, followed by
"*Connection secure*".
[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 site information*".
The dialog will change, click "*More information*".
![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 CertCommonName "ISRG Root X2";
:local CertFileName "ISRG-Root-X2.pem";
:local CertFingerprint "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470";
:local CertCommonName "Root YE";
:local CertFileName "Root-YE.pem";
:local CertFingerprint "e14ffcad5b0025731006caa43a121a22d8e9700f4fb9cf852f02a708aa5d5666";
:local CertSettings [ /certificate/settings/get ];
: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
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)
> **Info**: Note that the command above does *not* verify server
> 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:
> *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.
/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
a sensitive property, the passphrase.
@ -145,11 +145,11 @@ a sensitive property, the passphrase.
![screenshot: import certs](README.d/02-import-certs.avif)
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.
/certificate/set name="ISRG-Root-X2" [ find where common-name="ISRG Root X2" ];
/certificate/print proplist=name,fingerprint where fingerprint="69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470";
/certificate/set name="Root-YE" [ find where common-name="Root YE" ];
/certificate/print proplist=name,fingerprint where fingerprint="e14ffcad5b0025731006caa43a121a22d8e9700f4fb9cf852f02a708aa5d5666";
![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
cleanup add a scheduler entry.
$ScriptInstallUpdate dhcp-to-dns,dhcpv4-server-lease;
/ip/dhcp-server/set lease-script="dhcpv4-server-lease" [ find ];
$ScriptInstallUpdate dhcp-to-dns,lease-script;
/ip/dhcp-server/set lease-script=lease-script [ find ];
/system/scheduler/add name="dhcp-to-dns" interval=5m start-time=startup on-event="/system/script/run dhcp-to-dns;";
![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`)
* [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`)
* [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`)
* [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`)
@ -296,6 +294,7 @@ Available scripts
* [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`)

View file

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

View file

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

View file

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

View file

@ -60,8 +60,8 @@
http-header-field=({ [ $FetchUserAgentStr $ScriptName ] }) \
($CertRenewUrl . $CertFileName) dst-path=$CertFileName as-value;
} do={
:if (!($Err ~ "[Ss]tatus 404")) do={
$LogPrint warning $0 ("Failed fetching certificate by '" . $FetchName . "': " . $Err);
:if ($Err != "Fetch failed with status 404") do={
$LogPrint warning $0 ("Failed fetching certificate: " . $Err);
}
:error false;
}
@ -164,8 +164,7 @@
}
$WaitFullyConnected;
:foreach Cert in=[ /certificate/find where !revoked !scep-url expires-after<$CertRenewTime \
!ca (common-name or subject-alt-name) ] do={
:foreach Cert in=[ /certificate/find where !revoked !ca !scep-url expires-after<$CertRenewTime ] do={
:local CertVal [ /certificate/get $Cert ];
:local LastName;
:local FetchName;
@ -178,11 +177,9 @@
$LogPrint info $ScriptName ("Attempting to renew certificate '" . ($CertVal->"name") . "'.");
:local ImportSuccess false;
:if ([ :len ($CertVal->"common-name") ] > 0) do={
:set LastName ($CertVal->"common-name");
:set FetchName $LastName;
:set ImportSuccess [ $CheckCertificatesDownloadImport $ScriptName $LastName $FetchName ];
}
:set LastName ($CertVal->"common-name");
: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 ] ];
@ -245,8 +242,8 @@
}
}
:foreach Cert in=[ /certificate/find where !revoked !scep-url expires-after<$CertWarnTime \
!(expires-after=[]) !(fingerprint=[]) ] do={
:foreach Cert in=[ /certificate/find where !revoked !scep-url !(expires-after=[]) \
expires-after<$CertWarnTime !(fingerprint=[]) ] do={
:local CertVal [ /certificate/get $Cert ];
: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>
# https://rsc.eworm.de/COPYING.md
#
# provides: dhcpv4-server-lease, order=40
# provides: lease-script, order=40
# requires RouterOS, version=7.19
#
# collect wireless mac adresses in access list

View file

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

View file

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

View file

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

View file

@ -13,9 +13,7 @@ sed \
markdown -f toc,idanchor "${1}" | sed \
-e 's/href="\([-_\./[:alnum:]]*\)\.md\(#[-[:alnum:]]*\)\?"/href="\1.html\2"/g' \
-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|-3[f]-||g' \
-e '/<h[1234] /s|-2[1789cd]-||g' -e '/<h[1234] /s|--26-amp-3b-||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;"|'

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>(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>
<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).
#### 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
/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).
#### lease-script
/save lease-script Run other scripts on DHCP lease with [lease-script](https://rsc.eworm.de/doc/lease-script.md).
#### leds-mode
/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>
# https://rsc.eworm.de/COPYING.md
#
# provides: dhcpv4-server-lease, order=60
# provides: lease-script, order=60
# requires RouterOS, version=7.19
#
# 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>
# https://rsc.eworm.de/COPYING.md
#
# provides: dhcpv4-server-lease, order=60
# provides: lease-script, order=60
# requires RouterOS, version=7.19
#
# 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>
# https://rsc.eworm.de/COPYING.md
#
# provides: dhcpv4-server-lease, order=60
# provides: lease-script, order=60
# requires RouterOS, version=7.19
#
# 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>
# https://rsc.eworm.de/COPYING.md
#
# provides: dhcpv4-server-lease, order=60
# provides: lease-script, order=60
# requires RouterOS, version=7.19
#
# 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>
# https://rsc.eworm.de/COPYING.md
#
# provides: dhcpv4-server-lease, order=20
# provides: lease-script, order=20
# requires RouterOS, version=7.19
#
# check DHCP leases and add/remove/update DNS entries
@ -51,6 +51,7 @@
active-address=($DnsRecordVal->"address") server=($DnsRecordInfo->"server") status=bound ] ] > 0) do={
$LogPrint debug $ScriptName ("Lease for " . $MacInServer . " (" . $DnsRecordVal->"name" . ") still exists. Not deleting record.");
} else={
:local Found false;
$LogPrint info $ScriptName ("Lease expired for " . $MacInServer . ", deleting record (" . $DnsRecordVal->"name" . ").");
/ip/dns/static/remove $DnsRecord;
/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:
* `BackupFileNameDate`: whether to add date & time in filenames
* `BackupSendBinary`: whether to send binary backup
* `BackupSendExport`: whether to send configuration export
* `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:
* `BackupFileNameDate`: whether to add date & time in filenames
* `BackupSendBinary`: whether to send binary backup
* `BackupSendExport`: whether to send configuration export
* `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
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;
/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
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
--------
* [Comment DHCP leases with info from access list](dhcp-lease-comment.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)

View file

@ -50,14 +50,14 @@ Usage and invocation
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
[dhcpv4-server-lease](dhcpv4-server-lease.md).
[lease-script](lease-script.md).
See also
--------
* [Collect MAC addresses in wireless access list](collect-wireless-mac.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)

View file

@ -28,7 +28,7 @@ Just install the script:
$ScriptInstallUpdate dhcp-to-dns;
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:
@ -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
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
--------
* [Collect MAC addresses in wireless access list](collect-wireless-mac.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)
* [Run other scripts on DHCP lease](lease-script.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`:
$ScriptInstallUpdate hotspot-to-wpa-cleanup.wifi,dhcpv4-server-lease;
/system/scheduler/add interval=1d name="hotspot-to-wpa-cleanup" on-event="/system/script/run hotspot-to-wpa-cleanup.wifi;" start-time=startup;
$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;
For legacy CAPsMAN:
$ScriptInstallUpdate hotspot-to-wpa-cleanup.capsman,dhcpv4-server-lease;
/system/scheduler/add interval=1d name="hotspot-to-wpa-cleanup" on-event="/system/script/run hotspot-to-wpa-cleanup.capsman;" start-time=startup;
$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;
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
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
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
-------------
@ -117,7 +117,7 @@ passphrase from hotspot credentials.
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)

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;
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
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
--------
* [Run other scripts on IPv6 DHCP client lease](dhcpv6-client-lease.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.
Then edit `global-config-overlay`, add `EmailGeneralTo` with a valid
recipient address. Optionally add `EmailServerCertificate` and add the CA
certificate name if you have certificate verification enabled. Finally
reload the configuration.
recipient address. Finally reload the configuration.
> **Info**: Copy relevant configuration from
> [`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 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.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)
[![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;
The third part of the key (`user` in this example) is inherited as
`info` in RouterOS. Also the `MD5` fingerprint is recorded, this helps
to audit and verify the available keys.
`info` in RouterOS (or `key-owner` with RouterOS 7.20.x and before). Also
the `MD5` fingerprint is recorded, this helps to audit and verify the
available keys.
> **Info**: Use `ssh-keygen` to show a fingerprint of an existing public
> key file: `ssh-keygen -l -E md5 -f ~/.ssh/id_ed25519.pub`

View file

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

View file

@ -31,8 +31,6 @@
:global EmailGeneralCc "";
#:global EmailGeneralTo "mail@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
# 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.
:global TerminalColorOutput true;
# This defines whether to add date & time in filenames, what backups to generate,
# the password to use, and what random delay (between 0 and given seconds) to apply.
:global BackupFileNameDate false;
# This defines what backups to generate and what password to use.
:global BackupSendBinary false;
:global BackupSendExport true;
:global BackupSendGlobalConfig true;
@ -119,7 +115,7 @@
# cert="Root YE" };
{ 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="ISRG Root X1" };
cert="USERTrust RSA Certification Authority" };
{ url="https://www.dshield.org/block.txt"; cidr="/24";
cert="GTS Root R4" };
{ url="https://lists.blocklist.de/lists/strongips.txt";

View file

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

View file

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

View file

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

View file

@ -4,7 +4,6 @@
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.19
# provides: dhcpv6-client-lease, order=40
#
# update firewall and dns settings on IPv6 prefix change
# 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;
:local ScriptName [ :jobname ];
:global EitherOr;
:global LogPrint;
:global ParseKeyValueStore;
: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") ];
: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={
:if ([ $ScriptLock $ScriptName ] = false) do={
:set ExitOK true;
:error false;
}
@ -54,7 +50,7 @@
: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) 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 OldPrefix [ /ipv6/firewall/address-list/get ($AddrList->0) address ];

View file

@ -1,3 +1,65 @@
#!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
:set FlushEmailQueue do={ :onerror Err {
:global EmailQueue;
:global EmailServerCertificate;
:global CertificateAvailable;
:global EitherOr;
:global EMailGenerateFrom;
:global FileExists;
@ -50,10 +48,11 @@
:local AllDone true;
: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.");
/system/scheduler/remove [ find where name="_FlushEmailQueue" ];
/system/scheduler/remove $Scheduler;
:return false;
}
@ -61,19 +60,15 @@
: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 \
comment="Doing initial checks..." on-event=(":global FlushEmailQueue; \$FlushEmailQueue;");
:set Scheduler [ /system/scheduler/find where name="_FlushEmailQueue" ];
}
:do {
:if (([ /system/scheduler/get [ find where name="_FlushEmailQueue" ] ]->"interval") < 1m) do={
/system/scheduler/set interval=1m comment="Doing initial checks..." \
[ find where name="_FlushEmailQueue" ];
}
} on-error={
$LogPrint debug $0 ("The scheduler is gone, aborting.");
:return false;
:local SchedVal [ /system/scheduler/get $Scheduler ];
:if (($SchedVal->"interval") < 1m) do={
/system/scheduler/set interval=1m comment="Doing initial checks..." $Scheduler;
}
:if ([ /tool/e-mail/get last-status ] = "in-progress") do={
@ -92,16 +87,7 @@
:return false;
}
:if (([ /tool/e-mail/get ]->"certificate-verification") ~ "^yes" && \
[ :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" ];
/system/scheduler/set interval=($QueueLen . "m") comment="Sending..." $Scheduler;
:foreach Id,Message in=$EmailQueue do={
:if ([ :typeof $Message ] = "array" ) do={
@ -157,8 +143,8 @@
:return false;
}
/system/scheduler/set interval=(([ get [ find where name="_FlushEmailQueue" ] ]->"run-count") . "m") \
comment="Waiting for retry..." [ find where name="_FlushEmailQueue" ];
/system/scheduler/set interval=(($SchedVal->"run-count") . "m") \
comment="Waiting for retry..." $Scheduler;
} do={
:global ExitOnError; $ExitOnError $0 $Err;
} }

View file

@ -3,7 +3,7 @@
# Copyright (c) 2020-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.21
# requires RouterOS, version=7.19
#
# import ssh keys for public key authentication
# 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 RegEx ("\\bmd5=" . $FingerPrintMD5 . "\\b");
: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 . \
") is already available for user '" . $User . "'.");
:return false;

View file

@ -115,15 +115,13 @@
:local Data false;
:onerror Err {
:local I 1;
:retry {
:set I ($I ^ 1);
: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"; "\03net" }->$I) . "\00" . "\00\10" . "\00\01") ]) as-value ]->"data");
} delay=500ms max=6;
"\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);

View file

@ -64,19 +64,14 @@
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...";
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
: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\\r?\\n\" ] ] > 0) do={ /system/script/set name=\"mod/ssh-keys-import\" ssh-keys-import; \$ScriptInstallUpdate; };";
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; }";
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={ }; }; };";
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 ];";
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\" ]; };";
};