Merge branch 'main' into main

This commit is contained in:
ycg31 2025-12-01 22:08:08 +08:00 committed by GitHub
commit 32a3ca9e6a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
348 changed files with 13201 additions and 10559 deletions

13
.gitignore vendored
View file

@ -1,3 +1,16 @@
# backup and temporary files
*~
# patches and related files
*.orig
*.patch
*.rej
# html files (as generated from markdown)
*.html
# checksums file as used by $ScriptInstallUpdate
checksums.json
# Mac OS X folder settings file
.DS_Store

50
BRANCHES.md Normal file
View file

@ -0,0 +1,50 @@
Installing from branches
========================
[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network)
[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers)
[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.15-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts)
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
[⬅️ Go back to main README](README.md)
> ⚠️ **Warning**: 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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

83
CERTIFICATES.md Normal file
View file

@ -0,0 +1,83 @@
Certificate name from browser
=============================
[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network)
[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers)
[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.15-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts)
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
[⬅️ Go back to main README](README.md)
All well known desktop, mobile and server operating systems come with a
certificate store that is populated with a set of well known and trusted
certificates, acting as *trust anchors*.
However RouterOS does not, still sometimes a specific certificate is
required to properly verify a chain of trust. One example is downloading
the scripts from this repository with `fetch` command, thus the very
first step of [installation](README.md#the-long-way-in-detail) is importing
the certificate.
The scripts can install additional certificates when required. This happens
from this repository if available, or from [mkcert.org ↗️](https://mkcert.org)
as a fallback.
Get the certificate's CommonName
--------------------------------
But how to determine what certificate may be required? Often easiest way
is to use a desktop browser to get that information. This demonstration uses
[Mozilla Firefox ↗️](https://www.mozilla.org/firefox/).
Let's assume we want to make sure the certificate for
[git.eworm.de](https://git.eworm.de/) is available. Open that page in the
browser, then click the *lock* icon in addressbar, followed by "*Connection
secure*".
![screenshot: dialog A](CERTIFICATES.d/01-dialog-A.avif)
The dialog will change, click "*More information*".
![screenshot: dialog B](CERTIFICATES.d/02-dialog-B.avif)
A new window opens, click the button "*View Certificate*". (That window
can be closed now.)
![screenshot: window](CERTIFICATES.d/03-window.avif)
A new tab opens, showing information on the server certificate and its
chain of trust. The leftmost certificate is what we are interested in.
![screenshot: certificate](CERTIFICATES.d/04-certificate.avif)
Now we know that "`ISRG Root X2`" is required, some scripts need just
that information.
Import a certificate by CommonName
----------------------------------
Running the function `$CertificateAvailable` with that name as parameter
makes sure the certificate is available in the device's store:
$CertificateAvailable "ISRG Root X2" "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)

View file

@ -1,41 +1,66 @@
Past Contributions
==================
[◀ Go back to main README](README.md)
[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network)
[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers)
[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.15-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts)
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
Thanks a lot for your contributions!
[⬅️ Go back to main README](README.md)
Thanks a lot for your contributions! ❤️
## Patches
These persons contributed code or documentation. See the git history
for details!
* [Anatoly Bubenkov](mailto:bubenkoff@gmail.com) (@bubenkoff)
* [Ben Harris](mailto:mail@bharr.is) (@bharrisau)
* [Daniel Ziegenberg](mailto:daniel@ziegenberg.at) (@ziegenberg)
* [Ignacio Serrano](mailto:ignic@ignic.com) (@ignic)
* [Ilya Kulakov](mailto:kulakov.ilya@gmail.com) (@Kentzo)
* [Leonardo David Monteiro](mailto:leo@cub3.xyz) (@leosfsm)
* [Michael Gisbers](mailto:michael@gisbers.de) (@mgisbers)
* [Miquel Bonastre](mailto:mbonastre@yahoo.com) (@mbonastre)
* @netravnen
* [netztrip](mailto:dave-tvg@netztrip.de) (@netztrip)
* [Stefan Müller](mailto:stefan.mueller.83@gmail.com) (@PackElend)
## Donations
Add yourself to the list,
[donate with PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)!
[donate with PayPal ↗️](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)!
* Abdul Mannan Abbasi
* Alex Maier
* Andrea Ruffini Perico
* Andrew Cox
* Christoph Boss (@Kampfwurst)
* Daniel Ziegenberg (@ziegenberg)
* Devin Dean (@dd2594gh)
* Evaldo Gardenal
* Florian Estraviz
* Giorgio Bikos
* Harold Schoemaker
* Hugo BV
* 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
* Richard Österreicher
* Simon Hitzemann
* Sunny Chu (@sunnychuchu)
* Ulrich Wessendorf
* Zac Kornilakis
---
[ Go back to main README](README.md)
[ Go back to top](#top)
[⬅️ Go back to main README](README.md)
[⬆️ Go back to top](#top)

63
DEBUG.md Normal file
View file

@ -0,0 +1,63 @@
Debug output and logs
=====================
[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network)
[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers)
[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.15-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts)
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
[⬅️ Go back to main README](README.md)
Sometimes scripts do not behave as expected. In these cases debug output
or logs can help.
## Debug output
Run this command in a terminal:
:set PrintDebug true;
You will then see debug output when running the script from terminal.
To revert to default output run:
:set PrintDebug false;
### Debug output for specific script
Even having debug output for a specific script or function only (or a
set of) is possible. To enable debug output for `telegram-chat` run:
:set ($PrintDebugOverride->"telegram-chat") true;
## Debug logs
The debug info can go to system log. To make it show up in `memory` run:
/system/logging/add topics=script,debug action=memory;
Other actions (`disk`, `email`, `remote` or `support`) can be used as
well. I do not recommend using `echo` - use [debug output](#debug-output)
instead.
Disable or remove that setting to restore regular logging.
## Verbose output
Specific scripts can generate huge amount of output. These do use a function
`$LogPrintVerbose`, which is declared, but has no code, intentionally.
If you *really* want that output set the function to be the same as
`$LogPrint`:
:set LogPrintVerbose $LogPrint;
To revert that change just run:
:set LogPrintVerbose;
---
[⬅️ Go back to main README](README.md)
[⬆️ Go back to top](#top)

View file

@ -1,42 +1,69 @@
Initial commands
================
[◀ Go back to main README](README.md)
[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network)
[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers)
[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.15-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts)
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
> ⚠️ **Warning**: These command are inteneded for initial setup. If you are
[⬅️ Go back to main README](README.md)
> ⚠️ **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).
One extra step is required if you run RouterOS v6:
:global ScriptUpdatesUrlSuffix "\?h=routeros-v6";
Then run the complete base installation:
Run the complete base installation:
{
:global ScriptUpdatesUrlSuffix;
/ tool fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/R3.pem" dst-path="letsencrypt-R3.pem" as-value;
:delay 1s;
/ certificate import file-name=letsencrypt-R3.pem passphrase="";
:if ([ :len [ / certificate find where fingerprint="67add1166b020ae61b8f5fc96813c04c2aa589960796865572a3c7e737613dfd" or fingerprint="96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6" ] ] != 2) do={
:error "Something is wrong with your certificates!";
:local BaseUrl "https://rsc.eworm.de/main/";
:local CertCommonName "ISRG Root X2";
:local CertFileName "ISRG-Root-X2.pem";
:local CertFingerprint "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470";
:local CertSettings [ /certificate/settings/get ];
:if (!((($CertSettings->"builtin-trust-anchors") = "trusted" || \
($CertSettings->"builtin-trust-store") ~ "fetch" || \
($CertSettings->"builtin-trust-store") = "all") && \
[[ :parse (":return [ :len [ /certificate/builtin/find where common-name=\"" . $CertCommonName . "\" ] ]") ]] > 0)) do={
:put "Importing certificate...";
/tool/fetch ($BaseUrl . "certs/" . $CertFileName) dst-path=$CertFileName as-value;
:delay 1s;
/certificate/import file-name=$CertFileName passphrase="";
:if ([ :len [ /certificate/find where fingerprint=$CertFingerprint ] ] != 1) do={
:error "Something is wrong with your certificates!";
};
:delay 1s;
};
/ file remove "letsencrypt-R3.pem";
:delay 1s;
:put "Renaming global-config-overlay, if exists...";
/system/script/set name=("global-config-overlay-" . [ /system/clock/get date ] . "-" . [ /system/clock/get time ]) [ find where name="global-config-overlay" ];
:foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={
/ system script add name=$Script source=([ / tool fetch check-certificate=yes-without-crl ("https://git.eworm.de/cgit/routeros-scripts/plain/" . $Script . $ScriptUpdatesUrlSuffix) output=user as-value]->"data");
:put "Installing $Script...";
/system/script/remove [ find where name=$Script ];
/system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ($BaseUrl . $Script . ".rsc") output=user as-value ]->"data");
};
/ system script { run global-config; run global-functions; };
/ system scheduler add name="global-scripts" start-time=startup on-event="/ system script { run global-config; run global-functions; }";
:global CertificateNameByCN;
$CertificateNameByCN "R3";
$CertificateNameByCN "ISRG Root X1";
}
:put "Loading configuration and functions...";
/system/script { run global-config; run global-functions; };
:if ([ :len [ /certificate/find where fingerprint=$CertFingerprint ] ] > 0) do={
:put "Renaming certificate by its common-name...";
:global CertificateNameByCN;
$CertificateNameByCN $CertFingerprint;
};
};
Optional to update the scripts automatically:
Then continue setup with
[scheduled automatic updates](README.md#scheduled-automatic-updates) or
[editing configuration](README.md#editing-configuration).
/ system scheduler add name="ScriptInstallUpdate" start-time=startup interval=1d on-event=":global ScriptInstallUpdate; \$ScriptInstallUpdate;";
## Fix existing installation
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 top](#top)
[⬅️ Go back to main README](README.md)
[⬆️ Go back to top](#top)

View file

@ -2,24 +2,45 @@
# template scripts -> final scripts
# markdown files -> html files
TEMPLATE = $(wildcard *.template)
CAPSMAN = $(TEMPLATE:.template=.capsman)
LOCAL = $(TEMPLATE:.template=.local)
ALL_RSC := $(wildcard *.rsc */*.rsc)
GEN_RSC := $(wildcard *.capsman.rsc *.local.rsc *.wifi.rsc)
MARKDOWN = $(wildcard *.md doc/*.md doc/mod/*.md)
HTML = $(MARKDOWN:.md=.html)
MARKDOWN := $(wildcard *.md doc/*.md doc/mod/*.md)
HTML := $(MARKDOWN:.md=.html)
all: $(CAPSMAN) $(LOCAL) $(HTML)
DATE ?= $(shell date --rfc-email)
VERSION ?= $(shell git symbolic-ref --short HEAD 2>/dev/null)/$(shell git rev-list --count HEAD 2>/dev/null)/$(shell git rev-parse --short=8 HEAD 2>/dev/null)
export DATE VERSION
%.html: %.md Makefile
markdown $< | sed 's/href="\([-_\./[:alnum:]]*\)\.md"/href="\1.html"/g' > $@
.PHONY: all checksums commitinfo docs rsc clean
%.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!' \
< $< > $@
all: checksums docs rsc
%.capsman: %.template Makefile
sed -e '/\/ interface wireless/d' -e 's/%PATH%/caps-man/' -e 's/%TEMPL%/$(suffix $@)/' \
-e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \
< $< > $@
checksums: checksums.json
checksums.json: contrib/checksums.sh $(ALL_RSC)
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -1,3 +1,5 @@
#!rsc by RouterOS
:put ("Hello World from " . [ / system identity get name ] . "!");
:put ("Hello World from " . [ /system/identity/get name ] . "!");

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

386
README.md
View file

@ -1,44 +1,73 @@
RouterOS Scripts
================
[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?style=social)](https://github.com/eworm-de/routeros-scripts/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?style=social)](https://github.com/eworm-de/routeros-scripts/network)
[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?style=social)](https://github.com/eworm-de/routeros-scripts/watchers)
[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network)
[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers)
[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.15-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts)
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
![RouterOS Scripts Logo](logo.svg)
[RouterOS](https://mikrotik.com/software) is the operating system developed
by [MikroTik](https://mikrotik.com/aboutus) for networking tasks. This
repository holds a number of [scripts](https://wiki.mikrotik.com/wiki/Manual:Scripting)
[RouterOS ↗️](https://mikrotik.com/software) is the operating system developed
by [MikroTik ↗️](https://mikrotik.com/aboutus) for networking tasks. This
repository holds a number of [scripts ↗️](https://wiki.mikrotik.com/wiki/Manual:Scripting)
to manage RouterOS devices or extend their functionality.
*Use at your own risk*, pay attention to
[license and warranty](#license-and-warranty)!
[license and warranty](#license-and-warranty), and
[disclaimer on external links](#disclaimer-on-external-links)!
Requirements
------------
### Software (RouterOS)
Latest version of the scripts require recent RouterOS to function properly.
Make sure to install latest updates before you begin.
Make sure to install latest updates before you begin. If new functionality
or a breaking change in RouterOS `7.n` is used in my scripts I push my
change some time after `7.(n+1)` was released. At any time you should have
at least two minor and their bugfix releases to choose from.
Specific scripts may require even newer RouterOS version.
> **Info**: The `main` branch is now RouterOS v7 only. If you are still
> running RouterOS v6 switch to `routeros-v6` branch!
Starting with RouterOS 7.17 the
[device-mode ↗️](https://help.mikrotik.com/docs/spaces/ROS/pages/93749258/Device-mode)
has been extended to give more fine-grained control over what features are
available. You need to enable `scheduler` and `fetch` at least, specific
scripts may require additional features.
### Hardware
RouterOS packages increase in size with each release. This becomes a
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
-------------
### Get me ready!
If you know how things work just copy and paste the
[initial commands](INITIAL-COMMANDS.md). Remember to edit and rerun
[initial commands](INITIAL-COMMANDS.md). These also support fixing an
existing but broken installation. Remember to edit and rerun
`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
Want to see it in action? I've had a presentation [Repository based
RouterOS script distribution](https://www.youtube.com/watch?v=B9neG3oAhcY)
including demonstation recorded live at [MUM Europe
2019](https://mum.mikrotik.com/2019/EU/) in Vienna.
RouterOS script distribution ↗️](https://www.youtube.com/watch?v=B9neG3oAhcY)
including demonstration recorded live at [MUM Europe
2019 ↗️](https://mum.mikrotik.com/2019/EU/) in Vienna.
> ⚠️ **Warning**: Some details changed. So see the presentation, then follow
> the steps below for up-to-date commands.
@ -46,86 +75,112 @@ including demonstation recorded live at [MUM Europe
### The long way in detail
The update script does server certificate verification, so first step is to
download the certificates. If you intend to download the scripts from a
download the certificates.
> 💡️ **Hint**: RouterOS 7.19 comes with a builtin certificate store. You
> can skip the steps regarding certificate download and import and jump
> to [installation of scripts](#installation-of-scripts) if you set the
> trust for these builtin trust anchors:
> `/certificate/settings/set builtin-trust-anchors=trusted;`
> 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
certificate chain.
/ tool fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/R3.pem" dst-path="letsencrypt-R3.pem";
/tool/fetch "https://rsc.eworm.de/main/certs/ISRG-Root-X2.pem" dst-path="isrg-root-x2.pem";
![screenshot: download certs](README.d/01-download-certs.avif)
Note that the commands above do *not* verify server certificate, so if you
want to be safe download with your workstations's browser and transfer the
files to your MikroTik device.
file to your MikroTik device.
* [ISRG Root X1](https://letsencrypt.org/certs/isrgrootx1.pem)
* Let's Encrypt [R3](https://letsencrypt.org/certs/lets-encrypt-r3.pem)
* [ISRG Root X2 ↗️](https://letsencrypt.org/certs/isrg-root-x2.pem)
Then we import the certificates.
Then we import the certificate.
/ certificate import file-name=letsencrypt-R3.pem passphrase="";
/certificate/import file-name="isrg-root-x2.pem" passphrase="";
Do not worry that the command is not shown - that happens because it contains
a sensitive property, the passphrase.
![screenshot: import certs](README.d/02-import-certs.avif)
For basic verification we rename the certificates and print their count. Make
sure the certificate count is **two**.
For basic verification we rename the certificate and print it by
fingerprint. Make sure exactly this one certificate ("*ISRG-Root-X2*")
is shown.
/ certificate set name="R3" [ find where fingerprint="67add1166b020ae61b8f5fc96813c04c2aa589960796865572a3c7e737613dfd" ];
/ certificate set name="ISRG-Root-X1" [ find where fingerprint="96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6" ];
/ certificate print count-only where fingerprint="67add1166b020ae61b8f5fc96813c04c2aa589960796865572a3c7e737613dfd" or fingerprint="96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6";
/certificate/set name="ISRG-Root-X2" [ find where common-name="ISRG Root X2" ];
/certificate/print proplist=name,fingerprint where fingerprint="69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470";
![screenshot: check certs](README.d/03-check-certs.avif)
Always make sure there are no certificates installed you do not know or want!
#### Installation of scripts
All following commands will verify the server certificate. For validity the
certificate's lifetime is checked with local time, so make sure the device's
date and time is set correctly!
One extra step is required if you run RouterOS v6:
:global ScriptUpdatesUrlSuffix "\?h=routeros-v6";
Now let's download the main scripts and add them in configuration on the fly.
:global ScriptUpdatesUrlSuffix;
: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 . $ScriptUpdatesUrlSuffix) output=user as-value]->"data"); };
:foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={ /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ("https://rsc.eworm.de/main/" . $Script . ".rsc") output=user as-value ]->"data"); };
![screenshot: import scripts](README.d/04-import-scripts.avif)
And finally run configuration and functions. This will also add the
scheduler for loading at system startup automatically.
/system/script { run global-config; run global-functions; };
![screenshot: run scripts](README.d/05-run-scripts.avif)
> 💡️ **Hint**: You see complaints regarding syntax errors? Most likely the
> RouterOS on your device is too old. Check for updates!
### Scheduled automatic updates
The last step is optional: Add this scheduler **only** if you want the
scripts to be updated automatically!
/system/scheduler/add name="ScriptInstallUpdate" start-time=startup interval=1d on-event=":global ScriptInstallUpdate; \$ScriptInstallUpdate;";
![screenshot: schedule update](README.d/06-schedule-update.avif)
Editing configuration
---------------------
The configuration needs to be tweaked for your needs. Edit
`global-config-overlay`, copy configuration from
[`global-config`](global-config) (the one without `-overlay`).
`global-config-overlay`, copy relevant configuration from
[`global-config`](global-config.rsc) (the one without `-overlay`).
Save changes and exit with `Ctrl-o`.
/ system script edit global-config-overlay source;
/system/script/edit global-config-overlay source;
![screenshot: edit global-config-overlay](README.d/05-edit-global-config-overlay.avif)
![screenshot: edit global-config-overlay](README.d/07-edit-global-config-overlay.avif)
And finally load configuration and functions and add the scheduler.
Additionally creating configuration snippets is supported. The script name
of these snippets has to start with `global-config-overlay.d/` to make them
being loaded automatically. This allows to split off parts of the
configuration.
/ system script { run global-config; run global-functions; };
/ system scheduler add name="global-scripts" start-time=startup on-event="/ system script { run global-config; run global-functions; }";
To apply your changes run `global-config`, which will automatically load
the overlay as well:
![screenshot: run and schedule scripts](README.d/06-run-and-schedule-scripts.avif)
/system/script/run global-config;
The last step is optional: Add this scheduler **only** if you want the scripts
to be updated automatically!
![screenshot: apply configuration](README.d/08-apply-configuration.avif)
/ 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.
![screenshot: schedule update](README.d/07-schedule-update.avif)
### Changes for RouterOS v6
RouterOS v7 is the way to go, let's consider RouterOS v6 deprecated.
If you want to stay with RouterOS v6 for some time add these lines
to your `global-config-overlay`, if missing:
# Use branch routeros-v6 with RouterOS v6:
:global ScriptUpdatesUrlSuffix "\?h=routeros-v6";
Then reload the 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
----------------
@ -135,7 +190,12 @@ everything is up-to-date it will not produce any output.
$ScriptInstallUpdate;
![screenshot: update scripts](README.d/08-update-scripts.avif)
![screenshot: update scripts](README.d/09-update-scripts.avif)
If the update includes news or requires configuration changes a notification
is sent - in addition to terminal output and log messages.
![news and changes notification](README.d/notification-news-and-changes.avif)
Adding a script
---------------
@ -145,91 +205,143 @@ a comma separated list of script names.
$ScriptInstallUpdate check-certificates,check-routeros-update;
![screenshot: install scripts](README.d/09-install-scripts.avif)
![screenshot: install scripts](README.d/10-install-scripts.avif)
Scheduler and events
--------------------
Most scripts are designed to run regularly from
[scheduler](https://wiki.mikrotik.com/wiki/Manual:System/Scheduler). We just
added `check-routeros-update`, so let's run it every hour to make sure not to
[scheduler ↗️](https://wiki.mikrotik.com/wiki/Manual:System/Scheduler). We just
added `check-routeros-update`, so let's run it daily to make sure not to
miss an update.
/ system scheduler add name="check-routeros-update" interval=1h on-event="/ system script run check-routeros-update;";
/system/scheduler/add name="check-routeros-update" interval=1d start-time=startup on-event="/system/script/run check-routeros-update;";
![screenshot: schedule script](README.d/10-schedule-script.avif)
![screenshot: schedule script](README.d/11-schedule-script.avif)
Some events can run a script. If you want your DHCP hostnames to be available
in DNS use `dhcp-to-dns` with the events from dhcp server. For a regular
cleanup add a scheduler entry.
$ScriptInstallUpdate dhcp-to-dns,lease-script;
/ ip dhcp-server set lease-script=lease-script [ find ];
/ system scheduler add name="dhcp-to-dns" interval=5m on-event="/ system script run dhcp-to-dns;";
/ip/dhcp-server/set lease-script=lease-script [ find ];
/system/scheduler/add name="dhcp-to-dns" interval=5m start-time=startup on-event="/system/script/run dhcp-to-dns;";
![screenshot: setup lease script](README.d/11-setup-lease-script.avif)
![screenshot: setup lease script](README.d/12-setup-lease-script.avif)
There's much more to explore... Have fun!
Available scripts
-----------------
* [Find and remove access list duplicates](doc/accesslist-duplicates.md)
* [Upload backup to Mikrotik cloud](doc/backup-cloud.md)
* [Send backup via e-mail](doc/backup-email.md)
* [Save configuration to fallback partition](doc/backup-partition.md)
* [Upload backup to server](doc/backup-upload.md)
* [Download packages for CAP upgrade from CAPsMAN](doc/capsman-download-packages.md)
* [Run rolling CAP upgrades from CAPsMAN](doc/capsman-rolling-upgrade.md)
* [Renew locally issued certificates](doc/certificate-renew-issued.md)
* [Renew certificates and notify on expiration](doc/check-certificates.md)
* [Notify about health state](doc/check-health.md)
* [Notify on LTE firmware upgrade](doc/check-lte-firmware-upgrade.md)
* [Notify on RouterOS update](doc/check-routeros-update.md)
* [Collect MAC addresses in wireless access list](doc/collect-wireless-mac.md)
* [Use wireless network with daily psk](doc/daily-psk.md)
* [Comment DHCP leases with info from access list](doc/dhcp-lease-comment.md)
* [Create DNS records for DHCP leases](doc/dhcp-to-dns.md)
* [Automatically upgrade firmware and reboot](doc/firmware-upgrade-reboot.md)
* [Wait for global functions und modules](doc/global-wait.md)
* [Send GPS position to server](doc/gps-track.md)
* [Use WPA2 network with hotspot credentials](doc/hotspot-to-wpa.md)
* [Create DNS records for IPSec peers](doc/ipsec-to-dns.md)
* [Update configuration on IPv6 prefix change](doc/ipv6-update.md)
* [Manage IP addresses with bridge status](doc/ip-addr-bridge.md)
* [Run other scripts on DHCP lease](doc/lease-script.md)
* [Manage LEDs dark mode](doc/leds-mode.md)
* [Forward log messages via notification](doc/log-forward.md)
* [Mode button with multiple presses](doc/mode-button.md)
* [Manage DNS and DoH servers from netwatch](doc/netwatch-dns.md)
* [Notify on host up and down](doc/netwatch-notify.md)
* [Manage remote logging](doc/netwatch-syslog.md)
* [Visualize OSPF state via LEDs](doc/ospf-to-leds.md)
* [Manage system update](doc/packages-update.md)
* [Run scripts on ppp connection](doc/ppp-on-up.md)
* [Rotate NTP servers](doc/rotate-ntp.md)
* [Act on received SMS](doc/sms-action.md)
* [Forward received SMS](doc/sms-forward.md)
* [Import SSH keys](doc/ssh-keys-import.md)
* [Play Super Mario theme](doc/super-mario-theme.md)
* [Install LTE firmware upgrade](doc/unattended-lte-firmware-upgrade.md)
* [Update GRE configuration with dynamic addresses](doc/update-gre-address.md)
* [Update tunnelbroker configuration](doc/update-tunnelbroker.md)
[comment]: # (TODO: currently undocumented)
[comment]: # (* learn-mac-based-vlan)
[comment]: # (* manage-umts)
* [Find and remove access list duplicates](doc/accesslist-duplicates.md) (`accesslist-duplicates`)
* [Upload backup to Mikrotik cloud](doc/backup-cloud.md) (`backup-cloud`)
* [Send backup via e-mail](doc/backup-email.md) (`backup-email`)
* [Save configuration to fallback partition](doc/backup-partition.md) (`backup-partition`)
* [Upload backup to server](doc/backup-upload.md) (`backup-upload`)
* [Download packages for CAP upgrade from CAPsMAN](doc/capsman-download-packages.md) (`capsman-download-packages`)
* [Run rolling CAP upgrades from CAPsMAN](doc/capsman-rolling-upgrade.md) (`capsman-rolling-upgrade`)
* [Renew locally issued certificates](doc/certificate-renew-issued.md) (`certificate-renew-issued`)
* [Renew certificates and notify on expiration](doc/check-certificates.md) (`check-certificates`)
* [Notify about health state](doc/check-health.md) (`check-health`)
* [Notify on LTE firmware upgrade](doc/check-lte-firmware-upgrade.md) (`check-lte-firmware-upgrade`)
* [Check perpetual license on CHR](doc/check-perpetual-license.md) (`check-perpetual-license`)
* [Notify on RouterOS update](doc/check-routeros-update.md) (`check-routeros-update`)
* [Collect MAC addresses in wireless access list](doc/collect-wireless-mac.md) (`collect-wireless-mac`)
* [Use wireless network with daily psk](doc/daily-psk.md) (`daily-psk`)
* [Comment DHCP leases with info from access list](doc/dhcp-lease-comment.md) (`dhcp-lease-comment`)
* [Create DNS records for DHCP leases](doc/dhcp-to-dns.md) (`dhcp-to-dns`)
* [Automatically upgrade firmware and reboot](doc/firmware-upgrade-reboot.md) (`firmware-upgrade-reboot`)
* [Download, import and update firewall address-lists](doc/fw-addr-lists.md) (`fw-addr-lists`)
* [Wait for global functions und modules](doc/global-wait.md) (`global-wait`)
* [Send GPS position to server](doc/gps-track.md) (`gps-track`)
* [Use WPA network with hotspot credentials](doc/hotspot-to-wpa.md) (`hotspot-to-wpa` & `hotspot-to-wpa-cleanup`)
* [Create DNS records for IPSec peers](doc/ipsec-to-dns.md) (`ipsec-to-dns`)
* [Update configuration on IPv6 prefix change](doc/ipv6-update.md) (`ipv6-update`)
* [Manage IP addresses with bridge status](doc/ip-addr-bridge.md) (`ip-addr-bridge`)
* [Run other scripts on DHCP lease](doc/lease-script.md) (`lease-script`)
* [Manage LEDs dark mode](doc/leds-mode.md) (`leds-day-mode`, `leds-night-mode` & `leds-toggle-mode`)
* [Forward log messages via notification](doc/log-forward.md) (`log-forward`)
* [Mode button with multiple presses](doc/mode-button.md) (`mode-button`)
* [Manage DNS and DoH servers from netwatch](doc/netwatch-dns.md) (`netwatch-dns`)
* [Notify on host up and down](doc/netwatch-notify.md) (`netwatch-notify`)
* [Visualize OSPF state via LEDs](doc/ospf-to-leds.md) (`ospf-to-leds`)
* [Manage system update](doc/packages-update.md) (`packages-update`)
* [Run scripts on ppp connection](doc/ppp-on-up.md) (`ppp-on-up`)
* [Act on received SMS](doc/sms-action.md) (`sms-action`)
* [Forward received SMS](doc/sms-forward.md) (`sms-forward`)
* [Play Super Mario theme](doc/super-mario-theme.md) (`super-mario-theme`)
* [Chat with your router and send commands via Telegram bot](doc/telegram-chat.md) (`telegram-chat`)
* [Install LTE firmware upgrade](doc/unattended-lte-firmware-upgrade.md) (`unattended-lte-firmware-upgrade`)
* [Update GRE configuration with dynamic addresses](doc/update-gre-address.md) (`update-gre-address`)
* [Update tunnelbroker configuration](doc/update-tunnelbroker.md) (`update-tunnelbroker`)
Available modules
-----------------
* [Manage ports in bridge](doc/mod/bridge-port-to.md)
* [Manage VLANs on bridge ports](doc/mod/bridge-port-vlan.md)
* [Inspect variables](doc/mod/inspectvar.md)
* [IP address calculation](doc/mod/ipcalc.md)
* [Send notifications via Matrix](doc/mod/notification-matrix.md)
* [Send notifications via Telegram](doc/mod/notification-telegram.md)
* [Download script and run it once](doc/mod/scriptrunonce.md)
* [Manage ports in bridge](doc/mod/bridge-port-to.md) (`mod/bridge-port-to`)
* [Manage VLANs on bridge ports](doc/mod/bridge-port-vlan.md) (`mod/bridge-port-vlan`)
* [Inspect variables](doc/mod/inspectvar.md) (`mod/inspectvar`)
* [IP address calculation](doc/mod/ipcalc.md) (`mod/ipcalc`)
* [Send notifications via e-mail](doc/mod/notification-email.md) (`mod/notification-email`)
* [Send notifications via Gotify](doc/mod/notification-gotify.md) (`mod/notification-gotify`)
* [Send notifications via Matrix](doc/mod/notification-matrix.md) (`mod/notification-matrix`)
* [Send notifications via Ntfy](doc/mod/notification-ntfy.md) (`mod/notification-ntfy`)
* [Send notifications via Telegram](doc/mod/notification-telegram.md) (`mod/notification-telegram`)
* [Download script and run it once](doc/mod/scriptrunonce.md) (`mod/scriptrunonce`)
* [Import ssh keys for public key authentication](doc/mod/ssh-keys-import.md) (`mod/ssh-keys-import`)
Installing custom scripts & modules
-----------------------------------
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/";
![screenshot: install custom script](README.d/13-install-custom-script.avif)
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;
![screenshot: remove script](README.d/14-remove-script.avif)
Possibly a scheduler and other configuration has to be removed as well.
Installing custom scripts & modules
-----------------------------------
@ -256,9 +368,9 @@ automatically by `global-functions`.
Contact
-------
We have a Telegram Group [RouterOS-Scripts](https://t.me/routeros_scripts)!
We have a Telegram Group [RouterOS-Scripts ↗️](https://t.me/routeros_scripts)!
![RouterOS Scripts Telegram Group](README.d/telegram-group.avif)
[![RouterOS Scripts Telegram Group](README.d/telegram-group.avif)](https://t.me/routeros_scripts)
Get help, give feedback or just chat - but do not expect free professional
support!
@ -266,21 +378,23 @@ support!
Contribute
----------
Thanks a lot for [past contributions](CONTRIBUTIONS.md)!
Thanks a lot for [past contributions](CONTRIBUTIONS.md)! ❤️
### Patches, issues and whishlist
Feel free to contact me via e-mail or open an
[issue at github](https://github.com/eworm-de/routeros-scripts/issues).
[issue](https://github.com/eworm-de/routeros-scripts/issues) or
[pull request](https://github.com/eworm-de/routeros-scripts/pulls)
at github.
### Donate
This project is developed in private spare time and usage is free of charge
for you. If you like the scripts and think this is of value for you or your
business please consider to
[donate with PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J).
[donate with PayPal ↗️](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J).
[![donate with PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=for-the-badge)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)
Thanks a lot for your support!
@ -297,15 +411,33 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
[GNU General Public License](COPYING.md) for more details.
Disclaimer on external links
----------------------------
Our website contains links to the websites of third parties ("external
links"). As the content of these websites is not under our control, we
cannot assume any liability for such external content. In all cases, the
provider of information of the linked websites is liable for the content
and accuracy of the information provided. At the point in time when the
links were placed, no infringements of the law were recognisable to us.
As soon as an infringement of the law becomes known to us, we will
immediately remove the link in question.
> 💡️ **Hint**: All external links are marked with an arrow pointing
> diagonally in an up-right (or north-east) direction (↗️).
Upstream
--------
URL:
[GitHub.com](https://github.com/eworm-de/routeros-scripts#routeros-scripts)
[rsc.eworm.de](https://rsc.eworm.de/)
Mirror:
[eworm.de](https://git.eworm.de/cgit/routeros-scripts/about/)
[GitLab.com](https://gitlab.com/eworm-de/routeros-scripts#routeros-scripts)
[![upstream](general/qr-code.png)](https://rsc.eworm.de/)
### Code hosting
* [git.eworm.de](https://git.eworm.de/cgit/routeros-scripts/about/)
* [GitHub.com](https://github.com/eworm-de/routeros-scripts#routeros-scripts)
* [GitLab.com](https://gitlab.com/eworm-de/routeros-scripts#routeros-scripts)
---
[▲ Go back to top](#top)
[⬆️ Go back to top](#top)

View file

@ -1,42 +0,0 @@
#!rsc by RouterOS
# RouterOS script: accesslist-duplicates.capsman
# Copyright (c) 2018-2022 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 0 "accesslist-duplicates.capsman";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global Read;
: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 [ :tonum [ $Read ] ];
:if ([ :typeof $Remove ] = "num") do={
:put ("Removing numeric id " . $Remove . "...\n");
/ caps-man access-list remove $Remove;
}
}
}
}
:set Seen ($Seen, $Mac);
}

View file

@ -0,0 +1,37 @@
#!rsc by RouterOS
# RouterOS script: accesslist-duplicates.capsman
# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -1,42 +0,0 @@
#!rsc by RouterOS
# RouterOS script: accesslist-duplicates.local
# Copyright (c) 2018-2022 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 0 "accesslist-duplicates.local";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global Read;
: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 [ :tonum [ $Read ] ];
:if ([ :typeof $Remove ] = "num") do={
:put ("Removing numeric id " . $Remove . "...\n");
/ interface wireless access-list remove $Remove;
}
}
}
}
:set Seen ($Seen, $Mac);
}

View file

@ -0,0 +1,37 @@
#!rsc by RouterOS
# RouterOS script: accesslist-duplicates.local
# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -1,43 +0,0 @@
#!rsc by RouterOS
# RouterOS script: accesslist-duplicates%TEMPL%
# Copyright (c) 2018-2022 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 0 "accesslist-duplicates%TEMPL%";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global Read;
: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 [ :tonum [ $Read ] ];
:if ([ :typeof $Remove ] = "num") do={
:put ("Removing numeric id " . $Remove . "...\n");
/ %PATH% access-list remove $Remove;
}
}
}
}
:set Seen ($Seen, $Mac);
}

View file

@ -0,0 +1,46 @@
#!rsc by RouterOS
# RouterOS script: accesslist-duplicates%TEMPL%
# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -0,0 +1,37 @@
#!rsc by RouterOS
# RouterOS script: accesslist-duplicates.wifi
# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -1,58 +0,0 @@
#!rsc by RouterOS
# RouterOS script: backup-cloud
# Copyright (c) 2013-2022 Christian Hesse <mail@eworm.de>
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
#
# provides: backup-script
#
# upload backup to MikroTik cloud
# https://git.eworm.de/cgit/routeros-scripts/about/doc/backup-cloud.md
:local 0 "backup-cloud";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global BackupPassword;
:global BackupRandomDelay;
:global Identity;
:global DeviceInfo;
:global LogPrintExit2;
:global RandomDelay;
:global ScriptFromTerminal;
:global SendNotification2;
:global SymbolForNotification;
:global WaitFullyConnected;
$WaitFullyConnected;
:if ([ $ScriptFromTerminal $0 ] = false && $BackupRandomDelay > 0) do={
$RandomDelay $BackupRandomDelay;
}
: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) ];
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "floppy-disk,cloud" ] . "Cloud backup"); \
message=("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"); silent=true });
} on-error={
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "warning-sign" ] . "Cloud backup failed"); \
message=("Failed uploading backup for " . $Identity . " to cloud!\n\n" . [ $DeviceInfo ]) });
$LogPrintExit2 error $0 ("Failed uploading backup for " . $Identity . " to cloud!") true;
}

104
backup-cloud.rsc Normal file
View file

@ -0,0 +1,104 @@
#!rsc by RouterOS
# RouterOS script: backup-cloud
# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# provides: backup-script, order=40
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -1,80 +0,0 @@
#!rsc by RouterOS
# RouterOS script: backup-email
# Copyright (c) 2013-2022 Christian Hesse <mail@eworm.de>
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
#
# provides: backup-script
#
# create and email backup and config file
# https://git.eworm.de/cgit/routeros-scripts/about/doc/backup-email.md
:local 0 "backup-email";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global BackupPassword;
:global BackupRandomDelay;
:global BackupSendBinary;
:global BackupSendExport;
:global Domain;
:global Identity;
:global CharacterReplace;
:global DeviceInfo;
:global LogPrintExit2;
:global MkDir;
:global RandomDelay;
:global ScriptFromTerminal;
:global SendEMail2;
:global SymbolForNotification;
:global WaitForFile;
:global WaitFullyConnected;
:if ($BackupSendBinary != true && \
$BackupSendExport != true) do={
$LogPrintExit2 error $0 ("Configured to send neither backup nor config export.") true;
}
$WaitFullyConnected;
:if ([ $ScriptFromTerminal $0 ] = false && $BackupRandomDelay > 0) do={
$RandomDelay $BackupRandomDelay;
}
:if ([ $MkDir $0 ] = false) do={
$LogPrintExit2 error $0 ("Failed creating directory!") true;
}
# filename based on identity
:local FileName [ $CharacterReplace ($Identity . "." . $Domain) "." "_" ];
:local FilePath ($0 . "/" . $FileName);
:local BackupFile "none";
:local ConfigFile "none";
:local Attach [ :toarray "" ];
# 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 ConfigFile ($FileName . ".rsc");
:set Attach ($Attach, ($FilePath . ".rsc"));
}
# send email with status and files
$SendEMail2 ({ origin=$0; \
subject=([ $SymbolForNotification "floppy-disk,incoming-envelope" ] . \
"Backup & Config"); \
message=("See attached files for backup and config export for " . \
$Identity . ".\n\n" . \
[ $DeviceInfo ] . "\n\n" . \
"Backup file: " . $BackupFile . "\n" . \
"Config file: " . $ConfigFile); \
attach=$Attach; remove-attach=true });

143
backup-email.rsc Normal file
View file

@ -0,0 +1,143 @@
#!rsc by RouterOS
# RouterOS script: backup-email
# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# provides: backup-script, order=20
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -1,36 +0,0 @@
#!rsc by RouterOS
# RouterOS script: backup-partition
# Copyright (c) 2022 Christian Hesse <mail@eworm.de>
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
#
# provides: backup-script
#
# save configuration to fallback partition
# https://git.eworm.de/cgit/routeros-scripts/about/doc/backup-partition.md
:local 0 "backup-partition";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global LogPrintExit2;
:if ([ :len [ / partitions find ] ] < 2) do={
$LogPrintExit2 error $0 ("Device does not have a fallback partition.") true;
}
:local ActiveRunning [ / partitions find where active running ];
:if ([ :len $ActiveRunning ] < 1) do={
$LogPrintExit2 error $0 ("Device is not running from active partition.") true;
}
:local ActiveRunningVar [ / partitions get $ActiveRunning ];
:do {
/ partitions save-config-to ($ActiveRunningVar->"fallback-to");
$LogPrintExit2 info $0 ("Saved configuration to partition '" . \
($ActiveRunningVar->"fallback-to") . "'.") false;
} on-error={
$LogPrintExit2 error $0 ("Failed saving configuration to partition '" . \
($ActiveRunningVar->"fallback-to") . "'!") true;
}

128
backup-partition.rsc Normal file
View file

@ -0,0 +1,128 @@
#!rsc by RouterOS
# RouterOS script: backup-partition
# Copyright (c) 2022-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# provides: backup-script, order=70
# requires RouterOS, version=7.15
# 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;
}

View file

@ -1,106 +0,0 @@
#!rsc by RouterOS
# RouterOS script: backup-upload
# Copyright (c) 2013-2022 Christian Hesse <mail@eworm.de>
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
#
# provides: backup-script
#
# create and upload backup and config file
# https://git.eworm.de/cgit/routeros-scripts/about/doc/backup-upload.md
:local 0 "backup-upload";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global BackupPassword;
:global BackupRandomDelay;
:global BackupSendBinary;
:global BackupSendExport;
:global BackupUploadPass;
:global BackupUploadUrl;
:global BackupUploadUser;
:global Domain;
:global Identity;
:global CharacterReplace;
:global DeviceInfo;
:global IfThenElse;
:global LogPrintExit2;
:global MkDir;
:global RandomDelay;
:global ScriptFromTerminal;
:global SendNotification2;
:global SymbolForNotification;
:global WaitForFile;
:global WaitFullyConnected;
:if ($BackupSendBinary != true && \
$BackupSendExport != true) do={
$LogPrintExit2 error $0 ("Configured to send neither backup nor config export.") true;
}
$WaitFullyConnected;
:if ([ $ScriptFromTerminal $0 ] = false && $BackupRandomDelay > 0) do={
$RandomDelay $BackupRandomDelay;
}
:if ([ $MkDir $0 ] = false) do={
$LogPrintExit2 error $0 ("Failed creating directory!") true;
}
# filename based on identity
:local FileName [ $CharacterReplace ($Identity . "." . $Domain) "." "_" ];
:local FilePath ($0 . "/" . $FileName);
:local BackupFile "none";
:local ConfigFile "none";
:local Failed 0;
# binary backup
:if ($BackupSendBinary = true) do={
/ system backup save encryption=aes-sha256 name=$FilePath password=$BackupPassword;
$WaitForFile ($FilePath . ".backup");
:do {
/ tool fetch upload=yes url=($BackupUploadUrl . "/" . $FileName . ".backup") \
user=$BackupUploadUser password=$BackupUploadPass src-path=($FilePath . ".backup");
:set BackupFile ($FileName . ".backup");
} on-error={
$LogPrintExit2 error $0 ("Uploading backup file failed!") false;
:set BackupFile "failed";
:set Failed 1;
}
/ file remove ($FilePath . ".backup");
}
# create configuration export
:if ($BackupSendExport = true) do={
/ export terse show-sensitive file=$FilePath;
$WaitForFile ($FilePath . ".rsc");
:do {
/ tool fetch upload=yes url=($BackupUploadUrl . "/" . $FileName . ".rsc") \
user=$BackupUploadUser password=$BackupUploadPass src-path=($FilePath . ".rsc");
:set ConfigFile ($FileName . ".rsc");
} on-error={
$LogPrintExit2 error $0 ("Uploading configuration export failed!") false;
:set ConfigFile "failed";
:set Failed 1;
}
/ file remove ($FilePath . ".rsc");
}
$SendNotification2 ({ origin=$0; \
subject=[ $IfThenElse ($Failed > 0) \
([ $SymbolForNotification "warning-sign" ] . "Backup & Config upload with failure") \
([ $SymbolForNotification "floppy-disk,up-arrow" ] . "Backup & Config upload") ]; \
message=("Backup and config export upload for " . $Identity . ".\n\n" . \
[ $DeviceInfo ] . "\n\n" . \
"Backup file: " . $BackupFile . "\n" . \
"Config file: " . $ConfigFile); silent=true });
:if ($Failed = 1) do={
:error "An error occured!";
}

178
backup-upload.rsc Normal file
View file

@ -0,0 +1,178 @@
#!rsc by RouterOS
# RouterOS script: backup-upload
# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# provides: backup-script, order=50
# requires RouterOS, version=7.15
# 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;
}

View file

@ -1,86 +0,0 @@
#!rsc by RouterOS
# RouterOS script: capsman-download-packages
# Copyright (c) 2018-2022 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
:local 0 "capsman-download-packages";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global CleanFilePath;
:global DownloadPackage;
:global LogPrintExit2;
:global MkDir;
:global ScriptLock;
:global WaitFullyConnected;
$ScriptLock $0;
$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={
$LogPrintExit2 warning $0 ("The CAPsMAN package path is not defined, can not download packages.") true;
}
:if ([ :len [ / file find where name=$PackagePath type="directory" ] ] = 0) do={
:if ([ $MkDir $PackagePath ] = false) do={
$LogPrintExit2 warning $0 ("Creating directory at CAPsMAN package path (" . \
$PackagePath . ") failed!") true;
}
$LogPrintExit2 info $0 ("Created directory at CAPsMAN 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 ([ $DownloadPackage ($File->"package-name") $InstalledVersion \
($File->"package-architecture") $PackagePath ] = true) do={
:set Updated true;
/ file remove $Package;
}
}
:if ([ :len [ / system logging find where topics~"error" !(topics~"!error") \
!(topics~"!caps") action=memory !disabled !invalid ] ] < 1) do={
$LogPrintExit2 warning $0 ("Looks like error messages for 'caps' are not sent to memory. " . \
"Probably can not download packages automatically.") false;
} else={
:if ($Updated = false && [ / system resource get uptime ] < 2m) do={
$LogPrintExit2 info $0 ("No packages downloaded, yet. Delaying for logs.") false;
:delay 2m;
}
}
:foreach Log in=[ / log find where topics=({"caps", "error"}) \
message~("upgrade status: failed, failed to download file '.*-" . $InstalledVersion . \
"-.*\\.npk', no such file") ] do={
:local Message [ / log get $Log message ];
:local Package [ :pick $Message \
([ :find $Message "'" ] + 1) \
[ :find $Message ("-" . $InstalledVersion . "-") ] ];
:local Arch [ :pick $Message \
([ :find $Message ("-" . $InstalledVersion . "-") ] + 2 + [ :len $InstalledVersion ]) \
[ :find $Message ".npk" ] ];
:if ([ $DownloadPackage $Package $InstalledVersion $Arch $PackagePath ] = true) do={
:set Updated true;
}
}
: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 ];
}
}

View file

@ -0,0 +1,93 @@
#!rsc by RouterOS
# RouterOS script: capsman-download-packages.capsman
# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -0,0 +1,104 @@
#!rsc by RouterOS
# RouterOS script: capsman-download-packages%TEMPL%
# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -0,0 +1,95 @@
#!rsc by RouterOS
# RouterOS script: capsman-download-packages.wifi
# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# Michael Gisbers <michael@gisbers.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -1,36 +0,0 @@
#!rsc by RouterOS
# RouterOS script: capsman-rolling-upgrade
# Copyright (c) 2018-2022 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
:local 0 "capsman-rolling-upgrade";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global LogPrintExit2;
:global ScriptLock;
$ScriptLock $0;
: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={
$LogPrintExit2 info $0 ("Starting upgrade for " . $RemoteCapVal->"name" . \
" (" . $RemoteCapVal->"identity" . ")...") false;
/ caps-man remote-cap upgrade $RemoteCap;
} else={
$LogPrintExit2 warning $0 ("Remote CAP vanished, skipping upgrade.") false;
}
:delay ($Delay . "s");
}
}

View file

@ -0,0 +1,50 @@
#!rsc by RouterOS
# RouterOS script: capsman-rolling-upgrade.capsman
# Copyright (c) 2018-2025 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.15
#
# 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;
}

View file

@ -0,0 +1,58 @@
#!rsc by RouterOS
# RouterOS script: capsman-rolling-upgrade%TEMPL%
# Copyright (c) 2018-2025 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.15
#
# 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;
}

View file

@ -0,0 +1,51 @@
#!rsc by RouterOS
# RouterOS script: capsman-rolling-upgrade.wifi
# Copyright (c) 2018-2025 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.15
#
# 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;
}

View file

@ -1,38 +0,0 @@
#!rsc by RouterOS
# RouterOS script: certificate-renew-issued
# Copyright (c) 2019-2022 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
:local 0 "certificate-renew-issued";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global CertIssuedExportPass;
:global LogPrintExit2;
: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={
: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"));
$LogPrintExit2 info $0 ("Issued a new certificate for \"" . $CertVal->"common-name" . \
"\", exported to \"cert-issued/" . $CertVal->"common-name" . ".p12\".") false;
} else={
$LogPrintExit2 warning $0 ("Failed creating directory, not exporting certificate.") false;
}
} else={
$LogPrintExit2 info $0 ("Issued a new certificate for \"" . $CertVal->"common-name" . "\".") false;
}
}

View file

@ -0,0 +1,52 @@
#!rsc by RouterOS
# RouterOS script: certificate-renew-issued
# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -0,0 +1,29 @@
# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
# Label: "Certum Trusted Network CA"
# Serial: 279744
# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78
# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e
# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e
-----BEGIN CERTIFICATE-----
MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
-----END CERTIFICATE-----

View file

@ -1,166 +0,0 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
0a:37:87:64:5e:5f:b4:8c:22:4e:fd:1b:ed:14:0c:3c
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
Validity
Not Before: Jan 27 12:48:08 2020 GMT
Not After : Dec 31 23:59:59 2024 GMT
Subject: C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:b9:ad:4d:66:99:14:0b:46:ec:1f:81:d1:2a:50:
1e:9d:03:15:2f:34:12:7d:2d:96:b8:88:38:9b:85:
5f:8f:bf:bb:4d:ef:61:46:c4:c9:73:d4:24:4f:e0:
ee:1c:ce:6c:b3:51:71:2f:6a:ee:4c:05:09:77:d3:
72:62:a4:9b:d7
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Subject Key Identifier:
A5:CE:37:EA:EB:B0:75:0E:94:67:88:B4:45:FA:D9:24:10:87:96:1F
X509v3 Authority Key Identifier:
keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
Authority Information Access:
OCSP - URI:http://ocsp.digicert.com
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl3.digicert.com/Omniroot2025.crl
X509v3 Certificate Policies:
Policy: 2.16.840.1.114412.1.1
CPS: https://www.digicert.com/CPS
Policy: 2.16.840.1.114412.1.2
Policy: 2.23.140.1.2.1
Policy: 2.23.140.1.2.2
Policy: 2.23.140.1.2.3
Signature Algorithm: sha256WithRSAEncryption
05:24:1d:dd:1b:b0:2a:eb:98:d6:85:e3:39:4d:5e:6b:57:9d:
82:57:fc:eb:e8:31:a2:57:90:65:05:be:16:44:38:5a:77:02:
b9:cf:10:42:c6:e1:92:a4:e3:45:27:f8:00:47:2c:68:a8:56:
99:53:54:8f:ad:9e:40:c1:d0:0f:b6:d7:0d:0b:38:48:6c:50:
2c:49:90:06:5b:64:1d:8b:cc:48:30:2e:de:08:e2:9b:49:22:
c0:92:0c:11:5e:96:92:94:d5:fc:20:dc:56:6c:e5:92:93:bf:
7a:1c:c0:37:e3:85:49:15:fa:2b:e1:74:39:18:0f:b7:da:f3:
a2:57:58:60:4f:cc:8e:94:00:fc:46:7b:34:31:3e:4d:47:82:
81:3a:cb:f4:89:5d:0e:ef:4d:0d:6e:9c:1b:82:24:dd:32:25:
5d:11:78:51:10:3d:a0:35:23:04:2f:65:6f:9c:c1:d1:43:d7:
d0:1e:f3:31:67:59:27:dd:6b:d2:75:09:93:11:24:24:14:cf:
29:be:e6:23:c3:b8:8f:72:3f:e9:07:c8:24:44:53:7a:b3:b9:
61:65:a1:4c:0e:c6:48:00:c9:75:63:05:87:70:45:52:83:d3:
95:9d:45:ea:f0:e8:31:1d:7e:09:1f:0a:fe:3e:dd:aa:3c:5e:
74:d2:ac:b1
-----BEGIN CERTIFICATE-----
MIIDzTCCArWgAwIBAgIQCjeHZF5ftIwiTv0b7RQMPDANBgkqhkiG9w0BAQsFADBa
MQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJl
clRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTIw
MDEyNzEyNDgwOFoXDTI0MTIzMTIzNTk1OVowSjELMAkGA1UEBhMCVVMxGTAXBgNV
BAoTEENsb3VkZmxhcmUsIEluYy4xIDAeBgNVBAMTF0Nsb3VkZmxhcmUgSW5jIEVD
QyBDQS0zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEua1NZpkUC0bsH4HRKlAe
nQMVLzQSfS2WuIg4m4Vfj7+7Te9hRsTJc9QkT+DuHM5ss1FxL2ruTAUJd9NyYqSb
16OCAWgwggFkMB0GA1UdDgQWBBSlzjfq67B1DpRniLRF+tkkEIeWHzAfBgNVHSME
GDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0l
BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYI
KwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
b20wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL09t
bmlyb290MjAyNS5jcmwwbQYDVR0gBGYwZDA3BglghkgBhv1sAQEwKjAoBggrBgEF
BQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzALBglghkgBhv1sAQIw
CAYGZ4EMAQIBMAgGBmeBDAECAjAIBgZngQwBAgMwDQYJKoZIhvcNAQELBQADggEB
AAUkHd0bsCrrmNaF4zlNXmtXnYJX/OvoMaJXkGUFvhZEOFp3ArnPEELG4ZKk40Un
+ABHLGioVplTVI+tnkDB0A+21w0LOEhsUCxJkAZbZB2LzEgwLt4I4ptJIsCSDBFe
lpKU1fwg3FZs5ZKTv3ocwDfjhUkV+ivhdDkYD7fa86JXWGBPzI6UAPxGezQxPk1H
goE6y/SJXQ7vTQ1unBuCJN0yJV0ReFEQPaA1IwQvZW+cwdFD19Ae8zFnWSfda9J1
CZMRJCQUzym+5iPDuI9yP+kHyCREU3qzuWFloUwOxkgAyXVjBYdwRVKD05WdRerw
6DEdfgkfCv4+3ao8XnTSrLE=
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 33554617 (0x20000b9)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
Validity
Not Before: May 12 18:46:00 2000 GMT
Not After : May 12 23:59:00 2025 GMT
Subject: C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:a3:04:bb:22:ab:98:3d:57:e8:26:72:9a:b5:79:
d4:29:e2:e1:e8:95:80:b1:b0:e3:5b:8e:2b:29:9a:
64:df:a1:5d:ed:b0:09:05:6d:db:28:2e:ce:62:a2:
62:fe:b4:88:da:12:eb:38:eb:21:9d:c0:41:2b:01:
52:7b:88:77:d3:1c:8f:c7:ba:b9:88:b5:6a:09:e7:
73:e8:11:40:a7:d1:cc:ca:62:8d:2d:e5:8f:0b:a6:
50:d2:a8:50:c3:28:ea:f5:ab:25:87:8a:9a:96:1c:
a9:67:b8:3f:0c:d5:f7:f9:52:13:2f:c2:1b:d5:70:
70:f0:8f:c0:12:ca:06:cb:9a:e1:d9:ca:33:7a:77:
d6:f8:ec:b9:f1:68:44:42:48:13:d2:c0:c2:a4:ae:
5e:60:fe:b6:a6:05:fc:b4:dd:07:59:02:d4:59:18:
98:63:f5:a5:63:e0:90:0c:7d:5d:b2:06:7a:f3:85:
ea:eb:d4:03:ae:5e:84:3e:5f:ff:15:ed:69:bc:f9:
39:36:72:75:cf:77:52:4d:f3:c9:90:2c:b9:3d:e5:
c9:23:53:3f:1f:24:98:21:5c:07:99:29:bd:c6:3a:
ec:e7:6e:86:3a:6b:97:74:63:33:bd:68:18:31:f0:
78:8d:76:bf:fc:9e:8e:5d:2a:86:a7:4d:90:dc:27:
1a:39
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:3
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
Signature Algorithm: sha1WithRSAEncryption
85:0c:5d:8e:e4:6f:51:68:42:05:a0:dd:bb:4f:27:25:84:03:
bd:f7:64:fd:2d:d7:30:e3:a4:10:17:eb:da:29:29:b6:79:3f:
76:f6:19:13:23:b8:10:0a:f9:58:a4:d4:61:70:bd:04:61:6a:
12:8a:17:d5:0a:bd:c5:bc:30:7c:d6:e9:0c:25:8d:86:40:4f:
ec:cc:a3:7e:38:c6:37:11:4f:ed:dd:68:31:8e:4c:d2:b3:01:
74:ee:be:75:5e:07:48:1a:7f:70:ff:16:5c:84:c0:79:85:b8:
05:fd:7f:be:65:11:a3:0f:c0:02:b4:f8:52:37:39:04:d5:a9:
31:7a:18:bf:a0:2a:f4:12:99:f7:a3:45:82:e3:3c:5e:f5:9d:
9e:b5:c8:9e:7c:2e:c8:a4:9e:4e:08:14:4b:6d:fd:70:6d:6b:
1a:63:bd:64:e6:1f:b7:ce:f0:f2:9f:2e:bb:1b:b7:f2:50:88:
73:92:c2:e2:e3:16:8d:9a:32:02:ab:8e:18:dd:e9:10:11:ee:
7e:35:ab:90:af:3e:30:94:7a:d0:33:3d:a7:65:0f:f5:fc:8e:
9e:62:cf:47:44:2c:01:5d:bb:1d:b5:32:d2:47:d2:38:2e:d0:
fe:81:dc:32:6a:1e:b5:ee:3c:d5:fc:e7:81:1d:19:c3:24:42:
ea:63:39:a9
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----

View file

@ -1,174 +0,0 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
07:f2:f3:5c:87:a8:77:af:7a:ef:e9:47:99:35:25:bd
Signature Algorithm: sha384WithRSAEncryption
Issuer: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
Validity
Not Before: Apr 14 00:00:00 2021 GMT
Not After : Apr 13 23:59:59 2031 GMT
Subject: C = US, O = DigiCert Inc, CN = DigiCert TLS Hybrid ECC SHA384 2020 CA1
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (384 bit)
pub:
04:c1:1b:c6:9a:5b:98:d9:a4:29:a0:e9:d4:04:b5:
db:eb:a6:b2:6c:55:c0:ff:ed:98:c6:49:2f:06:27:
51:cb:bf:70:c1:05:7a:c3:b1:9d:87:89:ba:ad:b4:
13:17:c9:a8:b4:83:c8:b8:90:d1:cc:74:35:36:3c:
83:72:b0:b5:d0:f7:22:69:c8:f1:80:c4:7b:40:8f:
cf:68:87:26:5c:39:89:f1:4d:91:4d:da:89:8b:e4:
03:c3:43:e5:bf:2f:73
ASN1 OID: secp384r1
NIST CURVE: P-384
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Subject Key Identifier:
0A:BC:08:29:17:8C:A5:39:6D:7A:0E:CE:33:C7:2E:B3:ED:FB:C3:7A
X509v3 Authority Key Identifier:
keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Authority Information Access:
OCSP - URI:http://ocsp.digicert.com
CA Issuers - URI:http://cacerts.digicert.com/DigiCertGlobalRootCA.crt
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl
X509v3 Certificate Policies:
Policy: 2.16.840.1.114412.2.1
Policy: 2.23.140.1.1
Policy: 2.23.140.1.2.1
Policy: 2.23.140.1.2.2
Policy: 2.23.140.1.2.3
Signature Algorithm: sha384WithRSAEncryption
47:59:81:7f:d4:1b:1f:b0:71:f6:98:5d:18:ba:98:47:98:b0:
7e:76:2b:ea:ff:1a:8b:ac:26:b3:42:8d:31:e6:4a:e8:19:d0:
ef:da:14:e7:d7:14:92:a1:92:f2:a7:2e:2d:af:fb:1d:f6:fb:
53:b0:8a:3f:fc:d8:16:0a:e9:b0:2e:b6:a5:0b:18:90:35:26:
a2:da:f6:a8:b7:32:fc:95:23:4b:c6:45:b9:c4:cf:e4:7c:ee:
e6:c9:f8:90:bd:72:e3:99:c3:1d:0b:05:7c:6a:97:6d:b2:ab:
02:36:d8:c2:bc:2c:01:92:3f:04:a3:8b:75:11:c7:b9:29:bc:
11:d0:86:ba:92:bc:26:f9:65:c8:37:cd:26:f6:86:13:0c:04:
aa:89:e5:78:b1:c1:4e:79:bc:76:a3:0b:51:e4:c5:d0:9e:6a:
fe:1a:2c:56:ae:06:36:27:a3:73:1c:08:7d:93:32:d0:c2:44:
19:da:8d:f4:0e:7b:1d:28:03:2b:09:8a:76:ca:77:dc:87:7a:
ac:7b:52:26:55:a7:72:0f:9d:d2:88:4f:fe:b1:21:c5:1a:a1:
aa:39:f5:56:db:c2:84:c4:35:1f:70:da:bb:46:f0:86:bf:64:
00:c4:3e:f7:9f:46:1b:9d:23:05:b9:7d:b3:4f:0f:a9:45:3a:
e3:74:30:98
-----BEGIN CERTIFICATE-----
MIIEFzCCAv+gAwIBAgIQB/LzXIeod6967+lHmTUlvTANBgkqhkiG9w0BAQwFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0yMTA0MTQwMDAwMDBaFw0zMTA0MTMyMzU5NTlaMFYxCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMDAuBgNVBAMTJ0RpZ2lDZXJ0IFRMUyBI
eWJyaWQgRUNDIFNIQTM4NCAyMDIwIENBMTB2MBAGByqGSM49AgEGBSuBBAAiA2IA
BMEbxppbmNmkKaDp1AS12+umsmxVwP/tmMZJLwYnUcu/cMEFesOxnYeJuq20ExfJ
qLSDyLiQ0cx0NTY8g3KwtdD3ImnI8YDEe0CPz2iHJlw5ifFNkU3aiYvkA8ND5b8v
c6OCAYIwggF+MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAq8CCkXjKU5
bXoOzjPHLrPt+8N6MB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA4G
A1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYI
KwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
b20wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp
Q2VydEdsb2JhbFJvb3RDQS5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2Ny
bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA9BgNVHSAE
NjA0MAsGCWCGSAGG/WwCATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgG
BmeBDAECAzANBgkqhkiG9w0BAQwFAAOCAQEAR1mBf9QbH7Bx9phdGLqYR5iwfnYr
6v8ai6wms0KNMeZK6BnQ79oU59cUkqGS8qcuLa/7Hfb7U7CKP/zYFgrpsC62pQsY
kDUmotr2qLcy/JUjS8ZFucTP5Hzu5sn4kL1y45nDHQsFfGqXbbKrAjbYwrwsAZI/
BKOLdRHHuSm8EdCGupK8JvllyDfNJvaGEwwEqonleLHBTnm8dqMLUeTF0J5q/hos
Vq4GNiejcxwIfZMy0MJEGdqN9A57HSgDKwmKdsp33Id6rHtSJlWncg+d0ohP/rEh
xRqhqjn1VtvChMQ1H3Dau0bwhr9kAMQ+959GG50jBbl9s08PqUU643QwmA==
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
08:3b:e0:56:90:42:46:b1:a1:75:6a:c9:59:91:c7:4a
Signature Algorithm: sha1WithRSAEncryption
Issuer: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
Validity
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:e2:3b:e1:11:72:de:a8:a4:d3:a3:57:aa:50:a2:
8f:0b:77:90:c9:a2:a5:ee:12:ce:96:5b:01:09:20:
cc:01:93:a7:4e:30:b7:53:f7:43:c4:69:00:57:9d:
e2:8d:22:dd:87:06:40:00:81:09:ce:ce:1b:83:bf:
df:cd:3b:71:46:e2:d6:66:c7:05:b3:76:27:16:8f:
7b:9e:1e:95:7d:ee:b7:48:a3:08:da:d6:af:7a:0c:
39:06:65:7f:4a:5d:1f:bc:17:f8:ab:be:ee:28:d7:
74:7f:7a:78:99:59:85:68:6e:5c:23:32:4b:bf:4e:
c0:e8:5a:6d:e3:70:bf:77:10:bf:fc:01:f6:85:d9:
a8:44:10:58:32:a9:75:18:d5:d1:a2:be:47:e2:27:
6a:f4:9a:33:f8:49:08:60:8b:d4:5f:b4:3a:84:bf:
a1:aa:4a:4c:7d:3e:cf:4f:5f:6c:76:5e:a0:4b:37:
91:9e:dc:22:e6:6d:ce:14:1a:8e:6a:cb:fe:cd:b3:
14:64:17:c7:5b:29:9e:32:bf:f2:ee:fa:d3:0b:42:
d4:ab:b7:41:32:da:0c:d4:ef:f8:81:d5:bb:8d:58:
3f:b5:1b:e8:49:28:a2:70:da:31:04:dd:f7:b2:16:
f2:4c:0a:4e:07:a8:ed:4a:3d:5e:b5:7f:a3:90:c3:
af:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
X509v3 Authority Key Identifier:
keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
Signature Algorithm: sha1WithRSAEncryption
cb:9c:37:aa:48:13:12:0a:fa:dd:44:9c:4f:52:b0:f4:df:ae:
04:f5:79:79:08:a3:24:18:fc:4b:2b:84:c0:2d:b9:d5:c7:fe:
f4:c1:1f:58:cb:b8:6d:9c:7a:74:e7:98:29:ab:11:b5:e3:70:
a0:a1:cd:4c:88:99:93:8c:91:70:e2:ab:0f:1c:be:93:a9:ff:
63:d5:e4:07:60:d3:a3:bf:9d:5b:09:f1:d5:8e:e3:53:f4:8e:
63:fa:3f:a7:db:b4:66:df:62:66:d6:d1:6e:41:8d:f2:2d:b5:
ea:77:4a:9f:9d:58:e2:2b:59:c0:40:23:ed:2d:28:82:45:3e:
79:54:92:26:98:e0:80:48:a8:37:ef:f0:d6:79:60:16:de:ac:
e8:0e:cd:6e:ac:44:17:38:2f:49:da:e1:45:3e:2a:b9:36:53:
cf:3a:50:06:f7:2e:e8:c4:57:49:6c:61:21:18:d5:04:ad:78:
3c:2c:3a:80:6b:a7:eb:af:15:14:e9:d8:89:c1:b9:38:6c:e2:
91:6c:8a:ff:64:b9:77:25:57:30:c0:1b:24:a3:e1:dc:e9:df:
47:7c:b5:b4:24:08:05:30:ec:2d:bd:0b:bf:45:bf:50:b9:a9:
f3:eb:98:01:12:ad:c8:88:c6:98:34:5f:8d:0a:3c:c6:e9:d5:
95:95:6d:de
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----

View file

@ -0,0 +1,29 @@
# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
# Label: "DigiCert Global Root G2"
# Serial: 4293743540046975378534879503202253541
# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44
# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4
# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f
-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
MrY=
-----END CERTIFICATE-----

View file

@ -0,0 +1,22 @@
# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
# Label: "DigiCert Global Root G3"
# Serial: 7089244469030293291760083333884364146
# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca
# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e
# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0
-----BEGIN CERTIFICATE-----
MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
sycX
-----END CERTIFICATE-----

View file

@ -1,243 +0,0 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
b3:bd:df:f8:a7:84:5b:bc:e9:03:a0:41:35:b3:4a:45
Signature Algorithm: ecdsa-with-SHA384
Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X2
Validity
Not Before: Sep 4 00:00:00 2020 GMT
Not After : Sep 15 16:00:00 2025 GMT
Subject: C = US, O = Let's Encrypt, CN = E1
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (384 bit)
pub:
04:24:5c:2d:a2:2a:fd:1c:4b:a6:5d:97:73:27:31:
ac:b2:a0:69:62:ef:65:e8:a6:b0:f0:ac:4b:9f:ff:
1c:0b:70:0f:d3:98:2f:4d:fc:0f:00:9b:37:f0:74:
05:57:32:97:2e:05:ef:2a:43:25:a3:fb:6e:34:27:
13:f6:4f:7e:69:d3:02:99:5e:eb:24:47:92:c1:24:
9b:e6:b1:21:8f:c1:24:81:fc:68:cc:1f:69:ba:58:
f5:19:22:f7:74:c6:16
ASN1 OID: secp384r1
NIST CURVE: P-384
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Extended Key Usage:
TLS Web Client Authentication, TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Subject Key Identifier:
5A:F3:ED:2B:FC:36:C2:37:79:B9:52:30:EA:54:6F:CF:55:CB:2E:AC
X509v3 Authority Key Identifier:
keyid:7C:42:96:AE:DE:4B:48:3B:FA:92:F8:9E:8C:CF:6D:8B:A9:72:37:95
Authority Information Access:
CA Issuers - URI:http://x2.i.lencr.org/
X509v3 CRL Distribution Points:
Full Name:
URI:http://x2.c.lencr.org/
X509v3 Certificate Policies:
Policy: 2.23.140.1.2.1
Policy: 1.3.6.1.4.1.44947.1.1.1
Signature Algorithm: ecdsa-with-SHA384
30:64:02:30:7b:74:d5:52:13:8d:61:fe:0d:ba:3f:03:00:9d:
f3:d7:98:84:d9:57:2e:bd:e9:0f:9c:5c:48:04:21:f2:cb:b3:
60:72:8e:97:d6:12:4f:ca:44:f6:42:c9:d3:7b:86:a9:02:30:
5a:b1:b1:b4:ed:ea:60:99:20:b1:38:03:ca:3d:a0:26:b8:ee:
6e:2d:4a:f6:c6:66:1f:33:9a:db:92:4a:d5:f5:29:13:c6:70:
62:28:ba:23:8c:cf:3d:2f:cb:82:e9:7f
-----BEGIN CERTIFICATE-----
MIICxjCCAk2gAwIBAgIRALO93/inhFu86QOgQTWzSkUwCgYIKoZIzj0EAwMwTzEL
MAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNo
IEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDIwHhcNMjAwOTA0MDAwMDAwWhcN
MjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3MgRW5j
cnlwdDELMAkGA1UEAxMCRTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQkXC2iKv0c
S6Zdl3MnMayyoGli72XoprDwrEuf/xwLcA/TmC9N/A8AmzfwdAVXMpcuBe8qQyWj
+240JxP2T35p0wKZXuskR5LBJJvmsSGPwSSB/GjMH2m6WPUZIvd0xhajggEIMIIB
BDAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMB
MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFrz7Sv8NsI3eblSMOpUb89V
yy6sMB8GA1UdIwQYMBaAFHxClq7eS0g7+pL4nozPbYupcjeVMDIGCCsGAQUFBwEB
BCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL3gyLmkubGVuY3Iub3JnLzAnBgNVHR8E
IDAeMBygGqAYhhZodHRwOi8veDIuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYG
Z4EMAQIBMA0GCysGAQQBgt8TAQEBMAoGCCqGSM49BAMDA2cAMGQCMHt01VITjWH+
Dbo/AwCd89eYhNlXLr3pD5xcSAQh8suzYHKOl9YST8pE9kLJ03uGqQIwWrGxtO3q
YJkgsTgDyj2gJrjubi1K9sZmHzOa25JK1fUpE8ZwYii6I4zPPS/Lgul/
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
41:d2:9d:d1:72:ea:ee:a7:80:c1:2c:6c:e9:2f:87:52
Signature Algorithm: ecdsa-with-SHA384
Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X2
Validity
Not Before: Sep 4 00:00:00 2020 GMT
Not After : Sep 17 16:00:00 2040 GMT
Subject: C = US, O = Internet Security Research Group, CN = ISRG Root X2
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (384 bit)
pub:
04:cd:9b:d5:9f:80:83:0a:ec:09:4a:f3:16:4a:3e:
5c:cf:77:ac:de:67:05:0d:1d:07:b6:dc:16:fb:5a:
8b:14:db:e2:71:60:c4:ba:45:95:11:89:8e:ea:06:
df:f7:2a:16:1c:a4:b9:c5:c5:32:e0:03:e0:1e:82:
18:38:8b:d7:45:d8:0a:6a:6e:e6:00:77:fb:02:51:
7d:22:d8:0a:6e:9a:5b:77:df:f0:fa:41:ec:39:dc:
75:ca:68:07:0c:1f:ea
ASN1 OID: secp384r1
NIST CURVE: P-384
X509v3 extensions:
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
7C:42:96:AE:DE:4B:48:3B:FA:92:F8:9E:8C:CF:6D:8B:A9:72:37:95
Signature Algorithm: ecdsa-with-SHA384
30:65:02:30:7b:79:4e:46:50:84:c2:44:87:46:1b:45:70:ff:
58:99:de:f4:fd:a4:d2:55:a6:20:2d:74:d6:34:bc:41:a3:50:
5f:01:27:56:b4:be:27:75:06:af:12:2e:75:98:8d:fc:02:31:
00:8b:f5:77:6c:d4:c8:65:aa:e0:0b:2c:ee:14:9d:27:37:a4:
f9:53:a5:51:e4:29:83:d7:f8:90:31:5b:42:9f:0a:f5:fe:ae:
00:68:e7:8c:49:0f:b6:6f:5b:5b:15:f2:e7
-----BEGIN CERTIFICATE-----
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
/q4AaOeMSQ+2b1tbFfLn
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
82:10:cf:b0:d2:40:e3:59:44:63:e0:bb:63:82:8b:00
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X1
Validity
Not Before: Jun 4 11:04:38 2015 GMT
Not After : Jun 4 11:04:38 2035 GMT
Subject: C = US, O = Internet Security Research Group, CN = ISRG Root X1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (4096 bit)
Modulus:
00:ad:e8:24:73:f4:14:37:f3:9b:9e:2b:57:28:1c:
87:be:dc:b7:df:38:90:8c:6e:3c:e6:57:a0:78:f7:
75:c2:a2:fe:f5:6a:6e:f6:00:4f:28:db:de:68:86:
6c:44:93:b6:b1:63:fd:14:12:6b:bf:1f:d2:ea:31:
9b:21:7e:d1:33:3c:ba:48:f5:dd:79:df:b3:b8:ff:
12:f1:21:9a:4b:c1:8a:86:71:69:4a:66:66:6c:8f:
7e:3c:70:bf:ad:29:22:06:f3:e4:c0:e6:80:ae:e2:
4b:8f:b7:99:7e:94:03:9f:d3:47:97:7c:99:48:23:
53:e8:38:ae:4f:0a:6f:83:2e:d1:49:57:8c:80:74:
b6:da:2f:d0:38:8d:7b:03:70:21:1b:75:f2:30:3c:
fa:8f:ae:dd:da:63:ab:eb:16:4f:c2:8e:11:4b:7e:
cf:0b:e8:ff:b5:77:2e:f4:b2:7b:4a:e0:4c:12:25:
0c:70:8d:03:29:a0:e1:53:24:ec:13:d9:ee:19:bf:
10:b3:4a:8c:3f:89:a3:61:51:de:ac:87:07:94:f4:
63:71:ec:2e:e2:6f:5b:98:81:e1:89:5c:34:79:6c:
76:ef:3b:90:62:79:e6:db:a4:9a:2f:26:c5:d0:10:
e1:0e:de:d9:10:8e:16:fb:b7:f7:a8:f7:c7:e5:02:
07:98:8f:36:08:95:e7:e2:37:96:0d:36:75:9e:fb:
0e:72:b1:1d:9b:bc:03:f9:49:05:d8:81:dd:05:b4:
2a:d6:41:e9:ac:01:76:95:0a:0f:d8:df:d5:bd:12:
1f:35:2f:28:17:6c:d2:98:c1:a8:09:64:77:6e:47:
37:ba:ce:ac:59:5e:68:9d:7f:72:d6:89:c5:06:41:
29:3e:59:3e:dd:26:f5:24:c9:11:a7:5a:a3:4c:40:
1f:46:a1:99:b5:a7:3a:51:6e:86:3b:9e:7d:72:a7:
12:05:78:59:ed:3e:51:78:15:0b:03:8f:8d:d0:2f:
05:b2:3e:7b:4a:1c:4b:73:05:12:fc:c6:ea:e0:50:
13:7c:43:93:74:b3:ca:74:e7:8e:1f:01:08:d0:30:
d4:5b:71:36:b4:07:ba:c1:30:30:5c:48:b7:82:3b:
98:a6:7d:60:8a:a2:a3:29:82:cc:ba:bd:83:04:1b:
a2:83:03:41:a1:d6:05:f1:1b:c2:b6:f0:a8:7c:86:
3b:46:a8:48:2a:88:dc:76:9a:76:bf:1f:6a:a5:3d:
19:8f:eb:38:f3:64:de:c8:2b:0d:0a:28:ff:f7:db:
e2:15:42:d4:22:d0:27:5d:e1:79:fe:18:e7:70:88:
ad:4e:e6:d9:8b:3a:c6:dd:27:51:6e:ff:bc:64:f5:
33:43:4f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
79:B4:59:E6:7B:B6:E5:E4:01:73:80:08:88:C8:1A:58:F6:E9:9B:6E
Signature Algorithm: sha256WithRSAEncryption
55:1f:58:a9:bc:b2:a8:50:d0:0c:b1:d8:1a:69:20:27:29:08:
ac:61:75:5c:8a:6e:f8:82:e5:69:2f:d5:f6:56:4b:b9:b8:73:
10:59:d3:21:97:7e:e7:4c:71:fb:b2:d2:60:ad:39:a8:0b:ea:
17:21:56:85:f1:50:0e:59:eb:ce:e0:59:e9:ba:c9:15:ef:86:
9d:8f:84:80:f6:e4:e9:91:90:dc:17:9b:62:1b:45:f0:66:95:
d2:7c:6f:c2:ea:3b:ef:1f:cf:cb:d6:ae:27:f1:a9:b0:c8:ae:
fd:7d:7e:9a:fa:22:04:eb:ff:d9:7f:ea:91:2b:22:b1:17:0e:
8f:f2:8a:34:5b:58:d8:fc:01:c9:54:b9:b8:26:cc:8a:88:33:
89:4c:2d:84:3c:82:df:ee:96:57:05:ba:2c:bb:f7:c4:b7:c7:
4e:3b:82:be:31:c8:22:73:73:92:d1:c2:80:a4:39:39:10:33:
23:82:4c:3c:9f:86:b2:55:98:1d:be:29:86:8c:22:9b:9e:e2:
6b:3b:57:3a:82:70:4d:dc:09:c7:89:cb:0a:07:4d:6c:e8:5d:
8e:c9:ef:ce:ab:c7:bb:b5:2b:4e:45:d6:4a:d0:26:cc:e5:72:
ca:08:6a:a5:95:e3:15:a1:f7:a4:ed:c9:2c:5f:a5:fb:ff:ac:
28:02:2e:be:d7:7b:bb:e3:71:7b:90:16:d3:07:5e:46:53:7c:
37:07:42:8c:d3:c4:96:9c:d5:99:b5:2a:e0:95:1a:80:48:ae:
4c:39:07:ce:cc:47:a4:52:95:2b:ba:b8:fb:ad:d2:33:53:7d:
e5:1d:4d:6d:d5:a1:b1:c7:42:6f:e6:40:27:35:5c:a3:28:b7:
07:8d:e7:8d:33:90:e7:23:9f:fb:50:9c:79:6c:46:d5:b4:15:
b3:96:6e:7e:9b:0c:96:3a:b8:52:2d:3f:d6:5b:e1:fb:08:c2:
84:fe:24:a8:a3:89:da:ac:6a:e1:18:2a:b1:a8:43:61:5b:d3:
1f:dc:3b:8d:76:f2:2d:e8:8d:75:df:17:33:6c:3d:53:fb:7b:
cb:41:5f:ff:dc:a2:d0:61:38:e1:96:b8:ac:5d:8b:37:d7:75:
d5:33:c0:99:11:ae:9d:41:c1:72:75:84:be:02:41:42:5f:67:
24:48:94:d1:9b:27:be:07:3f:b9:b8:4f:81:74:51:e1:7a:b7:
ed:9d:23:e2:be:e0:d5:28:04:13:3c:31:03:9e:dd:7a:6c:8f:
c6:07:18:c6:7f:de:47:8e:3f:28:9e:04:06:cf:a5:54:34:77:
bd:ec:89:9b:e9:17:43:df:5b:db:5f:fe:8e:1e:57:a2:cd:40:
9d:7e:62:22:da:de:18:27
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----

View file

@ -1,242 +0,0 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
02:03:bc:53:59:6b:34:c7:18:f5:01:50:66
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = Google Trust Services LLC, CN = GTS Root R1
Validity
Not Before: Aug 13 00:00:42 2020 GMT
Not After : Sep 30 00:00:42 2027 GMT
Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:f5:88:df:e7:62:8c:1e:37:f8:37:42:90:7f:6c:
87:d0:fb:65:82:25:fd:e8:cb:6b:a4:ff:6d:e9:5a:
23:e2:99:f6:1c:e9:92:03:99:13:7c:09:0a:8a:fa:
42:d6:5e:56:24:aa:7a:33:84:1f:d1:e9:69:bb:b9:
74:ec:57:4c:66:68:93:77:37:55:53:fe:39:10:4d:
b7:34:bb:5f:25:77:37:3b:17:94:ea:3c:e5:9d:d5:
bc:c3:b4:43:eb:2e:a7:47:ef:b0:44:11:63:d8:b4:
41:85:dd:41:30:48:93:1b:bf:b7:f6:e0:45:02:21:
e0:96:42:17:cf:d9:2b:65:56:34:07:26:04:0d:a8:
fd:7d:ca:2e:ef:ea:48:7c:37:4d:3f:00:9f:83:df:
ef:75:84:2e:79:57:5c:fc:57:6e:1a:96:ff:fc:8c:
9a:a6:99:be:25:d9:7f:96:2c:06:f7:11:2a:02:80:
80:eb:63:18:3c:50:49:87:e5:8a:ca:5f:19:2b:59:
96:81:00:a0:fb:51:db:ca:77:0b:0b:c9:96:4f:ef:
70:49:c7:5c:6d:20:fd:99:b4:b4:e2:ca:2e:77:fd:
2d:dc:0b:b6:6b:13:0c:8c:19:2b:17:96:98:b9:f0:
8b:f6:a0:27:bb:b6:e3:8d:51:8f:bd:ae:c7:9b:b1:
89:9d
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Subject Key Identifier:
8A:74:7F:AF:85:CD:EE:95:CD:3D:9C:D0:E2:46:14:F3:71:35:1D:27
X509v3 Authority Key Identifier:
keyid:E4:AF:2B:26:71:1A:2B:48:27:85:2F:52:66:2C:EF:F0:89:13:71:3E
Authority Information Access:
OCSP - URI:http://ocsp.pki.goog/gtsr1
CA Issuers - URI:http://pki.goog/repo/certs/gtsr1.der
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.pki.goog/gtsr1/gtsr1.crl
X509v3 Certificate Policies:
Policy: 1.3.6.1.4.1.11129.2.5.3
CPS: https://pki.goog/repository/
Policy: 2.23.140.1.2.1
Policy: 2.23.140.1.2.2
Signature Algorithm: sha256WithRSAEncryption
89:7d:ac:20:5c:0c:3c:be:9a:a8:57:95:1b:b4:ae:fa:ab:a5:
72:71:b4:36:95:fd:df:40:11:03:4c:c2:46:14:bb:14:24:ab:
f0:50:71:22:db:ad:c4:6e:7f:cf:f1:6a:6f:c8:83:1b:d8:ce:
89:5f:87:6c:87:b8:a9:0c:a3:9b:a1:62:94:93:95:df:5b:ae:
66:19:0b:02:96:9e:fc:b5:e7:10:69:3e:7a:cb:46:49:5f:46:
e1:41:b1:d7:98:4d:65:34:00:80:1a:3f:4f:9f:6c:7f:49:00:
81:53:41:a4:92:21:82:82:1a:f1:a3:44:5b:2a:50:12:13:4d:
c1:53:36:f3:42:08:af:54:fa:8e:77:53:1b:64:38:27:17:09:
bd:58:c9:1b:7c:39:2d:5b:f3:ce:d4:ed:97:db:14:03:bf:09:
53:24:1f:c2:0c:04:79:98:26:f2:61:f1:53:52:fd:42:8c:1b:
66:2b:3f:15:a1:bb:ff:f6:9b:e3:81:9a:01:06:71:89:35:28:
24:dd:e1:bd:eb:19:2d:e1:48:cb:3d:59:83:51:b4:74:c6:9d:
7c:c6:b1:86:5b:af:cc:34:c4:d3:cc:d4:81:11:95:00:a1:f4:
12:22:01:fa:b4:83:71:af:8c:b7:8c:73:24:ac:37:53:c2:00:
90:3f:11:fe:5c:ed:36:94:10:3b:bd:29:ae:e2:c7:3a:62:3b:
6c:63:d9:80:bf:59:71:ac:63:27:b9:4c:17:a0:da:f6:73:15:
bf:2a:de:8f:f3:a5:6c:32:81:33:03:d0:86:51:71:99:34:ba:
93:8d:5d:b5:51:58:f7:b2:93:e8:01:f6:59:be:71:9b:fd:4d:
28:ce:cf:6d:c7:16:dc:f7:d1:d6:46:9b:a7:ca:6b:e9:77:0f:
fd:a0:b6:1b:23:83:1d:10:1a:d9:09:00:84:e0:44:d3:a2:75:
23:b3:34:86:f6:20:b0:a4:5e:10:1d:e0:52:46:00:9d:b1:0f:
1f:21:70:51:f5:9a:dd:06:fc:55:f4:2b:0e:33:77:c3:4b:42:
c2:f1:77:13:fc:73:80:94:eb:1f:bb:37:3f:ce:02:2a:66:b0:
73:1d:32:a5:32:6c:32:b0:8e:e0:c4:23:ff:5b:7d:4d:65:70:
ac:2b:9b:3d:ce:db:e0:6d:8e:32:80:be:96:9f:92:63:bc:97:
bb:5d:b9:f4:e1:71:5e:2a:e4:ef:03:22:b1:8a:65:3a:8f:c0:
93:65:d4:85:cd:0f:0f:5b:83:59:16:47:16:2d:9c:24:3a:c8:
80:a6:26:14:85:9b:f6:37:9b:ac:6f:f9:c5:c3:06:51:f3:e2:
7f:c5:b1:10:ba:51:f4:dd
-----BEGIN CERTIFICATE-----
MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw
MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp
kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX
lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm
BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA
gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL
tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud
DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T
AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD
VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG
CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw
AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt
MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG
A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br
aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN
AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ
cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL
RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U
+o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr
PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER
lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs
Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO
z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG
AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw
juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl
1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
6e:47:a9:c5:4b:47:0c:0d:ec:33:d0:89:b9:1c:f4:e1
Signature Algorithm: sha384WithRSAEncryption
Issuer: C = US, O = Google Trust Services LLC, CN = GTS Root R1
Validity
Not Before: Jun 22 00:00:00 2016 GMT
Not After : Jun 22 00:00:00 2036 GMT
Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (4096 bit)
Modulus:
00:b6:11:02:8b:1e:e3:a1:77:9b:3b:dc:bf:94:3e:
b7:95:a7:40:3c:a1:fd:82:f9:7d:32:06:82:71:f6:
f6:8c:7f:fb:e8:db:bc:6a:2e:97:97:a3:8c:4b:f9:
2b:f6:b1:f9:ce:84:1d:b1:f9:c5:97:de:ef:b9:f2:
a3:e9:bc:12:89:5e:a7:aa:52:ab:f8:23:27:cb:a4:
b1:9c:63:db:d7:99:7e:f0:0a:5e:eb:68:a6:f4:c6:
5a:47:0d:4d:10:33:e3:4e:b1:13:a3:c8:18:6c:4b:
ec:fc:09:90:df:9d:64:29:25:23:07:a1:b4:d2:3d:
2e:60:e0:cf:d2:09:87:bb:cd:48:f0:4d:c2:c2:7a:
88:8a:bb:ba:cf:59:19:d6:af:8f:b0:07:b0:9e:31:
f1:82:c1:c0:df:2e:a6:6d:6c:19:0e:b5:d8:7e:26:
1a:45:03:3d:b0:79:a4:94:28:ad:0f:7f:26:e5:a8:
08:fe:96:e8:3c:68:94:53:ee:83:3a:88:2b:15:96:
09:b2:e0:7a:8c:2e:75:d6:9c:eb:a7:56:64:8f:96:
4f:68:ae:3d:97:c2:84:8f:c0:bc:40:c0:0b:5c:bd:
f6:87:b3:35:6c:ac:18:50:7f:84:e0:4c:cd:92:d3:
20:e9:33:bc:52:99:af:32:b5:29:b3:25:2a:b4:48:
f9:72:e1:ca:64:f7:e6:82:10:8d:e8:9d:c2:8a:88:
fa:38:66:8a:fc:63:f9:01:f9:78:fd:7b:5c:77:fa:
76:87:fa:ec:df:b1:0e:79:95:57:b4:bd:26:ef:d6:
01:d1:eb:16:0a:bb:8e:0b:b5:c5:c5:8a:55:ab:d3:
ac:ea:91:4b:29:cc:19:a4:32:25:4e:2a:f1:65:44:
d0:02:ce:aa:ce:49:b4:ea:9f:7c:83:b0:40:7b:e7:
43:ab:a7:6c:a3:8f:7d:89:81:fa:4c:a5:ff:d5:8e:
c3:ce:4b:e0:b5:d8:b3:8e:45:cf:76:c0:ed:40:2b:
fd:53:0f:b0:a7:d5:3b:0d:b1:8a:a2:03:de:31:ad:
cc:77:ea:6f:7b:3e:d6:df:91:22:12:e6:be:fa:d8:
32:fc:10:63:14:51:72:de:5d:d6:16:93:bd:29:68:
33:ef:3a:66:ec:07:8a:26:df:13:d7:57:65:78:27:
de:5e:49:14:00:a2:00:7f:9a:a8:21:b6:a9:b1:95:
b0:a5:b9:0d:16:11:da:c7:6c:48:3c:40:e0:7e:0d:
5a:cd:56:3c:d1:97:05:b9:cb:4b:ed:39:4b:9c:c4:
3f:d2:55:13:6e:24:b0:d6:71:fa:f4:c1:ba:cc:ed:
1b:f5:fe:81:41:d8:00:98:3d:3a:c8:ae:7a:98:37:
18:05:95
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
E4:AF:2B:26:71:1A:2B:48:27:85:2F:52:66:2C:EF:F0:89:13:71:3E
Signature Algorithm: sha384WithRSAEncryption
38:96:0a:ee:3d:b4:96:1e:5f:ef:9d:9c:0b:33:9f:2b:e0:ca:
fd:d2:8e:0a:1f:41:74:a5:7c:aa:84:d4:e5:f2:1e:e6:37:52:
32:9c:0b:d1:61:1d:bf:28:c1:b6:44:29:35:75:77:98:b2:7c:
d9:bd:74:ac:8a:68:e3:a9:31:09:29:01:60:73:e3:47:7c:53:
a8:90:4a:27:ef:4b:d7:9f:93:e7:82:36:ce:9a:68:0c:82:e7:
cf:d4:10:16:6f:5f:0e:99:5c:f6:1f:71:7d:ef:ef:7b:2f:7e:
ea:36:d6:97:70:0b:15:ee:d7:5c:56:6a:33:a5:e3:49:38:0c:
b8:7d:fb:8d:85:a4:b1:59:5e:f4:6a:e1:dd:a1:f6:64:44:ae:
e6:51:83:21:66:c6:11:3e:f3:ce:47:ee:9c:28:1f:25:da:ff:
ac:66:95:dd:35:0f:5c:ef:20:2c:62:fd:91:ba:a9:cc:fc:5a:
9c:93:81:83:29:97:4a:7c:5a:72:b4:39:d0:b7:77:cb:79:fd:
69:3a:92:37:ed:6e:38:65:46:7e:e9:60:bd:79:88:97:5f:38:
12:f4:ee:af:5b:82:c8:86:d5:e1:99:6d:8c:04:f2:76:ba:49:
f6:6e:e9:6d:1e:5f:a0:ef:27:82:76:40:f8:a6:d3:58:5c:0f:
2c:42:da:42:c6:7b:88:34:c7:c1:d8:45:9b:c1:3e:c5:61:1d:
d9:63:50:49:f6:34:85:6a:e0:18:c5:6e:47:ab:41:42:29:9b:
f6:60:0d:d2:31:d3:63:98:23:93:5a:00:81:48:b4:ef:cd:8a:
cd:c9:cf:99:ee:d9:9e:aa:36:e1:68:4b:71:49:14:36:28:3a:
3d:1d:ce:9a:8f:25:e6:80:71:61:2b:b5:7b:cc:f9:25:16:81:
e1:31:5f:a1:a3:7e:16:a4:9c:16:6a:97:18:bd:76:72:a5:0b:
9e:1d:36:e6:2f:a1:2f:be:70:91:0f:a8:e6:da:f8:c4:92:40:
6c:25:7e:7b:b3:09:dc:b2:17:ad:80:44:f0:68:a5:8f:94:75:
ff:74:5a:e8:a8:02:7c:0c:09:e2:a9:4b:0b:a0:85:0b:62:b9:
ef:a1:31:92:fb:ef:f6:51:04:89:6c:e8:a9:74:a1:bb:17:b3:
b5:fd:49:0f:7c:3c:ec:83:18:20:43:4e:d5:93:ba:b4:34:b1:
1f:16:36:1f:0c:e6:64:39:16:4c:dc:e0:fe:1d:c8:a9:62:3d:
40:ea:ca:c5:34:02:b4:ae:89:88:33:35:dc:2c:13:73:d8:27:
f1:d0:72:ee:75:3b:22:de:98:68:66:5b:f1:c6:63:47:55:1c:
ba:a5:08:51:75:a6:48:25
-----BEGIN CERTIFICATE-----
MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy
MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl
cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM
f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX
mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7
zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P
fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc
vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4
Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp
zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO
Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW
k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+
DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF
lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW
Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1
d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z
XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR
gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3
d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv
J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg
DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM
+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy
F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9
SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws
E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl
-----END CERTIFICATE-----

38
certs/GTS-Root-R1.pem Normal file
View file

@ -0,0 +1,38 @@
# Issuer: CN=GTS Root R1 O=Google Trust Services LLC
# Subject: CN=GTS Root R1 O=Google Trust Services LLC
# Label: "GTS Root R1"
# Serial: 159662320309726417404178440727
# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40
# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a
# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf
-----BEGIN CERTIFICATE-----
MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo
27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w
Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw
TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl
qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH
szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8
Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk
MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p
aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN
VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID
AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb
C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe
QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy
h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4
7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J
ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef
MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/
Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ
0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
-----END CERTIFICATE-----

20
certs/GTS-Root-R4.pem Normal file
View file

@ -0,0 +1,20 @@
# Issuer: CN=GTS Root R4 O=Google Trust Services LLC
# Subject: CN=GTS Root R4 O=Google Trust Services LLC
# Label: "GTS Root R4"
# Serial: 159662532700760215368942768210
# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8
# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47
# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d
-----BEGIN CERTIFICATE-----
MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi
QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR
HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D
9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8
p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD
-----END CERTIFICATE-----

View file

@ -1,178 +0,0 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 7 (0x7)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
Validity
Not Before: May 3 07:00:00 2011 GMT
Not After : May 3 07:00:00 2031 GMT
Subject: C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certs.godaddy.com/repository/, CN = Go Daddy Secure Certificate Authority - G2
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:b9:e0:cb:10:d4:af:76:bd:d4:93:62:eb:30:64:
b8:81:08:6c:c3:04:d9:62:17:8e:2f:ff:3e:65:cf:
8f:ce:62:e6:3c:52:1c:da:16:45:4b:55:ab:78:6b:
63:83:62:90:ce:0f:69:6c:99:c8:1a:14:8b:4c:cc:
45:33:ea:88:dc:9e:a3:af:2b:fe:80:61:9d:79:57:
c4:cf:2e:f4:3f:30:3c:5d:47:fc:9a:16:bc:c3:37:
96:41:51:8e:11:4b:54:f8:28:be:d0:8c:be:f0:30:
38:1e:f3:b0:26:f8:66:47:63:6d:de:71:26:47:8f:
38:47:53:d1:46:1d:b4:e3:dc:00:ea:45:ac:bd:bc:
71:d9:aa:6f:00:db:db:cd:30:3a:79:4f:5f:4c:47:
f8:1d:ef:5b:c2:c4:9d:60:3b:b1:b2:43:91:d8:a4:
33:4e:ea:b3:d6:27:4f:ad:25:8a:a5:c6:f4:d5:d0:
a6:ae:74:05:64:57:88:b5:44:55:d4:2d:2a:3a:3e:
f8:b8:bd:e9:32:0a:02:94:64:c4:16:3a:50:f1:4a:
ae:e7:79:33:af:0c:20:07:7f:e8:df:04:39:c2:69:
02:6c:63:52:fa:77:c1:1b:c8:74:87:c8:b9:93:18:
50:54:35:4b:69:4e:bc:3b:d3:49:2e:1f:dc:c1:d2:
52:fb
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Subject Key Identifier:
40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE
X509v3 Authority Key Identifier:
keyid:3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
Authority Information Access:
OCSP - URI:http://ocsp.godaddy.com/
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.godaddy.com/gdroot-g2.crl
X509v3 Certificate Policies:
Policy: X509v3 Any Policy
CPS: https://certs.godaddy.com/repository/
Signature Algorithm: sha256WithRSAEncryption
08:7e:6c:93:10:c8:38:b8:96:a9:90:4b:ff:a1:5f:4f:04:ef:
6c:3e:9c:88:06:c9:50:8f:a6:73:f7:57:31:1b:be:bc:e4:2f:
db:f8:ba:d3:5b:e0:b4:e7:e6:79:62:0e:0c:a2:d7:6a:63:73:
31:b5:f5:a8:48:a4:3b:08:2d:a2:5d:90:d7:b4:7c:25:4f:11:
56:30:c4:b6:44:9d:7b:2c:9d:e5:5e:e6:ef:0c:61:aa:bf:e4:
2a:1b:ee:84:9e:b8:83:7d:c1:43:ce:44:a7:13:70:0d:91:1f:
f4:c8:13:ad:83:60:d9:d8:72:a8:73:24:1e:b5:ac:22:0e:ca:
17:89:62:58:44:1b:ab:89:25:01:00:0f:cd:c4:1b:62:db:51:
b4:d3:0f:51:2a:9b:f4:bc:73:fc:76:ce:36:a4:cd:d9:d8:2c:
ea:ae:9b:f5:2a:b2:90:d1:4d:75:18:8a:3f:8a:41:90:23:7d:
5b:4b:fe:a4:03:58:9b:46:b2:c3:60:60:83:f8:7d:50:41:ce:
c2:a1:90:c3:bb:ef:02:2f:d2:15:54:ee:44:15:d9:0a:ae:a7:
8a:33:ed:b1:2d:76:36:26:dc:04:eb:9f:f7:61:1f:15:dc:87:
6f:ee:46:96:28:ad:a1:26:7d:0a:09:a7:2e:04:a3:8d:bc:f8:
bc:04:30:01
-----BEGIN CERTIFICATE-----
MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3
MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE
CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD
EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD
BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv
K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e
cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY
pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n
eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB
AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv
9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n
b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG
CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv
MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz
91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2
RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi
DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11
GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x
LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
Validity
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
Subject: C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:bf:71:62:08:f1:fa:59:34:f7:1b:c9:18:a3:f7:
80:49:58:e9:22:83:13:a6:c5:20:43:01:3b:84:f1:
e6:85:49:9f:27:ea:f6:84:1b:4e:a0:b4:db:70:98:
c7:32:01:b1:05:3e:07:4e:ee:f4:fa:4f:2f:59:30:
22:e7:ab:19:56:6b:e2:80:07:fc:f3:16:75:80:39:
51:7b:e5:f9:35:b6:74:4e:a9:8d:82:13:e4:b6:3f:
a9:03:83:fa:a2:be:8a:15:6a:7f:de:0b:c3:b6:19:
14:05:ca:ea:c3:a8:04:94:3b:46:7c:32:0d:f3:00:
66:22:c8:8d:69:6d:36:8c:11:18:b7:d3:b2:1c:60:
b4:38:fa:02:8c:ce:d3:dd:46:07:de:0a:3e:eb:5d:
7c:c8:7c:fb:b0:2b:53:a4:92:62:69:51:25:05:61:
1a:44:81:8c:2c:a9:43:96:23:df:ac:3a:81:9a:0e:
29:c5:1c:a9:e9:5d:1e:b6:9e:9e:30:0a:39:ce:f1:
88:80:fb:4b:5d:cc:32:ec:85:62:43:25:34:02:56:
27:01:91:b4:3b:70:2a:3f:6e:b1:e8:9c:88:01:7d:
9f:d4:f9:db:53:6d:60:9d:bf:2c:e7:58:ab:b8:5f:
46:fc:ce:c4:1b:03:3c:09:eb:49:31:5c:69:46:b3:
e0:47
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Subject Key Identifier:
3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
Signature Algorithm: sha256WithRSAEncryption
99:db:5d:79:d5:f9:97:59:67:03:61:f1:7e:3b:06:31:75:2d:
a1:20:8e:4f:65:87:b4:f7:a6:9c:bc:d8:e9:2f:d0:db:5a:ee:
cf:74:8c:73:b4:38:42:da:05:7b:f8:02:75:b8:fd:a5:b1:d7:
ae:f6:d7:de:13:cb:53:10:7e:8a:46:d1:97:fa:b7:2e:2b:11:
ab:90:b0:27:80:f9:e8:9f:5a:e9:37:9f:ab:e4:df:6c:b3:85:
17:9d:3d:d9:24:4f:79:91:35:d6:5f:04:eb:80:83:ab:9a:02:
2d:b5:10:f4:d8:90:c7:04:73:40:ed:72:25:a0:a9:9f:ec:9e:
ab:68:12:99:57:c6:8f:12:3a:09:a4:bd:44:fd:06:15:37:c1:
9b:e4:32:a3:ed:38:e8:d8:64:f3:2c:7e:14:fc:02:ea:9f:cd:
ff:07:68:17:db:22:90:38:2d:7a:8d:d1:54:f1:69:e3:5f:33:
ca:7a:3d:7b:0a:e3:ca:7f:5f:39:e5:e2:75:ba:c5:76:18:33:
ce:2c:f0:2f:4c:ad:f7:b1:e7:ce:4f:a8:c4:9b:4a:54:06:c5:
7f:7d:d5:08:0f:e2:1c:fe:7e:17:b8:ac:5e:f6:d4:16:b2:43:
09:0c:4d:f6:a7:6b:b4:99:84:65:ca:7a:88:e2:e2:44:be:5c:
f7:ea:1c:f5
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
4uJEvlz36hz1
-----END CERTIFICATE-----

View file

@ -0,0 +1,30 @@
# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
# Label: "Go Daddy Root Certificate Authority - G2"
# Serial: 0
# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01
# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b
# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
4uJEvlz36hz1
-----END CERTIFICATE-----

38
certs/ISRG-Root-X1.pem Normal file
View file

@ -0,0 +1,38 @@
# Issuer: CN=ISRG Root X1 O=Internet Security Research Group
# Subject: CN=ISRG Root X1 O=Internet Security Research Group
# Label: "ISRG Root X1"
# Serial: 172886928669790476064670243504169061120
# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e
# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8
# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----

21
certs/ISRG-Root-X2.pem Normal file
View file

@ -0,0 +1,21 @@
# Issuer: CN=ISRG Root X2 O=Internet Security Research Group
# Subject: CN=ISRG Root X2 O=Internet Security Research Group
# Label: "ISRG Root X2"
# Serial: 87493402998870891108772069816698636114
# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5
# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af
# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70
-----BEGIN CERTIFICATE-----
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
/q4AaOeMSQ+2b1tbFfLn
-----END CERTIFICATE-----

58
certs/Makefile Normal file
View file

@ -0,0 +1,58 @@
# Makefile to check certificates
CURL = curl \
--capath /dev/null \
--connect-timeout 5 \
--output /dev/null \
--silent
DOMAINS_DUAL = \
api.macvendors.com/GTS-Root-R4 \
api.telegram.org/Go-Daddy-Root-Certificate-Authority-G2 \
cloudflare-dns.com/DigiCert-Global-Root-G2 \
dns.google/GTS-Root-R4 \
dns.quad9.net/DigiCert-Global-Root-G3 \
git.eworm.de/ISRG-Root-X2 \
lists.blocklist.de/Certum-Trusted-Network-CA \
matrix.org/GTS-Root-R4 \
raw.githubusercontent.com/USERTrust-RSA-Certification-Authority \
rsc.eworm.de/ISRG-Root-X2 \
upgrade.mikrotik.com/ISRG-Root-X1
DOMAINS_IPV4 = \
1.1.1.1/DigiCert-Global-Root-G2 \
8.8.8.8/GTS-Root-R1 \
9.9.9.9/DigiCert-Global-Root-G3 \
api.mullvad.net/ISRG-Root-X1 \
ipv4.showipv6.de/ISRG-Root-X1 \
ipv4.tunnelbroker.net/Starfield-Root-Certificate-Authority-G2 \
mkcert.org/ISRG-Root-X1 \
ntfy.sh/ISRG-Root-X1 \
www.dshield.org/ISRG-Root-X1 \
www.spamhaus.org/GTS-Root-R4
DOMAINS_IPV6 = \
[2606\:4700\:4700\:\:1111]/DigiCert-Global-Root-G2 \
[2001\:4860\:4860\:\:8888]/GTS-Root-R1 \
[2620\:fe\:\:9]/DigiCert-Global-Root-G3 \
ipv6.showipv6.de/ISRG-Root-X1
.PHONY: $(DOMAINS_DUAL) $(DOMAINS_IPV4) $(DOMAINS_IPV6)
all: $(DOMAINS_DUAL) $(DOMAINS_IPV4) $(DOMAINS_IPV6)
$(DOMAINS_DUAL):
ifndef NOIPV4
$(CURL) -4 --cacert $(notdir $@).pem https://$(dir $@)
endif
ifndef NOIPV6
$(CURL) -6 --cacert $(notdir $@).pem https://$(dir $@)
endif
$(DOMAINS_IPV4):
ifndef NOIPV4
$(CURL) -4 --cacert $(notdir $@).pem https://$(dir $@)
endif
$(DOMAINS_IPV6):
ifndef NOIPV6
$(CURL) -6 --cacert $(notdir $@).pem https://$(dir $@)
endif

View file

@ -1,237 +0,0 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
91:2b:08:4a:cf:0c:18:a7:53:f6:d6:2e:25:a7:5f:5a
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X1
Validity
Not Before: Sep 4 00:00:00 2020 GMT
Not After : Sep 15 16:00:00 2025 GMT
Subject: C = US, O = Let's Encrypt, CN = R3
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:bb:02:15:28:cc:f6:a0:94:d3:0f:12:ec:8d:55:
92:c3:f8:82:f1:99:a6:7a:42:88:a7:5d:26:aa:b5:
2b:b9:c5:4c:b1:af:8e:6b:f9:75:c8:a3:d7:0f:47:
94:14:55:35:57:8c:9e:a8:a2:39:19:f5:82:3c:42:
a9:4e:6e:f5:3b:c3:2e:db:8d:c0:b0:5c:f3:59:38:
e7:ed:cf:69:f0:5a:0b:1b:be:c0:94:24:25:87:fa:
37:71:b3:13:e7:1c:ac:e1:9b:ef:db:e4:3b:45:52:
45:96:a9:c1:53:ce:34:c8:52:ee:b5:ae:ed:8f:de:
60:70:e2:a5:54:ab:b6:6d:0e:97:a5:40:34:6b:2b:
d3:bc:66:eb:66:34:7c:fa:6b:8b:8f:57:29:99:f8:
30:17:5d:ba:72:6f:fb:81:c5:ad:d2:86:58:3d:17:
c7:e7:09:bb:f1:2b:f7:86:dc:c1:da:71:5d:d4:46:
e3:cc:ad:25:c1:88:bc:60:67:75:66:b3:f1:18:f7:
a2:5c:e6:53:ff:3a:88:b6:47:a5:ff:13:18:ea:98:
09:77:3f:9d:53:f9:cf:01:e5:f5:a6:70:17:14:af:
63:a4:ff:99:b3:93:9d:dc:53:a7:06:fe:48:85:1d:
a1:69:ae:25:75:bb:13:cc:52:03:f5:ed:51:a1:8b:
db:15
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Extended Key Usage:
TLS Web Client Authentication, TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Subject Key Identifier:
14:2E:B3:17:B7:58:56:CB:AE:50:09:40:E6:1F:AF:9D:8B:14:C2:C6
X509v3 Authority Key Identifier:
keyid:79:B4:59:E6:7B:B6:E5:E4:01:73:80:08:88:C8:1A:58:F6:E9:9B:6E
Authority Information Access:
CA Issuers - URI:http://x1.i.lencr.org/
X509v3 CRL Distribution Points:
Full Name:
URI:http://x1.c.lencr.org/
X509v3 Certificate Policies:
Policy: 2.23.140.1.2.1
Policy: 1.3.6.1.4.1.44947.1.1.1
Signature Algorithm: sha256WithRSAEncryption
85:ca:4e:47:3e:a3:f7:85:44:85:bc:d5:67:78:b2:98:63:ad:
75:4d:1e:96:3d:33:65:72:54:2d:81:a0:ea:c3:ed:f8:20:bf:
5f:cc:b7:70:00:b7:6e:3b:f6:5e:94:de:e4:20:9f:a6:ef:8b:
b2:03:e7:a2:b5:16:3c:91:ce:b4:ed:39:02:e7:7c:25:8a:47:
e6:65:6e:3f:46:f4:d9:f0:ce:94:2b:ee:54:ce:12:bc:8c:27:
4b:b8:c1:98:2f:a2:af:cd:71:91:4a:08:b7:c8:b8:23:7b:04:
2d:08:f9:08:57:3e:83:d9:04:33:0a:47:21:78:09:82:27:c3:
2a:c8:9b:b9:ce:5c:f2:64:c8:c0:be:79:c0:4f:8e:6d:44:0c:
5e:92:bb:2e:f7:8b:10:e1:e8:1d:44:29:db:59:20:ed:63:b9:
21:f8:12:26:94:93:57:a0:1d:65:04:c1:0a:22:ae:10:0d:43:
97:a1:18:1f:7e:e0:e0:86:37:b5:5a:b1:bd:30:bf:87:6e:2b:
2a:ff:21:4e:1b:05:c3:f5:18:97:f0:5e:ac:c3:a5:b8:6a:f0:
2e:bc:3b:33:b9:ee:4b:de:cc:fc:e4:af:84:0b:86:3f:c0:55:
43:36:f6:68:e1:36:17:6a:8e:99:d1:ff:a5:40:a7:34:b7:c0:
d0:63:39:35:39:75:6e:f2:ba:76:c8:93:02:e9:a9:4b:6c:17:
ce:0c:02:d9:bd:81:fb:9f:b7:68:d4:06:65:b3:82:3d:77:53:
f8:8e:79:03:ad:0a:31:07:75:2a:43:d8:55:97:72:c4:29:0e:
f7:c4:5d:4e:c8:ae:46:84:30:d7:f2:85:5f:18:a1:79:bb:e7:
5e:70:8b:07:e1:86:93:c3:b9:8f:dc:61:71:25:2a:af:df:ed:
25:50:52:68:8b:92:dc:e5:d6:b5:e3:da:7d:d0:87:6c:84:21:
31:ae:82:f5:fb:b9:ab:c8:89:17:3d:e1:4c:e5:38:0e:f6:bd:
2b:bd:96:81:14:eb:d5:db:3d:20:a7:7e:59:d3:e2:f8:58:f9:
5b:b8:48:cd:fe:5c:4f:16:29:fe:1e:55:23:af:c8:11:b0:8d:
ea:7c:93:90:17:2f:fd:ac:a2:09:47:46:3f:f0:e9:b0:b7:ff:
28:4d:68:32:d6:67:5e:1e:69:a3:93:b8:f5:9d:8b:2f:0b:d2:
52:43:a6:6f:32:57:65:4d:32:81:df:38:53:85:5d:7e:5d:66:
29:ea:b8:dd:e4:95:b5:cd:b5:56:12:42:cd:c4:4e:c6:25:38:
44:50:6d:ec:ce:00:55:18:fe:e9:49:64:d4:4e:ca:97:9c:b4:
5b:c0:73:a8:ab:b8:47:c2
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
82:10:cf:b0:d2:40:e3:59:44:63:e0:bb:63:82:8b:00
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X1
Validity
Not Before: Jun 4 11:04:38 2015 GMT
Not After : Jun 4 11:04:38 2035 GMT
Subject: C = US, O = Internet Security Research Group, CN = ISRG Root X1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (4096 bit)
Modulus:
00:ad:e8:24:73:f4:14:37:f3:9b:9e:2b:57:28:1c:
87:be:dc:b7:df:38:90:8c:6e:3c:e6:57:a0:78:f7:
75:c2:a2:fe:f5:6a:6e:f6:00:4f:28:db:de:68:86:
6c:44:93:b6:b1:63:fd:14:12:6b:bf:1f:d2:ea:31:
9b:21:7e:d1:33:3c:ba:48:f5:dd:79:df:b3:b8:ff:
12:f1:21:9a:4b:c1:8a:86:71:69:4a:66:66:6c:8f:
7e:3c:70:bf:ad:29:22:06:f3:e4:c0:e6:80:ae:e2:
4b:8f:b7:99:7e:94:03:9f:d3:47:97:7c:99:48:23:
53:e8:38:ae:4f:0a:6f:83:2e:d1:49:57:8c:80:74:
b6:da:2f:d0:38:8d:7b:03:70:21:1b:75:f2:30:3c:
fa:8f:ae:dd:da:63:ab:eb:16:4f:c2:8e:11:4b:7e:
cf:0b:e8:ff:b5:77:2e:f4:b2:7b:4a:e0:4c:12:25:
0c:70:8d:03:29:a0:e1:53:24:ec:13:d9:ee:19:bf:
10:b3:4a:8c:3f:89:a3:61:51:de:ac:87:07:94:f4:
63:71:ec:2e:e2:6f:5b:98:81:e1:89:5c:34:79:6c:
76:ef:3b:90:62:79:e6:db:a4:9a:2f:26:c5:d0:10:
e1:0e:de:d9:10:8e:16:fb:b7:f7:a8:f7:c7:e5:02:
07:98:8f:36:08:95:e7:e2:37:96:0d:36:75:9e:fb:
0e:72:b1:1d:9b:bc:03:f9:49:05:d8:81:dd:05:b4:
2a:d6:41:e9:ac:01:76:95:0a:0f:d8:df:d5:bd:12:
1f:35:2f:28:17:6c:d2:98:c1:a8:09:64:77:6e:47:
37:ba:ce:ac:59:5e:68:9d:7f:72:d6:89:c5:06:41:
29:3e:59:3e:dd:26:f5:24:c9:11:a7:5a:a3:4c:40:
1f:46:a1:99:b5:a7:3a:51:6e:86:3b:9e:7d:72:a7:
12:05:78:59:ed:3e:51:78:15:0b:03:8f:8d:d0:2f:
05:b2:3e:7b:4a:1c:4b:73:05:12:fc:c6:ea:e0:50:
13:7c:43:93:74:b3:ca:74:e7:8e:1f:01:08:d0:30:
d4:5b:71:36:b4:07:ba:c1:30:30:5c:48:b7:82:3b:
98:a6:7d:60:8a:a2:a3:29:82:cc:ba:bd:83:04:1b:
a2:83:03:41:a1:d6:05:f1:1b:c2:b6:f0:a8:7c:86:
3b:46:a8:48:2a:88:dc:76:9a:76:bf:1f:6a:a5:3d:
19:8f:eb:38:f3:64:de:c8:2b:0d:0a:28:ff:f7:db:
e2:15:42:d4:22:d0:27:5d:e1:79:fe:18:e7:70:88:
ad:4e:e6:d9:8b:3a:c6:dd:27:51:6e:ff:bc:64:f5:
33:43:4f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
79:B4:59:E6:7B:B6:E5:E4:01:73:80:08:88:C8:1A:58:F6:E9:9B:6E
Signature Algorithm: sha256WithRSAEncryption
55:1f:58:a9:bc:b2:a8:50:d0:0c:b1:d8:1a:69:20:27:29:08:
ac:61:75:5c:8a:6e:f8:82:e5:69:2f:d5:f6:56:4b:b9:b8:73:
10:59:d3:21:97:7e:e7:4c:71:fb:b2:d2:60:ad:39:a8:0b:ea:
17:21:56:85:f1:50:0e:59:eb:ce:e0:59:e9:ba:c9:15:ef:86:
9d:8f:84:80:f6:e4:e9:91:90:dc:17:9b:62:1b:45:f0:66:95:
d2:7c:6f:c2:ea:3b:ef:1f:cf:cb:d6:ae:27:f1:a9:b0:c8:ae:
fd:7d:7e:9a:fa:22:04:eb:ff:d9:7f:ea:91:2b:22:b1:17:0e:
8f:f2:8a:34:5b:58:d8:fc:01:c9:54:b9:b8:26:cc:8a:88:33:
89:4c:2d:84:3c:82:df:ee:96:57:05:ba:2c:bb:f7:c4:b7:c7:
4e:3b:82:be:31:c8:22:73:73:92:d1:c2:80:a4:39:39:10:33:
23:82:4c:3c:9f:86:b2:55:98:1d:be:29:86:8c:22:9b:9e:e2:
6b:3b:57:3a:82:70:4d:dc:09:c7:89:cb:0a:07:4d:6c:e8:5d:
8e:c9:ef:ce:ab:c7:bb:b5:2b:4e:45:d6:4a:d0:26:cc:e5:72:
ca:08:6a:a5:95:e3:15:a1:f7:a4:ed:c9:2c:5f:a5:fb:ff:ac:
28:02:2e:be:d7:7b:bb:e3:71:7b:90:16:d3:07:5e:46:53:7c:
37:07:42:8c:d3:c4:96:9c:d5:99:b5:2a:e0:95:1a:80:48:ae:
4c:39:07:ce:cc:47:a4:52:95:2b:ba:b8:fb:ad:d2:33:53:7d:
e5:1d:4d:6d:d5:a1:b1:c7:42:6f:e6:40:27:35:5c:a3:28:b7:
07:8d:e7:8d:33:90:e7:23:9f:fb:50:9c:79:6c:46:d5:b4:15:
b3:96:6e:7e:9b:0c:96:3a:b8:52:2d:3f:d6:5b:e1:fb:08:c2:
84:fe:24:a8:a3:89:da:ac:6a:e1:18:2a:b1:a8:43:61:5b:d3:
1f:dc:3b:8d:76:f2:2d:e8:8d:75:df:17:33:6c:3d:53:fb:7b:
cb:41:5f:ff:dc:a2:d0:61:38:e1:96:b8:ac:5d:8b:37:d7:75:
d5:33:c0:99:11:ae:9d:41:c1:72:75:84:be:02:41:42:5f:67:
24:48:94:d1:9b:27:be:07:3f:b9:b8:4f:81:74:51:e1:7a:b7:
ed:9d:23:e2:be:e0:d5:28:04:13:3c:31:03:9e:dd:7a:6c:8f:
c6:07:18:c6:7f:de:47:8e:3f:28:9e:04:06:cf:a5:54:34:77:
bd:ec:89:9b:e9:17:43:df:5b:db:5f:fe:8e:1e:57:a2:cd:40:
9d:7e:62:22:da:de:18:27
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----

View file

@ -1,179 +0,0 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 7 (0x7)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Root Certificate Authority - G2
Validity
Not Before: May 3 07:00:00 2011 GMT
Not After : May 3 07:00:00 2031 GMT
Subject: C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", OU = http://certs.starfieldtech.com/repository/, CN = Starfield Secure Certificate Authority - G2
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:e5:90:66:4b:ec:f9:46:71:a9:20:83:be:e9:6c:
bf:4a:c9:48:69:81:75:4e:6d:24:f6:cb:17:13:f8:
b0:71:59:84:7a:6b:2b:85:a4:34:b5:16:e5:cb:cc:
e9:41:70:2c:a4:2e:d6:fa:32:7d:e1:a8:de:94:10:
ac:31:c1:c0:d8:6a:ff:59:27:ab:76:d6:fc:0b:74:
6b:b8:a7:ae:3f:c4:54:f4:b4:31:44:dd:93:56:8c:
a4:4c:5e:9b:89:cb:24:83:9b:e2:57:7d:b7:d8:12:
1f:c9:85:6d:f4:d1:80:f1:50:9b:87:ae:d4:0b:10:
05:fb:27:ba:28:6d:17:e9:0e:d6:4d:b9:39:55:06:
ff:0a:24:05:7e:2f:c6:1d:72:6c:d4:8b:29:8c:57:
7d:da:d9:eb:66:1a:d3:4f:a7:df:7f:52:c4:30:c5:
a5:c9:0e:02:c5:53:bf:77:38:68:06:24:c3:66:c8:
37:7e:30:1e:45:71:23:35:ff:90:d8:2a:9d:8d:e7:
b0:92:4d:3c:7f:2a:0a:93:dc:cd:16:46:65:f7:60:
84:8b:76:4b:91:27:73:14:92:e0:ea:ee:8f:16:ea:
8d:0e:3e:76:17:bf:7d:89:80:80:44:43:e7:2d:e0:
43:09:75:da:36:e8:ad:db:89:3a:f5:5d:12:8e:23:
04:83
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Subject Key Identifier:
25:45:81:68:50:26:38:3D:3B:2D:2C:BE:CD:6A:D9:B6:3D:B3:66:63
X509v3 Authority Key Identifier:
keyid:7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27
Authority Information Access:
OCSP - URI:http://ocsp.starfieldtech.com/
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.starfieldtech.com/sfroot-g2.crl
X509v3 Certificate Policies:
Policy: X509v3 Any Policy
CPS: https://certs.starfieldtech.com/repository/
Signature Algorithm: sha256WithRSAEncryption
56:65:ca:fe:f3:3f:0a:a8:93:8b:18:c7:de:43:69:13:34:20:
be:4e:5f:78:a8:6b:9c:db:6a:4d:41:db:c1:13:ec:dc:31:00:
22:5e:f7:00:9e:0c:e0:34:65:34:f9:b1:3a:4e:48:c8:12:81:
88:5c:5b:3e:08:53:7a:f7:1a:64:df:b8:50:61:cc:53:51:40:
29:4b:c2:f4:ae:3a:5f:e4:ca:ad:26:cc:4e:61:43:e5:fd:57:
a6:37:70:ce:43:2b:b0:94:c3:92:e9:e1:5f:aa:10:49:b7:69:
e4:e0:d0:1f:64:a4:2b:cd:1f:6f:a0:f8:84:24:18:ce:79:3d:
a9:91:bf:54:18:13:89:99:54:11:0d:55:c5:26:0b:79:4f:5a:
1c:6e:f9:63:db:14:80:a4:07:ab:fa:b2:a5:b9:88:dd:91:fe:
65:3b:a4:a3:79:be:89:4d:e1:d0:b0:f4:c8:17:0c:0a:96:14:
7c:09:b7:6c:e1:c2:d8:55:d4:18:a0:aa:41:69:70:24:a3:b9:
ef:e9:5a:dc:3e:eb:94:4a:f0:b7:de:5f:0e:76:fa:fb:fb:69:
03:45:40:50:ee:72:0c:a4:12:86:81:cd:13:d1:4e:c4:3c:ca:
4e:0d:d2:26:f1:00:b7:b4:a6:a2:e1:6e:7a:81:fd:30:ac:7a:
1f:c7:59:7b
-----BEGIN CERTIFICATE-----
MIIFADCCA+igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAw
MFoXDTMxMDUwMzA3MDAwMFowgcYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
aG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydHMuc3RhcmZpZWxk
dGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNVBAMTK1N0YXJmaWVsZCBTZWN1cmUg
Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDlkGZL7PlGcakgg77pbL9KyUhpgXVObST2yxcT+LBxWYR6ayuF
pDS1FuXLzOlBcCykLtb6Mn3hqN6UEKwxwcDYav9ZJ6t21vwLdGu4p64/xFT0tDFE
3ZNWjKRMXpuJyySDm+JXfbfYEh/JhW300YDxUJuHrtQLEAX7J7oobRfpDtZNuTlV
Bv8KJAV+L8YdcmzUiymMV33a2etmGtNPp99/UsQwxaXJDgLFU793OGgGJMNmyDd+
MB5FcSM1/5DYKp2N57CSTTx/KgqT3M0WRmX3YISLdkuRJ3MUkuDq7o8W6o0OPnYX
v32JgIBEQ+ct4EMJddo26K3biTr1XRKOIwSDAgMBAAGjggEsMIIBKDAPBgNVHRMB
Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUJUWBaFAmOD07LSy+
zWrZtj2zZmMwHwYDVR0jBBgwFoAUfAwyH6fZMH/EfWijYqihzqsHWycwOgYIKwYB
BQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNo
LmNvbS8wOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0ZWNo
LmNvbS9zZnJvb3QtZzIuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF
BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv
MA0GCSqGSIb3DQEBCwUAA4IBAQBWZcr+8z8KqJOLGMfeQ2kTNCC+Tl94qGuc22pN
QdvBE+zcMQAiXvcAngzgNGU0+bE6TkjIEoGIXFs+CFN69xpk37hQYcxTUUApS8L0
rjpf5MqtJsxOYUPl/VemN3DOQyuwlMOS6eFfqhBJt2nk4NAfZKQrzR9voPiEJBjO
eT2pkb9UGBOJmVQRDVXFJgt5T1ocbvlj2xSApAer+rKluYjdkf5lO6Sjeb6JTeHQ
sPTIFwwKlhR8Cbds4cLYVdQYoKpBaXAko7nv6VrcPuuUSvC33l8Odvr7+2kDRUBQ
7nIMpBKGgc0T0U7EPMpODdIm8QC3tKai4W56gf0wrHofx1l7
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Root Certificate Authority - G2
Validity
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
Subject: C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Root Certificate Authority - G2
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:bd:ed:c1:03:fc:f6:8f:fc:02:b1:6f:5b:9f:48:
d9:9d:79:e2:a2:b7:03:61:56:18:c3:47:b6:d7:ca:
3d:35:2e:89:43:f7:a1:69:9b:de:8a:1a:fd:13:20:
9c:b4:49:77:32:29:56:fd:b9:ec:8c:dd:22:fa:72:
dc:27:61:97:ee:f6:5a:84:ec:6e:19:b9:89:2c:dc:
84:5b:d5:74:fb:6b:5f:c5:89:a5:10:52:89:46:55:
f4:b8:75:1c:e6:7f:e4:54:ae:4b:f8:55:72:57:02:
19:f8:17:71:59:eb:1e:28:07:74:c5:9d:48:be:6c:
b4:f4:a4:b0:f3:64:37:79:92:c0:ec:46:5e:7f:e1:
6d:53:4c:62:af:cd:1f:0b:63:bb:3a:9d:fb:fc:79:
00:98:61:74:cf:26:82:40:63:f3:b2:72:6a:19:0d:
99:ca:d4:0e:75:cc:37:fb:8b:89:c1:59:f1:62:7f:
5f:b3:5f:65:30:f8:a7:b7:4d:76:5a:1e:76:5e:34:
c0:e8:96:56:99:8a:b3:f0:7f:a4:cd:bd:dc:32:31:
7c:91:cf:e0:5f:11:f8:6b:aa:49:5c:d1:99:94:d1:
a2:e3:63:5b:09:76:b5:56:62:e1:4b:74:1d:96:d4:
26:d4:08:04:59:d0:98:0e:0e:e6:de:fc:c3:ec:1f:
90:f1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Subject Key Identifier:
7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27
Signature Algorithm: sha256WithRSAEncryption
11:59:fa:25:4f:03:6f:94:99:3b:9a:1f:82:85:39:d4:76:05:
94:5e:e1:28:93:6d:62:5d:09:c2:a0:a8:d4:b0:75:38:f1:34:
6a:9d:e4:9f:8a:86:26:51:e6:2c:d1:c6:2d:6e:95:20:4a:92:
01:ec:b8:8a:67:7b:31:e2:67:2e:8c:95:03:26:2e:43:9d:4a:
31:f6:0e:b5:0c:bb:b7:e2:37:7f:22:ba:00:a3:0e:7b:52:fb:
6b:bb:3b:c4:d3:79:51:4e:cd:90:f4:67:07:19:c8:3c:46:7a:
0d:01:7d:c5:58:e7:6d:e6:85:30:17:9a:24:c4:10:e0:04:f7:
e0:f2:7f:d4:aa:0a:ff:42:1d:37:ed:94:e5:64:59:12:20:77:
38:d3:32:3e:38:81:75:96:73:fa:68:8f:b1:cb:ce:1f:c5:ec:
fa:9c:7e:cf:7e:b1:f1:07:2d:b6:fc:bf:ca:a4:bf:d0:97:05:
4a:bc:ea:18:28:02:90:bd:54:78:09:21:71:d3:d1:7d:1d:d9:
16:b0:a9:61:3d:d0:0a:00:22:fc:c7:7b:cb:09:64:45:0b:3b:
40:81:f7:7d:7c:32:f5:98:ca:58:8e:7d:2a:ee:90:59:73:64:
f9:36:74:5e:25:a1:f5:66:05:2e:7f:39:15:a9:2a:fb:50:8b:
8e:85:69:f4
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE-----

View file

@ -0,0 +1,30 @@
# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
# Label: "Starfield Root Certificate Authority - G2"
# Serial: 0
# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96
# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e
# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE-----

View file

@ -0,0 +1,41 @@
# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
# Label: "USERTrust RSA Certification Authority"
# Serial: 2645093764781058787591871645665788717
# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5
# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e
# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2
-----BEGIN CERTIFICATE-----
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
jjxDah2nGN59PRbxYvnKkKj9
-----END CERTIFICATE-----

View file

@ -1,135 +0,0 @@
#!rsc by RouterOS
# RouterOS script: check-certificates
# Copyright (c) 2013-2022 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
:local 0 "check-certificates";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global CertRenewPass;
:global CertRenewTime;
:global CertRenewUrl;
:global Identity;
:global CertificateAvailable
:global CertificateNameByCN;
:global IfThenElse;
:global LogPrintExit2;
:global ParseKeyValueStore;
:global SendNotification2;
: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<$CertRenewTime ] do={
:local CertVal [ / certificate get $Cert ];
:do {
:if ([ :len $CertRenewUrl ] = 0) do={
$LogPrintExit2 info $0 ("No CertRenewUrl given.") true;
}
$LogPrintExit2 info $0 ("Attempting to renew certificate " . ($CertVal->"name") . ".") false;
: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 as-value;
$WaitForFile $CertFileName;
:foreach PassPhrase in=$CertRenewPass do={
/ certificate import file-name=$CertFileName passphrase=$PassPhrase as-value;
}
/ 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={
$LogPrintExit2 debug $0 ("Could not download certificate file " . $CertFileName) false;
}
}
:local CertNew [ / certificate find where common-name=($CertVal->"common-name") fingerprint!=[ :tostr ($CertVal->"fingerprint") ] expires-after>$CertRenewTime ];
:local CertNewVal [ / certificate get $CertNew ];
:if ([ $CertificateAvailable ([ $ParseKeyValueStore ($CertNewVal->"issuer") ]->"CN") ] = false) do={
$LogPrintExit2 warning $0 ("The certificate chain is not available!") false;
}
:if ($Cert != $CertNew) do={
$LogPrintExit2 debug $0 ("Certificate '" . $CertVal->"name" . "' was not updated, but replaced.") false;
:if (($CertVal->"private-key") = true && ($CertVal->"private-key") != ($CertNewVal->"private-key")) do={
/ certificate remove $CertNew;
$LogPrintExit2 warning $0 ("Old certificate '" . ($CertVal->"name") . "' has a private key, new certificate does not. Aborting renew.") true;
}
/ 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={
$LogPrintExit2 debug $0 ("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={
$LogPrintExit2 debug $0 ("Setting hotspot certificates failed. Package 'hotspot' not installed?") false;
}
/ certificate remove $Cert;
/ certificate set $CertNew name=($CertVal->"name");
}
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "lock-with-ink-pen" ] . "Certificate renewed"); \
message=("A certificate on " . $Identity . " has been renewed.\n\n" . \
"Name: " . ($CertVal->"name") . "\n" . \
"CommonName: " . ($CertNewVal->"common-name") . "\n" . \
"Private key: " . [ $IfThenElse (($CertNewVal->"private-key") = true) "available" "missing" ] . "\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") ]); silent=true });
$LogPrintExit2 info $0 ("The certificate " . ($CertVal->"name") . " has been renewed.") false;
} on-error={
$LogPrintExit2 debug $0 ("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={
$LogPrintExit2 debug $0 ("Certificate \"" . ($CertVal->"name") . "\" is handled by SCEP, skipping.") false;
} else={
:local State [ $IfThenElse (($CertVal->"expired") = true) "expired" "is about to expire" ];
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "warning-sign" ] . "Certificate warning!"); \
message=("A certificate on " . $Identity . " " . $State . ".\n\n" . \
"Name: " . ($CertVal->"name") . "\n" . \
"CommonName: " . ($CertVal->"common-name") . "\n" . \
"Private key: " . [ $IfThenElse (($CertVal->"private-key") = true) "available" "missing" ] . "\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") ] ]) });
$LogPrintExit2 info $0 ("The certificate " . ($CertVal->"name") . " " . $State . \
", it is invalid after " . ($CertVal->"invalid-after") . ".") false;
}
}

242
check-certificates.rsc Normal file
View file

@ -0,0 +1,242 @@
#!rsc by RouterOS
# RouterOS script: check-certificates
# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
# 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 EitherOr;
: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 . [ $EitherOr ([ $ParseKeyValueStore ($CertVal->"issuer") ]->"CN") \
([ $ParseKeyValueStore (($CertVal->"issuer")->0) ]->"CN") ]);
:set CertVal [ /certificate/get [ find where skid=($CertVal->"akid") ] ];
: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;
}

View file

@ -1,131 +0,0 @@
#!rsc by RouterOS
# RouterOS script: check-health
# Copyright (c) 2019-2022 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
:local 0 "check-health";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global CheckHealthLast;
:global CheckHealthTemperature;
:global CheckHealthTemperatureDeviation;
:global CheckHealthTemperatureNotified;
:global CheckHealthVoltageLow;
:global CheckHealthVoltagePercent;
:global Identity;
:global IfThenElse;
:global LogPrintExit2;
:global ScriptLock;
:global SendNotification2;
:global SymbolForNotification;
:local TempToNum do={
:global CharacterReplace;
:local T [ :toarray [ $CharacterReplace $1 "." "," ] ];
:return ($T->0 * 10 + $T->1);
}
:if ([ :len [ / system health find ] ] = 0) do={
$LogPrintExit2 error $0 ("Your device does not provide any health values.") true;
}
:if ([ :typeof $CheckHealthLast ] != "array") do={
:set CheckHealthLast [ :toarray "" ];
}
:if ([ :typeof $CheckHealthTemperatureNotified ] != "array") do={
:set CheckHealthTemperatureNotified [ :toarray "" ];
}
$ScriptLock $0;
: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=$0; \
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" . \
"old value: " . ($CheckHealthLast->$Name) . " V\n" . \
"new value: " . $Value . " V") });
} else={
:if ($NumCurr <= $CheckHealthVoltageLow && $NumLast > $CheckHealthVoltageLow) do={
$SendNotification2 ({ origin=$0; \
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=$0; \
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;
}
:foreach PSU in=[ / system health find where name~"^psu.*-state\$" ] do={
:local Name [ / system health get $PSU name ];
:local Value [ / system health get $PSU value ];
:if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
:if ($CheckHealthLast->$Name = "ok" && \
$Value != "ok") do={
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "cross-mark" ] . "Health warning: " . $Name); \
message=("The power supply unit '" . $Name . "' on " . $Identity . " failed!") });
}
:if ($CheckHealthLast->$Name != "ok" && \
$Value = "ok") do={
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \
message=("The power supply unit '" . $Name . "' on " . $Identity . " recovered!") });
}
}
:set ($CheckHealthLast->$Name) $Value;
}
: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={
$LogPrintExit2 info $0 ("No threshold given for " . $Name . ", assuming 50C.") false;
: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=$0; \
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=$0; \
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;
}

49
check-health.d/state.rsc Normal file
View file

@ -0,0 +1,49 @@
#!rsc by RouterOS
# RouterOS script: check-health.d/state
# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# check for RouterOS health state - state plugin
# https://rsc.eworm.de/doc/check-health.md
:global CheckHealthPlugins;
:set ($CheckHealthPlugins->[ :jobname ]) do={
:local FuncName [ :tostr $0 ];
: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;
}
}

View file

@ -0,0 +1,75 @@
#!rsc by RouterOS
# RouterOS script: check-health.d/temperature
# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# check for RouterOS health state - temperature plugin
# https://rsc.eworm.de/doc/check-health.md
:global CheckHealthPlugins;
:set ($CheckHealthPlugins->[ :jobname ]) do={
:local FuncName [ :tostr $0 ];
: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;
}
}

View file

@ -0,0 +1,64 @@
#!rsc by RouterOS
# RouterOS script: check-health.d/voltage
# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# check for RouterOS health state - voltage plugin
# https://rsc.eworm.de/doc/check-health.md
:global CheckHealthPlugins;
:set ($CheckHealthPlugins->[ :jobname ]) do={
:local FuncName [ :tostr $0 ];
: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 Normal file
View file

@ -0,0 +1,110 @@
#!rsc by RouterOS
# RouterOS script: check-health
# Copyright (c) 2019-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# check for RouterOS health state
# 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;
}

View file

@ -1,82 +0,0 @@
#!rsc by RouterOS
# RouterOS script: check-lte-firmware-upgrade
# Copyright (c) 2018-2022 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
:local 0 "check-lte-firmware-upgrade";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global SentLteFirmwareUpgradeNotification;
:if ([ :typeof $SentLteFirmwareUpgradeNotification ] != "array") do={
:global SentLteFirmwareUpgradeNotification [ :toarray "" ];
}
:local CheckInterface do={
:local Interface $1;
:global Identity;
:global SentLteFirmwareUpgradeNotification;
:global CharacterReplace;
:global LogPrintExit2;
:global ScriptFromTerminal;
:global SendNotification2;
:global SymbolForNotification;
:local IntName [ / interface lte get $Interface name ];
:local Firmware;
:local Info;
:do {
:set Firmware [ / interface lte firmware-upgrade $Interface once as-value ];
:set Info [ / interface lte monitor $Interface once as-value ];
} on-error={
$LogPrintExit2 debug $0 ("Could not get latest LTE firmware version for interface " . \
$IntName . ".") false;
:return false;
}
:if (($Firmware->"installed") = ($Firmware->"latest")) do={
:if ([ $ScriptFromTerminal "check-lte-firmware-upgrade" ] = true) do={
$LogPrintExit2 info $0 ("No firmware upgrade available for LTE interface " . $IntName . ".") false;
}
:return true;
}
:if ([ $ScriptFromTerminal "check-lte-firmware-upgrade" ] = 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;
$LogPrintExit2 info $0 ("Scheduled lte firmware upgrade for interface " . $IntName . "...") false;
:return true;
} else={
:put "Canceled...";
}
}
:if (($SentLteFirmwareUpgradeNotification->$IntName) = ($Firmware->"latest")) do={
$LogPrintExit2 debug $0 ("Already sent the LTE firmware upgrade notification for version " . \
($Firmware->"latest") . ".") false;
:return false;
}
$LogPrintExit2 info $0 ("A new firmware version " . ($Firmware->"latest") . " is available for " . \
"LTE interface " . $IntName . ".") false;
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "sparkles" ] . "LTE firmware upgrade"); \
message=("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")); silent=true });
:set ($SentLteFirmwareUpgradeNotification->$IntName) ($Firmware->"latest");
}
:foreach Interface in=[ / interface lte find ] do={
$CheckInterface $Interface;
}

View file

@ -0,0 +1,107 @@
#!rsc by RouterOS
# RouterOS script: check-lte-firmware-upgrade
# Copyright (c) 2018-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -0,0 +1,78 @@
#!rsc by RouterOS
# RouterOS script: check-perpetual-license
# Copyright (c) 2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
#
# check perpetual license on CHR
# https://rsc.eworm.de/doc/check-perpetual-license.md
:local ExitOK false;
:onerror Err {
:global GlobalConfigReady; :global GlobalFunctionsReady;
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global Identity;
:global SentCertificateNotification;
:global LogPrint;
:global ScriptLock;
:global SendNotification2;
:global SymbolForNotification;
:global WaitFullyConnected;
:if ([ $ScriptLock $ScriptName ] = false) do={
:set ExitOK true;
:error false;
}
$WaitFullyConnected;
:local License [ /system/license/get ];
:if ([ :typeof ($License->"deadline-at") ] != "str") do={
$LogPrint info $ScriptName ("This device does not have a perpetual license.");
:set ExitOK true;
:error true;
}
:if ([ :len ($License->"next-renewal-at") ] = 0 && ($License->"limited-upgrades") = true) do={
$LogPrint warning $ScriptName ("Your license expired on " . ($License->"deadline-at") . "!");
:if ($SentCertificateNotification != "expired") do={
$SendNotification2 ({ origin=$ScriptName; \
subject=([ $SymbolForNotification "scroll,warning-sign" ] . "License expired!"); \
message=("Your license expired on " . ($License->"deadline-at") . \
", can no longer update RouterOS on " . $Identity . "...") });
:set SentCertificateNotification "expired";
}
:set ExitOK true;
:error true;
}
:if ([ :totime ($License->"deadline-at") ] - 3w < [ :timestamp ]) do={
$LogPrint warning $ScriptName ("Your license will expire on " . ($License->"deadline-at") . "!");
:if ($SentCertificateNotification != "warning") do={
$SendNotification2 ({ origin=$ScriptName; \
subject=([ $SymbolForNotification "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;
}

View file

@ -1,145 +0,0 @@
#!rsc by RouterOS
# RouterOS script: check-routeros-update
# Copyright (c) 2013-2022 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
:local 0 "check-routeros-update";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global Identity;
:global SafeUpdateNeighbor;
:global SafeUpdateOnCap;
:global SafeUpdatePatch;
:global SafeUpdateUrl;
:global SentRouterosUpdateNotification;
:global DeviceInfo;
:global LogPrintExit2;
:global ScriptFromTerminal;
:global ScriptLock;
:global SendNotification2;
:global SymbolForNotification;
:global VersionToNum;
:global WaitFullyConnected;
: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.";
}
$ScriptLock $0;
$WaitFullyConnected;
: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 && \
$SafeUpdateOnCap != true) do={
$LogPrintExit2 error $0 ("System is managed by CAPsMAN, not checking for RouterOS version.") true;
}
}
:if ([ :len [ / system scheduler find where name="reboot-for-update" ] ] > 0) do={
:error "A reboot for update is already scheduled.";
}
$LogPrintExit2 debug $0 ("Checking for updates...") false;
/ system package update check-for-updates without-paging as-value;
:local Update [ / system package update get ];
:if ([ :len ($Update->"latest-version") ] = 0) do={
$LogPrintExit2 info $0 ("An empty string is not a valid version.") true;
}
:if ([ $ScriptFromTerminal $0 ] = true && ($Update->"installed-version") = ($Update->"latest-version")) do={
$LogPrintExit2 info $0 ("System is already up to date.") 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={
$LogPrintExit2 info $0 ("Version " . $Update->"latest-version" . " is a patch release, updating...") false;
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update"); \
message=("Version " . $Update->"latest-version" . " is a patch update for " . $Update->"channel" . \
", updating on " . $Identity . "..."); link=$Link; silent=true });
$DoUpdate;
}
:if ($SafeUpdateNeighbor = true && [ :len [ / ip neighbor find where \
version=($Update->"latest-version" . " (" . $Update->"channel" . ")") ] ] > 0) do={
$LogPrintExit2 info $0 ("Seen a neighbor running version " . $Update->"latest-version" . ", updating...") false;
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update"); \
message=("Seen a neighbor running version " . $Update->"latest-version" . " from " . $Update->"channel" . \
", updating on " . $Identity . "..."); link=$Link; silent=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={
$LogPrintExit2 warning $0 ("Failed receiving safe version for " . $Update->"channel" . ".") false;
}
:if ($Result->"status" = "finished" && $Result->"data" = $Update->"latest-version") do={
$LogPrintExit2 info $0 ("Version " . $Update->"latest-version" . " is considered safe, updating...") false;
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update"); \
message=("Version " . $Update->"latest-version" . " is considered safe for " . $Update->"channel" . \
", updating on " . $Identity . "..."); link=$Link; silent=true });
$DoUpdate;
}
}
:if ([ $ScriptFromTerminal $0 ] = 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={
$LogPrintExit2 info $0 ("Already sent the RouterOS update notification for version " . \
$Update->"latest-version" . ".") true;
}
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update"); \
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={
$LogPrintExit2 info $0 ("Already sent the RouterOS downgrade notification for version " . \
$Update->"latest-version" . ".") true;
}
$SendNotification2 ({ origin=$0; \
subject=([ $SymbolForNotification "warning-sign" ] . "RouterOS 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 });
$LogPrintExit2 info $0 ("A different RouterOS version " . ($Update->"latest-version") . \
" is available for downgrade.") false;
:set SentRouterosUpdateNotification ($Update->"latest-version");
}

225
check-routeros-update.rsc Normal file
View file

@ -0,0 +1,225 @@
#!rsc by RouterOS
# RouterOS script: check-routeros-update
# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.15
# 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 ];
:global LogPrint;
:if ([ :len [ /system/script/find where name="packages-update" ] ] > 0) do={
/system/script/run packages-update;
} else={
/system/package/update/install without-paging;
}
$LogPrint info $ScriptName ("Waiting for system to reboot.");
}
:if ([ $ScriptLock $ScriptName ] = false) do={
: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;
}

View file

@ -1,2 +0,0 @@
#!rsc by RouterOS
# dummy for migration

View file

@ -1,85 +0,0 @@
#!rsc by RouterOS
# RouterOS script: collect-wireless-mac.capsman
# Copyright (c) 2013-2022 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
#
# provides: lease-script, order=40
#
# !! Do not edit this file, it is generated from template!
:local 0 "collect-wireless-mac.capsman";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global Identity;
:global EitherOr;
:global GetMacVendor;
:global LogPrintExit2;
:global ScriptLock;
:global SendNotification2;
:global SymbolForNotification;
$ScriptLock $0 false 10;
:if ([ :len [ / caps-man access-list find where comment="--- collected above ---" disabled ] ] = 0) do={
/ caps-man access-list add comment="--- collected above ---" disabled=yes;
$LogPrintExit2 warning $0 ("Added disabled access-list entry with comment '--- collected above ---'.") false;
}
: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={
$LogPrintExit2 debug $0 ("Device already gone... Ignoring.") false;
}
: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={
$LogPrintExit2 debug $0 ("MAC address " . $RegVal->"mac-address" . " already known: " . \
[ / caps-man access-list get $AccessList comment ]) false;
}
: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=($RegVal->"mac-address") dynamic=yes status=bound ]->0);
:if ([ :len $Lease ] > 0) do={
:set Address [ / ip dhcp-server lease get $Lease 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 ];
}
}
: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");
$LogPrintExit2 info $0 $Message false;
/ caps-man access-list add place-before=$PlaceBefore comment=$Message mac-address=($RegVal->"mac-address") disabled=yes;
$SendNotification2 ({ origin=$0; \
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" . \
"Controller: " . $Identity . "\n" . \
"Interface: " . $RegVal->"interface" . "\n" . \
"SSID: " . $RegVal->"ssid" . "\n" . \
"MAC: " . $RegVal->"mac-address" . "\n" . \
"Vendor: " . $Vendor . "\n" . \
"Hostname: " . $HostName . "\n" . \
"Address: " . $Address . "\n" . \
"DNS name: " . $DnsName . "\n" . \
"Date: " . $DateTime) });
}
} else={
$LogPrintExit2 debug $0 ("No mac address available... Ignoring.") false;
}
}

View file

@ -0,0 +1,100 @@
#!rsc by RouterOS
# RouterOS script: collect-wireless-mac.capsman
# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=40
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -1,86 +0,0 @@
#!rsc by RouterOS
# RouterOS script: collect-wireless-mac.local
# Copyright (c) 2013-2022 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
#
# provides: lease-script, order=40
#
# !! Do not edit this file, it is generated from template!
:local 0 "collect-wireless-mac.local";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global Identity;
:global EitherOr;
:global GetMacVendor;
:global LogPrintExit2;
:global ScriptLock;
:global SendNotification2;
:global SymbolForNotification;
$ScriptLock $0 false 10;
:if ([ :len [ / interface wireless access-list find where comment="--- collected above ---" disabled ] ] = 0) do={
/ interface wireless access-list add comment="--- collected above ---" disabled=yes;
$LogPrintExit2 warning $0 ("Added disabled access-list entry with comment '--- collected above ---'.") false;
}
:local PlaceBefore ([ / interface wireless access-list find where comment="--- collected above ---" disabled ]->0);
:foreach Reg in=[ / interface wireless registration-table find ] do={
:local RegVal;
:do {
:set RegVal [ / interface wireless registration-table get $Reg ];
} on-error={
$LogPrintExit2 debug $0 ("Device already gone... Ignoring.") false;
}
: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={
$LogPrintExit2 debug $0 ("MAC address " . $RegVal->"mac-address" . " already known: " . \
[ / interface wireless access-list get $AccessList comment ]) false;
}
: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=($RegVal->"mac-address") dynamic=yes status=bound ]->0);
:if ([ :len $Lease ] > 0) do={
:set Address [ / ip dhcp-server lease get $Lease 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 ];
}
}
: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");
$LogPrintExit2 info $0 $Message false;
/ interface wireless access-list add place-before=$PlaceBefore comment=$Message mac-address=($RegVal->"mac-address") disabled=yes;
$SendNotification2 ({ origin=$0; \
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" . \
"Controller: " . $Identity . "\n" . \
"Interface: " . $RegVal->"interface" . "\n" . \
"SSID: " . $RegVal->"ssid" . "\n" . \
"MAC: " . $RegVal->"mac-address" . "\n" . \
"Vendor: " . $Vendor . "\n" . \
"Hostname: " . $HostName . "\n" . \
"Address: " . $Address . "\n" . \
"DNS name: " . $DnsName . "\n" . \
"Date: " . $DateTime) });
}
} else={
$LogPrintExit2 debug $0 ("No mac address available... Ignoring.") false;
}
}

View file

@ -0,0 +1,101 @@
#!rsc by RouterOS
# RouterOS script: collect-wireless-mac.local
# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=40
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -1,87 +0,0 @@
#!rsc by RouterOS
# RouterOS script: collect-wireless-mac%TEMPL%
# Copyright (c) 2013-2022 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
#
# provides: lease-script, order=40
#
# !! This is just a template! Replace '%PATH%' with 'caps-man'
# !! or 'interface wireless'!
:local 0 "collect-wireless-mac%TEMPL%";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }
:global Identity;
:global EitherOr;
:global GetMacVendor;
:global LogPrintExit2;
:global ScriptLock;
:global SendNotification2;
:global SymbolForNotification;
$ScriptLock $0 false 10;
:if ([ :len [ / %PATH% access-list find where comment="--- collected above ---" disabled ] ] = 0) do={
/ %PATH% access-list add comment="--- collected above ---" disabled=yes;
$LogPrintExit2 warning $0 ("Added disabled access-list entry with comment '--- collected above ---'.") false;
}
:local PlaceBefore ([ / %PATH% access-list find where comment="--- collected above ---" disabled ]->0);
:foreach Reg in=[ / %PATH% registration-table find ] do={
:local RegVal;
:do {
:set RegVal [ / %PATH% registration-table get $Reg ];
} on-error={
$LogPrintExit2 debug $0 ("Device already gone... Ignoring.") false;
}
:if ([ :len ($RegVal->"mac-address") ] > 0) do={
:local AccessList ([ / %PATH% access-list find where mac-address=($RegVal->"mac-address") ]->0);
:if ([ :len $AccessList ] > 0) do={
$LogPrintExit2 debug $0 ("MAC address " . $RegVal->"mac-address" . " already known: " . \
[ / %PATH% access-list get $AccessList comment ]) false;
}
: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=($RegVal->"mac-address") dynamic=yes status=bound ]->0);
:if ([ :len $Lease ] > 0) do={
:set Address [ / ip dhcp-server lease get $Lease 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 ];
}
}
: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");
$LogPrintExit2 info $0 $Message false;
/ %PATH% access-list add place-before=$PlaceBefore comment=$Message mac-address=($RegVal->"mac-address") disabled=yes;
$SendNotification2 ({ origin=$0; \
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" . \
"Controller: " . $Identity . "\n" . \
"Interface: " . $RegVal->"interface" . "\n" . \
"SSID: " . $RegVal->"ssid" . "\n" . \
"MAC: " . $RegVal->"mac-address" . "\n" . \
"Vendor: " . $Vendor . "\n" . \
"Hostname: " . $HostName . "\n" . \
"Address: " . $Address . "\n" . \
"DNS name: " . $DnsName . "\n" . \
"Date: " . $DateTime) });
}
} else={
$LogPrintExit2 debug $0 ("No mac address available... Ignoring.") false;
}
}

View file

@ -0,0 +1,118 @@
#!rsc by RouterOS
# RouterOS script: collect-wireless-mac%TEMPL%
# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=40
# requires RouterOS, version=7.15
#
# 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;
}

View file

@ -0,0 +1,100 @@
#!rsc by RouterOS
# RouterOS script: collect-wireless-mac.wifi
# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# provides: lease-script, order=40
# requires RouterOS, version=7.15
#
# 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;
}

17
contrib/Makefile Normal file
View file

@ -0,0 +1,17 @@
# 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)

6
contrib/badges.md Normal file
View file

@ -0,0 +1,6 @@
[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network)
[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers)
[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.15-yellow?style=flat)](https://mikrotik.com/download/changelogs/)
[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts)
[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)

Some files were not shown because too many files have changed in this diff Show more