Compare commits
No commits in common. "main" and "change-38" have entirely different histories.
13
.gitignore
vendored
|
|
@ -1,16 +1,3 @@
|
||||||
# backup and temporary files
|
|
||||||
*~
|
*~
|
||||||
|
|
||||||
# patches and related files
|
|
||||||
*.orig
|
|
||||||
*.patch
|
*.patch
|
||||||
*.rej
|
|
||||||
|
|
||||||
# html files (as generated from markdown)
|
|
||||||
*.html
|
*.html
|
||||||
|
|
||||||
# checksums file as used by $ScriptInstallUpdate
|
|
||||||
checksums.json
|
|
||||||
|
|
||||||
# Mac OS X folder settings file
|
|
||||||
.DS_Store
|
|
||||||
|
|
|
||||||
50
BRANCHES.md
|
|
@ -1,50 +0,0 @@
|
||||||
Installing from branches
|
|
||||||
========================
|
|
||||||
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/stargazers)
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/network)
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/watchers)
|
|
||||||
[](https://mikrotik.com/download/changelogs/)
|
|
||||||
[](https://t.me/routeros_scripts)
|
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
|
|
||||||
|
|
||||||
[⬅️ Go back to main README](README.md)
|
|
||||||
|
|
||||||
> ⚠️ **Warning**: Living on the edge? Great, read on!
|
|
||||||
> If not: Please use the `main` branch and leave this page!
|
|
||||||
|
|
||||||
These scripts are developed in a [git ↗️](https://git-scm.com/) repository.
|
|
||||||
Development and experimental branches are used to provide early access
|
|
||||||
for specific changes. You can install scripts from these branches
|
|
||||||
for testing.
|
|
||||||
|
|
||||||
## Install single script
|
|
||||||
|
|
||||||
To install a single script from `next` branch:
|
|
||||||
|
|
||||||
$ScriptInstallUpdate script-name "base-url=https://rsc.eworm.de/next/";
|
|
||||||
|
|
||||||
## Switch existing script
|
|
||||||
|
|
||||||
Alternatively switch an existing script to update from `next` branch:
|
|
||||||
|
|
||||||
/system/script/set comment="base-url=https://rsc.eworm.de/next/" script-name;
|
|
||||||
$ScriptInstallUpdate;
|
|
||||||
|
|
||||||
## Switch installation
|
|
||||||
|
|
||||||
Last but not least - to switch the complete installation to the `next`
|
|
||||||
branch edit `global-config-overlay` and add:
|
|
||||||
|
|
||||||
:global ScriptUpdatesBaseUrl "https://rsc.eworm.de/next/";
|
|
||||||
|
|
||||||
... then reload the configuration and update:
|
|
||||||
|
|
||||||
/system/script/run global-config;
|
|
||||||
$ScriptInstallUpdate;
|
|
||||||
|
|
||||||
> ℹ️ **Info**: Replace `next` with *whatever* to use another specific branch.
|
|
||||||
|
|
||||||
---
|
|
||||||
[⬅️ Go back to main README](README.md)
|
|
||||||
[⬆️ Go back to top](#top)
|
|
||||||
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
|
@ -1,83 +0,0 @@
|
||||||
Certificate name from browser
|
|
||||||
=============================
|
|
||||||
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/stargazers)
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/network)
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/watchers)
|
|
||||||
[](https://mikrotik.com/download/changelogs/)
|
|
||||||
[](https://t.me/routeros_scripts)
|
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
|
|
||||||
|
|
||||||
[⬅️ Go back to main README](README.md)
|
|
||||||
|
|
||||||
All well known desktop, mobile and server operating systems come with a
|
|
||||||
certificate store that is populated with a set of well known and trusted
|
|
||||||
certificates, acting as *trust anchors*.
|
|
||||||
|
|
||||||
However RouterOS does not, still sometimes a specific certificate is
|
|
||||||
required to properly verify a chain of trust. One example is downloading
|
|
||||||
the scripts from this repository with `fetch` command, thus the very
|
|
||||||
first step of [installation](README.md#the-long-way-in-detail) is importing
|
|
||||||
the certificate.
|
|
||||||
|
|
||||||
The scripts can install additional certificates when required. This happens
|
|
||||||
from this repository if available, or from [mkcert.org ↗️](https://mkcert.org)
|
|
||||||
as a fallback.
|
|
||||||
|
|
||||||
Get the certificate's CommonName
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
But how to determine what certificate may be required? Often easiest way
|
|
||||||
is to use a desktop browser to get that information. This demonstration uses
|
|
||||||
[Mozilla Firefox ↗️](https://www.mozilla.org/firefox/).
|
|
||||||
|
|
||||||
Let's assume we want to make sure the certificate for
|
|
||||||
[git.eworm.de](https://git.eworm.de/) is available. Open that page in the
|
|
||||||
browser, then click the *lock* icon in addressbar, followed by "*Connection
|
|
||||||
secure*".
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
The dialog will change, click "*More information*".
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
A new window opens, click the button "*View Certificate*". (That window
|
|
||||||
can be closed now.)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
A new tab opens, showing information on the server certificate and its
|
|
||||||
chain of trust. The leftmost certificate is what we are interested in.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Now we know that "`ISRG Root X2`" is required, some scripts need just
|
|
||||||
that information.
|
|
||||||
|
|
||||||
Import a certificate by CommonName
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
Running the function `$CertificateAvailable` with that name as parameter
|
|
||||||
makes sure the certificate is available in the device's store:
|
|
||||||
|
|
||||||
$CertificateAvailable "ISRG Root X2" "fetch";
|
|
||||||
|
|
||||||
If the certificate is actually available already nothing happens, and there
|
|
||||||
is no output. Otherwise the certificate is downloaded and imported.
|
|
||||||
|
|
||||||
If importing a certificate with that exact name fails a warning is given
|
|
||||||
and nothing is actually imported.
|
|
||||||
|
|
||||||
See also
|
|
||||||
--------
|
|
||||||
|
|
||||||
* [Download, import and update firewall address-lists](doc/fw-addr-lists.md)
|
|
||||||
* [Manage DNS and DoH servers from netwatch](doc/netwatch-dns.md)
|
|
||||||
* [Send notifications via Gotify](doc/mod/notification-gotify.md)
|
|
||||||
* [Send notifications via Matrix](doc/mod/notification-matrix.md)
|
|
||||||
* [Send notifications via Ntfy](doc/mod/notification-ntfy.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
[⬅️ Go back to main README](README.md)
|
|
||||||
[⬆️ Go back to top](#top)
|
|
||||||
|
|
@ -1,66 +1,28 @@
|
||||||
Past Contributions
|
Past Contributions
|
||||||
==================
|
==================
|
||||||
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/stargazers)
|
[◀ Go back to main README](README.md)
|
||||||
[](https://github.com/eworm-de/routeros-scripts/network)
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/watchers)
|
|
||||||
[](https://mikrotik.com/download/changelogs/)
|
|
||||||
[](https://t.me/routeros_scripts)
|
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
|
|
||||||
|
|
||||||
[⬅️ Go back to main README](README.md)
|
Thanks a lot for your contributions!
|
||||||
|
|
||||||
Thanks a lot for your contributions! ❤️
|
|
||||||
|
|
||||||
## Patches
|
## Patches
|
||||||
|
|
||||||
These persons contributed code or documentation. See the git history
|
These persons contributed code. See the git history for details!
|
||||||
for details!
|
|
||||||
|
|
||||||
* [Anatoly Bubenkov](mailto:bubenkoff@gmail.com) (@bubenkoff)
|
* [Michael Gisbers](mailto:michael@gisbers.de)
|
||||||
* [Ben Harris](mailto:mail@bharr.is) (@bharrisau)
|
|
||||||
* [Daniel Ziegenberg](mailto:daniel@ziegenberg.at) (@ziegenberg)
|
|
||||||
* [Ignacio Serrano](mailto:ignic@ignic.com) (@ignic)
|
|
||||||
* [Ilya Kulakov](mailto:kulakov.ilya@gmail.com) (@Kentzo)
|
|
||||||
* [Leonardo David Monteiro](mailto:leo@cub3.xyz) (@leosfsm)
|
|
||||||
* [Michael Gisbers](mailto:michael@gisbers.de) (@mgisbers)
|
|
||||||
* [Miquel Bonastre](mailto:mbonastre@yahoo.com) (@mbonastre)
|
|
||||||
* @netravnen
|
|
||||||
* [netztrip](mailto:dave-tvg@netztrip.de) (@netztrip)
|
* [netztrip](mailto:dave-tvg@netztrip.de) (@netztrip)
|
||||||
* [Stefan Müller](mailto:stefan.mueller.83@gmail.com) (@PackElend)
|
|
||||||
|
|
||||||
## Donations
|
## Donations
|
||||||
|
|
||||||
Add yourself to the list,
|
Add yourself to the list,
|
||||||
[donate with PayPal ↗️](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)!
|
[donate with PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)!
|
||||||
|
|
||||||
* Abdul Mannan Abbasi
|
|
||||||
* Alex Maier
|
|
||||||
* Andrea Ruffini Perico
|
|
||||||
* Andrew Cox
|
|
||||||
* Christoph Boss (@Kampfwurst)
|
|
||||||
* Daniel Ziegenberg (@ziegenberg)
|
|
||||||
* Devin Dean (@dd2594gh)
|
|
||||||
* Evaldo Gardenal
|
|
||||||
* Florian Estraviz
|
|
||||||
* Giorgio Bikos
|
|
||||||
* Harold Schoemaker
|
|
||||||
* Hugo BV
|
|
||||||
* Klaus Michael Rübsam
|
|
||||||
* Leonardo Valeri Manera
|
|
||||||
* Linux-Schmie.de Michael Gisbers
|
|
||||||
* Manuel Kuhn
|
|
||||||
* Marek Čábák
|
|
||||||
* Oleksandr Yukhymchuk
|
|
||||||
* Peter Holtkamp
|
|
||||||
* Peter Ponzel
|
|
||||||
* Reiner Vehrenkamp
|
* Reiner Vehrenkamp
|
||||||
* Richard Österreicher
|
* Linux-Schmie.de Michael Gisbers
|
||||||
* Simon Hitzemann
|
* Christoph Boss (@Kampfwurst)
|
||||||
* Sunny Chu (@sunnychuchu)
|
* Klaus Michael Rübsam
|
||||||
* Ulrich Wessendorf
|
* Marek Čábák
|
||||||
* Zac Kornilakis
|
|
||||||
|
|
||||||
---
|
---
|
||||||
[⬅️ Go back to main README](README.md)
|
[◀ Go back to main README](README.md)
|
||||||
[⬆️ Go back to top](#top)
|
[▲ Go back to top](#top)
|
||||||
|
|
|
||||||
63
DEBUG.md
|
|
@ -1,63 +0,0 @@
|
||||||
Debug output and logs
|
|
||||||
=====================
|
|
||||||
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/stargazers)
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/network)
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/watchers)
|
|
||||||
[](https://mikrotik.com/download/changelogs/)
|
|
||||||
[](https://t.me/routeros_scripts)
|
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
|
|
||||||
|
|
||||||
[⬅️ Go back to main README](README.md)
|
|
||||||
|
|
||||||
Sometimes scripts do not behave as expected. In these cases debug output
|
|
||||||
or logs can help.
|
|
||||||
|
|
||||||
## Debug output
|
|
||||||
|
|
||||||
Run this command in a terminal:
|
|
||||||
|
|
||||||
:set PrintDebug true;
|
|
||||||
|
|
||||||
You will then see debug output when running the script from terminal.
|
|
||||||
|
|
||||||
To revert to default output run:
|
|
||||||
|
|
||||||
:set PrintDebug false;
|
|
||||||
|
|
||||||
### Debug output for specific script
|
|
||||||
|
|
||||||
Even having debug output for a specific script or function only (or a
|
|
||||||
set of) is possible. To enable debug output for `telegram-chat` run:
|
|
||||||
|
|
||||||
:set ($PrintDebugOverride->"telegram-chat") true;
|
|
||||||
|
|
||||||
## Debug logs
|
|
||||||
|
|
||||||
The debug info can go to system log. To make it show up in `memory` run:
|
|
||||||
|
|
||||||
/system/logging/add topics=script,debug action=memory;
|
|
||||||
|
|
||||||
Other actions (`disk`, `email`, `remote` or `support`) can be used as
|
|
||||||
well. I do not recommend using `echo` - use [debug output](#debug-output)
|
|
||||||
instead.
|
|
||||||
|
|
||||||
Disable or remove that setting to restore regular logging.
|
|
||||||
|
|
||||||
## Verbose output
|
|
||||||
|
|
||||||
Specific scripts can generate huge amount of output. These do use a function
|
|
||||||
`$LogPrintVerbose`, which is declared, but has no code, intentionally.
|
|
||||||
|
|
||||||
If you *really* want that output set the function to be the same as
|
|
||||||
`$LogPrint`:
|
|
||||||
|
|
||||||
:set LogPrintVerbose $LogPrint;
|
|
||||||
|
|
||||||
To revert that change just run:
|
|
||||||
|
|
||||||
:set LogPrintVerbose;
|
|
||||||
|
|
||||||
---
|
|
||||||
[⬅️ Go back to main README](README.md)
|
|
||||||
[⬆️ Go back to top](#top)
|
|
||||||
|
|
@ -1,69 +1,39 @@
|
||||||
Initial commands
|
Initial commands
|
||||||
================
|
================
|
||||||
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/stargazers)
|
[◀ Go back to main README](README.md)
|
||||||
[](https://github.com/eworm-de/routeros-scripts/network)
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/watchers)
|
|
||||||
[](https://mikrotik.com/download/changelogs/)
|
|
||||||
[](https://t.me/routeros_scripts)
|
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
|
|
||||||
|
|
||||||
[⬅️ Go back to main README](README.md)
|
These command are inteneded for initial setup. If you are not aware of the
|
||||||
|
procedure please follow [the long way in detail](README.md#the-long-way-in-detail).
|
||||||
> ⚠️ **Warning**: These commands are intended for initial setup. If you are
|
|
||||||
> not aware of the procedure please follow
|
|
||||||
> [the long way in detail](README.md#the-long-way-in-detail).
|
|
||||||
|
|
||||||
Run the complete base installation:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
:local BaseUrl "https://rsc.eworm.de/main/";
|
/ tool fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/R3.pem" dst-path="letsencrypt-R3.pem";
|
||||||
:local CertCommonName "ISRG Root X2";
|
/ tool fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/Let%27s%20Encrypt%20Authority%20X3.pem" dst-path="letsencrypt-X3.pem";
|
||||||
:local CertFileName "ISRG-Root-X2.pem";
|
:delay 1s;
|
||||||
:local CertFingerprint "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470";
|
/ certificate import file-name=letsencrypt-R3.pem passphrase="";
|
||||||
|
/ certificate import file-name=letsencrypt-X3.pem passphrase="";
|
||||||
:local CertSettings [ /certificate/settings/get ];
|
:if ([ :len [ / certificate find where fingerprint="67add1166b020ae61b8f5fc96813c04c2aa589960796865572a3c7e737613dfd" or fingerprint="96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6" or fingerprint="731d3d9cfaa061487a1d71445a42f67df0afca2a6c2d2f98ff7b3ce112b1f568" or fingerprint="0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739" ] ] != 4) do={
|
||||||
:if (!((($CertSettings->"builtin-trust-anchors") = "trusted" || \
|
:error "Something is wrong with your certificates!";
|
||||||
($CertSettings->"builtin-trust-store") ~ "fetch" || \
|
}
|
||||||
($CertSettings->"builtin-trust-store") = "all") && \
|
/ file remove "letsencrypt-R3.pem";
|
||||||
[[ :parse (":return [ :len [ /certificate/builtin/find where common-name=\"" . $CertCommonName . "\" ] ]") ]] > 0)) do={
|
/ file remove "letsencrypt-X3.pem";
|
||||||
:put "Importing certificate...";
|
|
||||||
/tool/fetch ($BaseUrl . "certs/" . $CertFileName) dst-path=$CertFileName as-value;
|
|
||||||
:delay 1s;
|
|
||||||
/certificate/import file-name=$CertFileName passphrase="";
|
|
||||||
:if ([ :len [ /certificate/find where fingerprint=$CertFingerprint ] ] != 1) do={
|
|
||||||
:error "Something is wrong with your certificates!";
|
|
||||||
};
|
|
||||||
:delay 1s;
|
|
||||||
};
|
|
||||||
:put "Renaming global-config-overlay, if exists...";
|
|
||||||
/system/script/set name=("global-config-overlay-" . [ /system/clock/get date ] . "-" . [ /system/clock/get time ]) [ find where name="global-config-overlay" ];
|
|
||||||
:foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={
|
:foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={
|
||||||
:put "Installing $Script...";
|
/ system script add name=$Script source=([ / tool fetch check-certificate=yes-without-crl ("https://git.eworm.de/cgit/routeros-scripts/plain/" . $Script) output=user as-value]->"data");
|
||||||
/system/script/remove [ find where name=$Script ];
|
}
|
||||||
/system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ($BaseUrl . $Script . ".rsc") output=user as-value ]->"data");
|
/ system script set comment="ignore" global-config-overlay;
|
||||||
};
|
/ system script { run global-config; run global-config-overlay; run global-functions; }
|
||||||
:put "Loading configuration and functions...";
|
/ system scheduler add name="global-scripts" start-time=startup on-event="/ system script { run global-config; run global-config-overlay; run global-functions; }";
|
||||||
/system/script { run global-config; run global-functions; };
|
:global CertificateNameByCN;
|
||||||
:if ([ :len [ /certificate/find where fingerprint=$CertFingerprint ] ] > 0) do={
|
$CertificateNameByCN "R3";
|
||||||
:put "Renaming certificate by its common-name...";
|
$CertificateNameByCN "ISRG Root X1";
|
||||||
:global CertificateNameByCN;
|
$CertificateNameByCN "Let's Encrypt Authority X3";
|
||||||
$CertificateNameByCN $CertFingerprint;
|
$CertificateNameByCN "DST Root CA X3";
|
||||||
};
|
}
|
||||||
};
|
|
||||||
|
|
||||||
Then continue setup with
|
Optional to update the scripts automatically:
|
||||||
[scheduled automatic updates](README.md#scheduled-automatic-updates) or
|
|
||||||
[editing configuration](README.md#editing-configuration).
|
|
||||||
|
|
||||||
## Fix existing installation
|
/ system scheduler add name="ScriptInstallUpdate" start-time=startup interval=1d on-event=":global ScriptInstallUpdate; \$ScriptInstallUpdate;";
|
||||||
|
|
||||||
The [initial commands](#initial-commands) above allow to fix an existing
|
|
||||||
installation in case it ever breaks. If `global-config-overlay` did exist
|
|
||||||
before it is renamed with a date and time suffix (like
|
|
||||||
`global-config-overlay-2024-01-25-09:33:12`). Make sure to restore the
|
|
||||||
configuration overlay if required.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
[⬅️ Go back to main README](README.md)
|
[◀ Go back to main README](README.md)
|
||||||
[⬆️ Go back to top](#top)
|
[▲ Go back to top](#top)
|
||||||
|
|
|
||||||
53
Makefile
|
|
@ -2,45 +2,24 @@
|
||||||
# template scripts -> final scripts
|
# template scripts -> final scripts
|
||||||
# markdown files -> html files
|
# markdown files -> html files
|
||||||
|
|
||||||
ALL_RSC := $(wildcard *.rsc */*.rsc)
|
TEMPLATE = $(wildcard *.template)
|
||||||
GEN_RSC := $(wildcard *.capsman.rsc *.local.rsc *.wifi.rsc)
|
CAPSMAN = $(TEMPLATE:.template=.capsman)
|
||||||
|
LOCAL = $(TEMPLATE:.template=.local)
|
||||||
|
|
||||||
MARKDOWN := $(wildcard *.md doc/*.md doc/mod/*.md)
|
MARKDOWN = $(wildcard *.md)
|
||||||
HTML := $(MARKDOWN:.md=.html)
|
HTML = $(MARKDOWN:.md=.html)
|
||||||
|
|
||||||
DATE ?= $(shell date --rfc-email)
|
all: $(CAPSMAN) $(LOCAL) $(HTML)
|
||||||
VERSION ?= $(shell git symbolic-ref --short HEAD 2>/dev/null)/$(shell git rev-list --count HEAD 2>/dev/null)/$(shell git rev-parse --short=8 HEAD 2>/dev/null)
|
|
||||||
export DATE VERSION
|
|
||||||
|
|
||||||
.PHONY: all checksums commitinfo docs rsc clean
|
%.html: %.md Makefile
|
||||||
|
markdown $< | sed 's/href="\([-[:alnum:]]*\)\.md"/href="\1.html"/g' > $@
|
||||||
|
|
||||||
all: checksums docs rsc
|
%.local: %.template Makefile
|
||||||
|
sed -e '/\/ caps-man/d' -e 's|%PATH%|interface wireless|' -e 's|%TEMPL%|$(suffix $@)|' \
|
||||||
|
-e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \
|
||||||
|
< $< > $@
|
||||||
|
|
||||||
checksums: checksums.json
|
%.capsman: %.template Makefile
|
||||||
|
sed -e '/\/ interface wireless/d' -e 's/%PATH%/caps-man/' -e 's/%TEMPL%/$(suffix $@)/' \
|
||||||
checksums.json: contrib/checksums.sh $(ALL_RSC)
|
-e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \
|
||||||
contrib/checksums.sh > $@
|
< $< > $@
|
||||||
|
|
||||||
commitinfo: global-functions.rsc
|
|
||||||
contrib/commitinfo.sh $< > $<~
|
|
||||||
mv $<~ $<
|
|
||||||
|
|
||||||
docs: $(HTML)
|
|
||||||
|
|
||||||
%.html: %.md general/style.css contrib/html.sh contrib/html.sh.d/head.html contrib/html.sh.d/foot.html
|
|
||||||
contrib/html.sh $< > $@
|
|
||||||
|
|
||||||
rsc: $(GEN_RSC)
|
|
||||||
|
|
||||||
%.capsman.rsc: %.template.rsc contrib/template-capsman.sh
|
|
||||||
contrib/template-capsman.sh $< > $@
|
|
||||||
|
|
||||||
%.local.rsc: %.template.rsc contrib/template-local.sh
|
|
||||||
contrib/template-local.sh $< > $@
|
|
||||||
|
|
||||||
%.wifi.rsc: %.template.rsc contrib/template-wifi.sh
|
|
||||||
contrib/template-wifi.sh $< > $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(HTML) checksums.json
|
|
||||||
make -C contrib/ clean
|
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 5 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 6 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
|
@ -1,3 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
|
|
||||||
:put ("Hello World from " . [ /system/identity/get name ] . "!");
|
|
||||||
|
Before Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 891 B |
449
README.md
|
|
@ -1,75 +1,25 @@
|
||||||
RouterOS Scripts
|
RouterOS Scripts
|
||||||
================
|
================
|
||||||
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/stargazers)
|
[](https://github.com/eworm-de/routeros-scripts/network)
|
||||||
[](https://github.com/eworm-de/routeros-scripts/network)
|
[](https://github.com/eworm-de/routeros-scripts/stargazers)
|
||||||
[](https://github.com/eworm-de/routeros-scripts/watchers)
|
[](https://github.com/eworm-de/routeros-scripts/watchers)
|
||||||
[](https://mikrotik.com/download/changelogs/)
|
|
||||||
[](https://t.me/routeros_scripts)
|
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
|
|
||||||
|
|
||||||
**a collection of scripts for MikroTik RouterOS**
|
[RouterOS](https://mikrotik.com/software) is the operating system developed
|
||||||
|
by [MikroTik](https://mikrotik.com/aboutus) for networking tasks. This
|
||||||

|
repository holds a number of [scripts](https://wiki.mikrotik.com/wiki/Manual:Scripting)
|
||||||
|
|
||||||
[RouterOS ↗️](https://mikrotik.com/software) is the operating system developed
|
|
||||||
by [MikroTik ↗️](https://mikrotik.com/aboutus) for networking tasks. This
|
|
||||||
repository holds a number of [scripts ↗️](https://wiki.mikrotik.com/wiki/Manual:Scripting)
|
|
||||||
to manage RouterOS devices or extend their functionality.
|
to manage RouterOS devices or extend their functionality.
|
||||||
|
|
||||||
*Use at your own risk*, pay attention to
|
*Use at your own risk*, pay attention to
|
||||||
[license and warranty](#license-and-warranty), and
|
[license and warranty](#license-and-warranty)!
|
||||||
[disclaimer on external links](#disclaimer-on-external-links)!
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
|
||||||
### Software (RouterOS)
|
|
||||||
|
|
||||||
Latest version of the scripts require recent RouterOS to function properly.
|
Latest version of the scripts require recent RouterOS to function properly.
|
||||||
Make sure to install latest updates before you begin. This is supposed to
|
Make sure to install latest updates before you begin.
|
||||||
work flawlessly with these channels:
|
|
||||||
|
|
||||||
* `stable` - the latest version considered stable for daily use, including
|
Specific scripts may require even newer RouterOS version.
|
||||||
new features
|
|
||||||
* `long-term` - a version considered rock-solid, usually one minor version
|
|
||||||
behind `stable` (`7.(n-1)`)
|
|
||||||
|
|
||||||
New functionality or breaking changes in RouterOS are adopted fairly quick.
|
|
||||||
These changes are pushed for general availability once a version of
|
|
||||||
RouterOS supporting this had been released to the `long-term` channel a
|
|
||||||
reasonable time ago.
|
|
||||||
|
|
||||||
At any time you should have at least two minor versions and their bugfix
|
|
||||||
releases to choose from. Often way older versions of RouterOS work just
|
|
||||||
fine.
|
|
||||||
|
|
||||||
On the other hand in seldom cases and for good reasons *specific* scripts
|
|
||||||
may require an even newer RouterOS version, so only `stable` is supported
|
|
||||||
temporarily.
|
|
||||||
|
|
||||||
> 💡️ **Hint**: If in doubt have a look at the badge at the top of each
|
|
||||||
> page showing the minimum version required:
|
|
||||||
> 
|
|
||||||
|
|
||||||
> ℹ️ **Info**: The `main` branch is now RouterOS v7 only. If you are still
|
|
||||||
> running RouterOS v6 switch to `routeros-v6` branch!
|
|
||||||
|
|
||||||
#### Prerequisite configuration
|
|
||||||
|
|
||||||
Starting with RouterOS 7.17 the
|
|
||||||
[device-mode ↗️](https://help.mikrotik.com/docs/spaces/ROS/pages/93749258/Device-mode)
|
|
||||||
has been extended to give more fine-grained control over what features are
|
|
||||||
available. You need to enable `scheduler` and `fetch` at least, specific
|
|
||||||
scripts may require additional features.
|
|
||||||
|
|
||||||
### Hardware
|
|
||||||
|
|
||||||
RouterOS packages increase in size with each release. This becomes a
|
|
||||||
problem for devices with 16MB storage and below, those with an ARM CPU
|
|
||||||
are specifically affected.
|
|
||||||
|
|
||||||
Huge configuration and lots of scripts give an extra risk. **Take care!**
|
|
||||||
|
|
||||||
Initial setup
|
Initial setup
|
||||||
-------------
|
-------------
|
||||||
|
|
@ -77,147 +27,112 @@ Initial setup
|
||||||
### Get me ready!
|
### Get me ready!
|
||||||
|
|
||||||
If you know how things work just copy and paste the
|
If you know how things work just copy and paste the
|
||||||
[initial commands](INITIAL-COMMANDS.md). These also support fixing an
|
[initial commands](INITIAL-COMMANDS.md). Remember to edit and rerun
|
||||||
existing but broken installation. Remember to edit and rerun
|
|
||||||
`global-config-overlay`!
|
`global-config-overlay`!
|
||||||
|
First time users should take the long way below.
|
||||||
> 💡️ **Hint**: First time users should take
|
|
||||||
> [the long way in detail](#the-long-way-in-detail) below.
|
|
||||||
|
|
||||||
### Live presentation
|
### Live presentation
|
||||||
|
|
||||||
Want to see it in action? I've had a presentation [Repository based
|
Want to see it in action? I've had a presentation [Repository based
|
||||||
RouterOS script distribution ↗️](https://www.youtube.com/watch?v=B9neG3oAhcY)
|
RouterOS script distribution](https://www.youtube.com/watch?v=B9neG3oAhcY)
|
||||||
including demonstration recorded live at [MUM Europe
|
including demonstation recorded live at [MUM Europe
|
||||||
2019 ↗️](https://mum.mikrotik.com/2019/EU/) in Vienna.
|
2019](https://mum.mikrotik.com/2019/EU/) in Vienna.
|
||||||
|
|
||||||
> ⚠️ **Warning**: Some details changed. So see the presentation, then follow
|
*Be warned!* Some details changed. So see the presentation, then follow
|
||||||
> the steps below for up-to-date commands.
|
the steps below for up-to-date commands.
|
||||||
|
|
||||||
### The long way in detail
|
### The long way in detail
|
||||||
|
|
||||||
The update script does server certificate verification, so first step is to
|
The update script does server certificate verification, so first step is to
|
||||||
download the certificates.
|
download the certificates. If you intend to download the scripts from a
|
||||||
|
|
||||||
> 💡️ **Hint**: RouterOS 7.19 comes with a builtin certificate store. You
|
|
||||||
> can skip the steps regarding certificate download and import and jump
|
|
||||||
> to [installation of scripts](#installation-of-scripts) if you set the
|
|
||||||
> trust for these builtin trust anchors:
|
|
||||||
> `/certificate/settings/set builtin-trust-anchors=trusted;`
|
|
||||||
> With RouterOS 7.21 the functionality was changed. Set this at minimum,
|
|
||||||
> but make sure not to drop other targets:
|
|
||||||
> `/certificate/settings/set builtin-trust-store=fetch;`
|
|
||||||
|
|
||||||
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";
|
[admin@MikroTik] > / tool fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/R3.pem" dst-path="letsencrypt-R3.pem"
|
||||||
|
status: finished
|
||||||
|
downloaded: 4KiBC-z pause]
|
||||||
|
total: 4KiB
|
||||||
|
duration: 1s
|
||||||
|
|
||||||

|
[admin@MikroTik] > / tool fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/Let%27s%20Encrypt%20Authority%20X3.pem" dst-path="letsencrypt-X3.pem"
|
||||||
|
status: finished
|
||||||
|
downloaded: 5KiBC-z pause]
|
||||||
|
total: 5KiB
|
||||||
|
duration: 1s
|
||||||
|
|
||||||
Note that the commands above do *not* verify server certificate, so if you
|
Note that the commands above do *not* verify server certificate, so if you
|
||||||
want to be safe download with your workstations's browser and transfer the
|
want to be safe download with your workstations's browser and transfer the
|
||||||
file to your MikroTik device.
|
files to your MikroTik device.
|
||||||
|
|
||||||
* [ISRG Root X2 ↗️](https://letsencrypt.org/certs/isrg-root-x2.pem)
|
* [ISRG Root X1](https://letsencrypt.org/certs/isrgrootx1.pem)
|
||||||
|
* [Let's Encrypt Authority X3](https://letsencrypt.org/certs/letsencryptauthorityx3.pem)
|
||||||
|
* Let's Encrypt [R3](https://letsencrypt.org/certs/lets-encrypt-r3.pem)
|
||||||
|
|
||||||
Then we import the certificate.
|
Then we import the certificates.
|
||||||
|
|
||||||
/certificate/import file-name="isrg-root-x2.pem" passphrase="";
|
[admin@MikroTik] > / certificate import file-name=letsencrypt-R3.pem passphrase=""
|
||||||
|
certificates-imported: 3
|
||||||
|
private-keys-imported: 0
|
||||||
|
files-imported: 1
|
||||||
|
decryption-failures: 0
|
||||||
|
keys-with-no-certificate: 0
|
||||||
|
|
||||||
Do not worry that the command is not shown - that happens because it contains
|
[admin@MikroTik] > / certificate import file-name=letsencrypt-X3.pem passphrase=""
|
||||||
a sensitive property, the passphrase.
|
certificates-imported: 1
|
||||||
|
private-keys-imported: 0
|
||||||
|
files-imported: 1
|
||||||
|
decryption-failures: 0
|
||||||
|
keys-with-no-certificate: 0
|
||||||
|
|
||||||

|
For basic verification we rename the certifiactes and print their count. Make
|
||||||
|
sure the certificate count is **four**.
|
||||||
|
|
||||||
For basic verification we rename the certificate and print it by
|
[admin@MikroTik] > / certificate set name="R3" [ find where fingerprint="67add1166b020ae61b8f5fc96813c04c2aa589960796865572a3c7e737613dfd" ]
|
||||||
fingerprint. Make sure exactly this one certificate ("*ISRG-Root-X2*")
|
[admin@MikroTik] > / certificate set name="ISRG-Root-X1" [ find where fingerprint="96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6" ]
|
||||||
is shown.
|
[admin@MikroTik] > / certificate set name="Let-s-Encrypt-Authority-X3" [ find where fingerprint="731d3d9cfaa061487a1d71445a42f67df0afca2a6c2d2f98ff7b3ce112b1f568" ]
|
||||||
|
[admin@MikroTik] > / certificate set name="DST-Root-CA-X3" [ find where fingerprint="0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739" ]
|
||||||
/certificate/set name="ISRG-Root-X2" [ find where common-name="ISRG Root X2" ];
|
[admin@MikroTik] > / certificate print count-only where fingerprint="67add1166b020ae61b8f5fc96813c04c2aa589960796865572a3c7e737613dfd" or fingerprint="96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6" or fingerprint="731d3d9cfaa061487a1d71445a42f67df0afca2a6c2d2f98ff7b3ce112b1f568" or fingerprint="0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739"
|
||||||
/certificate/print proplist=name,fingerprint where fingerprint="69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470";
|
4
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Always make sure there are no certificates installed you do not know or want!
|
Always make sure there are no certificates installed you do not know or want!
|
||||||
|
|
||||||
#### Installation of scripts
|
Actually we do not require the certificate named `DST Root CA X3`, but as it
|
||||||
|
is used by `Let's Encrypt` to cross-sign we install it anyway - this makes
|
||||||
All following commands will verify the server certificate. For validity the
|
sure things do not go wrong if the intermediate certificate is replaced.
|
||||||
certificate's lifetime is checked with local time, so make sure the device's
|
The IdenTrust certificate *should* be available from their
|
||||||
date and time is set correctly!
|
[download page](https://www.identrust.com/support/downloads). The site is
|
||||||
|
crap and a good example how to *not* do it.
|
||||||
|
|
||||||
Now let's download the main scripts and add them in configuration on the fly.
|
Now let's download the main scripts and add them in configuration on the fly.
|
||||||
|
|
||||||
:foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={ /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ("https://rsc.eworm.de/main/" . $Script . ".rsc") output=user as-value ]->"data"); };
|
[admin@MikroTik] > :foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={ / system script add name=$Script source=([ / tool fetch check-certificate=yes-without-crl ("https://git.eworm.de/cgit/routeros-scripts/plain/" . $Script) output=user as-value]->"data"); }
|
||||||
|
|
||||||

|
Mark `global-config-overlay` not to be overwritten by future updates.
|
||||||
|
|
||||||
And finally run configuration and functions. This will also add the
|
[admin@MikroTik] > / system script set comment="ignore" global-config-overlay
|
||||||
scheduler for loading at system startup automatically.
|
|
||||||
|
|
||||||
/system/script { run global-config; run global-functions; };
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
> 💡️ **Hint**: You see complaints regarding syntax errors? Most likely the
|
|
||||||
> RouterOS on your device is too old. Check for updates!
|
|
||||||
|
|
||||||
### Scheduled automatic updates
|
|
||||||
|
|
||||||
The last step is optional: Add this scheduler **only** if you want the
|
|
||||||
scripts to be updated automatically!
|
|
||||||
|
|
||||||
/system/scheduler/add name="ScriptInstallUpdate" start-time=startup interval=1d on-event=":global ScriptInstallUpdate; \$ScriptInstallUpdate;";
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Editing configuration
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
The configuration needs to be tweaked for your needs. Edit
|
The configuration needs to be tweaked for your needs. Edit
|
||||||
`global-config-overlay`, copy relevant configuration from
|
`global-config-overlay`, copy configuration from
|
||||||
[`global-config`](global-config.rsc) (the one without `-overlay`).
|
[`global-config`](global-config) (the one without `-overlay`).
|
||||||
Save changes and exit with `Ctrl-o`.
|
|
||||||
|
|
||||||
/system/script/edit global-config-overlay source;
|
[admin@MikroTik] > / system script edit global-config-overlay source
|
||||||
|
|
||||||

|
And finally load configuration and functions and add the scheduler.
|
||||||
|
|
||||||
Additionally creating configuration snippets is supported. The script name
|
[admin@MikroTik] > / system script { run global-config; run global-config-overlay; run global-functions; }
|
||||||
of these snippets has to start with `global-config-overlay.d/` to make them
|
[admin@MikroTik] > / system scheduler add name="global-scripts" start-time=startup on-event="/ system script { run global-config; run global-config-overlay; run global-functions; }"
|
||||||
being loaded automatically. This allows to split off parts of the
|
|
||||||
configuration.
|
|
||||||
|
|
||||||
To apply your changes run `global-config`, which will automatically load
|
The last step is optional: Add this scheduler **only** if you want the scripts
|
||||||
the overlay as well:
|
to be updated automatically!
|
||||||
|
|
||||||
/system/script/run global-config;
|
[admin@MikroTik] > / system scheduler add name="ScriptInstallUpdate" start-time=startup interval=1d on-event=":global ScriptInstallUpdate; \$ScriptInstallUpdate;"
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
This last step is required when ever you make changes to your configuration.
|
|
||||||
|
|
||||||
> ℹ️ **Info**: It is recommended to edit the configuration using the command
|
|
||||||
> line interface. If using Winbox on Windows OS, the line endings may be
|
|
||||||
> missing. To fix this run:
|
|
||||||
> `/system/script/set source=[ :tocrlf [ get global-config-overlay source ] ] global-config-overlay;`
|
|
||||||
|
|
||||||
Updating scripts
|
Updating scripts
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
To update existing scripts just run function `$ScriptInstallUpdate`. If
|
To update existing scripts just run function `$ScriptInstallUpdate`.
|
||||||
everything is up-to-date it will not produce any output.
|
|
||||||
|
|
||||||
$ScriptInstallUpdate;
|
[admin@MikroTik] > $ScriptInstallUpdate
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
If the update includes news or requires configuration changes a notification
|
|
||||||
is sent - in addition to terminal output and log messages.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Adding a script
|
Adding a script
|
||||||
---------------
|
---------------
|
||||||
|
|
@ -225,176 +140,92 @@ Adding a script
|
||||||
To add a script from the repository run function `$ScriptInstallUpdate` with
|
To add a script from the repository run function `$ScriptInstallUpdate` with
|
||||||
a comma separated list of script names.
|
a comma separated list of script names.
|
||||||
|
|
||||||
$ScriptInstallUpdate check-certificates,check-routeros-update;
|
[admin@MikroTik] > $ScriptInstallUpdate check-certificates,check-routeros-update
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Scheduler and events
|
Scheduler and events
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Most scripts are designed to run regularly from
|
Most scripts are designed to run regularly from
|
||||||
[scheduler ↗️](https://wiki.mikrotik.com/wiki/Manual:System/Scheduler). We just
|
[scheduler](https://wiki.mikrotik.com/wiki/Manual:System/Scheduler). We just
|
||||||
added `check-routeros-update`, so let's run it daily to make sure not to
|
added `check-routeros-update`, so let's run it every hour to make sure not to
|
||||||
miss an update.
|
miss an update.
|
||||||
|
|
||||||
/system/scheduler/add name="check-routeros-update" interval=1d start-time=startup on-event="/system/script/run check-routeros-update;";
|
[admin@MikroTik] > / system scheduler add name="check-routeros-update" interval=1h on-event="/ system script run check-routeros-update;"
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Some events can run a script. If you want your DHCP hostnames to be available
|
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,lease-script;
|
[admin@MikroTik] > $ScriptInstallUpdate dhcp-to-dns,lease-script
|
||||||
/ip/dhcp-server/set lease-script=lease-script [ find ];
|
[admin@MikroTik] > / 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;";
|
[admin@MikroTik] > / system scheduler add name="dhcp-to-dns" interval=5m on-event="/ system script run dhcp-to-dns;"
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
There's much more to explore... Have fun!
|
There's much more to explore... Have fun!
|
||||||
|
|
||||||
Available scripts
|
Available Scripts
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
* [Find and remove access list duplicates](doc/accesslist-duplicates.md) (`accesslist-duplicates`)
|
* [Find and remove access list duplicates](doc/accesslist-duplicates.md)
|
||||||
* [Upload backup to Mikrotik cloud](doc/backup-cloud.md) (`backup-cloud`)
|
* [Manage ports in bridge](doc/bridge-port.md)
|
||||||
* [Send backup via e-mail](doc/backup-email.md) (`backup-email`)
|
* [Download packages for CAP upgrade from CAPsMAN](doc/capsman-download-packages.md)
|
||||||
* [Save configuration to fallback partition](doc/backup-partition.md) (`backup-partition`)
|
* [Run rolling CAP upgrades from CAPsMAN](doc/capsman-rolling-upgrade.md)
|
||||||
* [Upload backup to server](doc/backup-upload.md) (`backup-upload`)
|
* [Renew locally issued certificates](doc/certificate-renew-issued.md)
|
||||||
* [Download packages for CAP upgrade from CAPsMAN](doc/capsman-download-packages.md) (`capsman-download-packages`)
|
* [Renew certificates and notify on expiration](doc/check-certificates.md)
|
||||||
* [Run rolling CAP upgrades from CAPsMAN](doc/capsman-rolling-upgrade.md) (`capsman-rolling-upgrade`)
|
* [Notify about health state](doc/check-health.md)
|
||||||
* [Renew locally issued certificates](doc/certificate-renew-issued.md) (`certificate-renew-issued`)
|
* [Notify on LTE firmware upgrade](doc/check-lte-firmware-upgrade.md)
|
||||||
* [Renew certificates and notify on expiration](doc/check-certificates.md) (`check-certificates`)
|
* [Notify on RouterOS update](doc/check-routeros-update.md)
|
||||||
* [Notify about health state](doc/check-health.md) (`check-health`)
|
* [Upload backup to Mikrotik cloud](doc/cloud-backup.md)
|
||||||
* [Notify on LTE firmware upgrade](doc/check-lte-firmware-upgrade.md) (`check-lte-firmware-upgrade`)
|
* [Collect MAC addresses in wireless access list](doc/collect-wireless-mac.md)
|
||||||
* [Check perpetual license on CHR](doc/check-perpetual-license.md) (`check-perpetual-license`)
|
* [Use wireless network with daily psk](doc/daily-psk.md)
|
||||||
* [Notify on RouterOS update](doc/check-routeros-update.md) (`check-routeros-update`)
|
* [Comment DHCP leases with info from access list](doc/dhcp-lease-comment.md)
|
||||||
* [Collect MAC addresses in wireless access list](doc/collect-wireless-mac.md) (`collect-wireless-mac`)
|
* [Create DNS records for DHCP leases](doc/dhcp-to-dns.md)
|
||||||
* [Use wireless network with daily psk](doc/daily-psk.md) (`daily-psk`)
|
* [Send backup via e-mail](doc/email-backup.md)
|
||||||
* [Comment DHCP leases with info from access list](doc/dhcp-lease-comment.md) (`dhcp-lease-comment`)
|
* [Wait for configuration und functions](doc/global-wait.md)
|
||||||
* [Create DNS records for DHCP leases](doc/dhcp-to-dns.md) (`dhcp-to-dns`)
|
* [Send GPS position to server](doc/gps-track.md)
|
||||||
* [Automatically upgrade firmware and reboot](doc/firmware-upgrade-reboot.md) (`firmware-upgrade-reboot`)
|
* [Use WPA2 network with hotspot credentials](doc/hotspot-to-wpa.md)
|
||||||
* [Download, import and update firewall address-lists](doc/fw-addr-lists.md) (`fw-addr-lists`)
|
* [Update configuration on IPv6 prefix change](doc/ipv6-update.md)
|
||||||
* [Wait for global functions und modules](doc/global-wait.md) (`global-wait`)
|
* [Manage IP addresses with bridge status](doc/ip-addr-bridge.md)
|
||||||
* [Send GPS position to server](doc/gps-track.md) (`gps-track`)
|
* [Run other scripts on DHCP lease](doc/lease-script.md)
|
||||||
* [Use WPA network with hotspot credentials](doc/hotspot-to-wpa.md) (`hotspot-to-wpa` & `hotspot-to-wpa-cleanup`)
|
* [Manage LEDs dark mode](doc/leds-mode.md)
|
||||||
* [Create DNS records for IPSec peers](doc/ipsec-to-dns.md) (`ipsec-to-dns`)
|
* [Forward log messages via notification](doc/log-forward.md)
|
||||||
* [Update configuration on IPv6 prefix change](doc/ipv6-update.md) (`ipv6-update`)
|
* [Mode button with multiple presses](doc/mode-button.md)
|
||||||
* [Manage IP addresses with bridge status](doc/ip-addr-bridge.md) (`ip-addr-bridge`)
|
* [Notify on host up and down](doc/netwatch-notify.md)
|
||||||
* [Run other scripts on DHCP lease](doc/lease-script.md) (`lease-script`)
|
* [Manage remote logging](doc/netwatch-syslog.md)
|
||||||
* [Manage LEDs dark mode](doc/leds-mode.md) (`leds-day-mode`, `leds-night-mode` & `leds-toggle-mode`)
|
* [Visualize OSPF state via LEDs](doc/ospf-to-leds.md)
|
||||||
* [Forward log messages via notification](doc/log-forward.md) (`log-forward`)
|
* [Manage system update](doc/packages-update.md)
|
||||||
* [Mode button with multiple presses](doc/mode-button.md) (`mode-button`)
|
* [Run scripts on ppp connection](doc/ppp-on-up.md)
|
||||||
* [Manage DNS and DoH servers from netwatch](doc/netwatch-dns.md) (`netwatch-dns`)
|
* [Rotate NTP servers](doc/rotate-ntp.md)
|
||||||
* [Notify on host up and down](doc/netwatch-notify.md) (`netwatch-notify`)
|
* [Act on received SMS](doc/sms-action.md)
|
||||||
* [Visualize OSPF state via LEDs](doc/ospf-to-leds.md) (`ospf-to-leds`)
|
* [Forward received SMS](doc/sms-forward.md)
|
||||||
* [Manage system update](doc/packages-update.md) (`packages-update`)
|
* [Import SSH keys](doc/ssh-keys-import.md)
|
||||||
* [Run scripts on ppp connection](doc/ppp-on-up.md) (`ppp-on-up`)
|
* [Play Super Mario theme](doc/super-mario-theme.md)
|
||||||
* [Act on received SMS](doc/sms-action.md) (`sms-action`)
|
* [Install LTE firmware upgrade](doc/unattended-lte-firmware-upgrade.md)
|
||||||
* [Forward received SMS](doc/sms-forward.md) (`sms-forward`)
|
* [Update GRE configuration with dynamic addresses](doc/update-gre-address.md)
|
||||||
* [Play Super Mario theme](doc/super-mario-theme.md) (`super-mario-theme`)
|
* [Update tunnelbroker configuration](doc/update-tunnelbroker.md)
|
||||||
* [Chat with your router and send commands via Telegram bot](doc/telegram-chat.md) (`telegram-chat`)
|
* [Upload backup to server](doc/upload-backup.md)
|
||||||
* [Install LTE firmware upgrade](doc/unattended-lte-firmware-upgrade.md) (`unattended-lte-firmware-upgrade`)
|
|
||||||
* [Update GRE configuration with dynamic addresses](doc/update-gre-address.md) (`update-gre-address`)
|
|
||||||
* [Update tunnelbroker configuration](doc/update-tunnelbroker.md) (`update-tunnelbroker`)
|
|
||||||
|
|
||||||
Available modules
|
[comment]: # (TODO: currently undocumented)
|
||||||
-----------------
|
[comment]: # (* learn-mac-based-vlan)
|
||||||
|
[comment]: # (* manage-umts)
|
||||||
* [Manage ports in bridge](doc/mod/bridge-port-to.md) (`mod/bridge-port-to`)
|
|
||||||
* [Manage VLANs on bridge ports](doc/mod/bridge-port-vlan.md) (`mod/bridge-port-vlan`)
|
|
||||||
* [Inspect variables](doc/mod/inspectvar.md) (`mod/inspectvar`)
|
|
||||||
* [IP address calculation](doc/mod/ipcalc.md) (`mod/ipcalc`)
|
|
||||||
* [Send notifications via e-mail](doc/mod/notification-email.md) (`mod/notification-email`)
|
|
||||||
* [Send notifications via Gotify](doc/mod/notification-gotify.md) (`mod/notification-gotify`)
|
|
||||||
* [Send notifications via Matrix](doc/mod/notification-matrix.md) (`mod/notification-matrix`)
|
|
||||||
* [Send notifications via Ntfy](doc/mod/notification-ntfy.md) (`mod/notification-ntfy`)
|
|
||||||
* [Send notifications via Telegram](doc/mod/notification-telegram.md) (`mod/notification-telegram`)
|
|
||||||
* [Download script and run it once](doc/mod/scriptrunonce.md) (`mod/scriptrunonce`)
|
|
||||||
* [Import ssh keys for public key authentication](doc/mod/ssh-keys-import.md) (`mod/ssh-keys-import`)
|
|
||||||
|
|
||||||
Installing custom scripts & modules
|
|
||||||
-----------------------------------
|
|
||||||
|
|
||||||
My scripts cover a lot of use cases, but you may have your own ones. You can
|
|
||||||
still use my scripts to manage and deploy yours, by specifying `base-url`
|
|
||||||
(and `url-suffix`) for each script.
|
|
||||||
|
|
||||||
This will fetch and install a script `hello-world.rsc` from the given url:
|
|
||||||
|
|
||||||
$ScriptInstallUpdate hello-world "base-url=https://git.eworm.de/cgit/routeros-scripts-custom/plain/";
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
For a script to be considered valid it has to begin with a *magic token*.
|
|
||||||
Have a look at [any script](README.d/hello-world.rsc) and copy the first line
|
|
||||||
without modification.
|
|
||||||
|
|
||||||
Starting a script's name with `mod/` makes it a module and it is run
|
|
||||||
automatically by `global-functions`.
|
|
||||||
|
|
||||||
### Linked custom scripts & modules
|
|
||||||
|
|
||||||
> ⚠️ **Warning**: These links are being provided for your convenience only;
|
|
||||||
> they do not constitute an endorsement or an approval by me. I bear no
|
|
||||||
> responsibility for the accuracy, legality or content of the external site
|
|
||||||
> or for that of subsequent links. Contact the external site for answers to
|
|
||||||
> questions regarding its content.
|
|
||||||
|
|
||||||
* [Hello World](https://git.eworm.de/cgit/routeros-scripts-custom/about/doc/hello-world.md)
|
|
||||||
(This is a demo script to show how the linking to external documentation
|
|
||||||
will be done.)
|
|
||||||
|
|
||||||
> ℹ️ **Info**: You have your own set of scripts and/or modules and want these
|
|
||||||
> to be listed here? There should be a general info page that links here,
|
|
||||||
> and documentation for each script. You can start by cloning my
|
|
||||||
> [Custom RouterOS-Scripts](https://git.eworm.de/cgit/routeros-scripts-custom/)
|
|
||||||
> (or fork on [GitHub](https://github.com/eworm-de/routeros-scripts-custom)
|
|
||||||
> or [GitLab](https://gitlab.com/eworm-de/routeros-scripts-custom)) and make
|
|
||||||
> your changes. Then please [get in contact](#patches-issues-and-whishlist)...
|
|
||||||
|
|
||||||
Removing a script
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
There is no specific function for script removal. Just remove it from
|
|
||||||
configuration...
|
|
||||||
|
|
||||||
/system/script/remove to-be-removed;
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Possibly a scheduler and other configuration has to be removed as well.
|
|
||||||
|
|
||||||
Contact
|
|
||||||
-------
|
|
||||||
|
|
||||||
We have a Telegram Group [RouterOS-Scripts ↗️](https://t.me/routeros_scripts)!
|
|
||||||
|
|
||||||
[](https://t.me/routeros_scripts)
|
|
||||||
|
|
||||||
Get help, give feedback or just chat - but do not expect free professional
|
|
||||||
support!
|
|
||||||
|
|
||||||
Contribute
|
Contribute
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Thanks a lot for [past contributions](CONTRIBUTIONS.md)! ❤️
|
Thanks a lot for [past contributions](CONTRIBUTIONS.md)!
|
||||||
|
|
||||||
### Patches, issues and whishlist
|
### Patches, issues and whishlist
|
||||||
|
|
||||||
Feel free to contact me via e-mail or open an
|
Feel free to contact me via e-mail or open an
|
||||||
[issue](https://github.com/eworm-de/routeros-scripts/issues) or
|
[issue at github](https://github.com/eworm-de/routeros-scripts/issues).
|
||||||
[pull request](https://github.com/eworm-de/routeros-scripts/pulls)
|
|
||||||
at github.
|
|
||||||
|
|
||||||
### Donate
|
### Donate
|
||||||
|
|
||||||
This project is developed in private spare time and usage is free of charge
|
This project is developed in private spare time and usage is free of charge
|
||||||
for you. If you like the scripts and think this is of value for you or your
|
for you. If you like the scripts and think this is of value for you or your
|
||||||
business please consider to
|
business please consider to
|
||||||
[donate with PayPal ↗️](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J).
|
[donate with PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J).
|
||||||
|
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
|
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
|
||||||
|
|
||||||
Thanks a lot for your support!
|
Thanks a lot for your support!
|
||||||
|
|
||||||
|
|
@ -411,33 +242,15 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
[GNU General Public License](COPYING.md) for more details.
|
[GNU General Public License](COPYING.md) for more details.
|
||||||
|
|
||||||
Disclaimer on external links
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
Our website contains links to the websites of third parties ("external
|
|
||||||
links"). As the content of these websites is not under our control, we
|
|
||||||
cannot assume any liability for such external content. In all cases, the
|
|
||||||
provider of information of the linked websites is liable for the content
|
|
||||||
and accuracy of the information provided. At the point in time when the
|
|
||||||
links were placed, no infringements of the law were recognisable to us.
|
|
||||||
As soon as an infringement of the law becomes known to us, we will
|
|
||||||
immediately remove the link in question.
|
|
||||||
|
|
||||||
> 💡️ **Hint**: All external links are marked with an arrow pointing
|
|
||||||
> diagonally in an up-right (or north-east) direction (↗️).
|
|
||||||
|
|
||||||
Upstream
|
Upstream
|
||||||
--------
|
--------
|
||||||
|
|
||||||
[rsc.eworm.de](https://rsc.eworm.de/)
|
URL:
|
||||||
|
[GitHub.com](https://github.com/eworm-de/routeros-scripts#routeros-scripts)
|
||||||
|
|
||||||
[](https://rsc.eworm.de/)
|
Mirror:
|
||||||
|
[eworm.de](https://git.eworm.de/cgit/routeros-scripts/about/)
|
||||||
### Code hosting
|
[GitLab.com](https://gitlab.com/eworm-de/routeros-scripts#routeros-scripts)
|
||||||
|
|
||||||
* [git.eworm.de](https://git.eworm.de/cgit/routeros-scripts/about/)
|
|
||||||
* [GitHub.com](https://github.com/eworm-de/routeros-scripts#routeros-scripts)
|
|
||||||
* [GitLab.com](https://gitlab.com/eworm-de/routeros-scripts#routeros-scripts)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
[⬆️ Go back to top](#top)
|
[▲ Go back to top](#top)
|
||||||
|
|
|
||||||
36
accesslist-duplicates.capsman
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: accesslist-duplicates.capsman
|
||||||
|
# Copyright (c) 2018-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# print duplicate antries in wireless access list
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/accesslist-duplicates.md
|
||||||
|
#
|
||||||
|
# !! Do not edit this file, it is generated from template!
|
||||||
|
|
||||||
|
:local Seen [ :toarray "" ];
|
||||||
|
:local Shown [ :toarray "" ];
|
||||||
|
|
||||||
|
:foreach AccList in=[ / caps-man access-list find where mac-address!="00:00:00:00:00:00" ] do={
|
||||||
|
:local Mac [ / caps-man access-list get $AccList mac-address ];
|
||||||
|
:foreach SeenMac in=$Seen do={
|
||||||
|
:if ($SeenMac = $Mac) do={
|
||||||
|
:local Skip 0;
|
||||||
|
:foreach ShownMac in=$Shown do={
|
||||||
|
:if ($ShownMac = $Mac) do={ :set Skip 1; }
|
||||||
|
}
|
||||||
|
:if ($Skip = 0) do={
|
||||||
|
/ caps-man access-list print where mac-address=$Mac;
|
||||||
|
:set Shown ($Shown, $Mac);
|
||||||
|
|
||||||
|
:put "\nNumeric id to remove, any key to skip!";
|
||||||
|
:local Remove ([ :terminal inkey ] - 48);
|
||||||
|
:if ($Remove >= 0 && $Remove <= 9) do={
|
||||||
|
:put ("Removing numeric id " . $Remove . "...\n");
|
||||||
|
/ caps-man access-list remove $Remove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:set Seen ($Seen, $Mac);
|
||||||
|
}
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: accesslist-duplicates.capsman
|
|
||||||
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# print duplicate antries in wireless access list
|
|
||||||
# https://rsc.eworm.de/doc/accesslist-duplicates.md
|
|
||||||
#
|
|
||||||
# !! Do not edit this file, it is generated from template!
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:local Seen ({});
|
|
||||||
|
|
||||||
:foreach AccList in=[ /caps-man/access-list/find where mac-address!="00:00:00:00:00:00" ] do={
|
|
||||||
:local Mac [ /caps-man/access-list/get $AccList mac-address ];
|
|
||||||
:if ($Seen->$Mac = 1) do={
|
|
||||||
/caps-man/access-list/print without-paging where mac-address=$Mac;
|
|
||||||
:local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ];
|
|
||||||
|
|
||||||
:if ([ :typeof $Remove ] = "num") do={
|
|
||||||
:put ("Removing numeric id " . $Remove . "...\n");
|
|
||||||
/caps-man/access-list/remove $Remove;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:set ($Seen->$Mac) 1;
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
36
accesslist-duplicates.local
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: accesslist-duplicates.local
|
||||||
|
# Copyright (c) 2018-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# print duplicate antries in wireless access list
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/accesslist-duplicates.md
|
||||||
|
#
|
||||||
|
# !! Do not edit this file, it is generated from template!
|
||||||
|
|
||||||
|
:local Seen [ :toarray "" ];
|
||||||
|
:local Shown [ :toarray "" ];
|
||||||
|
|
||||||
|
:foreach AccList in=[ / interface wireless access-list find where mac-address!="00:00:00:00:00:00" ] do={
|
||||||
|
:local Mac [ / interface wireless access-list get $AccList mac-address ];
|
||||||
|
:foreach SeenMac in=$Seen do={
|
||||||
|
:if ($SeenMac = $Mac) do={
|
||||||
|
:local Skip 0;
|
||||||
|
:foreach ShownMac in=$Shown do={
|
||||||
|
:if ($ShownMac = $Mac) do={ :set Skip 1; }
|
||||||
|
}
|
||||||
|
:if ($Skip = 0) do={
|
||||||
|
/ interface wireless access-list print where mac-address=$Mac;
|
||||||
|
:set Shown ($Shown, $Mac);
|
||||||
|
|
||||||
|
:put "\nNumeric id to remove, any key to skip!";
|
||||||
|
:local Remove ([ :terminal inkey ] - 48);
|
||||||
|
:if ($Remove >= 0 && $Remove <= 9) do={
|
||||||
|
:put ("Removing numeric id " . $Remove . "...\n");
|
||||||
|
/ interface wireless access-list remove $Remove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:set Seen ($Seen, $Mac);
|
||||||
|
}
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: accesslist-duplicates.local
|
|
||||||
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# print duplicate antries in wireless access list
|
|
||||||
# https://rsc.eworm.de/doc/accesslist-duplicates.md
|
|
||||||
#
|
|
||||||
# !! Do not edit this file, it is generated from template!
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:local Seen ({});
|
|
||||||
|
|
||||||
:foreach AccList in=[ /interface/wireless/access-list/find where mac-address!="00:00:00:00:00:00" ] do={
|
|
||||||
:local Mac [ /interface/wireless/access-list/get $AccList mac-address ];
|
|
||||||
:if ($Seen->$Mac = 1) do={
|
|
||||||
/interface/wireless/access-list/print without-paging where mac-address=$Mac;
|
|
||||||
:local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ];
|
|
||||||
|
|
||||||
:if ([ :typeof $Remove ] = "num") do={
|
|
||||||
:put ("Removing numeric id " . $Remove . "...\n");
|
|
||||||
/interface/wireless/access-list/remove $Remove;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:set ($Seen->$Mac) 1;
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
37
accesslist-duplicates.template
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: accesslist-duplicates%TEMPL%
|
||||||
|
# Copyright (c) 2018-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# print duplicate antries in wireless access list
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/accesslist-duplicates.md
|
||||||
|
#
|
||||||
|
# !! This is just a template! Replace '%PATH%' with 'caps-man'
|
||||||
|
# !! or 'interface wireless'!
|
||||||
|
|
||||||
|
:local Seen [ :toarray "" ];
|
||||||
|
:local Shown [ :toarray "" ];
|
||||||
|
|
||||||
|
:foreach AccList in=[ / %PATH% access-list find where mac-address!="00:00:00:00:00:00" ] do={
|
||||||
|
:local Mac [ / %PATH% access-list get $AccList mac-address ];
|
||||||
|
:foreach SeenMac in=$Seen do={
|
||||||
|
:if ($SeenMac = $Mac) do={
|
||||||
|
:local Skip 0;
|
||||||
|
:foreach ShownMac in=$Shown do={
|
||||||
|
:if ($ShownMac = $Mac) do={ :set Skip 1; }
|
||||||
|
}
|
||||||
|
:if ($Skip = 0) do={
|
||||||
|
/ %PATH% access-list print where mac-address=$Mac;
|
||||||
|
:set Shown ($Shown, $Mac);
|
||||||
|
|
||||||
|
:put "\nNumeric id to remove, any key to skip!";
|
||||||
|
:local Remove ([ :terminal inkey ] - 48);
|
||||||
|
:if ($Remove >= 0 && $Remove <= 9) do={
|
||||||
|
:put ("Removing numeric id " . $Remove . "...\n");
|
||||||
|
/ %PATH% access-list remove $Remove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:set Seen ($Seen, $Mac);
|
||||||
|
}
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: accesslist-duplicates%TEMPL%
|
|
||||||
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# print duplicate antries in wireless access list
|
|
||||||
# https://rsc.eworm.de/doc/accesslist-duplicates.md
|
|
||||||
#
|
|
||||||
# !! This is just a template to generate the real script!
|
|
||||||
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:local Seen ({});
|
|
||||||
|
|
||||||
:foreach AccList in=[ /caps-man/access-list/find where mac-address!="00:00:00:00:00:00" ] do={
|
|
||||||
:foreach AccList in=[ /interface/wifi/access-list/find where mac-address!="00:00:00:00:00:00" ] do={
|
|
||||||
:foreach AccList in=[ /interface/wireless/access-list/find where mac-address!="00:00:00:00:00:00" ] do={
|
|
||||||
:local Mac [ /caps-man/access-list/get $AccList mac-address ];
|
|
||||||
:local Mac [ /interface/wifi/access-list/get $AccList mac-address ];
|
|
||||||
:local Mac [ /interface/wireless/access-list/get $AccList mac-address ];
|
|
||||||
:if ($Seen->$Mac = 1) do={
|
|
||||||
/caps-man/access-list/print without-paging where mac-address=$Mac;
|
|
||||||
/interface/wifi/access-list/print without-paging where mac-address=$Mac;
|
|
||||||
/interface/wireless/access-list/print without-paging where mac-address=$Mac;
|
|
||||||
:local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ];
|
|
||||||
|
|
||||||
:if ([ :typeof $Remove ] = "num") do={
|
|
||||||
:put ("Removing numeric id " . $Remove . "...\n");
|
|
||||||
/caps-man/access-list/remove $Remove;
|
|
||||||
/interface/wifi/access-list/remove $Remove;
|
|
||||||
/interface/wireless/access-list/remove $Remove;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:set ($Seen->$Mac) 1;
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: accesslist-duplicates.wifi
|
|
||||||
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# print duplicate antries in wireless access list
|
|
||||||
# https://rsc.eworm.de/doc/accesslist-duplicates.md
|
|
||||||
#
|
|
||||||
# !! Do not edit this file, it is generated from template!
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:local Seen ({});
|
|
||||||
|
|
||||||
:foreach AccList in=[ /interface/wifi/access-list/find where mac-address!="00:00:00:00:00:00" ] do={
|
|
||||||
:local Mac [ /interface/wifi/access-list/get $AccList mac-address ];
|
|
||||||
:if ($Seen->$Mac = 1) do={
|
|
||||||
/interface/wifi/access-list/print without-paging where mac-address=$Mac;
|
|
||||||
:local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ];
|
|
||||||
|
|
||||||
:if ([ :typeof $Remove ] = "num") do={
|
|
||||||
:put ("Removing numeric id " . $Remove . "...\n");
|
|
||||||
/interface/wifi/access-list/remove $Remove;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:set ($Seen->$Mac) 1;
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
104
backup-cloud.rsc
|
|
@ -1,104 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: backup-cloud
|
|
||||||
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# provides: backup-script, order=40
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# upload backup to MikroTik cloud
|
|
||||||
# https://rsc.eworm.de/doc/backup-cloud.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 BackupRandomDelay;
|
|
||||||
:global Identity;
|
|
||||||
:global PackagesUpdateBackupFailure;
|
|
||||||
|
|
||||||
:global DeviceInfo;
|
|
||||||
:global FormatLine;
|
|
||||||
:global HumanReadableNum;
|
|
||||||
:global LogPrint;
|
|
||||||
:global MkDir;
|
|
||||||
:global RandomDelay;
|
|
||||||
:global RmDir;
|
|
||||||
:global ScriptFromTerminal;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
:global WaitForFile;
|
|
||||||
:global WaitFullyConnected;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /system/scheduler/find where name="running-from-backup-partition" ] ] > 0) do={
|
|
||||||
$LogPrint warning $ScriptName ("Running from backup partition, refusing to act.");
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$WaitFullyConnected;
|
|
||||||
|
|
||||||
:if ([ $ScriptFromTerminal $ScriptName ] = false && $BackupRandomDelay > 0) do={
|
|
||||||
$RandomDelay $BackupRandomDelay;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $MkDir ("tmpfs/backup-cloud") ] = false) do={
|
|
||||||
$LogPrint error $ScriptName ("Failed creating directory!");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local I 5;
|
|
||||||
:do {
|
|
||||||
:execute {
|
|
||||||
:global BackupPassword;
|
|
||||||
|
|
||||||
:local Backup ([ /system/backup/cloud/find ]->0);
|
|
||||||
:if ([ :typeof $Backup ] = "id") do={
|
|
||||||
/system/backup/cloud/upload-file action=create-and-upload \
|
|
||||||
password=$BackupPassword replace=$Backup;
|
|
||||||
} else={
|
|
||||||
/system/backup/cloud/upload-file action=create-and-upload \
|
|
||||||
password=$BackupPassword;
|
|
||||||
}
|
|
||||||
/file/add name="tmpfs/backup-cloud/done";
|
|
||||||
} as-string;
|
|
||||||
:set I ($I - 1);
|
|
||||||
} while=([ $WaitForFile "tmpfs/backup-cloud/done" 200ms ] = false && $I > 0);
|
|
||||||
|
|
||||||
:if ([ $WaitForFile "tmpfs/backup-cloud/done" ] = true) do={
|
|
||||||
:if ($I < 4) do={
|
|
||||||
:log warning ($ScriptName . ": Retry successful, please discard previous connection errors.");
|
|
||||||
}
|
|
||||||
|
|
||||||
:local Cloud [ /system/backup/cloud/get ([ find ]->0) ];
|
|
||||||
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "floppy-disk,cloud" ] . "Cloud backup"); \
|
|
||||||
message=("Uploaded backup for " . $Identity . " to cloud.\n\n" . \
|
|
||||||
[ $DeviceInfo ] . "\n\n" . \
|
|
||||||
[ $FormatLine "Name" ($Cloud->"name") ] . "\n" . \
|
|
||||||
[ $FormatLine "Size" ([ $HumanReadableNum ($Cloud->"size") 1024 ] . "B") ] . "\n" . \
|
|
||||||
[ $FormatLine "Download key" ($Cloud->"secret-download-key") ]); silent=true });
|
|
||||||
} else={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "floppy-disk,warning-sign" ] . "Cloud backup failed"); \
|
|
||||||
message=("Failed uploading backup for " . $Identity . " to cloud!\n\n" . [ $DeviceInfo ]) });
|
|
||||||
$LogPrint error $ScriptName ("Failed uploading backup for " . $Identity . " to cloud!");
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
}
|
|
||||||
$RmDir "tmpfs/backup-cloud";
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
143
backup-email.rsc
|
|
@ -1,143 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: backup-email
|
|
||||||
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# provides: backup-script, order=20
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# create and email backup and config file
|
|
||||||
# https://rsc.eworm.de/doc/backup-email.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 BackupPassword;
|
|
||||||
:global BackupRandomDelay;
|
|
||||||
:global BackupSendBinary;
|
|
||||||
:global BackupSendExport;
|
|
||||||
:global BackupSendGlobalConfig;
|
|
||||||
:global Domain;
|
|
||||||
:global Identity;
|
|
||||||
:global PackagesUpdateBackupFailure;
|
|
||||||
|
|
||||||
:global CleanName;
|
|
||||||
:global DeviceInfo;
|
|
||||||
:global FileExists;
|
|
||||||
:global FormatLine;
|
|
||||||
:global LogPrint;
|
|
||||||
:global MkDir;
|
|
||||||
:global RandomDelay;
|
|
||||||
:global ScriptFromTerminal;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global SendEMail2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
:global WaitForFile;
|
|
||||||
:global WaitFullyConnected;
|
|
||||||
|
|
||||||
:if ([ :typeof $SendEMail2 ] = "nothing") do={
|
|
||||||
$LogPrint error $ScriptName ("The module for sending notifications via e-mail is not installed.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ($BackupSendBinary != true && \
|
|
||||||
$BackupSendExport != true) do={
|
|
||||||
$LogPrint error $ScriptName ("Configured to send neither backup nor config export.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /system/scheduler/find where name="running-from-backup-partition" ] ] > 0) do={
|
|
||||||
$LogPrint warning $ScriptName ("Running from backup partition, refusing to act.");
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$WaitFullyConnected;
|
|
||||||
|
|
||||||
:if ([ $ScriptFromTerminal $ScriptName ] = false && $BackupRandomDelay > 0) do={
|
|
||||||
$RandomDelay $BackupRandomDelay;
|
|
||||||
}
|
|
||||||
|
|
||||||
# filename based on identity
|
|
||||||
:local DirName ("tmpfs/" . $ScriptName);
|
|
||||||
:local FileName [ $CleanName ($Identity . "." . $Domain) ];
|
|
||||||
:local FilePath ($DirName . "/" . $FileName);
|
|
||||||
:local BackupFile "none";
|
|
||||||
:local ExportFile "none";
|
|
||||||
:local ConfigFile "none";
|
|
||||||
:local Attach ({});
|
|
||||||
|
|
||||||
:if ([ $MkDir $DirName ] = false) do={
|
|
||||||
$LogPrint error $ScriptName ("Failed creating directory!");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
# binary backup
|
|
||||||
:if ($BackupSendBinary = true) do={
|
|
||||||
/system/backup/save encryption=aes-sha256 name=$FilePath password=$BackupPassword;
|
|
||||||
$WaitForFile ($FilePath . ".backup");
|
|
||||||
:set BackupFile ($FileName . ".backup");
|
|
||||||
:set Attach ($Attach, ($FilePath . ".backup"));
|
|
||||||
}
|
|
||||||
|
|
||||||
# create configuration export
|
|
||||||
:if ($BackupSendExport = true) do={
|
|
||||||
/export terse show-sensitive file=$FilePath;
|
|
||||||
$WaitForFile ($FilePath . ".rsc");
|
|
||||||
:set ExportFile ($FileName . ".rsc");
|
|
||||||
:set Attach ($Attach, ($FilePath . ".rsc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
# global-config-overlay
|
|
||||||
:if ($BackupSendGlobalConfig = true) do={
|
|
||||||
# Do *NOT* use '/file/add ...' here, as it is limited to 4095 bytes!
|
|
||||||
:execute script={ :put [ /system/script/get global-config-overlay source ]; } \
|
|
||||||
file=($FilePath . ".conf\00");
|
|
||||||
$WaitForFile ($FilePath . ".conf");
|
|
||||||
:set ConfigFile ($FileName . ".conf");
|
|
||||||
:set Attach ($Attach, ($FilePath . ".conf"));
|
|
||||||
}
|
|
||||||
|
|
||||||
# send email with status and files
|
|
||||||
$SendEMail2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "floppy-disk,incoming-envelope" ] . \
|
|
||||||
"Backup & Config"); \
|
|
||||||
message=("See attached files for backup and config export for " . \
|
|
||||||
$Identity . ".\n\n" . \
|
|
||||||
[ $DeviceInfo ] . "\n\n" . \
|
|
||||||
[ $FormatLine "Backup file" $BackupFile ] . "\n" . \
|
|
||||||
[ $FormatLine "Export file" $ExportFile ] . "\n" . \
|
|
||||||
[ $FormatLine "Config file" $ConfigFile ]); \
|
|
||||||
attach=$Attach; remove-attach=true });
|
|
||||||
|
|
||||||
# wait for the mail to be sent
|
|
||||||
:do {
|
|
||||||
:retry {
|
|
||||||
:if ([ $FileExists ($FilePath . ".conf") ".conf file" ] = true || \
|
|
||||||
[ $FileExists ($FilePath . ".backup") "backup" ] = true || \
|
|
||||||
[ $FileExists ($FilePath . ".rsc") "script" ] = true) do={
|
|
||||||
:error "Files are still available.";
|
|
||||||
}
|
|
||||||
} delay=1s max=120;
|
|
||||||
} on-error={
|
|
||||||
$LogPrint warning $ScriptName ("Files are still available, sending e-mail failed.");
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
}
|
|
||||||
# do not remove the files here, as the mail is still queued!
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: backup-partition
|
|
||||||
# Copyright (c) 2022-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# provides: backup-script, order=70
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
# requires device-mode, scheduler
|
|
||||||
#
|
|
||||||
# save configuration to fallback partition
|
|
||||||
# https://rsc.eworm.de/doc/backup-partition.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 BackupPartitionCopyBeforeFeatureUpdate;
|
|
||||||
:global PackagesUpdateBackupFailure;
|
|
||||||
|
|
||||||
:global LogPrint;
|
|
||||||
:global ScriptFromTerminal;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global VersionToNum;
|
|
||||||
|
|
||||||
:local CopyTo do={
|
|
||||||
:local ScriptName [ :tostr $1 ];
|
|
||||||
:local FallbackTo [ :toid $2 ];
|
|
||||||
:local FallbackToName [ :tostr $3 ];
|
|
||||||
|
|
||||||
:global LogPrint;
|
|
||||||
|
|
||||||
:onerror Err {
|
|
||||||
/partitions/copy-to $FallbackTo;
|
|
||||||
$LogPrint info $ScriptName ("Copied RouterOS to partition '" . $FallbackToName . "'.");
|
|
||||||
} do={
|
|
||||||
$LogPrint error $ScriptName ("Failed copying RouterOS to partition '" . \
|
|
||||||
$FallbackToName . "': " . $Err);
|
|
||||||
:return false;
|
|
||||||
}
|
|
||||||
:return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /system/scheduler/find where name="running-from-backup-partition" ] ] > 0) do={
|
|
||||||
$LogPrint warning $ScriptName ("Running from backup partition, refusing to act.");
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /partitions/find ] ] < 2) do={
|
|
||||||
$LogPrint error $ScriptName ("Device does not have a fallback partition.");
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local ActiveRunning [ /partitions/find where active running ];
|
|
||||||
|
|
||||||
:if ([ :len $ActiveRunning ] < 1) do={
|
|
||||||
$LogPrint error $ScriptName ("Device is not running from active partition.");
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local FallbackToName [ /partitions/get $ActiveRunning fallback-to ];
|
|
||||||
:local FallbackTo [ /partition/find where name=$FallbackToName !active ];
|
|
||||||
|
|
||||||
:if ([ :len $FallbackTo ] < 1) do={
|
|
||||||
$LogPrint error $ScriptName ("There is no inactive partition named '" . $FallbackToName . "'.");
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ /partitions/get $ActiveRunning version ] != [ /partitions/get $FallbackTo version]) do={
|
|
||||||
:if ([ $ScriptFromTerminal $ScriptName ] = true) do={
|
|
||||||
:put ("The partitions have different RouterOS versions. Copy over to '" . $FallbackToName . "'? [y/N]");
|
|
||||||
:if (([ /terminal/inkey timeout=60 ] % 32) = 25) do={
|
|
||||||
:if ([ $CopyTo $ScriptName $FallbackTo $FallbackToName ] = false) do={
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else={
|
|
||||||
:local Update [ /system/package/update/get ];
|
|
||||||
:local NumInstalled [ $VersionToNum ($Update->"installed-version") ];
|
|
||||||
:local NumLatest [ $VersionToNum ($Update->"latest-version") ];
|
|
||||||
:local BitMask [ $VersionToNum "255.255zero0" ];
|
|
||||||
:if ($BackupPartitionCopyBeforeFeatureUpdate = true && $NumLatest > 0 && \
|
|
||||||
($NumInstalled & $BitMask) != ($NumLatest & $BitMask)) do={
|
|
||||||
:if ([ $CopyTo $ScriptName $FallbackTo $FallbackToName ] = false) do={
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:onerror Err {
|
|
||||||
/system/scheduler/add start-time=startup name="running-from-backup-partition" \
|
|
||||||
on-event=(":log warning (\"Running from partition '\" . " . \
|
|
||||||
"[ /partitions/get [ find where running ] name ] . \"'!\")");
|
|
||||||
/partitions/save-config-to $FallbackTo;
|
|
||||||
/system/scheduler/remove "running-from-backup-partition";
|
|
||||||
$LogPrint info $ScriptName ("Saved configuration to partition '" . $FallbackToName . "'.");
|
|
||||||
} do={
|
|
||||||
/system/scheduler/remove [ find where name="running-from-backup-partition" ];
|
|
||||||
$LogPrint error $ScriptName ("Failed saving configuration to partition '" . \
|
|
||||||
$FallbackToName . "': " . $Err);
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
|
|
@ -1,178 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: backup-upload
|
|
||||||
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# provides: backup-script, order=50
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
# requires device-mode, fetch
|
|
||||||
#
|
|
||||||
# create and upload backup and config file
|
|
||||||
# https://rsc.eworm.de/doc/backup-upload.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 BackupPassword;
|
|
||||||
:global BackupRandomDelay;
|
|
||||||
:global BackupSendBinary;
|
|
||||||
:global BackupSendExport;
|
|
||||||
:global BackupSendGlobalConfig;
|
|
||||||
:global BackupUploadPass;
|
|
||||||
:global BackupUploadUrl;
|
|
||||||
:global BackupUploadUser;
|
|
||||||
:global Domain;
|
|
||||||
:global Identity;
|
|
||||||
:global PackagesUpdateBackupFailure;
|
|
||||||
|
|
||||||
:global CleanName;
|
|
||||||
:global DeviceInfo;
|
|
||||||
:global IfThenElse;
|
|
||||||
:global LogPrint;
|
|
||||||
:global MkDir;
|
|
||||||
:global RandomDelay;
|
|
||||||
:global RmDir;
|
|
||||||
:global RmFile;
|
|
||||||
:global ScriptFromTerminal;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
:global WaitForFile;
|
|
||||||
:global WaitFullyConnected;
|
|
||||||
|
|
||||||
:if ($BackupSendBinary != true && \
|
|
||||||
$BackupSendExport != true) do={
|
|
||||||
$LogPrint error $ScriptName ("Configured to send neither backup nor config export.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /system/scheduler/find where name="running-from-backup-partition" ] ] > 0) do={
|
|
||||||
$LogPrint warning $ScriptName ("Running from backup partition, refusing to act.");
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$WaitFullyConnected;
|
|
||||||
|
|
||||||
:if ([ $ScriptFromTerminal $ScriptName ] = false && $BackupRandomDelay > 0) do={
|
|
||||||
$RandomDelay $BackupRandomDelay;
|
|
||||||
}
|
|
||||||
|
|
||||||
# filename based on identity
|
|
||||||
:local DirName ("tmpfs/" . $ScriptName);
|
|
||||||
:local FileName [ $CleanName ($Identity . "." . $Domain) ];
|
|
||||||
:local FilePath ($DirName . "/" . $FileName);
|
|
||||||
:local BackupFile "none";
|
|
||||||
:local ExportFile "none";
|
|
||||||
:local ConfigFile "none";
|
|
||||||
:local Failed 0;
|
|
||||||
|
|
||||||
:if ([ $MkDir $DirName ] = false) do={
|
|
||||||
$LogPrint error $ScriptName ("Failed creating directory!");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
# binary backup
|
|
||||||
:if ($BackupSendBinary = true) do={
|
|
||||||
/system/backup/save encryption=aes-sha256 name=$FilePath password=$BackupPassword;
|
|
||||||
$WaitForFile ($FilePath . ".backup");
|
|
||||||
|
|
||||||
:onerror Err {
|
|
||||||
/tool/fetch upload=yes url=($BackupUploadUrl . "/" . $FileName . ".backup") \
|
|
||||||
user=$BackupUploadUser password=$BackupUploadPass src-path=($FilePath . ".backup");
|
|
||||||
:set BackupFile [ /file/get ($FilePath . ".backup") ];
|
|
||||||
:set ($BackupFile->"name") ($FileName . ".backup");
|
|
||||||
} do={
|
|
||||||
$LogPrint error $ScriptName ("Uploading backup file failed: " . $Err);
|
|
||||||
:set BackupFile "failed";
|
|
||||||
:set Failed 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$RmFile ($FilePath . ".backup");
|
|
||||||
}
|
|
||||||
|
|
||||||
# create configuration export
|
|
||||||
:if ($BackupSendExport = true) do={
|
|
||||||
/export terse show-sensitive file=$FilePath;
|
|
||||||
$WaitForFile ($FilePath . ".rsc");
|
|
||||||
|
|
||||||
:onerror Err {
|
|
||||||
/tool/fetch upload=yes url=($BackupUploadUrl . "/" . $FileName . ".rsc") \
|
|
||||||
user=$BackupUploadUser password=$BackupUploadPass src-path=($FilePath . ".rsc");
|
|
||||||
:set ExportFile [ /file/get ($FilePath . ".rsc") ];
|
|
||||||
:set ($ExportFile->"name") ($FileName . ".rsc");
|
|
||||||
} do={
|
|
||||||
$LogPrint error $ScriptName ("Uploading configuration export failed: " . $Err);
|
|
||||||
:set ExportFile "failed";
|
|
||||||
:set Failed 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$RmFile ($FilePath . ".rsc");
|
|
||||||
}
|
|
||||||
|
|
||||||
# global-config-overlay
|
|
||||||
:if ($BackupSendGlobalConfig = true) do={
|
|
||||||
# Do *NOT* use '/file/add ...' here, as it is limited to 4095 bytes!
|
|
||||||
:execute script={ :put [ /system/script/get global-config-overlay source ]; } \
|
|
||||||
file=($FilePath . ".conf\00");
|
|
||||||
$WaitForFile ($FilePath . ".conf");
|
|
||||||
|
|
||||||
:onerror Err {
|
|
||||||
/tool/fetch upload=yes url=($BackupUploadUrl . "/" . $FileName . ".conf") \
|
|
||||||
user=$BackupUploadUser password=$BackupUploadPass src-path=($FilePath . ".conf");
|
|
||||||
:set ConfigFile [ /file/get ($FilePath . ".conf") ];
|
|
||||||
:set ($ConfigFile->"name") ($FileName . ".conf");
|
|
||||||
} do={
|
|
||||||
$LogPrint error $ScriptName ("Uploading global-config-overlay failed: " . $Err);
|
|
||||||
:set ConfigFile "failed";
|
|
||||||
:set Failed 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$RmFile ($FilePath . ".conf");
|
|
||||||
}
|
|
||||||
|
|
||||||
:local FileInfo do={
|
|
||||||
:local Name $1;
|
|
||||||
:local File $2;
|
|
||||||
|
|
||||||
:global FormatLine;
|
|
||||||
:global HumanReadableNum;
|
|
||||||
:global IfThenElse;
|
|
||||||
|
|
||||||
:return \
|
|
||||||
[ $IfThenElse ([ :typeof $File ] = "array") \
|
|
||||||
($Name . ":\n" . [ $FormatLine " name" ($File->"name") ] . "\n" . \
|
|
||||||
[ $FormatLine " size" ([ $HumanReadableNum ($File->"size") 1024 ] . "B") ]) \
|
|
||||||
[ $FormatLine $Name $File ] ];
|
|
||||||
}
|
|
||||||
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=[ $IfThenElse ($Failed > 0) \
|
|
||||||
([ $SymbolForNotification "floppy-disk,warning-sign" ] . "Backup & Config upload with failure") \
|
|
||||||
([ $SymbolForNotification "floppy-disk,arrow-up" ] . "Backup & Config upload") ]; \
|
|
||||||
message=("Backup and config export upload for " . $Identity . ".\n\n" . \
|
|
||||||
[ $DeviceInfo ] . "\n\n" . \
|
|
||||||
[ $FileInfo "Backup file" $BackupFile ] . "\n" . \
|
|
||||||
[ $FileInfo "Export file" $ExportFile ] . "\n" . \
|
|
||||||
[ $FileInfo "Config file" $ConfigFile ]); silent=true });
|
|
||||||
|
|
||||||
:if ($Failed = 1) do={
|
|
||||||
:set PackagesUpdateBackupFailure true;
|
|
||||||
}
|
|
||||||
$RmDir $DirName;
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
49
bridge-port-to-default
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: bridge-port-to-default
|
||||||
|
# Copyright (c) 2013-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# reset bridge ports to default bridge
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/bridge-port.md
|
||||||
|
|
||||||
|
:global BridgePortTo;
|
||||||
|
|
||||||
|
:global IfThenElse;
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global ParseKeyValueStore;
|
||||||
|
|
||||||
|
:foreach BridgePort in=[ / interface bridge port find where !(comment=[]) ] do={
|
||||||
|
:local BridgePortVal [ / interface bridge port get $BridgePort ];
|
||||||
|
:foreach Config,BridgeDefault in=[ $ParseKeyValueStore ($BridgePortVal->"comment") ] do={
|
||||||
|
:if ($Config = $BridgePortTo) do={
|
||||||
|
:local DHCPClient [ / ip dhcp-client find where interface=$BridgePortVal->"interface" comment="toggle with bridge port" ];
|
||||||
|
|
||||||
|
:if ($BridgeDefault = "dhcp-client") do={
|
||||||
|
:if ([ :len $DHCPClient ] != 1) do={
|
||||||
|
$LogPrintExit warning ([ $IfThenElse ([ :len $DHCPClient ] = 0) "Missing" "Duplicate" ] . \
|
||||||
|
" dhcp client configuration for interface " . $BridgePortVal->"interface" . "!") true;
|
||||||
|
}
|
||||||
|
:local DHCPClientDisabled [ / ip dhcp-client get $DHCPClient disabled ];
|
||||||
|
|
||||||
|
:if ($BridgePortVal->"disabled" = false || $DHCPClientDisabled = true) do={
|
||||||
|
$LogPrintExit info ("Disabling bridge port for interface " . $BridgePortVal->"interface" . ", enabling dhcp client.") false;
|
||||||
|
/ interface bridge port disable $BridgePort;
|
||||||
|
/ ip dhcp-client enable $DHCPClient;
|
||||||
|
}
|
||||||
|
} else={
|
||||||
|
:if ($BridgePortVal->"disabled" = true || $BridgeDefault != $BridgePortVal->"bridge") do={
|
||||||
|
$LogPrintExit info ("Enabling bridge port for interface " . $BridgePortVal->"interface" . ", changing to " . $BridgePortTo . \
|
||||||
|
" bridge " . $BridgeDefault . ", disabling dhcp client.") false;
|
||||||
|
:if ([ :len $DHCPClient ] = 1) do={
|
||||||
|
/ ip dhcp-client disable $DHCPClient;
|
||||||
|
:delay 200ms;
|
||||||
|
}
|
||||||
|
/ interface bridge port set disabled=no bridge=$BridgeDefault $BridgePort;
|
||||||
|
} else={
|
||||||
|
$LogPrintExit debug ("Interface " . $BridgePortVal->"interface" . " already connected to " . $BridgePortTo . \
|
||||||
|
" bridge " . $BridgeDefault . ".") false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
bridge-port-toggle
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: bridge-port-toggle
|
||||||
|
# Copyright (c) 2013-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# toggle bridge ports between default and alt bridge
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/bridge-port.md
|
||||||
|
|
||||||
|
:global BridgePortTo;
|
||||||
|
|
||||||
|
:if ($BridgePortTo != "default") do={
|
||||||
|
:set BridgePortTo "default";
|
||||||
|
} else={
|
||||||
|
:set BridgePortTo "alt";
|
||||||
|
}
|
||||||
|
|
||||||
|
/ system script run bridge-port-to-default;
|
||||||
51
capsman-download-packages
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: capsman-download-packages
|
||||||
|
# Copyright (c) 2018-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# Michael Gisbers <michael@gisbers.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# download and cleanup packages for CAP installation from CAPsMAN
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/capsman-download-packages.md
|
||||||
|
|
||||||
|
:global CleanFilePath;
|
||||||
|
:global DownloadPackage;
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global MkDir;
|
||||||
|
:global ScriptLock;
|
||||||
|
:global WaitFullyConnected;
|
||||||
|
|
||||||
|
$ScriptLock "capsman-download-packages";
|
||||||
|
$WaitFullyConnected;
|
||||||
|
|
||||||
|
:local PackagePath [ $CleanFilePath [ / caps-man manager get package-path ] ];
|
||||||
|
:local InstalledVersion [ / system package update get installed-version ];
|
||||||
|
:local Updated false;
|
||||||
|
|
||||||
|
:if ([ :len [ / file find where name=$PackagePath type="directory" ] ] = 0) do={
|
||||||
|
$MkDir $PackagePath;
|
||||||
|
$LogPrintExit info ("Created directory at package path (" . $PackagePath . \
|
||||||
|
"). Please place your packages!") false;
|
||||||
|
}
|
||||||
|
|
||||||
|
:foreach Package in=[ / file find where type=package \
|
||||||
|
package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={
|
||||||
|
:local File [ / file get $Package ];
|
||||||
|
:if ($File->"package-architecture" = "mips") do={
|
||||||
|
:set ($File->"package-architecture") "mipsbe";
|
||||||
|
}
|
||||||
|
:if ($File->"package-name" = "wireless@") do={
|
||||||
|
:set ($File->"package-name") "wireless";
|
||||||
|
}
|
||||||
|
:if ([ $DownloadPackage ($File->"package-name") $InstalledVersion ($File->"package-architecture") $PackagePath ] = true) do={
|
||||||
|
:set Updated true;
|
||||||
|
/ file remove $Package;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:if ($Updated = true) do={
|
||||||
|
:if ([ :len [ / system script find where name="capsman-rolling-upgrade" ] ] > 0) do={
|
||||||
|
/ system script run capsman-rolling-upgrade;
|
||||||
|
} else={
|
||||||
|
/ caps-man remote-cap upgrade [ find where version!=$InstalledVersion ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: capsman-download-packages.capsman
|
|
||||||
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# Michael Gisbers <michael@gisbers.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# download and cleanup packages for CAP installation from CAPsMAN
|
|
||||||
# https://rsc.eworm.de/doc/capsman-download-packages.md
|
|
||||||
#
|
|
||||||
# !! Do not edit this file, it is generated from template!
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global CleanFilePath;
|
|
||||||
:global DownloadPackage;
|
|
||||||
:global FileGet;
|
|
||||||
:global LogPrint;
|
|
||||||
:global MkDir;
|
|
||||||
:global RmFile;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global WaitFullyConnected;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
$WaitFullyConnected;
|
|
||||||
|
|
||||||
:local PackagePath [ $CleanFilePath [ /caps-man/manager/get package-path ] ];
|
|
||||||
:local InstalledVersion [ /system/package/update/get installed-version ];
|
|
||||||
:local Updated false;
|
|
||||||
|
|
||||||
:if ([ :len $PackagePath ] = 0) do={
|
|
||||||
$LogPrint warning $ScriptName ("The CAPsMAN package path is not defined, can not download packages.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $FileGet $PackagePath ] = false) do={
|
|
||||||
:if ([ $MkDir $PackagePath ] = false) do={
|
|
||||||
$LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \
|
|
||||||
$PackagePath . ") failed!");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
$LogPrint info $ScriptName ("Created directory at CAPsMAN package path (" . $PackagePath . \
|
|
||||||
"). Please place your packages!");
|
|
||||||
}
|
|
||||||
|
|
||||||
:foreach Package in=[ /file/find where type="package" \
|
|
||||||
package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={
|
|
||||||
:local File [ /file/get $Package ];
|
|
||||||
:if ($File->"package-architecture" = "mips") do={
|
|
||||||
:set ($File->"package-architecture") "mipsbe";
|
|
||||||
}
|
|
||||||
:if ([ $DownloadPackage ($File->"package-name") $InstalledVersion \
|
|
||||||
($File->"package-architecture") $PackagePath ] = true) do={
|
|
||||||
:set Updated true;
|
|
||||||
$RmFile ($File->"name");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /file/find where type="package" name~("^" . $PackagePath) ] ] = 0) do={
|
|
||||||
$LogPrint info $ScriptName ("No packages available, downloading default set.");
|
|
||||||
:foreach Arch in={ "arm"; "mipsbe" } do={
|
|
||||||
:foreach Package in={ "routeros"; "wireless" } do={
|
|
||||||
:if ([ $DownloadPackage $Package $InstalledVersion $Arch $PackagePath ] = true) do={
|
|
||||||
:set Updated true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ($Updated = true) do={
|
|
||||||
:local Scripts [ /system/script/find where source~"\n# provides: capsman-rolling-upgrade.capsman\r?\n" ];
|
|
||||||
:if ([ :len $Scripts ] > 0) do={
|
|
||||||
:foreach Script in=$Scripts do={
|
|
||||||
/system/script/run $Script;
|
|
||||||
}
|
|
||||||
} else={
|
|
||||||
/caps-man/remote-cap/upgrade [ find where version!=$InstalledVersion ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
|
|
@ -1,104 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: capsman-download-packages%TEMPL%
|
|
||||||
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# Michael Gisbers <michael@gisbers.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# download and cleanup packages for CAP installation from CAPsMAN
|
|
||||||
# https://rsc.eworm.de/doc/capsman-download-packages.md
|
|
||||||
#
|
|
||||||
# !! This is just a template to generate the real script!
|
|
||||||
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global CleanFilePath;
|
|
||||||
:global DownloadPackage;
|
|
||||||
:global FileGet;
|
|
||||||
:global LogPrint;
|
|
||||||
:global MkDir;
|
|
||||||
:global RmFile;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global WaitFullyConnected;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
$WaitFullyConnected;
|
|
||||||
|
|
||||||
:local PackagePath [ $CleanFilePath [ /caps-man/manager/get package-path ] ];
|
|
||||||
:local PackagePath [ $CleanFilePath [ /interface/wifi/capsman/get package-path ] ];
|
|
||||||
:local InstalledVersion [ /system/package/update/get installed-version ];
|
|
||||||
:local Updated false;
|
|
||||||
|
|
||||||
:if ([ :len $PackagePath ] = 0) do={
|
|
||||||
$LogPrint warning $ScriptName ("The CAPsMAN package path is not defined, can not download packages.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $FileGet $PackagePath ] = false) do={
|
|
||||||
:if ([ $MkDir $PackagePath ] = false) do={
|
|
||||||
$LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \
|
|
||||||
$PackagePath . ") failed!");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
$LogPrint info $ScriptName ("Created directory at CAPsMAN package path (" . $PackagePath . \
|
|
||||||
"). Please place your packages!");
|
|
||||||
}
|
|
||||||
|
|
||||||
:foreach Package in=[ /file/find where type="package" \
|
|
||||||
package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={
|
|
||||||
:local File [ /file/get $Package ];
|
|
||||||
:if ($File->"package-architecture" = "mips") do={
|
|
||||||
:set ($File->"package-architecture") "mipsbe";
|
|
||||||
}
|
|
||||||
:if ([ $DownloadPackage ($File->"package-name") $InstalledVersion \
|
|
||||||
($File->"package-architecture") $PackagePath ] = true) do={
|
|
||||||
:set Updated true;
|
|
||||||
$RmFile ($File->"name");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /file/find where type="package" name~("^" . $PackagePath) ] ] = 0) do={
|
|
||||||
$LogPrint info $ScriptName ("No packages available, downloading default set.");
|
|
||||||
# NOT /interface/wifi/ #
|
|
||||||
:foreach Arch in={ "arm"; "mipsbe" } do={
|
|
||||||
:foreach Package in={ "routeros"; "wireless" } do={
|
|
||||||
# NOT /interface/wifi/ #
|
|
||||||
# NOT /caps-man/ #
|
|
||||||
:foreach Arch in={ "arm"; "arm64" } do={
|
|
||||||
:local Packages { "arm"={ "routeros"; "wifi-qcom"; "wifi-qcom-ac" };
|
|
||||||
"arm64"={ "routeros"; "wifi-qcom" } };
|
|
||||||
:foreach Package in=($Packages->$Arch) do={
|
|
||||||
# NOT /caps-man/ #
|
|
||||||
:if ([ $DownloadPackage $Package $InstalledVersion $Arch $PackagePath ] = true) do={
|
|
||||||
:set Updated true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ($Updated = true) do={
|
|
||||||
:local Scripts [ /system/script/find where source~"\n# provides: capsman-rolling-upgrade%TEMPL%\r?\n" ];
|
|
||||||
:if ([ :len $Scripts ] > 0) do={
|
|
||||||
:foreach Script in=$Scripts do={
|
|
||||||
/system/script/run $Script;
|
|
||||||
}
|
|
||||||
} else={
|
|
||||||
/caps-man/remote-cap/upgrade [ find where version!=$InstalledVersion ];
|
|
||||||
/interface/wifi/capsman/remote-cap/upgrade [ find where version!=$InstalledVersion ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: capsman-download-packages.wifi
|
|
||||||
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# Michael Gisbers <michael@gisbers.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# download and cleanup packages for CAP installation from CAPsMAN
|
|
||||||
# https://rsc.eworm.de/doc/capsman-download-packages.md
|
|
||||||
#
|
|
||||||
# !! Do not edit this file, it is generated from template!
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global CleanFilePath;
|
|
||||||
:global DownloadPackage;
|
|
||||||
:global FileGet;
|
|
||||||
:global LogPrint;
|
|
||||||
:global MkDir;
|
|
||||||
:global RmFile;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global WaitFullyConnected;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
$WaitFullyConnected;
|
|
||||||
|
|
||||||
:local PackagePath [ $CleanFilePath [ /interface/wifi/capsman/get package-path ] ];
|
|
||||||
:local InstalledVersion [ /system/package/update/get installed-version ];
|
|
||||||
:local Updated false;
|
|
||||||
|
|
||||||
:if ([ :len $PackagePath ] = 0) do={
|
|
||||||
$LogPrint warning $ScriptName ("The CAPsMAN package path is not defined, can not download packages.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $FileGet $PackagePath ] = false) do={
|
|
||||||
:if ([ $MkDir $PackagePath ] = false) do={
|
|
||||||
$LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \
|
|
||||||
$PackagePath . ") failed!");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
$LogPrint info $ScriptName ("Created directory at CAPsMAN package path (" . $PackagePath . \
|
|
||||||
"). Please place your packages!");
|
|
||||||
}
|
|
||||||
|
|
||||||
:foreach Package in=[ /file/find where type="package" \
|
|
||||||
package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={
|
|
||||||
:local File [ /file/get $Package ];
|
|
||||||
:if ($File->"package-architecture" = "mips") do={
|
|
||||||
:set ($File->"package-architecture") "mipsbe";
|
|
||||||
}
|
|
||||||
:if ([ $DownloadPackage ($File->"package-name") $InstalledVersion \
|
|
||||||
($File->"package-architecture") $PackagePath ] = true) do={
|
|
||||||
:set Updated true;
|
|
||||||
$RmFile ($File->"name");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /file/find where type="package" name~("^" . $PackagePath) ] ] = 0) do={
|
|
||||||
$LogPrint info $ScriptName ("No packages available, downloading default set.");
|
|
||||||
:foreach Arch in={ "arm"; "arm64" } do={
|
|
||||||
:local Packages { "arm"={ "routeros"; "wifi-qcom"; "wifi-qcom-ac" };
|
|
||||||
"arm64"={ "routeros"; "wifi-qcom" } };
|
|
||||||
:foreach Package in=($Packages->$Arch) do={
|
|
||||||
:if ([ $DownloadPackage $Package $InstalledVersion $Arch $PackagePath ] = true) do={
|
|
||||||
:set Updated true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ($Updated = true) do={
|
|
||||||
:local Scripts [ /system/script/find where source~"\n# provides: capsman-rolling-upgrade.wifi\r?\n" ];
|
|
||||||
:if ([ :len $Scripts ] > 0) do={
|
|
||||||
:foreach Script in=$Scripts do={
|
|
||||||
/system/script/run $Script;
|
|
||||||
}
|
|
||||||
} else={
|
|
||||||
/interface/wifi/capsman/remote-cap/upgrade [ find where version!=$InstalledVersion ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
28
capsman-rolling-upgrade
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: capsman-rolling-upgrade
|
||||||
|
# Copyright (c) 2018-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# Michael Gisbers <michael@gisbers.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# upgrade CAPs one after another
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/capsman-rolling-upgrade.md
|
||||||
|
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global ScriptLock;
|
||||||
|
|
||||||
|
$ScriptLock "capsman-rolling-upgrade";
|
||||||
|
|
||||||
|
:local InstalledVersion [ / system package update get installed-version ];
|
||||||
|
|
||||||
|
:local RemoteCapCount [ :len [ / caps-man remote-cap find ] ];
|
||||||
|
:if ($RemoteCapCount > 0) do={
|
||||||
|
:local Delay (600 / $RemoteCapCount);
|
||||||
|
:if ($Delay > 120) do={ :set Delay 120; }
|
||||||
|
:foreach RemoteCap in=[ / caps-man remote-cap find where version!=$InstalledVersion ] do={
|
||||||
|
:local RemoteCapVal [ / caps-man remote-cap get $RemoteCap ];
|
||||||
|
$LogPrintExit info ("Starting upgrade for " . $RemoteCapVal->"name" . \
|
||||||
|
" (" . $RemoteCapVal->"identity" . ")...") false;
|
||||||
|
/ caps-man remote-cap upgrade [ find where name=$RemoteCapVal->"name" ];
|
||||||
|
:delay ($Delay . "s");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: capsman-rolling-upgrade.capsman
|
|
||||||
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# Michael Gisbers <michael@gisbers.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# provides: capsman-rolling-upgrade.capsman
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# upgrade CAPs one after another
|
|
||||||
# https://rsc.eworm.de/doc/capsman-rolling-upgrade.md
|
|
||||||
#
|
|
||||||
# !! Do not edit this file, it is generated from template!
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global LogPrint;
|
|
||||||
:global ScriptLock;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local InstalledVersion [ /system/package/update/get installed-version ];
|
|
||||||
|
|
||||||
:local RemoteCapCount [ :len [ /caps-man/remote-cap/find ] ];
|
|
||||||
:if ($RemoteCapCount > 0) do={
|
|
||||||
:local Delay (600 / $RemoteCapCount);
|
|
||||||
:if ($Delay > 120) do={ :set Delay 120; }
|
|
||||||
:foreach RemoteCap in=[ /caps-man/remote-cap/find where version!=$InstalledVersion ] do={
|
|
||||||
:local RemoteCapVal [ /caps-man/remote-cap/get $RemoteCap ];
|
|
||||||
:if ([ :len $RemoteCapVal ] > 1) do={
|
|
||||||
$LogPrint info $ScriptName ("Starting upgrade for " . $RemoteCapVal->"name" . \
|
|
||||||
" (" . $RemoteCapVal->"identity" . ")...");
|
|
||||||
/caps-man/remote-cap/upgrade $RemoteCap;
|
|
||||||
} else={
|
|
||||||
$LogPrint warning $ScriptName ("Remote CAP vanished, skipping upgrade.");
|
|
||||||
}
|
|
||||||
:delay ($Delay . "s");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: capsman-rolling-upgrade%TEMPL%
|
|
||||||
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# Michael Gisbers <michael@gisbers.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# provides: capsman-rolling-upgrade%TEMPL%
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# upgrade CAPs one after another
|
|
||||||
# https://rsc.eworm.de/doc/capsman-rolling-upgrade.md
|
|
||||||
#
|
|
||||||
# !! This is just a template to generate the real script!
|
|
||||||
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global LogPrint;
|
|
||||||
:global ScriptLock;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local InstalledVersion [ /system/package/update/get installed-version ];
|
|
||||||
|
|
||||||
:local RemoteCapCount [ :len [ /caps-man/remote-cap/find ] ];
|
|
||||||
:local RemoteCapCount [ :len [ /interface/wifi/capsman/remote-cap/find ] ];
|
|
||||||
:if ($RemoteCapCount > 0) do={
|
|
||||||
:local Delay (600 / $RemoteCapCount);
|
|
||||||
:if ($Delay > 120) do={ :set Delay 120; }
|
|
||||||
:foreach RemoteCap in=[ /caps-man/remote-cap/find where version!=$InstalledVersion ] do={
|
|
||||||
:foreach RemoteCap in=[ /interface/wifi/capsman/remote-cap/find where version!=$InstalledVersion ] do={
|
|
||||||
:local RemoteCapVal [ /caps-man/remote-cap/get $RemoteCap ];
|
|
||||||
:local RemoteCapVal [ /interface/wifi/capsman/remote-cap/get $RemoteCap ];
|
|
||||||
:if ([ :len $RemoteCapVal ] > 1) do={
|
|
||||||
# NOT /caps-man/ #
|
|
||||||
:set ($RemoteCapVal->"name") ($RemoteCapVal->"common-name");
|
|
||||||
# NOT /caps-man/ #
|
|
||||||
$LogPrint info $ScriptName ("Starting upgrade for " . $RemoteCapVal->"name" . \
|
|
||||||
" (" . $RemoteCapVal->"identity" . ")...");
|
|
||||||
/caps-man/remote-cap/upgrade $RemoteCap;
|
|
||||||
/interface/wifi/capsman/remote-cap/upgrade $RemoteCap;
|
|
||||||
} else={
|
|
||||||
$LogPrint warning $ScriptName ("Remote CAP vanished, skipping upgrade.");
|
|
||||||
}
|
|
||||||
:delay ($Delay . "s");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: capsman-rolling-upgrade.wifi
|
|
||||||
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# Michael Gisbers <michael@gisbers.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# provides: capsman-rolling-upgrade.wifi
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# upgrade CAPs one after another
|
|
||||||
# https://rsc.eworm.de/doc/capsman-rolling-upgrade.md
|
|
||||||
#
|
|
||||||
# !! Do not edit this file, it is generated from template!
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global LogPrint;
|
|
||||||
:global ScriptLock;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local InstalledVersion [ /system/package/update/get installed-version ];
|
|
||||||
|
|
||||||
:local RemoteCapCount [ :len [ /interface/wifi/capsman/remote-cap/find ] ];
|
|
||||||
:if ($RemoteCapCount > 0) do={
|
|
||||||
:local Delay (600 / $RemoteCapCount);
|
|
||||||
:if ($Delay > 120) do={ :set Delay 120; }
|
|
||||||
:foreach RemoteCap in=[ /interface/wifi/capsman/remote-cap/find where version!=$InstalledVersion ] do={
|
|
||||||
:local RemoteCapVal [ /interface/wifi/capsman/remote-cap/get $RemoteCap ];
|
|
||||||
:if ([ :len $RemoteCapVal ] > 1) do={
|
|
||||||
:set ($RemoteCapVal->"name") ($RemoteCapVal->"common-name");
|
|
||||||
$LogPrint info $ScriptName ("Starting upgrade for " . $RemoteCapVal->"name" . \
|
|
||||||
" (" . $RemoteCapVal->"identity" . ")...");
|
|
||||||
/interface/wifi/capsman/remote-cap/upgrade $RemoteCap;
|
|
||||||
} else={
|
|
||||||
$LogPrint warning $ScriptName ("Remote CAP vanished, skipping upgrade.");
|
|
||||||
}
|
|
||||||
:delay ($Delay . "s");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
31
certificate-renew-issued
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: certificate-renew-issued
|
||||||
|
# Copyright (c) 2019-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# renew locally issued certificates
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/certificate-renew-issued.md
|
||||||
|
|
||||||
|
:global CertIssuedExportPass;
|
||||||
|
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global MkDir;
|
||||||
|
|
||||||
|
:foreach Cert in=[ / certificate find where issued expires-after<3w ] do={
|
||||||
|
:local CertVal [ / certificate get $Cert ];
|
||||||
|
/ certificate issued-revoke $Cert;
|
||||||
|
/ certificate set name=($CertVal->"name" . "-revoked-" . [ / system clock get date ]) $Cert;
|
||||||
|
/ certificate add name=($CertVal->"name") common-name=($CertVal->"common-name") \
|
||||||
|
key-usage=($CertVal->"key-usage") subject-alt-name=($CertVal->"subject-alt-name");
|
||||||
|
/ certificate sign ($CertVal->"name") ca=($CertVal->"ca");
|
||||||
|
:if ([ :typeof ($CertIssuedExportPass->($CertVal->"common-name")) ] = "str") do={
|
||||||
|
$MkDir "cert-issued";
|
||||||
|
/ certificate export-certificate ($CertVal->"name") type=pkcs12 \
|
||||||
|
file-name=("cert-issued/" . $CertVal->"common-name") \
|
||||||
|
export-passphrase=($CertIssuedExportPass->($CertVal->"common-name"));
|
||||||
|
$LogPrintExit info ("Issued a new certificate for \"" . $CertVal->"common-name" . \
|
||||||
|
"\", exported to \"cert-issued/" . $CertVal->"common-name" . ".p12\".") false;
|
||||||
|
} else={
|
||||||
|
$LogPrintExit info ("Issued a new certificate for \"" . $CertVal->"common-name" . "\".") false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: certificate-renew-issued
|
|
||||||
# Copyright (c) 2019-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# renew locally issued certificates
|
|
||||||
# https://rsc.eworm.de/doc/certificate-renew-issued.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 CertIssuedExportPass;
|
|
||||||
|
|
||||||
:global LogPrint;
|
|
||||||
:global MkDir;
|
|
||||||
:global ScriptLock;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:foreach Cert in=[ /certificate/find where issued expires-after<3w ] do={
|
|
||||||
:local CertVal [ /certificate/get $Cert ];
|
|
||||||
/certificate/issued-revoke $Cert;
|
|
||||||
/certificate/set name=($CertVal->"name" . "-revoked-" . [ /system/clock/get date ]) $Cert;
|
|
||||||
/certificate/add name=($CertVal->"name") common-name=($CertVal->"common-name") \
|
|
||||||
key-usage=($CertVal->"key-usage") subject-alt-name=($CertVal->"subject-alt-name");
|
|
||||||
/certificate/sign ($CertVal->"name") ca=($CertVal->"ca");
|
|
||||||
:if ([ :typeof ($CertIssuedExportPass->($CertVal->"common-name")) ] = "str") do={
|
|
||||||
:if ([ $MkDir "cert-issued" ] = true) do={
|
|
||||||
/certificate/export-certificate ($CertVal->"name") type=pkcs12 \
|
|
||||||
file-name=("cert-issued/" . $CertVal->"common-name") \
|
|
||||||
export-passphrase=($CertIssuedExportPass->($CertVal->"common-name"));
|
|
||||||
$LogPrint info $ScriptName ("Issued a new certificate for '" . $CertVal->"common-name" . \
|
|
||||||
"', exported to 'cert-issued/" . $CertVal->"common-name" . ".p12'.");
|
|
||||||
} else={
|
|
||||||
$LogPrint warning $ScriptName ("Failed creating directory, not exporting certificate.");
|
|
||||||
}
|
|
||||||
} else={
|
|
||||||
$LogPrint info $ScriptName ("Issued a new certificate for '" . $CertVal->"common-name" . "'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
|
|
||||||
# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
|
|
||||||
# Label: "Certum Trusted Network CA"
|
|
||||||
# Serial: 279744
|
|
||||||
# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78
|
|
||||||
# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e
|
|
||||||
# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
|
|
||||||
MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
|
|
||||||
ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
|
|
||||||
cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
|
|
||||||
WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
|
|
||||||
Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
|
|
||||||
IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
|
|
||||||
AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
|
|
||||||
UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
|
|
||||||
TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
|
|
||||||
BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
|
|
||||||
kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
|
|
||||||
AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
|
|
||||||
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
|
|
||||||
HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
|
|
||||||
sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
|
|
||||||
I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
|
|
||||||
J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
|
|
||||||
VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
|
|
||||||
03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
44
certs/DigiCert ECC Secure Server CA.pem
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDrDCCApSgAwIBAgIQCssoukZe5TkIdnRw883GEjANBgkqhkiG9w0BAQwFADBh
|
||||||
|
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||||
|
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
|
||||||
|
QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEwxCzAJBgNVBAYTAlVT
|
||||||
|
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJjAkBgNVBAMTHURpZ2lDZXJ0IEVDQyBT
|
||||||
|
ZWN1cmUgU2VydmVyIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ghC6nfYJN6g
|
||||||
|
LGSkE85AnCNyqQIKDjc/ITa4jVMU9tWRlUvzlgKNcR7E2Munn17voOZ/WpIRllNv
|
||||||
|
68DLP679Wz9HJOeaBy6Wvqgvu1cYr3GkvXg6HuhbPGtkESvMNCuMo4IBITCCAR0w
|
||||||
|
EgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwNAYIKwYBBQUHAQEE
|
||||||
|
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQgYDVR0f
|
||||||
|
BDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xv
|
||||||
|
YmFsUm9vdENBLmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYc
|
||||||
|
aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUo53mH/naOU/A
|
||||||
|
buiRy5Wl2jHiCp8wHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJ
|
||||||
|
KoZIhvcNAQEMBQADggEBAMeKoENL7HTJxavVHzA1Nm6YVntIrAVjrnuaVyRXzG/6
|
||||||
|
3qttnMe2uuzO58pzZNvfBDcKAEmzP58mrZGMIOgfiA4q+2Y3yDDo0sIkp0VILeoB
|
||||||
|
UEoxlBPfjV/aKrtJPGHzecicZpIalir0ezZYoyxBEHQa0+1IttK7igZFcTMQMHp6
|
||||||
|
mCHdJLnsnLWSB62DxsRq+HfmNb4TDydkskO/g+l3VtsIh5RHFPVfKK+jaEyDj2D3
|
||||||
|
loB5hWp2Jp2VDCADjT7ueihlZGak2YPqmXTNbk19HOuNssWvFhtOyPNV6og4ETQd
|
||||||
|
Ea8/B6hPatJ0ES8q/HO3X8IVQwVs1n3aAr0im0/T+Xc=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
|
||||||
|
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||||
|
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
|
||||||
|
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
|
||||||
|
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
|
||||||
|
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
|
||||||
|
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
|
||||||
|
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
|
||||||
|
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
|
||||||
|
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
|
||||||
|
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
|
||||||
|
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
|
||||||
|
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
|
||||||
|
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
|
||||||
|
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
|
||||||
|
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
|
||||||
|
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
|
||||||
|
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
|
||||||
|
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
|
||||||
|
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
|
|
||||||
# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
|
|
||||||
# Label: "DigiCert Global Root G2"
|
|
||||||
# Serial: 4293743540046975378534879503202253541
|
|
||||||
# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44
|
|
||||||
# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4
|
|
||||||
# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
|
|
||||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
|
||||||
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
|
|
||||||
MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
|
|
||||||
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
|
|
||||||
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
|
|
||||||
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
|
|
||||||
2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
|
|
||||||
1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
|
|
||||||
q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
|
|
||||||
tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
|
|
||||||
vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
|
|
||||||
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
|
|
||||||
5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
|
|
||||||
1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
|
|
||||||
NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
|
|
||||||
Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
|
|
||||||
8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
|
|
||||||
pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
|
|
||||||
MrY=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
|
|
||||||
# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
|
|
||||||
# Label: "DigiCert Global Root G3"
|
|
||||||
# Serial: 7089244469030293291760083333884364146
|
|
||||||
# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca
|
|
||||||
# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e
|
|
||||||
# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
|
|
||||||
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
|
|
||||||
ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
|
|
||||||
Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
|
|
||||||
EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
|
|
||||||
IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
|
|
||||||
K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
|
|
||||||
fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
|
|
||||||
Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
|
|
||||||
BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
|
|
||||||
AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
|
|
||||||
oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
|
|
||||||
sycX
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
31
certs/E1.pem
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICxjCCAk2gAwIBAgIRALO93/inhFu86QOgQTWzSkUwCgYIKoZIzj0EAwMwTzEL
|
||||||
|
MAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNo
|
||||||
|
IEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDIwHhcNMjAwOTA0MDAwMDAwWhcN
|
||||||
|
MjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3MgRW5j
|
||||||
|
cnlwdDELMAkGA1UEAxMCRTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQkXC2iKv0c
|
||||||
|
S6Zdl3MnMayyoGli72XoprDwrEuf/xwLcA/TmC9N/A8AmzfwdAVXMpcuBe8qQyWj
|
||||||
|
+240JxP2T35p0wKZXuskR5LBJJvmsSGPwSSB/GjMH2m6WPUZIvd0xhajggEIMIIB
|
||||||
|
BDAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMB
|
||||||
|
MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFrz7Sv8NsI3eblSMOpUb89V
|
||||||
|
yy6sMB8GA1UdIwQYMBaAFHxClq7eS0g7+pL4nozPbYupcjeVMDIGCCsGAQUFBwEB
|
||||||
|
BCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL3gyLmkubGVuY3Iub3JnLzAnBgNVHR8E
|
||||||
|
IDAeMBygGqAYhhZodHRwOi8veDIuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYG
|
||||||
|
Z4EMAQIBMA0GCysGAQQBgt8TAQEBMAoGCCqGSM49BAMDA2cAMGQCMHt01VITjWH+
|
||||||
|
Dbo/AwCd89eYhNlXLr3pD5xcSAQh8suzYHKOl9YST8pE9kLJ03uGqQIwWrGxtO3q
|
||||||
|
YJkgsTgDyj2gJrjubi1K9sZmHzOa25JK1fUpE8ZwYii6I4zPPS/Lgul/
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
|
||||||
|
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
|
||||||
|
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
|
||||||
|
MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
|
||||||
|
ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
|
||||||
|
EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
|
||||||
|
+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
|
||||||
|
ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
|
||||||
|
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
|
||||||
|
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
|
||||||
|
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
|
||||||
|
/q4AaOeMSQ+2b1tbFfLn
|
||||||
|
-----END CERTIFICATE-----
|
||||||
47
certs/GTS CA 1O1.pem
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
|
||||||
|
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
|
||||||
|
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
|
||||||
|
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
|
||||||
|
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
|
||||||
|
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
|
||||||
|
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
|
||||||
|
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
|
||||||
|
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
|
||||||
|
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
|
||||||
|
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
|
||||||
|
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
|
||||||
|
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
|
||||||
|
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
|
||||||
|
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
|
||||||
|
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
|
||||||
|
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
|
||||||
|
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
|
||||||
|
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
|
||||||
|
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIESjCCAzKgAwIBAgINAeO0mqGNiqmBJWlQuDANBgkqhkiG9w0BAQsFADBMMSAw
|
||||||
|
HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs
|
||||||
|
U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAwNDJaFw0yMTEy
|
||||||
|
MTUwMDAwNDJaMEIxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3Qg
|
||||||
|
U2VydmljZXMxEzARBgNVBAMTCkdUUyBDQSAxTzEwggEiMA0GCSqGSIb3DQEBAQUA
|
||||||
|
A4IBDwAwggEKAoIBAQDQGM9F1IvN05zkQO9+tN1pIRvJzzyOTHW5DzEZhD2ePCnv
|
||||||
|
UA0Qk28FgICfKqC9EksC4T2fWBYk/jCfC3R3VZMdS/dN4ZKCEPZRrAzDsiKUDzRr
|
||||||
|
mBBJ5wudgzndIMYcLe/RGGFl5yODIKgjEv/SJH/UL+dEaltN11BmsK+eQmMF++Ac
|
||||||
|
xGNhr59qM/9il71I2dN8FGfcddwuaej4bXhp0LcQBbjxMcI7JP0aM3T4I+DsaxmK
|
||||||
|
FsbjzaTNC9uzpFlgOIg7rR25xoynUxv8vNmkq7zdPGHXkxWY7oG9j+JkRyBABk7X
|
||||||
|
rJfoucBZEqFJJSPk7XA0LKW0Y3z5oz2D0c1tJKwHAgMBAAGjggEzMIIBLzAOBgNV
|
||||||
|
HQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1Ud
|
||||||
|
EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFJjR+G4Q68+b7GCfGJAboOt9Cf0rMB8G
|
||||||
|
A1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYuMDUGCCsGAQUFBwEBBCkwJzAl
|
||||||
|
BggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyMjAyBgNVHR8EKzAp
|
||||||
|
MCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dzcjIvZ3NyMi5jcmwwPwYDVR0g
|
||||||
|
BDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9wa2kuZ29vZy9y
|
||||||
|
ZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAGoA+Nnn78y6pRjd9XlQWNa7H
|
||||||
|
TgiZ/r3RNGkmUmYHPQq6Scti9PEajvwRT2iWTHQr02fesqOqBY2ETUwgZQ+lltoN
|
||||||
|
FvhsO9tvBCOIazpswWC9aJ9xju4tWDQH8NVU6YZZ/XteDSGU9YzJqPjY8q3MDxrz
|
||||||
|
mqepBCf5o8mw/wJ4a2G6xzUr6Fb6T8McDO22PLRL6u3M4Tzs3A2M1j6bykJYi8wW
|
||||||
|
IRdAvKLWZu/axBVbzYmqmwkm5zLSDW5nIAJbELCQCZwMH56t2Dvqofxs6BBcCFIZ
|
||||||
|
USpxu6x6td0V7SvJCCosirSmIatj/9dSSVDQibet8q/7UK4v4ZUN80atnZz1yg==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
# Issuer: CN=GTS Root R1 O=Google Trust Services LLC
|
|
||||||
# Subject: CN=GTS Root R1 O=Google Trust Services LLC
|
|
||||||
# Label: "GTS Root R1"
|
|
||||||
# Serial: 159662320309726417404178440727
|
|
||||||
# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40
|
|
||||||
# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a
|
|
||||||
# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
|
|
||||||
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
|
|
||||||
MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
|
|
||||||
MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
|
|
||||||
Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA
|
|
||||||
A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo
|
|
||||||
27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w
|
|
||||||
Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw
|
|
||||||
TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl
|
|
||||||
qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH
|
|
||||||
szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8
|
|
||||||
Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk
|
|
||||||
MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
|
|
||||||
wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p
|
|
||||||
aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN
|
|
||||||
VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID
|
|
||||||
AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
|
|
||||||
FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb
|
|
||||||
C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe
|
|
||||||
QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy
|
|
||||||
h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4
|
|
||||||
7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J
|
|
||||||
ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef
|
|
||||||
MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/
|
|
||||||
Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
|
|
||||||
6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ
|
|
||||||
0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
|
|
||||||
2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
|
|
||||||
bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
# Issuer: CN=GTS Root R4 O=Google Trust Services LLC
|
|
||||||
# Subject: CN=GTS Root R4 O=Google Trust Services LLC
|
|
||||||
# Label: "GTS Root R4"
|
|
||||||
# Serial: 159662532700760215368942768210
|
|
||||||
# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8
|
|
||||||
# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47
|
|
||||||
# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD
|
|
||||||
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
|
|
||||||
A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
|
|
||||||
WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
|
|
||||||
IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
|
|
||||||
AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi
|
|
||||||
QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR
|
|
||||||
HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
|
|
||||||
BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D
|
|
||||||
9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8
|
|
||||||
p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
51
certs/Go Daddy Secure Certificate Authority - G2.pem
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
|
||||||
|
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
|
||||||
|
EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
|
||||||
|
ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
|
||||||
|
NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
|
||||||
|
EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
|
||||||
|
AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
|
||||||
|
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
|
||||||
|
E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
|
||||||
|
/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
|
||||||
|
DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
|
||||||
|
GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
|
||||||
|
tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
|
||||||
|
AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
|
||||||
|
FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
|
||||||
|
WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
|
||||||
|
9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
|
||||||
|
gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
|
||||||
|
2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
|
||||||
|
LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
|
||||||
|
4uJEvlz36hz1
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
|
||||||
|
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
|
||||||
|
EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
|
||||||
|
ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3
|
||||||
|
MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
|
||||||
|
EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE
|
||||||
|
CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD
|
||||||
|
EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi
|
||||||
|
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD
|
||||||
|
BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv
|
||||||
|
K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e
|
||||||
|
cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY
|
||||||
|
pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n
|
||||||
|
eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB
|
||||||
|
AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
|
||||||
|
HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv
|
||||||
|
9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
|
||||||
|
b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n
|
||||||
|
b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG
|
||||||
|
CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv
|
||||||
|
MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz
|
||||||
|
91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2
|
||||||
|
RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi
|
||||||
|
DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11
|
||||||
|
GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x
|
||||||
|
LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
|
|
||||||
# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
|
|
||||||
# Label: "Go Daddy Root Certificate Authority - G2"
|
|
||||||
# Serial: 0
|
|
||||||
# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01
|
|
||||||
# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b
|
|
||||||
# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
|
|
||||||
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
|
|
||||||
EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
|
|
||||||
ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
|
|
||||||
NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
|
|
||||||
EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
|
|
||||||
AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
|
|
||||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
|
|
||||||
E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
|
|
||||||
/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
|
|
||||||
DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
|
|
||||||
GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
|
|
||||||
tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
|
|
||||||
AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
|
|
||||||
FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
|
|
||||||
WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
|
|
||||||
9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
|
|
||||||
gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
|
|
||||||
2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
|
|
||||||
LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
|
|
||||||
4uJEvlz36hz1
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
# Issuer: CN=ISRG Root X1 O=Internet Security Research Group
|
|
||||||
# Subject: CN=ISRG Root X1 O=Internet Security Research Group
|
|
||||||
# Label: "ISRG Root X1"
|
|
||||||
# Serial: 172886928669790476064670243504169061120
|
|
||||||
# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e
|
|
||||||
# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8
|
|
||||||
# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
|
|
||||||
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
|
||||||
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
|
|
||||||
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
|
|
||||||
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
|
|
||||||
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
|
|
||||||
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
|
|
||||||
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
|
|
||||||
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
|
|
||||||
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
|
|
||||||
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
|
|
||||||
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
|
|
||||||
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
|
|
||||||
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
|
|
||||||
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
|
|
||||||
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
|
|
||||||
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
|
|
||||||
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
|
|
||||||
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
|
|
||||||
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
|
|
||||||
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
|
|
||||||
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
|
|
||||||
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
|
|
||||||
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
|
|
||||||
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
|
|
||||||
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
|
|
||||||
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
|
|
||||||
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
|
|
||||||
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
# Issuer: CN=ISRG Root X2 O=Internet Security Research Group
|
|
||||||
# Subject: CN=ISRG Root X2 O=Internet Security Research Group
|
|
||||||
# Label: "ISRG Root X2"
|
|
||||||
# Serial: 87493402998870891108772069816698636114
|
|
||||||
# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5
|
|
||||||
# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af
|
|
||||||
# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
|
|
||||||
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
|
|
||||||
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
|
|
||||||
MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
|
|
||||||
ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
|
|
||||||
EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
|
|
||||||
+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
|
|
||||||
ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
|
|
||||||
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
|
|
||||||
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
|
|
||||||
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
|
|
||||||
/q4AaOeMSQ+2b1tbFfLn
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
83
certs/Let's Encrypt Authority X3.pem
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
|
||||||
|
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||||
|
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
|
||||||
|
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
|
||||||
|
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
|
||||||
|
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
|
||||||
|
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
|
||||||
|
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
|
||||||
|
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
|
||||||
|
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
|
||||||
|
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
|
||||||
|
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
|
||||||
|
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
|
||||||
|
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
|
||||||
|
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
|
||||||
|
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
|
||||||
|
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
|
||||||
|
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
|
||||||
|
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
|
||||||
|
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
|
||||||
|
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
|
||||||
|
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
|
||||||
|
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
|
||||||
|
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
|
||||||
|
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
|
||||||
|
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
|
||||||
|
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
|
||||||
|
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
|
||||||
|
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFjTCCA3WgAwIBAgIRANOxciY0IzLc9AUoUSrsnGowDQYJKoZIhvcNAQELBQAw
|
||||||
|
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||||
|
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTYxMDA2MTU0MzU1
|
||||||
|
WhcNMjExMDA2MTU0MzU1WjBKMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
|
||||||
|
RW5jcnlwdDEjMCEGA1UEAxMaTGV0J3MgRW5jcnlwdCBBdXRob3JpdHkgWDMwggEi
|
||||||
|
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc0wzwWuUuR7dyXTeDs2hjMOrX
|
||||||
|
NSYZJeG9vjXxcJIvt7hLQQWrqZ41CFjssSrEaIcLo+N15Obzp2JxunmBYB/XkZqf
|
||||||
|
89B4Z3HIaQ6Vkc/+5pnpYDxIzH7KTXcSJJ1HG1rrueweNwAcnKx7pwXqzkrrvUHl
|
||||||
|
Npi5y/1tPJZo3yMqQpAMhnRnyH+lmrhSYRQTP2XpgofL2/oOVvaGifOFP5eGr7Dc
|
||||||
|
Gu9rDZUWfcQroGWymQQ2dYBrrErzG5BJeC+ilk8qICUpBMZ0wNAxzY8xOJUWuqgz
|
||||||
|
uEPxsR/DMH+ieTETPS02+OP88jNquTkxxa/EjQ0dZBYzqvqEKbbUC8DYfcOTAgMB
|
||||||
|
AAGjggFnMIIBYzAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADBU
|
||||||
|
BgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEBATAwMC4GCCsGAQUFBwIB
|
||||||
|
FiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQub3JnMB0GA1UdDgQWBBSo
|
||||||
|
SmpjBH3duubRObemRWXv86jsoTAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js
|
||||||
|
LnJvb3QteDEubGV0c2VuY3J5cHQub3JnMHIGCCsGAQUFBwEBBGYwZDAwBggrBgEF
|
||||||
|
BQcwAYYkaHR0cDovL29jc3Aucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcvMDAGCCsG
|
||||||
|
AQUFBzAChiRodHRwOi8vY2VydC5yb290LXgxLmxldHNlbmNyeXB0Lm9yZy8wHwYD
|
||||||
|
VR0jBBgwFoAUebRZ5nu25eQBc4AIiMgaWPbpm24wDQYJKoZIhvcNAQELBQADggIB
|
||||||
|
ABnPdSA0LTqmRf/Q1eaM2jLonG4bQdEnqOJQ8nCqxOeTRrToEKtwT++36gTSlBGx
|
||||||
|
A/5dut82jJQ2jxN8RI8L9QFXrWi4xXnA2EqA10yjHiR6H9cj6MFiOnb5In1eWsRM
|
||||||
|
UM2v3e9tNsCAgBukPHAg1lQh07rvFKm/Bz9BCjaxorALINUfZ9DD64j2igLIxle2
|
||||||
|
DPxW8dI/F2loHMjXZjqG8RkqZUdoxtID5+90FgsGIfkMpqgRS05f4zPbCEHqCXl1
|
||||||
|
eO5HyELTgcVlLXXQDgAWnRzut1hFJeczY1tjQQno6f6s+nMydLN26WuU4s3UYvOu
|
||||||
|
OsUxRlJu7TSRHqDC3lSE5XggVkzdaPkuKGQbGpny+01/47hfXXNB7HntWNZ6N2Vw
|
||||||
|
p7G6OfY+YQrZwIaQmhrIqJZuigsrbe3W+gdn5ykE9+Ky0VgVUsfxo52mwFYs1JKY
|
||||||
|
2PGDuWx8M6DlS6qQkvHaRUo0FMd8TsSlbF0/v965qGFKhSDeQoMpYnwcmQilRh/0
|
||||||
|
ayLThlHLN81gSkJjVrPI0Y8xCVPB4twb1PFUd2fPM3sA1tJ83sZ5v8vgFv2yofKR
|
||||||
|
PB0t6JzUA81mSqM3kxl5e+IZwhYAyO0OTg3/fs8HqGTNKd9BqoUwSRBzp06JMg5b
|
||||||
|
rUCGwbCUDI0mxadJ3Bz4WxR6fyNpBK2yAinWEsikxqEt
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
|
||||||
|
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
|
||||||
|
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
|
||||||
|
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
|
||||||
|
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||||
|
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
|
||||||
|
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
|
||||||
|
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
|
||||||
|
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
|
||||||
|
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
|
||||||
|
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
|
||||||
|
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
|
||||||
|
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
|
||||||
|
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
|
||||||
|
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
|
||||||
|
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
|
||||||
|
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
|
||||||
|
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
# Makefile to check certificates
|
|
||||||
|
|
||||||
CURL = curl \
|
|
||||||
--capath /dev/null \
|
|
||||||
--connect-timeout 5 \
|
|
||||||
--output /dev/null \
|
|
||||||
--silent
|
|
||||||
|
|
||||||
DOMAINS_DUAL = \
|
|
||||||
api.macvendors.com/GTS-Root-R4 \
|
|
||||||
api.telegram.org/Go-Daddy-Root-Certificate-Authority-G2 \
|
|
||||||
cloudflare-dns.com/DigiCert-Global-Root-G2 \
|
|
||||||
dns.google/GTS-Root-R4 \
|
|
||||||
dns.quad9.net/DigiCert-Global-Root-G3 \
|
|
||||||
git.eworm.de/ISRG-Root-X2 \
|
|
||||||
lists.blocklist.de/Certum-Trusted-Network-CA \
|
|
||||||
matrix.org/GTS-Root-R4 \
|
|
||||||
raw.githubusercontent.com/USERTrust-RSA-Certification-Authority \
|
|
||||||
rsc.eworm.de/ISRG-Root-X2 \
|
|
||||||
upgrade.mikrotik.com/ISRG-Root-X1
|
|
||||||
DOMAINS_IPV4 = \
|
|
||||||
1.1.1.1/DigiCert-Global-Root-G2 \
|
|
||||||
8.8.8.8/GTS-Root-R1 \
|
|
||||||
9.9.9.9/DigiCert-Global-Root-G3 \
|
|
||||||
api.mullvad.net/ISRG-Root-X1 \
|
|
||||||
ipv4.showipv6.de/ISRG-Root-X1 \
|
|
||||||
ipv4.tunnelbroker.net/Starfield-Root-Certificate-Authority-G2 \
|
|
||||||
mkcert.org/ISRG-Root-X1 \
|
|
||||||
ntfy.sh/ISRG-Root-X1 \
|
|
||||||
www.dshield.org/ISRG-Root-X1 \
|
|
||||||
www.spamhaus.org/GTS-Root-R4
|
|
||||||
DOMAINS_IPV6 = \
|
|
||||||
[2606\:4700\:4700\:\:1111]/DigiCert-Global-Root-G2 \
|
|
||||||
[2001\:4860\:4860\:\:8888]/GTS-Root-R1 \
|
|
||||||
[2620\:fe\:\:9]/DigiCert-Global-Root-G3 \
|
|
||||||
ipv6.showipv6.de/ISRG-Root-X1
|
|
||||||
|
|
||||||
.PHONY: $(DOMAINS_DUAL) $(DOMAINS_IPV4) $(DOMAINS_IPV6)
|
|
||||||
|
|
||||||
all: $(DOMAINS_DUAL) $(DOMAINS_IPV4) $(DOMAINS_IPV6)
|
|
||||||
|
|
||||||
$(DOMAINS_DUAL):
|
|
||||||
ifndef NOIPV4
|
|
||||||
$(CURL) -4 --cacert $(notdir $@).pem https://$(dir $@)
|
|
||||||
endif
|
|
||||||
ifndef NOIPV6
|
|
||||||
$(CURL) -6 --cacert $(notdir $@).pem https://$(dir $@)
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(DOMAINS_IPV4):
|
|
||||||
ifndef NOIPV4
|
|
||||||
$(CURL) -4 --cacert $(notdir $@).pem https://$(dir $@)
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(DOMAINS_IPV6):
|
|
||||||
ifndef NOIPV6
|
|
||||||
$(CURL) -6 --cacert $(notdir $@).pem https://$(dir $@)
|
|
||||||
endif
|
|
||||||
81
certs/R3.pem
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
|
||||||
|
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||||
|
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
|
||||||
|
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
|
||||||
|
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||||
|
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
|
||||||
|
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
|
||||||
|
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
|
||||||
|
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
|
||||||
|
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
|
||||||
|
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
|
||||||
|
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
|
||||||
|
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
|
||||||
|
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
|
||||||
|
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
|
||||||
|
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
|
||||||
|
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
|
||||||
|
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
|
||||||
|
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
|
||||||
|
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
|
||||||
|
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
|
||||||
|
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
|
||||||
|
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
|
||||||
|
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
|
||||||
|
hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
|
||||||
|
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
|
||||||
|
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
|
||||||
|
nLRbwHOoq7hHwg==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
|
||||||
|
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||||
|
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
|
||||||
|
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
|
||||||
|
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
|
||||||
|
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
|
||||||
|
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
|
||||||
|
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
|
||||||
|
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
|
||||||
|
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
|
||||||
|
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
|
||||||
|
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
|
||||||
|
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
|
||||||
|
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
|
||||||
|
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
|
||||||
|
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
|
||||||
|
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
|
||||||
|
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
|
||||||
|
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
|
||||||
|
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
|
||||||
|
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
|
||||||
|
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
|
||||||
|
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
|
||||||
|
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
|
||||||
|
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
|
||||||
|
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
|
||||||
|
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
|
||||||
|
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
|
||||||
|
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
|
||||||
|
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
|
||||||
|
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
|
||||||
|
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
|
||||||
|
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||||
|
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
|
||||||
|
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
|
||||||
|
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
|
||||||
|
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
|
||||||
|
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
|
||||||
|
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
|
||||||
|
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
|
||||||
|
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
|
||||||
|
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
|
||||||
|
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
|
||||||
|
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
|
||||||
|
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
|
||||||
|
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
|
||||||
|
-----END CERTIFICATE-----
|
||||||
52
certs/Starfield Secure Certificate Authority - G2.pem
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
|
||||||
|
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
|
||||||
|
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
|
||||||
|
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
|
||||||
|
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
|
||||||
|
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
|
||||||
|
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
|
||||||
|
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
||||||
|
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
|
||||||
|
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
|
||||||
|
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
|
||||||
|
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
|
||||||
|
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
|
||||||
|
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
|
||||||
|
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
|
||||||
|
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
|
||||||
|
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
|
||||||
|
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
|
||||||
|
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
|
||||||
|
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
|
||||||
|
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFADCCA+igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
|
||||||
|
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
|
||||||
|
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
|
||||||
|
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAw
|
||||||
|
MFoXDTMxMDUwMzA3MDAwMFowgcYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
|
||||||
|
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
|
||||||
|
aG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydHMuc3RhcmZpZWxk
|
||||||
|
dGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNVBAMTK1N0YXJmaWVsZCBTZWN1cmUg
|
||||||
|
Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
||||||
|
DwAwggEKAoIBAQDlkGZL7PlGcakgg77pbL9KyUhpgXVObST2yxcT+LBxWYR6ayuF
|
||||||
|
pDS1FuXLzOlBcCykLtb6Mn3hqN6UEKwxwcDYav9ZJ6t21vwLdGu4p64/xFT0tDFE
|
||||||
|
3ZNWjKRMXpuJyySDm+JXfbfYEh/JhW300YDxUJuHrtQLEAX7J7oobRfpDtZNuTlV
|
||||||
|
Bv8KJAV+L8YdcmzUiymMV33a2etmGtNPp99/UsQwxaXJDgLFU793OGgGJMNmyDd+
|
||||||
|
MB5FcSM1/5DYKp2N57CSTTx/KgqT3M0WRmX3YISLdkuRJ3MUkuDq7o8W6o0OPnYX
|
||||||
|
v32JgIBEQ+ct4EMJddo26K3biTr1XRKOIwSDAgMBAAGjggEsMIIBKDAPBgNVHRMB
|
||||||
|
Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUJUWBaFAmOD07LSy+
|
||||||
|
zWrZtj2zZmMwHwYDVR0jBBgwFoAUfAwyH6fZMH/EfWijYqihzqsHWycwOgYIKwYB
|
||||||
|
BQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNo
|
||||||
|
LmNvbS8wOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0ZWNo
|
||||||
|
LmNvbS9zZnJvb3QtZzIuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF
|
||||||
|
BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv
|
||||||
|
MA0GCSqGSIb3DQEBCwUAA4IBAQBWZcr+8z8KqJOLGMfeQ2kTNCC+Tl94qGuc22pN
|
||||||
|
QdvBE+zcMQAiXvcAngzgNGU0+bE6TkjIEoGIXFs+CFN69xpk37hQYcxTUUApS8L0
|
||||||
|
rjpf5MqtJsxOYUPl/VemN3DOQyuwlMOS6eFfqhBJt2nk4NAfZKQrzR9voPiEJBjO
|
||||||
|
eT2pkb9UGBOJmVQRDVXFJgt5T1ocbvlj2xSApAer+rKluYjdkf5lO6Sjeb6JTeHQ
|
||||||
|
sPTIFwwKlhR8Cbds4cLYVdQYoKpBaXAko7nv6VrcPuuUSvC33l8Odvr7+2kDRUBQ
|
||||||
|
7nIMpBKGgc0T0U7EPMpODdIm8QC3tKai4W56gf0wrHofx1l7
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
|
|
||||||
# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
|
|
||||||
# Label: "Starfield Root Certificate Authority - G2"
|
|
||||||
# Serial: 0
|
|
||||||
# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96
|
|
||||||
# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e
|
|
||||||
# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
|
|
||||||
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
|
|
||||||
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
|
|
||||||
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
|
|
||||||
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
|
|
||||||
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
|
|
||||||
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
|
|
||||||
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
|
||||||
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
|
|
||||||
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
|
|
||||||
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
|
|
||||||
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
|
|
||||||
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
|
|
||||||
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
|
|
||||||
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
|
|
||||||
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
|
|
||||||
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
|
|
||||||
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
|
|
||||||
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
|
|
||||||
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
|
|
||||||
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
|
|
||||||
# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
|
|
||||||
# Label: "USERTrust RSA Certification Authority"
|
|
||||||
# Serial: 2645093764781058787591871645665788717
|
|
||||||
# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5
|
|
||||||
# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e
|
|
||||||
# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
|
|
||||||
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
|
|
||||||
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
|
|
||||||
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
|
|
||||||
MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
|
|
||||||
BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
|
|
||||||
aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
|
|
||||||
dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
|
|
||||||
AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
|
|
||||||
3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
|
|
||||||
tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
|
|
||||||
Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
|
|
||||||
VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
|
|
||||||
79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
|
|
||||||
c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
|
|
||||||
Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
|
|
||||||
c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
|
|
||||||
UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
|
|
||||||
Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
|
|
||||||
BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
|
|
||||||
A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
|
|
||||||
Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
|
|
||||||
VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
|
|
||||||
ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
|
|
||||||
8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
|
|
||||||
iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
|
|
||||||
Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
|
|
||||||
XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
|
|
||||||
qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
|
|
||||||
VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
|
|
||||||
L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
|
|
||||||
jjxDah2nGN59PRbxYvnKkKj9
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
120
check-certificates
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: check-certificates
|
||||||
|
# Copyright (c) 2013-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# check for certificate validity
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/check-certificates.md
|
||||||
|
|
||||||
|
:global CertRenewPass;
|
||||||
|
:global CertRenewUrl;
|
||||||
|
:global Identity;
|
||||||
|
|
||||||
|
:global CertificateAvailable
|
||||||
|
:global CertificateNameByCN;
|
||||||
|
:global IfThenElse;
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global ParseKeyValueStore;
|
||||||
|
:global SendNotification;
|
||||||
|
:global SymbolForNotification;
|
||||||
|
:global UrlEncode;
|
||||||
|
:global WaitForFile;
|
||||||
|
:global WaitFullyConnected;
|
||||||
|
|
||||||
|
:local FormatExpire do={
|
||||||
|
:global CharacterReplace;
|
||||||
|
:return [ $CharacterReplace [ $CharacterReplace [ :tostr $1 ] "w" "w " ] "d" "d " ];
|
||||||
|
}
|
||||||
|
|
||||||
|
$WaitFullyConnected;
|
||||||
|
|
||||||
|
:foreach Cert in=[ / certificate find where !revoked !ca !scep-url expires-after<3w ] do={
|
||||||
|
:local CertVal [ / certificate get $Cert ];
|
||||||
|
|
||||||
|
:do {
|
||||||
|
:if ([ :len $CertRenewUrl ] = 0) do={
|
||||||
|
$LogPrintExit info ("No CertRenewUrl given.") true;
|
||||||
|
}
|
||||||
|
|
||||||
|
:foreach Type in={ ".pem"; ".p12" } do={
|
||||||
|
:local CertFileName ([ $UrlEncode ($CertVal->"common-name") ] . $Type);
|
||||||
|
:do {
|
||||||
|
/ tool fetch check-certificate=yes-without-crl \
|
||||||
|
($CertRenewUrl . $CertFileName) dst-path=$CertFileName;
|
||||||
|
$WaitForFile $CertFileName;
|
||||||
|
:foreach PassPhrase in=$CertRenewPass do={
|
||||||
|
/ certificate import file-name=$CertFileName passphrase=$PassPhrase;
|
||||||
|
}
|
||||||
|
/ file remove [ find where name=$CertFileName ];
|
||||||
|
|
||||||
|
:foreach CertInChain in=[ / certificate find where name~("^" . $CertFileName . "_[0-9]+\$") common-name!=($CertVal->"common-name") ] do={
|
||||||
|
$CertificateNameByCN [ / certificate get $CertInChain common-name ];
|
||||||
|
}
|
||||||
|
} on-error={
|
||||||
|
$LogPrintExit debug ("Could not download certificate file " . $CertFileName) false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:local CertNew [ / certificate find where common-name=($CertVal->"common-name") fingerprint!=[ :tostr ($CertVal->"fingerprint") ] expires-after>3w ];
|
||||||
|
:local CertNewVal [ / certificate get $CertNew ];
|
||||||
|
|
||||||
|
:if ([ $CertificateAvailable ([ $ParseKeyValueStore ($CertNewVal->"issuer") ]->"CN") ] = false) do={
|
||||||
|
$LogPrintExit warning ("The certificate chain is not available!") false;
|
||||||
|
}
|
||||||
|
|
||||||
|
:if ($Cert != $CertNew) do={
|
||||||
|
$LogPrintExit debug ("Certificate '" . $CertVal->"name" . "' was not updated, but replaced.") false;
|
||||||
|
|
||||||
|
/ ip service set certificate=($CertNewVal->"name") [ find where certificate=($CertVal->"name") ];
|
||||||
|
|
||||||
|
:do {
|
||||||
|
/ ip ipsec identity set certificate=($CertNewVal->"name") [ / ip ipsec identity find where certificate=($CertVal->"name") ];
|
||||||
|
/ ip ipsec identity set remote-certificate=($CertNewVal->"name") [ / ip ipsec identity find where remote-certificate=($CertVal->"name") ];
|
||||||
|
} on-error={
|
||||||
|
$LogPrintExit debug ("Setting IPSEC certificates failed. Package 'security' not installed?") false;
|
||||||
|
}
|
||||||
|
|
||||||
|
:do {
|
||||||
|
/ ip hotspot profile set ssl-certificate=($CertNewVal->"name") [ / ip hotspot profile find where ssl-certificate=($CertVal->"name") ];
|
||||||
|
} on-error={
|
||||||
|
$LogPrintExit debug ("Setting hotspot certificates failed. Package 'hotspot' not installed?") false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/ certificate remove $Cert;
|
||||||
|
/ certificate set $CertNew name=($CertVal->"name");
|
||||||
|
}
|
||||||
|
|
||||||
|
$SendNotification ([ $SymbolForNotification "lock-with-ink-pen" ] . "Certificate renewed") \
|
||||||
|
("A certificate on " . $Identity . " has been renewed.\n\n" . \
|
||||||
|
"Name: " . ($CertVal->"name") . "\n" . \
|
||||||
|
"CommonName: " . ($CertNewVal->"common-name") . "\n" . \
|
||||||
|
"Fingerprint: " . ($CertNewVal->"fingerprint") . "\n" . \
|
||||||
|
"Issuer: " . ([ $ParseKeyValueStore ($CertNewVal->"issuer") ]->"CN") . "\n" . \
|
||||||
|
"Validity: " . ($CertNewVal->"invalid-before") . " to " . ($CertNewVal->"invalid-after") . "\n" . \
|
||||||
|
"Expires in: " . [ $FormatExpire ($CertNewVal->"expires-after") ]) "" "" "true";
|
||||||
|
$LogPrintExit info ("The certificate " . ($CertVal->"name") . " has been renewed.") false;
|
||||||
|
} on-error={
|
||||||
|
$LogPrintExit debug ("Could not renew certificate " . ($CertVal->"name") . ".") false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:foreach Cert in=[ / certificate find where !revoked !scep-url !(expires-after=[]) expires-after<2w !(fingerprint=[]) ] do={
|
||||||
|
:local CertVal [ / certificate get $Cert ];
|
||||||
|
|
||||||
|
:if ([ :len [ / certificate scep-server find where ca-cert=($CertVal->"ca") ] ] > 0) do={
|
||||||
|
$LogPrintExit debug ("Certificate \"" . ($CertVal->"name") . "\" is handled by SCEP, skipping.") false;
|
||||||
|
} else={
|
||||||
|
:local State [ $IfThenElse (($CertVal->"expired") = true) "expired" "is about to expire" ];
|
||||||
|
|
||||||
|
$SendNotification ([ $SymbolForNotification "warning-sign" ] . "Certificate warning!") \
|
||||||
|
("A certificate on " . $Identity . " " . $State . ".\n\n" . \
|
||||||
|
"Name: " . ($CertVal->"name") . "\n" . \
|
||||||
|
"CommonName: " . ($CertVal->"common-name") . "\n" . \
|
||||||
|
"Fingerprint: " . ($CertVal->"fingerprint") . "\n" . \
|
||||||
|
"Issuer: " . ($CertVal->"ca") . ([ $ParseKeyValueStore ($CertVal->"issuer") ]->"CN") . "\n" . \
|
||||||
|
"Validity: " . ($CertVal->"invalid-before") . " to " . ($CertVal->"invalid-after") . "\n" . \
|
||||||
|
"Expires in: " . [ $IfThenElse (($CertVal->"expired") = true) "expired" [ $FormatExpire ($CertVal->"expires-after") ] ]);
|
||||||
|
$LogPrintExit info ("The certificate " . ($CertVal->"name") . " " . $State . \
|
||||||
|
", it is invalid after " . ($CertVal->"invalid-after") . ".") false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,250 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: check-certificates
|
|
||||||
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
# requires device-mode, fetch
|
|
||||||
#
|
|
||||||
# check for certificate validity
|
|
||||||
# https://rsc.eworm.de/doc/check-certificates.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 CertRenewTime;
|
|
||||||
:global CertRenewUrl;
|
|
||||||
:global CertWarnTime;
|
|
||||||
:global Identity;
|
|
||||||
|
|
||||||
:global CertificateAvailable;
|
|
||||||
:global EscapeForRegEx;
|
|
||||||
:global IfThenElse;
|
|
||||||
:global LogPrint;
|
|
||||||
:global ParseKeyValueStore;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
:global UrlEncode;
|
|
||||||
:global WaitFullyConnected;
|
|
||||||
|
|
||||||
:local CheckCertificatesDownloadImport do={
|
|
||||||
:local ScriptName [ :tostr $1 ];
|
|
||||||
:local CertName [ :tostr $2 ];
|
|
||||||
:local FetchName [ :tostr $3 ];
|
|
||||||
|
|
||||||
:global CertRenewUrl;
|
|
||||||
:global CertRenewPass;
|
|
||||||
|
|
||||||
:global CertificateNameByCN;
|
|
||||||
:global EscapeForRegEx;
|
|
||||||
:global FetchUserAgentStr;
|
|
||||||
:global LogPrint;
|
|
||||||
:global RmFile;
|
|
||||||
:global UrlEncode;
|
|
||||||
:global WaitForFile;
|
|
||||||
|
|
||||||
:foreach Type in={ "p12"; "pem" } do={
|
|
||||||
:local CertFileName ([ $UrlEncode $FetchName ] . "." . $Type);
|
|
||||||
$LogPrint debug $ScriptName ("Trying type '" . $Type . "' for '" . $CertName . \
|
|
||||||
"' (file '" . $CertFileName . "')...");
|
|
||||||
|
|
||||||
:do {
|
|
||||||
/tool/fetch check-certificate=yes-without-crl http-header-field=({ [ $FetchUserAgentStr $ScriptName ] }) \
|
|
||||||
($CertRenewUrl . $CertFileName) dst-path=$CertFileName as-value;
|
|
||||||
$WaitForFile $CertFileName;
|
|
||||||
|
|
||||||
:local DecryptionFailed true;
|
|
||||||
:foreach I,PassPhrase in=$CertRenewPass do={
|
|
||||||
:do {
|
|
||||||
$LogPrint debug $ScriptName ("Trying " . $I . ". passphrase... ");
|
|
||||||
:local Result [ /certificate/import file-name=$CertFileName passphrase=$PassPhrase as-value ];
|
|
||||||
:if ($Result->"decryption-failures" = 0) do={
|
|
||||||
$LogPrint debug $ScriptName ("Success!");
|
|
||||||
:set DecryptionFailed false;
|
|
||||||
}
|
|
||||||
} on-error={ }
|
|
||||||
}
|
|
||||||
$RmFile $CertFileName;
|
|
||||||
|
|
||||||
:if ($DecryptionFailed = true) do={
|
|
||||||
$LogPrint warning $ScriptName ("Decryption failed for certificate file '" . $CertFileName . "'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
:foreach CertInChain in=[ /certificate/find where common-name!=$CertName !private-key \
|
|
||||||
name~("^" . [ $EscapeForRegEx $CertFileName ] . "_[0-9]+\$") \
|
|
||||||
!(subject-alt-name~("(^|\\W)(DNS|IP):" . [ $EscapeForRegEx $CertName ] . "(\\W|\$)")) \
|
|
||||||
!(common-name=[]) ] do={
|
|
||||||
$CertificateNameByCN [ /certificate/get $CertInChain common-name ];
|
|
||||||
}
|
|
||||||
|
|
||||||
:return true;
|
|
||||||
} on-error={
|
|
||||||
$LogPrint debug $ScriptName ("Could not download certificate file '" . $CertFileName . "'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local FormatInfo do={
|
|
||||||
:local Cert $1;
|
|
||||||
|
|
||||||
:global FormatLine;
|
|
||||||
:global FormatMultiLines;
|
|
||||||
:global IfThenElse;
|
|
||||||
|
|
||||||
:local FormatExpire do={
|
|
||||||
:global CharacterReplace;
|
|
||||||
:return [ $CharacterReplace [ $CharacterReplace [ :tostr $1 ] "w" "w " ] "d" "d " ];
|
|
||||||
}
|
|
||||||
|
|
||||||
:local FormatCertChain do={
|
|
||||||
:local Cert $1;
|
|
||||||
|
|
||||||
:global ParseKeyValueStore;
|
|
||||||
|
|
||||||
:local CertVal [ /certificate/get $Cert ];
|
|
||||||
|
|
||||||
:if ([ :typeof ($CertVal->"issuer") ] = "nothing") do={
|
|
||||||
:return "self-signed";
|
|
||||||
}
|
|
||||||
|
|
||||||
:local Return "";
|
|
||||||
:for I from=0 to=5 do={
|
|
||||||
:set Return ($Return . [ $ParseKeyValueStore ($CertVal->"issuer") ]->"CN");
|
|
||||||
:local CertSettings [ /certificate/settings/get ];
|
|
||||||
:if (([ :len ($CertSettings->"builtin-trust-anchors") ] > 0 || \
|
|
||||||
[ :len ($CertSettings->"builtin-trust-store") ] > 0) && \
|
|
||||||
[[ :parse (":return [ :len [ /certificate/builtin/find where skid=\"" . ($CertVal->"akid") . "\" ] ]") ]] > 0) do={
|
|
||||||
:return $Return;
|
|
||||||
}
|
|
||||||
:do {
|
|
||||||
:set CertVal [ /certificate/get [ find where skid=($CertVal->"akid") ] ];
|
|
||||||
} on-error={
|
|
||||||
:return ($Return . " (possibly incomplete!)");
|
|
||||||
}
|
|
||||||
:if (($CertVal->"akid") = "" || ($CertVal->"akid") = ($CertVal->"skid")) do={
|
|
||||||
:return $Return;
|
|
||||||
}
|
|
||||||
:set Return ($Return . " -> ");
|
|
||||||
}
|
|
||||||
:return ($Return . "...");
|
|
||||||
}
|
|
||||||
|
|
||||||
:local CertVal [ /certificate/get $Cert ];
|
|
||||||
|
|
||||||
:return ( \
|
|
||||||
[ $FormatLine "Name" ($CertVal->"name") ] . "\n" . \
|
|
||||||
[ $IfThenElse ([ :len ($CertVal->"common-name") ] > 0) ([ $FormatLine "CommonName" ($CertVal->"common-name") ] . "\n") ] . \
|
|
||||||
[ $IfThenElse ([ :len ($CertVal->"subject-alt-name") ] > 0) ([ $FormatMultiLines "SubjectAltNames" ($CertVal->"subject-alt-name") ] . "\n") ] . \
|
|
||||||
[ $FormatLine "Private key" [ $IfThenElse (($CertVal->"private-key") = true) "available" "missing" ] ] . "\n" . \
|
|
||||||
[ $FormatLine "Fingerprint" ($CertVal->"fingerprint") ] . "\n" . \
|
|
||||||
[ $IfThenElse ([ :len ($CertVal->"ca") ] > 0) [ $FormatLine "Issuer" ($CertVal->"ca") ] [ $FormatLine "Issuer chain" [ $FormatCertChain $Cert ] ] ] . "\n" . \
|
|
||||||
"Validity:\n" . \
|
|
||||||
[ $FormatLine " from" ($CertVal->"invalid-before") ] . "\n" . \
|
|
||||||
[ $FormatLine " to" ($CertVal->"invalid-after") ] . "\n" . \
|
|
||||||
[ $FormatLine "Expires in" [ $IfThenElse (($CertVal->"expired") = true) "expired" [ $FormatExpire ($CertVal->"expires-after") ] ] ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
$WaitFullyConnected;
|
|
||||||
|
|
||||||
:foreach Cert in=[ /certificate/find where !revoked !ca !scep-url expires-after<$CertRenewTime ] do={
|
|
||||||
:local CertVal [ /certificate/get $Cert ];
|
|
||||||
:local LastName;
|
|
||||||
:local FetchName;
|
|
||||||
|
|
||||||
:do {
|
|
||||||
:if ([ :len $CertRenewUrl ] = 0) do={
|
|
||||||
$LogPrint info $ScriptName ("No CertRenewUrl given.");
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
$LogPrint info $ScriptName ("Attempting to renew certificate '" . ($CertVal->"name") . "'.");
|
|
||||||
|
|
||||||
:local ImportSuccess false;
|
|
||||||
: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 ] ];
|
|
||||||
:set FetchName $LastName;
|
|
||||||
:set ImportSuccess [ $CheckCertificatesDownloadImport $ScriptName $LastName $FetchName ];
|
|
||||||
:if ($ImportSuccess = false && [ :pick $LastName 0 2 ] = "*.") do={
|
|
||||||
:set FetchName ("star." . [ :pick $LastName 2 [ :len $LastName ] ]);
|
|
||||||
:set ImportSuccess [ $CheckCertificatesDownloadImport $ScriptName $LastName $FetchName ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:if ($ImportSuccess = false) do={ :error false; }
|
|
||||||
|
|
||||||
:if ([ :len ($CertVal->"fingerprint") ] > 0 && $CertVal->"fingerprint" != [ /certificate/get $Cert fingerprint ]) do={
|
|
||||||
$LogPrint debug $ScriptName ("Certificate '" . $CertVal->"name" . "' was updated in place.");
|
|
||||||
:set CertVal [ /certificate/get $Cert ];
|
|
||||||
} else={
|
|
||||||
$LogPrint debug $ScriptName ("Certificate '" . $CertVal->"name" . "' was not updated, but replaced.");
|
|
||||||
|
|
||||||
:local CertNew [ /certificate/find where name~("^" . [ $EscapeForRegEx [ $UrlEncode $FetchName ] ] . "\\.(p12|pem)_[0-9]+\$") \
|
|
||||||
(common-name=($CertVal->"common-name") or subject-alt-name~("(^|\\W)(DNS|IP):" . [ $EscapeForRegEx $LastName ] . "(\\W|\$)")) \
|
|
||||||
fingerprint!=[ :tostr ($CertVal->"fingerprint") ] expires-after>$CertRenewTime ];
|
|
||||||
:local CertNewVal [ /certificate/get $CertNew ];
|
|
||||||
|
|
||||||
:if ([ $CertificateAvailable ([ $ParseKeyValueStore ($CertNewVal->"issuer") ]->"CN") "fetch" ] = false) do={
|
|
||||||
$LogPrint warning $ScriptName ("The certificate chain is not available!");
|
|
||||||
}
|
|
||||||
|
|
||||||
:if (($CertVal->"private-key") = true && ($CertVal->"private-key") != ($CertNewVal->"private-key")) do={
|
|
||||||
/certificate/remove $CertNew;
|
|
||||||
$LogPrint warning $ScriptName ("Old certificate '" . ($CertVal->"name") . "' has a private key, new certificate does not. Aborting renew.");
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/ip/service/set certificate=($CertNewVal->"name") [ find where certificate=($CertVal->"name") ];
|
|
||||||
|
|
||||||
/ip/ipsec/identity/set certificate=($CertNewVal->"name") [ find where certificate=($CertVal->"name") ];
|
|
||||||
/ip/ipsec/identity/set remote-certificate=($CertNewVal->"name") [ find where remote-certificate=($CertVal->"name") ];
|
|
||||||
|
|
||||||
/ip/hotspot/profile/set ssl-certificate=($CertNewVal->"name") [ find where ssl-certificate=($CertVal->"name") ];
|
|
||||||
|
|
||||||
/certificate/remove $Cert;
|
|
||||||
/certificate/set $CertNew name=($CertVal->"name");
|
|
||||||
:set Cert $CertNew;
|
|
||||||
:set CertVal [ /certificate/get $CertNew ];
|
|
||||||
}
|
|
||||||
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; silent=true; \
|
|
||||||
subject=([ $SymbolForNotification "lock-with-ink-pen" ] . "Certificate renewed: " . ($CertVal->"name")); \
|
|
||||||
message=("A certificate on " . $Identity . " has been renewed.\n\n" . [ $FormatInfo $Cert ]) });
|
|
||||||
$LogPrint info $ScriptName ("The certificate '" . ($CertVal->"name") . "' has been renewed.");
|
|
||||||
} on-error={
|
|
||||||
$LogPrint debug $ScriptName ("Could not renew certificate '" . ($CertVal->"name") . "'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
: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={
|
|
||||||
$LogPrint debug $ScriptName ("Certificate '" . ($CertVal->"name") . "' is handled by SCEP, skipping.");
|
|
||||||
} else={
|
|
||||||
:local State [ $IfThenElse (($CertVal->"expired") = true) "expired" "is about to expire" ];
|
|
||||||
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "lock-with-ink-pen,warning-sign" ] . "Certificate warning: " . ($CertVal->"name")); \
|
|
||||||
message=("A certificate on " . $Identity . " " . $State . ".\n\n" . [ $FormatInfo $Cert ]) });
|
|
||||||
$LogPrint info $ScriptName ("The certificate '" . ($CertVal->"name") . "' " . $State . \
|
|
||||||
", it is invalid after " . ($CertVal->"invalid-after") . ".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
95
check-health
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: check-health
|
||||||
|
# Copyright (c) 2019-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# check for RouterOS health state
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/check-health.md
|
||||||
|
|
||||||
|
:global CheckHealthLast;
|
||||||
|
:global CheckHealthTemperature;
|
||||||
|
:global CheckHealthTemperatureDeviation;
|
||||||
|
:global CheckHealthTemperatureNotified;
|
||||||
|
:global CheckHealthVoltagePercent;
|
||||||
|
:global Identity;
|
||||||
|
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global SendNotification;
|
||||||
|
:global SymbolForNotification;
|
||||||
|
|
||||||
|
:local FormatVoltage do={
|
||||||
|
:local Voltage [ :tonum $1 ];
|
||||||
|
:return (($Voltage / 10) . "." . [ :pick $Voltage ([ :len $Voltage ] - 1) ] . "V");
|
||||||
|
}
|
||||||
|
|
||||||
|
:local CheckHealthCurrent [ / system health get ];
|
||||||
|
|
||||||
|
:if ([ :len $CheckHealthCurrent ] = 0) do={
|
||||||
|
$LogPrintExit error ("Your device does not provide any health values.") true;
|
||||||
|
}
|
||||||
|
|
||||||
|
:if ([ :typeof $CheckHealthTemperatureNotified ] != "array") do={
|
||||||
|
:set CheckHealthTemperatureNotified [ :toarray "" ];
|
||||||
|
}
|
||||||
|
|
||||||
|
:foreach Name,Voltage in=$CheckHealthCurrent do={
|
||||||
|
:if ($Name ~ "(battery|voltage)" && \
|
||||||
|
[ :typeof ($CheckHealthLast->$Name) ] = "num" && \
|
||||||
|
[ :typeof $Voltage ] = "num") do={
|
||||||
|
:if ($CheckHealthLast->$Name * (100 + $CheckHealthVoltagePercent) < $Voltage * 100 || \
|
||||||
|
$CheckHealthLast->$Name * 100 > $Voltage * (100 + $CheckHealthVoltagePercent)) do={
|
||||||
|
$SendNotification ([ $SymbolForNotification "high-voltage-sign" ] . "Health warning: " . $Name) \
|
||||||
|
("The " . $Name . " on " . $Identity . " jumped more than " . $CheckHealthVoltagePercent . "%.\n\n" . \
|
||||||
|
"old value: " . [ $FormatVoltage ($CheckHealthLast->$Name) ] . "\n" . \
|
||||||
|
"new value: " . [ $FormatVoltage $Voltage ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:foreach Name,PSU in=$CheckHealthCurrent do={
|
||||||
|
:if ($Name ~ "psu.*-state" && \
|
||||||
|
[ :typeof ($CheckHealthLast->$Name) ] = "str" && \
|
||||||
|
[ :typeof $PSU ] = "str") do={
|
||||||
|
:if ($CheckHealthLast->$Name = "ok" && \
|
||||||
|
$PSU != "ok") do={
|
||||||
|
$SendNotification ([ $SymbolForNotification "cross-mark" ] . "Health warning: " . $Name) \
|
||||||
|
("The power supply unit '" . $Name . "' on " . $Identity . " failed!");
|
||||||
|
}
|
||||||
|
:if ($CheckHealthLast->$Name != "ok" && \
|
||||||
|
$PSU = "ok") do={
|
||||||
|
$SendNotification ([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name) \
|
||||||
|
("The power supply unit '" . $Name . "' on " . $Identity . " recovered!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:foreach Name,Temperature in=$CheckHealthCurrent do={
|
||||||
|
:if ($Name ~ "temperature" && \
|
||||||
|
[ :typeof $Temperature ] = "num") do={
|
||||||
|
:if ([ :typeof ($CheckHealthTemperature->$Name) ] != "num" ) do={
|
||||||
|
$LogPrintExit info ("No threshold given for " . $Name . ", assuming 50C.") false;
|
||||||
|
:set ($CheckHealthTemperature->$Name) 50;
|
||||||
|
}
|
||||||
|
:local Validate [ / system health get $Name ];
|
||||||
|
:while ($Temperature != $Validate) do={
|
||||||
|
:set Temperature $Validate;
|
||||||
|
:set Validate [ / system health get $Name ];
|
||||||
|
}
|
||||||
|
:if ($Temperature > $CheckHealthTemperature->$Name && \
|
||||||
|
$CheckHealthTemperatureNotified->$Name != true) do={
|
||||||
|
$SendNotification ([ $SymbolForNotification "fire" ] . "Health warning: " . $Name) \
|
||||||
|
("The " . $Name . " on " . $Identity . " is above threshold: " . \
|
||||||
|
$Temperature . "\C2\B0" . "C");
|
||||||
|
:set ($CheckHealthTemperatureNotified->$Name) true;
|
||||||
|
}
|
||||||
|
:if ($Temperature <= ($CheckHealthTemperature->$Name - $CheckHealthTemperatureDeviation) && \
|
||||||
|
$CheckHealthTemperatureNotified->$Name = true) do={
|
||||||
|
$SendNotification ([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name) \
|
||||||
|
("The " . $Name . " on " . $Identity . " dropped below threshold: " . \
|
||||||
|
$Temperature . "\C2\B0" . "C");
|
||||||
|
:set ($CheckHealthTemperatureNotified->$Name) false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:set CheckHealthLast $CheckHealthCurrent;
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: check-health.d/state
|
|
||||||
# Copyright (c) 2019-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# check for RouterOS health state - state plugin
|
|
||||||
# https://rsc.eworm.de/doc/check-health.md
|
|
||||||
|
|
||||||
:global CheckHealthPlugins;
|
|
||||||
|
|
||||||
:set ($CheckHealthPlugins->[ :jobname ]) do={
|
|
||||||
:local FuncName [ :tostr $0 ];
|
|
||||||
:local ScriptName [ :tostr $1 ];
|
|
||||||
|
|
||||||
:global CheckHealthLast;
|
|
||||||
:global Identity;
|
|
||||||
|
|
||||||
:global LogPrint;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
|
|
||||||
:if ([ :len [ /system/health/find where type="" name~"-state\$"] ] = 0) do={
|
|
||||||
$LogPrint debug $FuncName ("Your device does not provide any state health values.");
|
|
||||||
:return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:foreach State in=[ /system/health/find where type="" name~"-state\$" ] do={
|
|
||||||
:local Name [ /system/health/get $State name ];
|
|
||||||
:local Value [ /system/health/get $State value ];
|
|
||||||
|
|
||||||
:if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
|
|
||||||
:if ($CheckHealthLast->$Name = "ok" && \
|
|
||||||
$Value != "ok") do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "cross-mark" ] . "Health warning: " . $Name); \
|
|
||||||
message=("The device '" . $Name . "' on " . $Identity . " failed!") });
|
|
||||||
}
|
|
||||||
:if ($CheckHealthLast->$Name != "ok" && \
|
|
||||||
$Value = "ok") do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \
|
|
||||||
message=("The device '" . $Name . "' on " . $Identity . " recovered!") });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:set ($CheckHealthLast->$Name) $Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: check-health.d/temperature
|
|
||||||
# Copyright (c) 2019-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# check for RouterOS health state - temperature plugin
|
|
||||||
# https://rsc.eworm.de/doc/check-health.md
|
|
||||||
|
|
||||||
:global CheckHealthPlugins;
|
|
||||||
|
|
||||||
:set ($CheckHealthPlugins->[ :jobname ]) do={
|
|
||||||
:local FuncName [ :tostr $0 ];
|
|
||||||
:local ScriptName [ :tostr $1 ];
|
|
||||||
|
|
||||||
:global CheckHealthLast;
|
|
||||||
:global CheckHealthTemperature;
|
|
||||||
:global CheckHealthTemperatureDeviation;
|
|
||||||
:global CheckHealthTemperatureNotified;
|
|
||||||
:global Identity;
|
|
||||||
|
|
||||||
:global LogPrint;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
|
|
||||||
:if ([ :len [ /system/health/find where type="C" ] ] = 0) do={
|
|
||||||
$LogPrint debug $FuncName ("Your device does not provide any voltage health values.");
|
|
||||||
:return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local TempToNum do={
|
|
||||||
:global CharacterReplace;
|
|
||||||
:local T [ :toarray [ $CharacterReplace $1 "." "," ] ];
|
|
||||||
:return ($T->0 * 10 + $T->1);
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :typeof $CheckHealthTemperatureNotified ] != "array") do={
|
|
||||||
:set CheckHealthTemperatureNotified ({});
|
|
||||||
}
|
|
||||||
|
|
||||||
:foreach Temperature in=[ /system/health/find where type="C" ] do={
|
|
||||||
:local Name [ /system/health/get $Temperature name ];
|
|
||||||
:local Value [ /system/health/get $Temperature value ];
|
|
||||||
|
|
||||||
:if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
|
|
||||||
:if ([ :typeof ($CheckHealthTemperature->$Name) ] != "num" ) do={
|
|
||||||
$LogPrint info $FuncName ("No threshold given for " . $Name . ", assuming 50C.");
|
|
||||||
:set ($CheckHealthTemperature->$Name) 50;
|
|
||||||
}
|
|
||||||
:local Validate [ /system/health/get [ find where name=$Name ] value ];
|
|
||||||
:while ($Value != $Validate) do={
|
|
||||||
:set Value $Validate;
|
|
||||||
:set Validate [ /system/health/get [ find where name=$Name ] value ];
|
|
||||||
}
|
|
||||||
:if ($Value > $CheckHealthTemperature->$Name && \
|
|
||||||
$CheckHealthTemperatureNotified->$Name != true) do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "fire" ] . "Health warning: " . $Name); \
|
|
||||||
message=("The " . $Name . " on " . $Identity . " is above threshold: " . \
|
|
||||||
$Value . "\C2\B0" . "C") });
|
|
||||||
:set ($CheckHealthTemperatureNotified->$Name) true;
|
|
||||||
}
|
|
||||||
:if ($Value <= ($CheckHealthTemperature->$Name - $CheckHealthTemperatureDeviation) && \
|
|
||||||
$CheckHealthTemperatureNotified->$Name = true) do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \
|
|
||||||
message=("The " . $Name . " on " . $Identity . " dropped below threshold: " . \
|
|
||||||
$Value . "\C2\B0" . "C") });
|
|
||||||
:set ($CheckHealthTemperatureNotified->$Name) false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:set ($CheckHealthLast->$Name) $Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: check-health.d/voltage
|
|
||||||
# Copyright (c) 2019-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# check for RouterOS health state - voltage plugin
|
|
||||||
# https://rsc.eworm.de/doc/check-health.md
|
|
||||||
|
|
||||||
:global CheckHealthPlugins;
|
|
||||||
|
|
||||||
:set ($CheckHealthPlugins->[ :jobname ]) do={
|
|
||||||
:local FuncName [ :tostr $0 ];
|
|
||||||
:local ScriptName [ :tostr $1 ];
|
|
||||||
|
|
||||||
:global CheckHealthLast;
|
|
||||||
:global CheckHealthVoltageLow;
|
|
||||||
:global CheckHealthVoltagePercent;
|
|
||||||
:global Identity;
|
|
||||||
|
|
||||||
:global FormatLine;
|
|
||||||
:global IfThenElse;
|
|
||||||
:global LogPrint;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
|
|
||||||
:if ([ :len [ /system/health/find where type="V" ] ] = 0) do={
|
|
||||||
$LogPrint debug $FuncName ("Your device does not provide any voltage health values.");
|
|
||||||
:return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:foreach Voltage in=[ /system/health/find where type="V" ] do={
|
|
||||||
:local Name [ /system/health/get $Voltage name ];
|
|
||||||
:local Value [ /system/health/get $Voltage value ];
|
|
||||||
|
|
||||||
:if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
|
|
||||||
:local NumCurr [ $TempToNum $Value ];
|
|
||||||
:local NumLast [ $TempToNum ($CheckHealthLast->$Name) ];
|
|
||||||
|
|
||||||
:if ($NumLast * (100 + $CheckHealthVoltagePercent) < $NumCurr * 100 || \
|
|
||||||
$NumLast * 100 > $NumCurr * (100 + $CheckHealthVoltagePercent)) do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification ("high-voltage-sign,chart-" . [ $IfThenElse ($NumLast < \
|
|
||||||
$NumCurr) "in" "de" ] . "creasing") ] . "Health warning: " . $Name); \
|
|
||||||
message=("The " . $Name . " on " . $Identity . " jumped more than " . $CheckHealthVoltagePercent . "%.\n\n" . \
|
|
||||||
[ $FormatLine "old value" ($CheckHealthLast->$Name . " V") 12 ] . "\n" . \
|
|
||||||
[ $FormatLine "new value" ($Value . " V") 12 ]) });
|
|
||||||
} else={
|
|
||||||
:if ($NumCurr <= $CheckHealthVoltageLow && $NumLast > $CheckHealthVoltageLow) do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "high-voltage-sign,chart-decreasing" ] . "Health warning: Low " . $Name); \
|
|
||||||
message=("The " . $Name . " on " . $Identity . " dropped to " . $Value . " V below hard limit.") });
|
|
||||||
}
|
|
||||||
:if ($NumCurr > $CheckHealthVoltageLow && $NumLast <= $CheckHealthVoltageLow) do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "high-voltage-sign,chart-increasing" ] . "Health recovery: Low " . $Name); \
|
|
||||||
message=("The " . $Name . " on " . $Identity . " recovered to " . $Value . " V above hard limit.") });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:set ($CheckHealthLast->$Name) $Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
110
check-health.rsc
|
|
@ -1,110 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: check-health
|
|
||||||
# Copyright (c) 2019-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# check for RouterOS health state
|
|
||||||
# https://rsc.eworm.de/doc/check-health.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 CheckHealthCPUUtilization;
|
|
||||||
:global CheckHealthCPUUtilizationNotified;
|
|
||||||
:global CheckHealthLast;
|
|
||||||
:global CheckHealthRAMUtilizationNotified;
|
|
||||||
:global Identity;
|
|
||||||
|
|
||||||
:global FormatLine;
|
|
||||||
:global HumanReadableNum;
|
|
||||||
:global IfThenElse;
|
|
||||||
:global LogPrint;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
:global ValidateSyntax;
|
|
||||||
|
|
||||||
:local TempToNum do={
|
|
||||||
:global CharacterReplace;
|
|
||||||
:local T [ :toarray [ $CharacterReplace $1 "." "," ] ];
|
|
||||||
:return ($T->0 * 10 + $T->1);
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local Resource [ /system/resource/get ];
|
|
||||||
|
|
||||||
:set CheckHealthCPUUtilization (($CheckHealthCPUUtilization * 4 + ($Resource->"cpu-load") * 10) / 5);
|
|
||||||
:if ($CheckHealthCPUUtilization > 750 && $CheckHealthCPUUtilizationNotified != true) do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "abacus,chart-increasing" ] . "Health warning: CPU utilization"); \
|
|
||||||
message=("The average CPU utilization on " . $Identity . " is at " . ($CheckHealthCPUUtilization / 10) . "%!") });
|
|
||||||
:set CheckHealthCPUUtilizationNotified true;
|
|
||||||
}
|
|
||||||
:if ($CheckHealthCPUUtilization < 650 && $CheckHealthCPUUtilizationNotified = true) do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "abacus,chart-decreasing" ] . "Health recovery: CPU utilization"); \
|
|
||||||
message=("The average CPU utilization on " . $Identity . " decreased to " . ($CheckHealthCPUUtilization / 10) . "%.") });
|
|
||||||
:set CheckHealthCPUUtilizationNotified false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local CheckHealthRAMUtilization (($Resource->"total-memory" - $Resource->"free-memory") * 100 / $Resource->"total-memory");
|
|
||||||
:if ($CheckHealthRAMUtilization >=80 && $CheckHealthRAMUtilizationNotified != true) do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "card-file-box,chart-increasing" ] . "Health warning: RAM utilization"); \
|
|
||||||
message=("The RAM utilization on " . $Identity . " is at " . $CheckHealthRAMUtilization . "%!\n\n" . \
|
|
||||||
[ $FormatLine "total" ([ $HumanReadableNum ($Resource->"total-memory") 1024 ] . "B") 8 ] . "\n" . \
|
|
||||||
[ $FormatLine "used" ([ $HumanReadableNum ($Resource->"total-memory" - $Resource->"free-memory") 1024 ] . "B") 8 ] . "\n" . \
|
|
||||||
[ $FormatLine "free" ([ $HumanReadableNum ($Resource->"free-memory") 1024 ] . "B") 8 ]) });
|
|
||||||
:set CheckHealthRAMUtilizationNotified true;
|
|
||||||
}
|
|
||||||
:if ($CheckHealthRAMUtilization < 70 && $CheckHealthRAMUtilizationNotified = true) do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "card-file-box,chart-decreasing" ] . "Health recovery: RAM utilization"); \
|
|
||||||
message=("The RAM utilization on " . $Identity . " decreased to " . $CheckHealthRAMUtilization . "%.") });
|
|
||||||
:set CheckHealthRAMUtilizationNotified false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local Plugins [ /system/script/find where name~"^check-health\\.d/." ];
|
|
||||||
:if ([ :len $Plugins ] = 0) do={
|
|
||||||
$LogPrint debug $ScriptName ("No plugins installed.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global CheckHealthPlugins ({});
|
|
||||||
:if ([ :typeof $CheckHealthLast ] != "array") do={
|
|
||||||
:set CheckHealthLast ({});
|
|
||||||
}
|
|
||||||
|
|
||||||
:foreach Plugin in=$Plugins do={
|
|
||||||
:local PluginVal [ /system/script/get $Plugin ];
|
|
||||||
:if ([ $ValidateSyntax ($PluginVal->"source") ] = true) do={
|
|
||||||
:onerror Err {
|
|
||||||
/system/script/run $Plugin;
|
|
||||||
} do={
|
|
||||||
$LogPrint error $ScriptName ("Plugin '" . $PluginVal->"name" . "' failed to run: " . $Err);
|
|
||||||
}
|
|
||||||
} else={
|
|
||||||
$LogPrint error $ScriptName ("Plugin '" . $PluginVal->"name" . "' failed syntax validation, skipping.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:foreach PluginName,Discard in=$CheckHealthPlugins do={
|
|
||||||
($CheckHealthPlugins->$PluginName) \
|
|
||||||
("\$CheckHealthPlugins->\"" . $PluginName . "\"") $ScriptName;
|
|
||||||
}
|
|
||||||
|
|
||||||
:set CheckHealthPlugins;
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
41
check-lte-firmware-upgrade
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: check-lte-firmware-upgrade
|
||||||
|
# Copyright (c) 2018-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# check for LTE firmware upgrade, send notification
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/check-lte-firmware-upgrade.md
|
||||||
|
|
||||||
|
:global Identity;
|
||||||
|
:global SentLteFirmwareUpgradeNotification;
|
||||||
|
|
||||||
|
:global CharacterReplace;
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global SendNotification;
|
||||||
|
:global SymbolForNotification;
|
||||||
|
|
||||||
|
:foreach Interface in=[ / interface lte find ] do={
|
||||||
|
:local IntName [ / interface lte get $Interface name ];
|
||||||
|
:do {
|
||||||
|
:local Firmware [ / interface lte firmware-upgrade $Interface once as-value ];
|
||||||
|
|
||||||
|
:if ($SentLteFirmwareUpgradeNotification = ($Firmware->"latest")) do={
|
||||||
|
$LogPrintExit debug ("Already sent the LTE firmware upgrade notification for version " . \
|
||||||
|
($Firmware->"latest") . ".") false;
|
||||||
|
} else={
|
||||||
|
:if (($Firmware->"installed") != ($Firmware->"latest")) do={
|
||||||
|
:local Info [ / interface lte info $Interface once as-value ];
|
||||||
|
$SendNotification ([ $SymbolForNotification "sparkles" ] . "LTE firmware upgrade") \
|
||||||
|
("A new firmware version " . ($Firmware->"latest") . " is available for " . \
|
||||||
|
"LTE interface " . $IntName . " on " . $Identity . ".\n\n" . \
|
||||||
|
"Interface: " . [ $CharacterReplace ($Info->"manufacturer" . " " . $Info->"model") ("\"") "" ] . "\n" . \
|
||||||
|
"Installed: " . ($Firmware->"installed") . "\n" . \
|
||||||
|
"Available: " . ($Firmware->"latest")) "" "" "true";
|
||||||
|
:set SentLteFirmwareUpgradeNotification ($Firmware->"latest");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} on-error={
|
||||||
|
$LogPrintExit debug ("Could not get latest LTE firmware version for interface " . \
|
||||||
|
$IntName . ".") false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: check-lte-firmware-upgrade
|
|
||||||
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# check for LTE firmware upgrade, send notification
|
|
||||||
# https://rsc.eworm.de/doc/check-lte-firmware-upgrade.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 SentLteFirmwareUpgradeNotification;
|
|
||||||
|
|
||||||
:global ScriptLock;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :typeof $SentLteFirmwareUpgradeNotification ] != "array") do={
|
|
||||||
:global SentLteFirmwareUpgradeNotification ({});
|
|
||||||
}
|
|
||||||
|
|
||||||
:local CheckInterface do={
|
|
||||||
:local ScriptName $1;
|
|
||||||
:local Interface $2;
|
|
||||||
|
|
||||||
:global Identity;
|
|
||||||
:global SentLteFirmwareUpgradeNotification;
|
|
||||||
|
|
||||||
:global FormatLine;
|
|
||||||
:global IfThenElse;
|
|
||||||
:global LogPrint;
|
|
||||||
:global ScriptFromTerminal;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
|
|
||||||
:local IntName [ /interface/lte/get $Interface name ];
|
|
||||||
:local Firmware;
|
|
||||||
:local Info;
|
|
||||||
:onerror Err {
|
|
||||||
:set Firmware [ /interface/lte/firmware-upgrade $Interface as-value ];
|
|
||||||
:set Info [ /interface/lte/monitor $Interface once as-value ];
|
|
||||||
} do={
|
|
||||||
$LogPrint debug $ScriptName ("Could not get latest LTE firmware version for interface " . \
|
|
||||||
$IntName . ": " . $Err);
|
|
||||||
:return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len ($Firmware->"latest") ] = 0) do={
|
|
||||||
$LogPrint info $ScriptName ("An empty string is not a valid version.");
|
|
||||||
:return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if (($Firmware->"installed") = ($Firmware->"latest")) do={
|
|
||||||
:if ([ $ScriptFromTerminal $ScriptName ] = true) do={
|
|
||||||
$LogPrint info $ScriptName ("No firmware upgrade available for LTE interface " . $IntName . ".");
|
|
||||||
}
|
|
||||||
:return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $ScriptFromTerminal $ScriptName ] = true && \
|
|
||||||
[ :len [ /system/script/find where name="unattended-lte-firmware-upgrade" ] ] > 0) do={
|
|
||||||
:put ("Do you want to start unattended lte firmware upgrade for interface " . $IntName . "? [y/N]");
|
|
||||||
:if (([ /terminal/inkey timeout=60 ] % 32) = 25) do={
|
|
||||||
/system/script/run unattended-lte-firmware-upgrade;
|
|
||||||
$LogPrint info $ScriptName ("Scheduled lte firmware upgrade for interface " . $IntName . "...");
|
|
||||||
:return true;
|
|
||||||
} else={
|
|
||||||
:put "Canceled...";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:if (($SentLteFirmwareUpgradeNotification->$IntName) = ($Firmware->"latest")) do={
|
|
||||||
$LogPrint debug $ScriptName ("Already sent the LTE firmware upgrade notification for version " . \
|
|
||||||
($Firmware->"latest") . ".");
|
|
||||||
:return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$LogPrint info $ScriptName ("A new firmware version " . ($Firmware->"latest") . " is available for " . \
|
|
||||||
"LTE interface " . $IntName . ".");
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "sparkles" ] . "LTE firmware upgrade"); \
|
|
||||||
message=("A new firmware version " . ($Firmware->"latest") . " is available for " . \
|
|
||||||
"LTE interface " . $IntName . " on " . $Identity . ".\n\n" . \
|
|
||||||
[ $IfThenElse ([ :len ($Info->"manufacturer") ] > 0) ([ $FormatLine "Manufacturer" ($Info->"manufacturer") ] . "\n") ] . \
|
|
||||||
[ $IfThenElse ([ :len ($Info->"model") ] > 0) ([ $FormatLine "Model" ($Info->"model") ] . "\n") ] . \
|
|
||||||
[ $IfThenElse ([ :len ($Info->"revision") ] > 0) ([ $FormatLine "Revision" ($Info->"revision") ] . "\n") ] . \
|
|
||||||
"Firmware version:\n" . \
|
|
||||||
[ $FormatLine " Installed" ($Firmware->"installed") ] . "\n" . \
|
|
||||||
[ $FormatLine " Available" ($Firmware->"latest") ]); silent=true });
|
|
||||||
:set ($SentLteFirmwareUpgradeNotification->$IntName) ($Firmware->"latest");
|
|
||||||
}
|
|
||||||
|
|
||||||
:foreach Interface in=[ /interface/lte/find ] do={
|
|
||||||
$CheckInterface $ScriptName $Interface;
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: check-perpetual-license
|
|
||||||
# Copyright (c) 2025-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# check perpetual license on CHR
|
|
||||||
# https://rsc.eworm.de/doc/check-perpetual-license.md
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global Identity;
|
|
||||||
:global SentCertificateNotification;
|
|
||||||
|
|
||||||
:global LogPrint;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
:global WaitFullyConnected;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$WaitFullyConnected;
|
|
||||||
|
|
||||||
:local License [ /system/license/get ];
|
|
||||||
:if ([ :typeof ($License->"deadline-at") ] != "str") do={
|
|
||||||
$LogPrint info $ScriptName ("This device does not have a perpetual license.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len ($License->"next-renewal-at") ] = 0 && ($License->"limited-upgrades") = true) do={
|
|
||||||
$LogPrint warning $ScriptName ("Your license expired on " . ($License->"deadline-at") . "!");
|
|
||||||
:if ($SentCertificateNotification != "expired") do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "scroll,cross-mark" ] . "License expired!"); \
|
|
||||||
message=("Your license expired on " . ($License->"deadline-at") . \
|
|
||||||
", can no longer update RouterOS on " . $Identity . "...") });
|
|
||||||
:set SentCertificateNotification "expired";
|
|
||||||
}
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :totime ($License->"deadline-at") ] - 3w < [ :timestamp ]) do={
|
|
||||||
$LogPrint warning $ScriptName ("Your license will expire on " . ($License->"deadline-at") . "!");
|
|
||||||
:if ($SentCertificateNotification != "warning") do={
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "scroll,warning-sign" ] . "License about to expire!"); \
|
|
||||||
message=("Your license failed to renew and is about to expire on " . \
|
|
||||||
($License->"deadline-at") . " on " . $Identity . "...") });
|
|
||||||
:set SentCertificateNotification "warning";
|
|
||||||
}
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :typeof $SentCertificateNotification ] = "str" && \
|
|
||||||
[ :totime ($License->"deadline-at") ] - 4w > [ :timestamp ]) do={
|
|
||||||
$LogPrint info $ScriptName ("Your license was successfully renewed.");
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "scroll,white-heavy-check-mark" ] . "License renewed"); \
|
|
||||||
message=("Your license was successfully renewed on " . $Identity . \
|
|
||||||
". It is now valid until " . ($License->"deadline-at") . ".") });
|
|
||||||
:set SentCertificateNotification;
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
123
check-routeros-update
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: check-routeros-update
|
||||||
|
# Copyright (c) 2013-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# check for RouterOS update, send notification and/or install
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/check-routeros-update.md
|
||||||
|
|
||||||
|
:global Identity;
|
||||||
|
:global SafeUpdateNeighbor;
|
||||||
|
:global SafeUpdatePatch;
|
||||||
|
:global SafeUpdateUrl;
|
||||||
|
:global SentRouterosUpdateNotification;
|
||||||
|
|
||||||
|
:global DeviceInfo;
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global ScriptFromTerminal;
|
||||||
|
:global SendNotification;
|
||||||
|
:global SymbolForNotification;
|
||||||
|
:global VersionToNum;
|
||||||
|
|
||||||
|
:local DoUpdate do={
|
||||||
|
:if ([ :len [ / system script find where name="packages-update" ] ] > 0) do={
|
||||||
|
/ system script run packages-update;
|
||||||
|
} else={
|
||||||
|
/ system package update install without-paging;
|
||||||
|
}
|
||||||
|
:error "Waiting for system to reboot.";
|
||||||
|
}
|
||||||
|
|
||||||
|
:if ([ :len [ / system package find where name="wireless" disabled=no ] ] > 0) do={
|
||||||
|
:if ([ / interface wireless cap get enabled ] = true && \
|
||||||
|
[ / caps-man manager get enabled ] = false) do={
|
||||||
|
$LogPrintExit error "System is managed by CAPsMAN, not checking." true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:if ([ :len [ / system scheduler find where name="reboot-for-update" ] ] > 0) do={
|
||||||
|
:error "A reboot for update is already scheduled.";
|
||||||
|
}
|
||||||
|
|
||||||
|
/ system package update check-for-updates without-paging;
|
||||||
|
:local Update [ / system package update get ];
|
||||||
|
|
||||||
|
:if ([ :len ($Update->"latest-version") ] = 0) do={
|
||||||
|
$LogPrintExit info "An empty string is not a valid version." true;
|
||||||
|
}
|
||||||
|
|
||||||
|
:local NumInstalled [ $VersionToNum ($Update->"installed-version") ];
|
||||||
|
:local NumLatest [ $VersionToNum ($Update->"latest-version") ];
|
||||||
|
:local Link ("https://mikrotik.com/download/changelogs/" . $Update->"channel" . "-release-tree");
|
||||||
|
|
||||||
|
:if ($NumInstalled < $NumLatest) do={
|
||||||
|
:if ($SafeUpdatePatch = true && ($NumInstalled & 0xffff0000) = ($NumLatest & 0xffff0000)) do={
|
||||||
|
$LogPrintExit info ("Version " . $Update->"latest-version" . " is a patch release, updating...") false;
|
||||||
|
$SendNotification ([ $SymbolForNotification "sparkles" ] . "RouterOS update") \
|
||||||
|
("Version " . $Update->"latest-version" . " is a patch update for " . $Update->"channel" . \
|
||||||
|
", updating on " . $Identity . "...") $Link "" "true";
|
||||||
|
$DoUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
:if ($SafeUpdateNeighbor = true && [ :len [ / ip neighbor find where \
|
||||||
|
version=($Update->"latest-version" . " (" . $Update->"channel" . ")") ] ] > 0) do={
|
||||||
|
$LogPrintExit info ("Seen a neighbor running version " . $Update->"latest-version" . ", updating...") false;
|
||||||
|
$SendNotification ([ $SymbolForNotification "sparkles" ] . "RouterOS update") \
|
||||||
|
("Seen a neighbor running version " . $Update->"latest-version" . " from " . $Update->"channel" . \
|
||||||
|
", updating on " . $Identity . "...") $Link "" "true";
|
||||||
|
$DoUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
:if ([ :len $SafeUpdateUrl ] > 0) do={
|
||||||
|
:local Result;
|
||||||
|
:do {
|
||||||
|
:set Result [ / tool fetch check-certificate=yes-without-crl \
|
||||||
|
($SafeUpdateUrl . $Update->"channel" . "?installed=" . $Update->"installed-version" . \
|
||||||
|
"&latest=" . $Update->"latest-version") output=user as-value ];
|
||||||
|
} on-error={
|
||||||
|
$LogPrintExit warning ("Failed receiving safe version for " . $Update->"channel" . ".") false;
|
||||||
|
}
|
||||||
|
:if ($Result->"status" = "finished" && $Result->"data" = $Update->"latest-version") do={
|
||||||
|
$LogPrintExit info ("Version " . $Update->"latest-version" . " is considered safe, updating...") false;
|
||||||
|
$SendNotification ([ $SymbolForNotification "sparkles" ] . "RouterOS update") \
|
||||||
|
("Version " . $Update->"latest-version" . " is considered safe for " . $Update->"channel" . \
|
||||||
|
", updating on " . $Identity . "...") $Link "" "true";
|
||||||
|
$DoUpdate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:if ([ $ScriptFromTerminal "check-routeros-update" ] = true) do={
|
||||||
|
:put ("Do you want to install RouterOS version " . $Update->"latest-version" . "? [y/N]");
|
||||||
|
:if (([ :terminal inkey timeout=60 ] % 32) = 25) do={
|
||||||
|
$DoUpdate;
|
||||||
|
} else={
|
||||||
|
:put "Canceled...";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:if ($SentRouterosUpdateNotification = $Update->"latest-version") do={
|
||||||
|
$LogPrintExit info ("Already sent the RouterOS update notification for version " . \
|
||||||
|
$Update->"latest-version" . ".") true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$SendNotification ([ $SymbolForNotification "sparkles" ] . "RouterOS update") \
|
||||||
|
("A new RouterOS version " . ($Update->"latest-version") . \
|
||||||
|
" is available for " . $Identity . ".\n\n" . \
|
||||||
|
[ $DeviceInfo ]) $Link "" "true";
|
||||||
|
:set SentRouterosUpdateNotification ($Update->"latest-version");
|
||||||
|
}
|
||||||
|
|
||||||
|
:if ($NumInstalled > $NumLatest) do={
|
||||||
|
:if ($SentRouterosUpdateNotification = $Update->"latest-version") do={
|
||||||
|
$LogPrintExit info ("Already sent the RouterOS downgrade notification for version " . \
|
||||||
|
$Update->"latest-version" . ".") true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$SendNotification ([ $SymbolForNotification "warning-sign" ] . "RouterOS version") \
|
||||||
|
("A different RouterOS version " . ($Update->"latest-version") . \
|
||||||
|
" is available for " . $Identity . ", but it is a downgrade.\n\n" . \
|
||||||
|
[ $DeviceInfo ]) $Link "" "true";
|
||||||
|
$LogPrintExit info ("A different RouterOS version " . ($Update->"latest-version") . \
|
||||||
|
" is available for downgrade.") false;
|
||||||
|
:set SentRouterosUpdateNotification ($Update->"latest-version");
|
||||||
|
}
|
||||||
|
|
@ -1,222 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: check-routeros-update
|
|
||||||
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
# requires device-mode, fetch, scheduler
|
|
||||||
#
|
|
||||||
# check for RouterOS update, send notification and/or install
|
|
||||||
# https://rsc.eworm.de/doc/check-routeros-update.md
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global Identity;
|
|
||||||
:global SafeUpdateAll;
|
|
||||||
:global SafeUpdateNeighbor;
|
|
||||||
:global SafeUpdateNeighborIdentity;
|
|
||||||
:global SafeUpdatePatch;
|
|
||||||
:global SafeUpdateUrl;
|
|
||||||
:global SentRouterosUpdateNotification;
|
|
||||||
|
|
||||||
:global DeviceInfo;
|
|
||||||
:global EscapeForRegEx;
|
|
||||||
:global FetchUserAgentStr;
|
|
||||||
:global LogPrint;
|
|
||||||
:global RebootForUpdate;
|
|
||||||
:global ScriptFromTerminal;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
:global VersionToNum;
|
|
||||||
:global WaitFullyConnected;
|
|
||||||
|
|
||||||
:local DoUpdate do={
|
|
||||||
:local ScriptName [ :tostr $1 ];
|
|
||||||
|
|
||||||
:if ([ :len [ /system/script/find where name="packages-update" ] ] > 0) do={
|
|
||||||
/system/script/run packages-update;
|
|
||||||
} else={
|
|
||||||
/system/package/update/install without-paging;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /system/scheduler/find where name="running-from-backup-partition" ] ] > 0) do={
|
|
||||||
$LogPrint warning $ScriptName ("Running from backup partition, refusing to act.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$WaitFullyConnected;
|
|
||||||
|
|
||||||
:if ([ :len [ /system/scheduler/find where name="_RebootForUpdate" ] ] > 0) do={
|
|
||||||
:if ([ :typeof $RebootForUpdate ] = "nothing") do={
|
|
||||||
$LogPrint info $ScriptName ("Found a stale scheduler for reboot, removing.");
|
|
||||||
/system/scheduler/remove "_RebootForUpdate";
|
|
||||||
} else={
|
|
||||||
$LogPrint info $ScriptName ("A reboot for update is already scheduled.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$LogPrint debug $ScriptName ("Checking for updates...");
|
|
||||||
/system/package/update/check-for-updates without-paging as-value;
|
|
||||||
:local Update [ /system/package/update/get ];
|
|
||||||
|
|
||||||
:if (($Update->"installed-version") = ($Update->"latest-version")) do={
|
|
||||||
:if ([ $ScriptFromTerminal $ScriptName ] = true) do={
|
|
||||||
$LogPrint info $ScriptName ("System is already up to date.");
|
|
||||||
}
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len ($Update->"latest-version") ] = 0) do={
|
|
||||||
$LogPrint info $ScriptName ("Received an empty version string from server.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:local NumInstalled [ $VersionToNum ($Update->"installed-version") ];
|
|
||||||
:local NumLatest [ $VersionToNum ($Update->"latest-version") ];
|
|
||||||
:local BitMask [ $VersionToNum "255.255zero0" ];
|
|
||||||
:local NumInstalledFeature ($NumInstalled & $BitMask);
|
|
||||||
:local NumLatestFeature ($NumLatest & $BitMask);
|
|
||||||
:local Link ("https://mikrotik.com/download/changelogs/" . $Update->"channel" . "-release-tree");
|
|
||||||
|
|
||||||
:if ($NumLatest < [ $VersionToNum "7.0" ]) do={
|
|
||||||
$LogPrint warning $ScriptName ("The version '" . ($Update->"latest-version") . "' is not a valid version.");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ($NumInstalled < $NumLatest) do={
|
|
||||||
:if ($SafeUpdateAll ~ "^YES,? ?PLEASE!?\$") do={
|
|
||||||
$LogPrint info $ScriptName ("Installing ALL versions automatically, including " . \
|
|
||||||
$Update->"latest-version" . "...");
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update: " . $Update->"latest-version"); \
|
|
||||||
message=("Installing ALL versions automatically, including " . $Update->"latest-version" . \
|
|
||||||
"... Updating on " . $Identity . "..."); link=$Link; silent=true });
|
|
||||||
$DoUpdate $ScriptName;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ($SafeUpdatePatch = true && $NumInstalledFeature = $NumLatestFeature) do={
|
|
||||||
$LogPrint info $ScriptName ("Version " . $Update->"latest-version" . " is a patch release, updating...");
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update: " . $Update->"latest-version"); \
|
|
||||||
message=("Version " . $Update->"latest-version" . " is a patch update for " . $Update->"channel" . \
|
|
||||||
", updating on " . $Identity . "..."); link=$Link; silent=true });
|
|
||||||
$DoUpdate $ScriptName;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ($SafeUpdateNeighbor = true) do={
|
|
||||||
:local Neighbors [ /ip/neighbor/find where platform="MikroTik" identity~$SafeUpdateNeighborIdentity \
|
|
||||||
version~("^" . [ $EscapeForRegEx ($Update->"latest-version") ] . "\\b") ];
|
|
||||||
:if ([ :len $Neighbors ] > 0) do={
|
|
||||||
:local Neighbor [ /ip/neighbor/get ($Neighbors->0) identity ];
|
|
||||||
$LogPrint info $ScriptName ("Seen a neighbor (" . $Neighbor . ") running version " . \
|
|
||||||
$Update->"latest-version" . " from " . $Update->"channel" . ", updating...");
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update: " . $Update->"latest-version"); \
|
|
||||||
message=("Seen a neighbor (" . $Neighbor . ") running version " . $Update->"latest-version" . \
|
|
||||||
" from " . $Update->"channel" . ", updating on " . $Identity . "..."); link=$Link; silent=true });
|
|
||||||
$DoUpdate $ScriptName;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len $SafeUpdateUrl ] > 0) do={
|
|
||||||
:local Result;
|
|
||||||
:onerror Err {
|
|
||||||
:set Result [ /tool/fetch check-certificate=yes-without-crl \
|
|
||||||
($SafeUpdateUrl . $Update->"channel" . "?installed=" . $Update->"installed-version" . \
|
|
||||||
"&latest=" . $Update->"latest-version") http-header-field=({ [ $FetchUserAgentStr $ScriptName ] }) \
|
|
||||||
output=user as-value ];
|
|
||||||
} do={
|
|
||||||
$LogPrint warning $ScriptName ("Failed receiving safe version for " . $Update->"channel" . ": " . $Err);
|
|
||||||
}
|
|
||||||
:if ($Result->"status" = "finished" && $Result->"data" = $Update->"latest-version") do={
|
|
||||||
$LogPrint info $ScriptName ("Version " . $Update->"latest-version" . " is considered safe, updating...");
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update: " . $Update->"latest-version"); \
|
|
||||||
message=("Version " . $Update->"latest-version" . " is considered safe for " . $Update->"channel" . \
|
|
||||||
", updating on " . $Identity . "..."); link=$Link; silent=true });
|
|
||||||
$DoUpdate $ScriptName;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ $ScriptFromTerminal $ScriptName ] = true) do={
|
|
||||||
:if (($Update->"channel") = "testing" && $NumInstalledFeature < $NumLatestFeature) do={
|
|
||||||
:put ("This is a feature update in testing channel. Switch to channel 'stable'? [y/N]");
|
|
||||||
:if (([ /terminal/inkey timeout=60 ] % 32) = 25) do={
|
|
||||||
/system/package/update/set channel=stable;
|
|
||||||
$LogPrint info $ScriptName ("Switched to channel 'stable', please re-run!");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:put ("Do you want to install RouterOS version " . $Update->"latest-version" . "? [y/N]");
|
|
||||||
:if (([ /terminal/inkey timeout=60 ] % 32) = 25) do={
|
|
||||||
$DoUpdate $ScriptName;
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
} else={
|
|
||||||
:put "Canceled...";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ($SentRouterosUpdateNotification = $Update->"latest-version") do={
|
|
||||||
$LogPrint info $ScriptName ("Already sent the RouterOS update notification for version " . \
|
|
||||||
$Update->"latest-version" . ".");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update: " . $Update->"latest-version"); \
|
|
||||||
message=("A new RouterOS version " . ($Update->"latest-version") . \
|
|
||||||
" is available for " . $Identity . ".\n\n" . \
|
|
||||||
[ $DeviceInfo ]); link=$Link; silent=true });
|
|
||||||
:set SentRouterosUpdateNotification ($Update->"latest-version");
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ($NumInstalled > $NumLatest) do={
|
|
||||||
:if ($SentRouterosUpdateNotification = $Update->"latest-version") do={
|
|
||||||
$LogPrint info $ScriptName ("Already sent the RouterOS downgrade notification for version " . \
|
|
||||||
$Update->"latest-version" . ".");
|
|
||||||
:set ExitOK true;
|
|
||||||
:error true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "warning-sign" ] . "RouterOS version: " . $Update->"latest-version"); \
|
|
||||||
message=("A different RouterOS version " . ($Update->"latest-version") . \
|
|
||||||
" is available for " . $Identity . ", but it is a downgrade.\n\n" . \
|
|
||||||
[ $DeviceInfo ]); link=$Link; silent=true });
|
|
||||||
$LogPrint info $ScriptName ("A different RouterOS version " . ($Update->"latest-version") . \
|
|
||||||
" is available for downgrade.");
|
|
||||||
:set SentRouterosUpdateNotification ($Update->"latest-version");
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
40
cloud-backup
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: cloud-backup
|
||||||
|
# Copyright (c) 2013-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# upload backup to MikroTik cloud
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/cloud-backup.md
|
||||||
|
|
||||||
|
:global BackupPassword;
|
||||||
|
:global Identity;
|
||||||
|
|
||||||
|
:global DeviceInfo;
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global SendNotification;
|
||||||
|
:global SymbolForNotification;
|
||||||
|
|
||||||
|
:do {
|
||||||
|
# we are not interested in output, but print is
|
||||||
|
# required to fetch information from cloud
|
||||||
|
/ system backup cloud print as-value;
|
||||||
|
:if ([ :len [ / system backup cloud find ] ] > 0) do={
|
||||||
|
/ system backup cloud upload-file action=create-and-upload \
|
||||||
|
password=$BackupPassword replace=[ get ([ find ]->0) name ];
|
||||||
|
} else={
|
||||||
|
/ system backup cloud upload-file action=create-and-upload \
|
||||||
|
password=$BackupPassword;
|
||||||
|
}
|
||||||
|
:local Cloud [ / system backup cloud get ([ find ]->0) ];
|
||||||
|
|
||||||
|
$SendNotification ([ $SymbolForNotification "floppy-disk" ] . "Cloud backup") \
|
||||||
|
("Uploaded backup for " . $Identity . " to cloud.\n\n" . \
|
||||||
|
[ $DeviceInfo ] . "\n\n" . \
|
||||||
|
"Name: " . $Cloud->"name" . "\n" . \
|
||||||
|
"Size: " . $Cloud->"size" . " B (" . ($Cloud->"size" / 1024) . " KiB)\n" . \
|
||||||
|
"Download key: " . $Cloud->"secret-download-key") "" "" "true";
|
||||||
|
} on-error={
|
||||||
|
$SendNotification ([ $SymbolForNotification "warning-sign" ] . "Cloud backup failed") \
|
||||||
|
("Failed uploading backup for " . $Identity . " to cloud!\n\n" . [ $DeviceInfo ]);
|
||||||
|
$LogPrintExit error ("Failed uploading backup for " . $Identity . " to cloud!") true;
|
||||||
|
}
|
||||||
70
collect-wireless-mac.capsman
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: collect-wireless-mac.capsman
|
||||||
|
# Copyright (c) 2013-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# collect wireless mac adresses in access list
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/collect-wireless-mac.md
|
||||||
|
#
|
||||||
|
# !! Do not edit this file, it is generated from template!
|
||||||
|
|
||||||
|
:global Identity;
|
||||||
|
|
||||||
|
:global GetMacVendor;
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global ScriptLock;
|
||||||
|
:global SendNotification;
|
||||||
|
:global SymbolForNotification;
|
||||||
|
|
||||||
|
$ScriptLock "collect-wireless-mac.capsman";
|
||||||
|
|
||||||
|
:if ([ :len [ / caps-man access-list find where comment="--- collected above ---" disabled ] ] = 0) do={
|
||||||
|
/ caps-man access-list add comment="--- collected above ---" disabled=yes;
|
||||||
|
$LogPrintExit warning "Added disabled access-list entry with comment '--- collected above ---'." false;
|
||||||
|
}
|
||||||
|
:local PlaceBefore [ / caps-man access-list find where comment="--- collected above ---" disabled ];
|
||||||
|
|
||||||
|
:foreach RegTbl in=[ / caps-man registration-table find ] do={
|
||||||
|
:local Mac [ / caps-man registration-table get $RegTbl mac-address ];
|
||||||
|
:local AccessList ([ / caps-man access-list find where mac-address=$Mac ]->0);
|
||||||
|
:if ([ :len $AccessList ] = 0) do={
|
||||||
|
:local Address "no dhcp lease";
|
||||||
|
:local DnsName "no dhcp lease";
|
||||||
|
:local HostName "no dhcp lease";
|
||||||
|
:local Lease [ / ip dhcp-server lease find where mac-address=$Mac dynamic=yes status=bound ];
|
||||||
|
:if ([ :len $Lease ] > 0) do={
|
||||||
|
:set Address [ / ip dhcp-server lease get $Lease address ];
|
||||||
|
:set HostName [ / ip dhcp-server lease get $Lease host-name ];
|
||||||
|
:if ([ :len $HostName ] = 0) do={
|
||||||
|
:set HostName "no hostname";
|
||||||
|
}
|
||||||
|
:set DnsName [ / ip dns static get ([ find where address=$Address ]->0) name ];
|
||||||
|
:if ([ :len $DnsName ] = 0) do={
|
||||||
|
:set DnsName "no dns name";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:local RegEntry [ / caps-man registration-table find where mac-address=$Mac ];
|
||||||
|
:local Interface [ / caps-man registration-table get $RegEntry interface ];
|
||||||
|
:local Ssid [ / caps-man registration-table get $RegEntry ssid ];
|
||||||
|
:local DateTime ([ / system clock get date ] . " " . [ / system clock get time ]);
|
||||||
|
:local Vendor [ $GetMacVendor $Mac ];
|
||||||
|
:local Message ("unknown MAC address " . $Mac . " (" . $Vendor . ", " . $HostName . ") " . \
|
||||||
|
"first seen on " . $DateTime . " connected to SSID " . $Ssid . ", interface " . $Interface);
|
||||||
|
$LogPrintExit info $Message false;
|
||||||
|
/ caps-man access-list add place-before=$PlaceBefore comment=$Message mac-address=$Mac disabled=yes;
|
||||||
|
$SendNotification ([ $SymbolForNotification "mobile-phone" ] . $Mac . " connected to " . $Ssid) \
|
||||||
|
("A device with unknown MAC address connected to " . $Ssid . " on " . $Identity . ".\n\n" . \
|
||||||
|
"Controller: " . $Identity . "\n" . \
|
||||||
|
"Interface: " . $Interface . "\n" . \
|
||||||
|
"SSID: " . $Ssid . "\n" . \
|
||||||
|
"MAC: " . $Mac . "\n" . \
|
||||||
|
"Vendor: " . $Vendor . "\n" . \
|
||||||
|
"Hostname: " . $HostName . "\n" . \
|
||||||
|
"Address: " . $Address . "\n" . \
|
||||||
|
"DNS name: " . $DnsName . "\n" . \
|
||||||
|
"Date: " . $DateTime);
|
||||||
|
} else={
|
||||||
|
$LogPrintExit debug ("MAC address " . $Mac . " already known: " . \
|
||||||
|
[ / caps-man access-list get $AccessList comment ]) false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: collect-wireless-mac.capsman
|
|
||||||
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# provides: lease-script, order=40
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# collect wireless mac adresses in access list
|
|
||||||
# https://rsc.eworm.de/doc/collect-wireless-mac.md
|
|
||||||
#
|
|
||||||
# !! Do not edit this file, it is generated from template!
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global Identity;
|
|
||||||
|
|
||||||
:global EitherOr;
|
|
||||||
:global FormatLine;
|
|
||||||
:global FormatMultiLines;
|
|
||||||
:global GetMacVendor;
|
|
||||||
:global LogPrint;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /caps-man/access-list/find where comment="--- collected above ---" disabled ] ] = 0) do={
|
|
||||||
/caps-man/access-list/add comment="--- collected above ---" disabled=yes;
|
|
||||||
$LogPrint warning $ScriptName ("Added disabled access-list entry with comment '--- collected above ---'.");
|
|
||||||
}
|
|
||||||
:local PlaceBefore ([ /caps-man/access-list/find where comment="--- collected above ---" disabled ]->0);
|
|
||||||
|
|
||||||
:foreach Reg in=[ /caps-man/registration-table/find ] do={
|
|
||||||
:local RegVal;
|
|
||||||
:do {
|
|
||||||
:set RegVal [ /caps-man/registration-table/get $Reg ];
|
|
||||||
} on-error={
|
|
||||||
$LogPrint debug $ScriptName ("Device already gone... Ignoring.");
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len ($RegVal->"mac-address") ] > 0) do={
|
|
||||||
:local AccessList ([ /caps-man/access-list/find where mac-address=($RegVal->"mac-address") ]->0);
|
|
||||||
:if ([ :len $AccessList ] > 0) do={
|
|
||||||
$LogPrint debug $ScriptName ("MAC address " . $RegVal->"mac-address" . " already known: " . \
|
|
||||||
[ /caps-man/access-list/get $AccessList comment ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len $AccessList ] = 0) do={
|
|
||||||
:local Address "no dhcp lease";
|
|
||||||
:local DnsName "no dhcp lease";
|
|
||||||
:local HostName "no dhcp lease";
|
|
||||||
:local Lease ([ /ip/dhcp-server/lease/find where active-mac-address=($RegVal->"mac-address") dynamic=yes status=bound ]->0);
|
|
||||||
:if ([ :len $Lease ] > 0) do={
|
|
||||||
:set Address [ /ip/dhcp-server/lease/get $Lease active-address ];
|
|
||||||
:set HostName [ $EitherOr [ /ip/dhcp-server/lease/get $Lease host-name ] "no hostname" ];
|
|
||||||
:set DnsName "no dns name";
|
|
||||||
:local DnsRec ([ /ip/dns/static/find where address=$Address ]->0);
|
|
||||||
:if ([ :len $DnsRec ] > 0) do={
|
|
||||||
:set DnsName ({ [ /ip/dns/static/get $DnsRec name ] });
|
|
||||||
:foreach CName in=[ /ip/dns/static/find where type=CNAME cname=($DnsName->0) ] do={
|
|
||||||
:set DnsName ($DnsName, [ /ip/dns/static/get $CName name ]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:local DateTime ([ /system/clock/get date ] . " " . [ /system/clock/get time ]);
|
|
||||||
:local Vendor [ $GetMacVendor ($RegVal->"mac-address") ];
|
|
||||||
:local Message ("MAC address " . $RegVal->"mac-address" . " (" . $Vendor . ", " . $HostName . ") " . \
|
|
||||||
"first seen on " . $DateTime . " connected to SSID " . $RegVal->"ssid" . ", interface " . $RegVal->"interface");
|
|
||||||
$LogPrint info $ScriptName $Message;
|
|
||||||
/caps-man/access-list/add place-before=$PlaceBefore comment=$Message mac-address=($RegVal->"mac-address") disabled=yes;
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "mobile-phone" ] . $RegVal->"mac-address" . " connected to " . $RegVal->"ssid"); \
|
|
||||||
message=("A device with unknown MAC address connected to " . $RegVal->"ssid" . " on " . $Identity . ".\n\n" . \
|
|
||||||
[ $FormatLine "Controller" $Identity ] . "\n" . \
|
|
||||||
[ $FormatLine "Interface" ($RegVal->"interface") ] . "\n" . \
|
|
||||||
[ $FormatLine "SSID" ($RegVal->"ssid") ] . "\n" . \
|
|
||||||
[ $FormatLine "MAC" ($RegVal->"mac-address") ] . "\n" . \
|
|
||||||
[ $FormatLine "Vendor" $Vendor ] . "\n" . \
|
|
||||||
[ $FormatLine "Hostname" $HostName ] . "\n" . \
|
|
||||||
[ $FormatLine "Address" $Address ] . "\n" . \
|
|
||||||
[ $FormatMultiLines "DNS name" $DnsName ] . "\n" . \
|
|
||||||
[ $FormatLine "Date" $DateTime ]) });
|
|
||||||
}
|
|
||||||
} else={
|
|
||||||
$LogPrint debug $ScriptName ("No mac address available... Ignoring.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
70
collect-wireless-mac.local
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: collect-wireless-mac.local
|
||||||
|
# Copyright (c) 2013-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# collect wireless mac adresses in access list
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/collect-wireless-mac.md
|
||||||
|
#
|
||||||
|
# !! Do not edit this file, it is generated from template!
|
||||||
|
|
||||||
|
:global Identity;
|
||||||
|
|
||||||
|
:global GetMacVendor;
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global ScriptLock;
|
||||||
|
:global SendNotification;
|
||||||
|
:global SymbolForNotification;
|
||||||
|
|
||||||
|
$ScriptLock "collect-wireless-mac.local";
|
||||||
|
|
||||||
|
:if ([ :len [ / interface wireless access-list find where comment="--- collected above ---" disabled ] ] = 0) do={
|
||||||
|
/ interface wireless access-list add comment="--- collected above ---" disabled=yes;
|
||||||
|
$LogPrintExit warning "Added disabled access-list entry with comment '--- collected above ---'." false;
|
||||||
|
}
|
||||||
|
:local PlaceBefore [ / interface wireless access-list find where comment="--- collected above ---" disabled ];
|
||||||
|
|
||||||
|
:foreach RegTbl in=[ / interface wireless registration-table find ] do={
|
||||||
|
:local Mac [ / interface wireless registration-table get $RegTbl mac-address ];
|
||||||
|
:local AccessList ([ / interface wireless access-list find where mac-address=$Mac ]->0);
|
||||||
|
:if ([ :len $AccessList ] = 0) do={
|
||||||
|
:local Address "no dhcp lease";
|
||||||
|
:local DnsName "no dhcp lease";
|
||||||
|
:local HostName "no dhcp lease";
|
||||||
|
:local Lease [ / ip dhcp-server lease find where mac-address=$Mac dynamic=yes status=bound ];
|
||||||
|
:if ([ :len $Lease ] > 0) do={
|
||||||
|
:set Address [ / ip dhcp-server lease get $Lease address ];
|
||||||
|
:set HostName [ / ip dhcp-server lease get $Lease host-name ];
|
||||||
|
:if ([ :len $HostName ] = 0) do={
|
||||||
|
:set HostName "no hostname";
|
||||||
|
}
|
||||||
|
:set DnsName [ / ip dns static get ([ find where address=$Address ]->0) name ];
|
||||||
|
:if ([ :len $DnsName ] = 0) do={
|
||||||
|
:set DnsName "no dns name";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:local RegEntry [ / interface wireless registration-table find where mac-address=$Mac ];
|
||||||
|
:local Interface [ / interface wireless registration-table get $RegEntry interface ];
|
||||||
|
:local Ssid [ / interface wireless get [ find where name=$Interface ] ssid ];
|
||||||
|
:local DateTime ([ / system clock get date ] . " " . [ / system clock get time ]);
|
||||||
|
:local Vendor [ $GetMacVendor $Mac ];
|
||||||
|
:local Message ("unknown MAC address " . $Mac . " (" . $Vendor . ", " . $HostName . ") " . \
|
||||||
|
"first seen on " . $DateTime . " connected to SSID " . $Ssid . ", interface " . $Interface);
|
||||||
|
$LogPrintExit info $Message false;
|
||||||
|
/ interface wireless access-list add place-before=$PlaceBefore comment=$Message mac-address=$Mac disabled=yes;
|
||||||
|
$SendNotification ([ $SymbolForNotification "mobile-phone" ] . $Mac . " connected to " . $Ssid) \
|
||||||
|
("A device with unknown MAC address connected to " . $Ssid . " on " . $Identity . ".\n\n" . \
|
||||||
|
"Controller: " . $Identity . "\n" . \
|
||||||
|
"Interface: " . $Interface . "\n" . \
|
||||||
|
"SSID: " . $Ssid . "\n" . \
|
||||||
|
"MAC: " . $Mac . "\n" . \
|
||||||
|
"Vendor: " . $Vendor . "\n" . \
|
||||||
|
"Hostname: " . $HostName . "\n" . \
|
||||||
|
"Address: " . $Address . "\n" . \
|
||||||
|
"DNS name: " . $DnsName . "\n" . \
|
||||||
|
"Date: " . $DateTime);
|
||||||
|
} else={
|
||||||
|
$LogPrintExit debug ("MAC address " . $Mac . " already known: " . \
|
||||||
|
[ / interface wireless access-list get $AccessList comment ]) false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: collect-wireless-mac.local
|
|
||||||
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# provides: lease-script, order=40
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# collect wireless mac adresses in access list
|
|
||||||
# https://rsc.eworm.de/doc/collect-wireless-mac.md
|
|
||||||
#
|
|
||||||
# !! Do not edit this file, it is generated from template!
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global Identity;
|
|
||||||
|
|
||||||
:global EitherOr;
|
|
||||||
:global FormatLine;
|
|
||||||
:global FormatMultiLines;
|
|
||||||
:global GetMacVendor;
|
|
||||||
:global LogPrint;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /interface/wireless/access-list/find where comment="--- collected above ---" disabled ] ] = 0) do={
|
|
||||||
/interface/wireless/access-list/add comment="--- collected above ---" disabled=yes;
|
|
||||||
$LogPrint warning $ScriptName ("Added disabled access-list entry with comment '--- collected above ---'.");
|
|
||||||
}
|
|
||||||
:local PlaceBefore ([ /interface/wireless/access-list/find where comment="--- collected above ---" disabled ]->0);
|
|
||||||
|
|
||||||
:foreach Reg in=[ /interface/wireless/registration-table/find where ap=no ] do={
|
|
||||||
:local RegVal;
|
|
||||||
:do {
|
|
||||||
:set RegVal [ /interface/wireless/registration-table/get $Reg ];
|
|
||||||
} on-error={
|
|
||||||
$LogPrint debug $ScriptName ("Device already gone... Ignoring.");
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len ($RegVal->"mac-address") ] > 0) do={
|
|
||||||
:local AccessList ([ /interface/wireless/access-list/find where mac-address=($RegVal->"mac-address") ]->0);
|
|
||||||
:if ([ :len $AccessList ] > 0) do={
|
|
||||||
$LogPrint debug $ScriptName ("MAC address " . $RegVal->"mac-address" . " already known: " . \
|
|
||||||
[ /interface/wireless/access-list/get $AccessList comment ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len $AccessList ] = 0) do={
|
|
||||||
:local Address "no dhcp lease";
|
|
||||||
:local DnsName "no dhcp lease";
|
|
||||||
:local HostName "no dhcp lease";
|
|
||||||
:local Lease ([ /ip/dhcp-server/lease/find where active-mac-address=($RegVal->"mac-address") dynamic=yes status=bound ]->0);
|
|
||||||
:if ([ :len $Lease ] > 0) do={
|
|
||||||
:set Address [ /ip/dhcp-server/lease/get $Lease active-address ];
|
|
||||||
:set HostName [ $EitherOr [ /ip/dhcp-server/lease/get $Lease host-name ] "no hostname" ];
|
|
||||||
:set DnsName "no dns name";
|
|
||||||
:local DnsRec ([ /ip/dns/static/find where address=$Address ]->0);
|
|
||||||
:if ([ :len $DnsRec ] > 0) do={
|
|
||||||
:set DnsName ({ [ /ip/dns/static/get $DnsRec name ] });
|
|
||||||
:foreach CName in=[ /ip/dns/static/find where type=CNAME cname=($DnsName->0) ] do={
|
|
||||||
:set DnsName ($DnsName, [ /ip/dns/static/get $CName name ]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:set ($RegVal->"ssid") [ /interface/wireless/get [ find where name=($RegVal->"interface") ] ssid ];
|
|
||||||
:local DateTime ([ /system/clock/get date ] . " " . [ /system/clock/get time ]);
|
|
||||||
:local Vendor [ $GetMacVendor ($RegVal->"mac-address") ];
|
|
||||||
:local Message ("MAC address " . $RegVal->"mac-address" . " (" . $Vendor . ", " . $HostName . ") " . \
|
|
||||||
"first seen on " . $DateTime . " connected to SSID " . $RegVal->"ssid" . ", interface " . $RegVal->"interface");
|
|
||||||
$LogPrint info $ScriptName $Message;
|
|
||||||
/interface/wireless/access-list/add place-before=$PlaceBefore comment=$Message mac-address=($RegVal->"mac-address") disabled=yes;
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "mobile-phone" ] . $RegVal->"mac-address" . " connected to " . $RegVal->"ssid"); \
|
|
||||||
message=("A device with unknown MAC address connected to " . $RegVal->"ssid" . " on " . $Identity . ".\n\n" . \
|
|
||||||
[ $FormatLine "Controller" $Identity ] . "\n" . \
|
|
||||||
[ $FormatLine "Interface" ($RegVal->"interface") ] . "\n" . \
|
|
||||||
[ $FormatLine "SSID" ($RegVal->"ssid") ] . "\n" . \
|
|
||||||
[ $FormatLine "MAC" ($RegVal->"mac-address") ] . "\n" . \
|
|
||||||
[ $FormatLine "Vendor" $Vendor ] . "\n" . \
|
|
||||||
[ $FormatLine "Hostname" $HostName ] . "\n" . \
|
|
||||||
[ $FormatLine "Address" $Address ] . "\n" . \
|
|
||||||
[ $FormatMultiLines "DNS name" $DnsName ] . "\n" . \
|
|
||||||
[ $FormatLine "Date" $DateTime ]) });
|
|
||||||
}
|
|
||||||
} else={
|
|
||||||
$LogPrint debug $ScriptName ("No mac address available... Ignoring.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
72
collect-wireless-mac.template
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#!rsc by RouterOS
|
||||||
|
# RouterOS script: collect-wireless-mac%TEMPL%
|
||||||
|
# Copyright (c) 2013-2020 Christian Hesse <mail@eworm.de>
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
||||||
|
#
|
||||||
|
# collect wireless mac adresses in access list
|
||||||
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/collect-wireless-mac.md
|
||||||
|
#
|
||||||
|
# !! This is just a template! Replace '%PATH%' with 'caps-man'
|
||||||
|
# !! or 'interface wireless'!
|
||||||
|
|
||||||
|
:global Identity;
|
||||||
|
|
||||||
|
:global GetMacVendor;
|
||||||
|
:global LogPrintExit;
|
||||||
|
:global ScriptLock;
|
||||||
|
:global SendNotification;
|
||||||
|
:global SymbolForNotification;
|
||||||
|
|
||||||
|
$ScriptLock "collect-wireless-mac%TEMPL%";
|
||||||
|
|
||||||
|
:if ([ :len [ / %PATH% access-list find where comment="--- collected above ---" disabled ] ] = 0) do={
|
||||||
|
/ %PATH% access-list add comment="--- collected above ---" disabled=yes;
|
||||||
|
$LogPrintExit warning "Added disabled access-list entry with comment '--- collected above ---'." false;
|
||||||
|
}
|
||||||
|
:local PlaceBefore [ / %PATH% access-list find where comment="--- collected above ---" disabled ];
|
||||||
|
|
||||||
|
:foreach RegTbl in=[ / %PATH% registration-table find ] do={
|
||||||
|
:local Mac [ / %PATH% registration-table get $RegTbl mac-address ];
|
||||||
|
:local AccessList ([ / %PATH% access-list find where mac-address=$Mac ]->0);
|
||||||
|
:if ([ :len $AccessList ] = 0) do={
|
||||||
|
:local Address "no dhcp lease";
|
||||||
|
:local DnsName "no dhcp lease";
|
||||||
|
:local HostName "no dhcp lease";
|
||||||
|
:local Lease [ / ip dhcp-server lease find where mac-address=$Mac dynamic=yes status=bound ];
|
||||||
|
:if ([ :len $Lease ] > 0) do={
|
||||||
|
:set Address [ / ip dhcp-server lease get $Lease address ];
|
||||||
|
:set HostName [ / ip dhcp-server lease get $Lease host-name ];
|
||||||
|
:if ([ :len $HostName ] = 0) do={
|
||||||
|
:set HostName "no hostname";
|
||||||
|
}
|
||||||
|
:set DnsName [ / ip dns static get ([ find where address=$Address ]->0) name ];
|
||||||
|
:if ([ :len $DnsName ] = 0) do={
|
||||||
|
:set DnsName "no dns name";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:local RegEntry [ / %PATH% registration-table find where mac-address=$Mac ];
|
||||||
|
:local Interface [ / %PATH% registration-table get $RegEntry interface ];
|
||||||
|
:local Ssid [ / caps-man registration-table get $RegEntry ssid ];
|
||||||
|
:local Ssid [ / interface wireless get [ find where name=$Interface ] ssid ];
|
||||||
|
:local DateTime ([ / system clock get date ] . " " . [ / system clock get time ]);
|
||||||
|
:local Vendor [ $GetMacVendor $Mac ];
|
||||||
|
:local Message ("unknown MAC address " . $Mac . " (" . $Vendor . ", " . $HostName . ") " . \
|
||||||
|
"first seen on " . $DateTime . " connected to SSID " . $Ssid . ", interface " . $Interface);
|
||||||
|
$LogPrintExit info $Message false;
|
||||||
|
/ %PATH% access-list add place-before=$PlaceBefore comment=$Message mac-address=$Mac disabled=yes;
|
||||||
|
$SendNotification ([ $SymbolForNotification "mobile-phone" ] . $Mac . " connected to " . $Ssid) \
|
||||||
|
("A device with unknown MAC address connected to " . $Ssid . " on " . $Identity . ".\n\n" . \
|
||||||
|
"Controller: " . $Identity . "\n" . \
|
||||||
|
"Interface: " . $Interface . "\n" . \
|
||||||
|
"SSID: " . $Ssid . "\n" . \
|
||||||
|
"MAC: " . $Mac . "\n" . \
|
||||||
|
"Vendor: " . $Vendor . "\n" . \
|
||||||
|
"Hostname: " . $HostName . "\n" . \
|
||||||
|
"Address: " . $Address . "\n" . \
|
||||||
|
"DNS name: " . $DnsName . "\n" . \
|
||||||
|
"Date: " . $DateTime);
|
||||||
|
} else={
|
||||||
|
$LogPrintExit debug ("MAC address " . $Mac . " already known: " . \
|
||||||
|
[ / %PATH% access-list get $AccessList comment ]) false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,118 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: collect-wireless-mac%TEMPL%
|
|
||||||
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# provides: lease-script, order=40
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# collect wireless mac adresses in access list
|
|
||||||
# https://rsc.eworm.de/doc/collect-wireless-mac.md
|
|
||||||
#
|
|
||||||
# !! This is just a template to generate the real script!
|
|
||||||
# !! Pattern '%TEMPL%' is replaced, paths are filtered.
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global Identity;
|
|
||||||
|
|
||||||
:global EitherOr;
|
|
||||||
:global FormatLine;
|
|
||||||
:global FormatMultiLines;
|
|
||||||
:global GetMacVendor;
|
|
||||||
:global LogPrint;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /caps-man/access-list/find where comment="--- collected above ---" disabled ] ] = 0) do={
|
|
||||||
:if ([ :len [ /interface/wifi/access-list/find where comment="--- collected above ---" disabled ] ] = 0) do={
|
|
||||||
:if ([ :len [ /interface/wireless/access-list/find where comment="--- collected above ---" disabled ] ] = 0) do={
|
|
||||||
/caps-man/access-list/add comment="--- collected above ---" disabled=yes;
|
|
||||||
/interface/wifi/access-list/add comment="--- collected above ---" disabled=yes;
|
|
||||||
/interface/wireless/access-list/add comment="--- collected above ---" disabled=yes;
|
|
||||||
$LogPrint warning $ScriptName ("Added disabled access-list entry with comment '--- collected above ---'.");
|
|
||||||
}
|
|
||||||
:local PlaceBefore ([ /caps-man/access-list/find where comment="--- collected above ---" disabled ]->0);
|
|
||||||
:local PlaceBefore ([ /interface/wifi/access-list/find where comment="--- collected above ---" disabled ]->0);
|
|
||||||
:local PlaceBefore ([ /interface/wireless/access-list/find where comment="--- collected above ---" disabled ]->0);
|
|
||||||
|
|
||||||
:foreach Reg in=[ /caps-man/registration-table/find ] do={
|
|
||||||
:foreach Reg in=[ /interface/wifi/registration-table/find ] do={
|
|
||||||
:foreach Reg in=[ /interface/wireless/registration-table/find where ap=no ] do={
|
|
||||||
:local RegVal;
|
|
||||||
:do {
|
|
||||||
:set RegVal [ /caps-man/registration-table/get $Reg ];
|
|
||||||
:set RegVal [ /interface/wifi/registration-table/get $Reg ];
|
|
||||||
:set RegVal [ /interface/wireless/registration-table/get $Reg ];
|
|
||||||
} on-error={
|
|
||||||
$LogPrint debug $ScriptName ("Device already gone... Ignoring.");
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len ($RegVal->"mac-address") ] > 0) do={
|
|
||||||
:local AccessList ([ /caps-man/access-list/find where mac-address=($RegVal->"mac-address") ]->0);
|
|
||||||
:local AccessList ([ /interface/wifi/access-list/find where mac-address=($RegVal->"mac-address") ]->0);
|
|
||||||
:local AccessList ([ /interface/wireless/access-list/find where mac-address=($RegVal->"mac-address") ]->0);
|
|
||||||
:if ([ :len $AccessList ] > 0) do={
|
|
||||||
$LogPrint debug $ScriptName ("MAC address " . $RegVal->"mac-address" . " already known: " . \
|
|
||||||
[ /caps-man/access-list/get $AccessList comment ]);
|
|
||||||
[ /interface/wifi/access-list/get $AccessList comment ]);
|
|
||||||
[ /interface/wireless/access-list/get $AccessList comment ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len $AccessList ] = 0) do={
|
|
||||||
:local Address "no dhcp lease";
|
|
||||||
:local DnsName "no dhcp lease";
|
|
||||||
:local HostName "no dhcp lease";
|
|
||||||
:local Lease ([ /ip/dhcp-server/lease/find where active-mac-address=($RegVal->"mac-address") dynamic=yes status=bound ]->0);
|
|
||||||
:if ([ :len $Lease ] > 0) do={
|
|
||||||
:set Address [ /ip/dhcp-server/lease/get $Lease active-address ];
|
|
||||||
:set HostName [ $EitherOr [ /ip/dhcp-server/lease/get $Lease host-name ] "no hostname" ];
|
|
||||||
:set DnsName "no dns name";
|
|
||||||
:local DnsRec ([ /ip/dns/static/find where address=$Address ]->0);
|
|
||||||
:if ([ :len $DnsRec ] > 0) do={
|
|
||||||
:set DnsName ({ [ /ip/dns/static/get $DnsRec name ] });
|
|
||||||
:foreach CName in=[ /ip/dns/static/find where type=CNAME cname=($DnsName->0) ] do={
|
|
||||||
:set DnsName ($DnsName, [ /ip/dns/static/get $CName name ]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:set ($RegVal->"ssid") [ /interface/wireless/get [ find where name=($RegVal->"interface") ] ssid ];
|
|
||||||
:local DateTime ([ /system/clock/get date ] . " " . [ /system/clock/get time ]);
|
|
||||||
:local Vendor [ $GetMacVendor ($RegVal->"mac-address") ];
|
|
||||||
:local Message ("MAC address " . $RegVal->"mac-address" . " (" . $Vendor . ", " . $HostName . ") " . \
|
|
||||||
"first seen on " . $DateTime . " connected to SSID " . $RegVal->"ssid" . ", interface " . $RegVal->"interface");
|
|
||||||
$LogPrint info $ScriptName $Message;
|
|
||||||
/caps-man/access-list/add place-before=$PlaceBefore comment=$Message mac-address=($RegVal->"mac-address") disabled=yes;
|
|
||||||
/interface/wifi/access-list/add place-before=$PlaceBefore comment=$Message mac-address=($RegVal->"mac-address") disabled=yes;
|
|
||||||
/interface/wireless/access-list/add place-before=$PlaceBefore comment=$Message mac-address=($RegVal->"mac-address") disabled=yes;
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "mobile-phone" ] . $RegVal->"mac-address" . " connected to " . $RegVal->"ssid"); \
|
|
||||||
message=("A device with unknown MAC address connected to " . $RegVal->"ssid" . " on " . $Identity . ".\n\n" . \
|
|
||||||
[ $FormatLine "Controller" $Identity ] . "\n" . \
|
|
||||||
[ $FormatLine "Interface" ($RegVal->"interface") ] . "\n" . \
|
|
||||||
[ $FormatLine "SSID" ($RegVal->"ssid") ] . "\n" . \
|
|
||||||
[ $FormatLine "MAC" ($RegVal->"mac-address") ] . "\n" . \
|
|
||||||
[ $FormatLine "Vendor" $Vendor ] . "\n" . \
|
|
||||||
[ $FormatLine "Hostname" $HostName ] . "\n" . \
|
|
||||||
[ $FormatLine "Address" $Address ] . "\n" . \
|
|
||||||
[ $FormatMultiLines "DNS name" $DnsName ] . "\n" . \
|
|
||||||
[ $FormatLine "Date" $DateTime ]) });
|
|
||||||
}
|
|
||||||
} else={
|
|
||||||
$LogPrint debug $ScriptName ("No mac address available... Ignoring.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
#!rsc by RouterOS
|
|
||||||
# RouterOS script: collect-wireless-mac.wifi
|
|
||||||
# Copyright (c) 2013-2026 Christian Hesse <mail@eworm.de>
|
|
||||||
# https://rsc.eworm.de/COPYING.md
|
|
||||||
#
|
|
||||||
# provides: lease-script, order=40
|
|
||||||
# requires RouterOS, version=7.17
|
|
||||||
#
|
|
||||||
# collect wireless mac adresses in access list
|
|
||||||
# https://rsc.eworm.de/doc/collect-wireless-mac.md
|
|
||||||
#
|
|
||||||
# !! Do not edit this file, it is generated from template!
|
|
||||||
|
|
||||||
:local ExitOK false;
|
|
||||||
:onerror Err {
|
|
||||||
:global GlobalConfigReady; :global GlobalFunctionsReady;
|
|
||||||
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
|
|
||||||
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
|
|
||||||
:local ScriptName [ :jobname ];
|
|
||||||
|
|
||||||
:global Identity;
|
|
||||||
|
|
||||||
:global EitherOr;
|
|
||||||
:global FormatLine;
|
|
||||||
:global FormatMultiLines;
|
|
||||||
:global GetMacVendor;
|
|
||||||
:global LogPrint;
|
|
||||||
:global ScriptLock;
|
|
||||||
:global SendNotification2;
|
|
||||||
:global SymbolForNotification;
|
|
||||||
|
|
||||||
:if ([ $ScriptLock $ScriptName 10 ] = false) do={
|
|
||||||
:set ExitOK true;
|
|
||||||
:error false;
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len [ /interface/wifi/access-list/find where comment="--- collected above ---" disabled ] ] = 0) do={
|
|
||||||
/interface/wifi/access-list/add comment="--- collected above ---" disabled=yes;
|
|
||||||
$LogPrint warning $ScriptName ("Added disabled access-list entry with comment '--- collected above ---'.");
|
|
||||||
}
|
|
||||||
:local PlaceBefore ([ /interface/wifi/access-list/find where comment="--- collected above ---" disabled ]->0);
|
|
||||||
|
|
||||||
:foreach Reg in=[ /interface/wifi/registration-table/find ] do={
|
|
||||||
:local RegVal;
|
|
||||||
:do {
|
|
||||||
:set RegVal [ /interface/wifi/registration-table/get $Reg ];
|
|
||||||
} on-error={
|
|
||||||
$LogPrint debug $ScriptName ("Device already gone... Ignoring.");
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len ($RegVal->"mac-address") ] > 0) do={
|
|
||||||
:local AccessList ([ /interface/wifi/access-list/find where mac-address=($RegVal->"mac-address") ]->0);
|
|
||||||
:if ([ :len $AccessList ] > 0) do={
|
|
||||||
$LogPrint debug $ScriptName ("MAC address " . $RegVal->"mac-address" . " already known: " . \
|
|
||||||
[ /interface/wifi/access-list/get $AccessList comment ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
:if ([ :len $AccessList ] = 0) do={
|
|
||||||
:local Address "no dhcp lease";
|
|
||||||
:local DnsName "no dhcp lease";
|
|
||||||
:local HostName "no dhcp lease";
|
|
||||||
:local Lease ([ /ip/dhcp-server/lease/find where active-mac-address=($RegVal->"mac-address") dynamic=yes status=bound ]->0);
|
|
||||||
:if ([ :len $Lease ] > 0) do={
|
|
||||||
:set Address [ /ip/dhcp-server/lease/get $Lease active-address ];
|
|
||||||
:set HostName [ $EitherOr [ /ip/dhcp-server/lease/get $Lease host-name ] "no hostname" ];
|
|
||||||
:set DnsName "no dns name";
|
|
||||||
:local DnsRec ([ /ip/dns/static/find where address=$Address ]->0);
|
|
||||||
:if ([ :len $DnsRec ] > 0) do={
|
|
||||||
:set DnsName ({ [ /ip/dns/static/get $DnsRec name ] });
|
|
||||||
:foreach CName in=[ /ip/dns/static/find where type=CNAME cname=($DnsName->0) ] do={
|
|
||||||
:set DnsName ($DnsName, [ /ip/dns/static/get $CName name ]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:local DateTime ([ /system/clock/get date ] . " " . [ /system/clock/get time ]);
|
|
||||||
:local Vendor [ $GetMacVendor ($RegVal->"mac-address") ];
|
|
||||||
:local Message ("MAC address " . $RegVal->"mac-address" . " (" . $Vendor . ", " . $HostName . ") " . \
|
|
||||||
"first seen on " . $DateTime . " connected to SSID " . $RegVal->"ssid" . ", interface " . $RegVal->"interface");
|
|
||||||
$LogPrint info $ScriptName $Message;
|
|
||||||
/interface/wifi/access-list/add place-before=$PlaceBefore comment=$Message mac-address=($RegVal->"mac-address") disabled=yes;
|
|
||||||
$SendNotification2 ({ origin=$ScriptName; \
|
|
||||||
subject=([ $SymbolForNotification "mobile-phone" ] . $RegVal->"mac-address" . " connected to " . $RegVal->"ssid"); \
|
|
||||||
message=("A device with unknown MAC address connected to " . $RegVal->"ssid" . " on " . $Identity . ".\n\n" . \
|
|
||||||
[ $FormatLine "Controller" $Identity ] . "\n" . \
|
|
||||||
[ $FormatLine "Interface" ($RegVal->"interface") ] . "\n" . \
|
|
||||||
[ $FormatLine "SSID" ($RegVal->"ssid") ] . "\n" . \
|
|
||||||
[ $FormatLine "MAC" ($RegVal->"mac-address") ] . "\n" . \
|
|
||||||
[ $FormatLine "Vendor" $Vendor ] . "\n" . \
|
|
||||||
[ $FormatLine "Hostname" $HostName ] . "\n" . \
|
|
||||||
[ $FormatLine "Address" $Address ] . "\n" . \
|
|
||||||
[ $FormatMultiLines "DNS name" $DnsName ] . "\n" . \
|
|
||||||
[ $FormatLine "Date" $DateTime ]) });
|
|
||||||
}
|
|
||||||
} else={
|
|
||||||
$LogPrint debug $ScriptName ("No mac address available... Ignoring.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} do={
|
|
||||||
:global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
# Makefile
|
|
||||||
|
|
||||||
HTML := $(shell grep -xl '<!-- static html //-->' *.html)
|
|
||||||
|
|
||||||
.PHONY: all docs clean
|
|
||||||
|
|
||||||
all: docs
|
|
||||||
|
|
||||||
badges.html: badges.md
|
|
||||||
markdown $< > $@
|
|
||||||
|
|
||||||
docs: static-html.sh $(HTML) badges.html
|
|
||||||
./static-html.sh $(HTML)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f badges.html
|
|
||||||
git checkout HEAD -- $(HTML)
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
[](https://github.com/eworm-de/routeros-scripts/stargazers)
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/network)
|
|
||||||
[](https://github.com/eworm-de/routeros-scripts/watchers)
|
|
||||||
[](https://mikrotik.com/download/changelogs/)
|
|
||||||
[](https://t.me/routeros_scripts)
|
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# generate a checksums file as used by $ScriptInstallUpdate
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
md5sum $(find -name '*.rsc' | sort) | \
|
|
||||||
sed -e "s| \./||" -e 's|.rsc$||' | \
|
|
||||||
jq --raw-input --null-input '[ inputs | split (" ") | { (.[1]): (.[0]) }] | add'
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
sed \
|
|
||||||
-e "/^:global CommitId/c :global CommitId \"${COMMITID:-unknown}\";" \
|
|
||||||
-e "/^:global CommitInfo/c :global CommitInfo \"${COMMITINFO:-unknown}\";" \
|
|
||||||
< "${1}"
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
RELTO="$(dirname "${1}")"
|
|
||||||
|
|
||||||
sed \
|
|
||||||
-e "s|__TITLE__|$(head -n1 "${1}")|" \
|
|
||||||
-e "s|__GENERAL__|$(realpath --relative-to="${RELTO}" general/)|" \
|
|
||||||
-e "s|__ROOT__|$(realpath --relative-to="${RELTO}" ./)|" \
|
|
||||||
< "${0}.d/head.html"
|
|
||||||
|
|
||||||
markdown -f toc,idanchor "${1}" | sed \
|
|
||||||
-e 's/href="\([-_\./[:alnum:]]*\)\.md\(#[-[:alnum:]]*\)\?"/href="\1.html\2"/g' \
|
|
||||||
-e '/<h[1234] /s| id="\(.*\)">| id="\L\1">|' \
|
|
||||||
-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;"|'
|
|
||||||
|
|
||||||
sed \
|
|
||||||
-e "s|__DATE__|${DATE:-$(date --rfc-email)}|" \
|
|
||||||
-e "s|__VERSION__|${VERSION:-unknown}|" \
|
|
||||||
< "${0}.d/foot.html"
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
<p class="foot">RouterOS Scripts documentation generated on <i>__DATE__</i> for <i>__VERSION__</i><br />
|
|
||||||
Copyright © 2013-2026 Christian Hesse <mail@eworm.de></p>
|
|
||||||
|
|
||||||
</body></html>
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
<!DOCTYPE html><html lang="en">
|
|
||||||
<head><meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
|
||||||
<title>RouterOS Scripts :: __TITLE__</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="__GENERAL__/style.css">
|
|
||||||
<link rel="icon" type="image/png" href="__ROOT__/logo.png">
|
|
||||||
<script type="text/javascript" src="__GENERAL__/clipboard.js"></script>
|
|
||||||
</head><body>
|
|
||||||
|
|
||||||
<table><tr>
|
|
||||||
<td><img src="__GENERAL__/eworm-meadow.avif" alt="eworm on meadow" /></td>
|
|
||||||
<td><img src="__GENERAL__/qr-code.png" alt="QR code: rsc.eworm.de" /></td>
|
|
||||||
<td class="head"><span class="top">RouterOS Scripts</span><br />
|
|
||||||
<span class="bottom">a collection of scripts for MikroTik RouterOS</span></td>
|
|
||||||
</tr></table>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 25 KiB |