From 302fc0bb82f7a10403a7d029cd06598e20bd2942 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 15 Jan 2026 16:00:08 +0100 Subject: [PATCH 01/12] fw-addr-lists: lists.blocklist.de requires 'GTS Root R4' --- certs/Makefile | 2 +- global-config.rsc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/certs/Makefile b/certs/Makefile index 3ccad6e2..35a50c81 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -13,7 +13,7 @@ DOMAINS_DUAL = \ 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 \ + lists.blocklist.de/GTS-Root-R4 \ matrix.org/GTS-Root-R4 \ raw.githubusercontent.com/USERTrust-RSA-Certification-Authority \ rsc.eworm.de/ISRG-Root-X2 \ diff --git a/global-config.rsc b/global-config.rsc index 25254123..19787a8d 100644 --- a/global-config.rsc +++ b/global-config.rsc @@ -119,7 +119,7 @@ { url="https://www.dshield.org/block.txt"; cidr="/24"; cert="ISRG Root X1" }; { url="https://lists.blocklist.de/lists/strongips.txt"; - cert="Certum Trusted Network CA" }; + cert="GTS Root R4" }; # { url="https://www.spamhaus.org/drop/drop_v4.json"; # cert="GTS Root R4" }; # { url="https://www.spamhaus.org/drop/drop_v6.json"; From 156b0e4aaf02b6ad5edf734945253e48d90f2c58 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 15 Jan 2026 16:03:38 +0100 Subject: [PATCH 02/12] fw-addr-lists: www.dshield.org requires 'GTS Root R4' --- certs/Makefile | 2 +- global-config.rsc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/certs/Makefile b/certs/Makefile index 35a50c81..da681d09 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -27,7 +27,7 @@ DOMAINS_IPV4 = \ 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.dshield.org/GTS-Root-R4 \ www.spamhaus.org/GTS-Root-R4 DOMAINS_IPV6 = \ [2606\:4700\:4700\:\:1111]/DigiCert-Global-Root-G2 \ diff --git a/global-config.rsc b/global-config.rsc index 19787a8d..9c35d13f 100644 --- a/global-config.rsc +++ b/global-config.rsc @@ -117,7 +117,7 @@ # # higher level (decrease the numerical value) for more addresses, and vice versa cert="USERTrust RSA Certification Authority" }; { url="https://www.dshield.org/block.txt"; cidr="/24"; - cert="ISRG Root X1" }; + cert="GTS Root R4" }; { url="https://lists.blocklist.de/lists/strongips.txt"; cert="GTS Root R4" }; # { url="https://www.spamhaus.org/drop/drop_v4.json"; From b72a79824e947871bae437e6ad8095b5cc01b045 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 15 Jan 2026 23:04:07 +0100 Subject: [PATCH 03/12] certs: add 'SSL.com Root Certification Authority ECC'... ... to use with Cloudflare DNS. curl -d '["SSL.com Root Certification Authority ECC"]' https://mkcert.org/generate/ | grep -v '^$' > certs/SSL-com-Root-Certification-Authority-ECC.pem --- certs/Makefile | 6 ++--- ...L-com-Root-Certification-Authority-ECC.pem | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 certs/SSL-com-Root-Certification-Authority-ECC.pem diff --git a/certs/Makefile b/certs/Makefile index da681d09..4114b3ff 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -9,7 +9,7 @@ CURL = curl \ DOMAINS_DUAL = \ api.macvendors.com/GTS-Root-R4 \ api.telegram.org/Go-Daddy-Root-Certificate-Authority-G2 \ - cloudflare-dns.com/DigiCert-Global-Root-G2 \ + cloudflare-dns.com/SSL-com-Root-Certification-Authority-ECC \ dns.google/GTS-Root-R4 \ dns.quad9.net/DigiCert-Global-Root-G3 \ git.eworm.de/ISRG-Root-X2 \ @@ -19,7 +19,7 @@ DOMAINS_DUAL = \ rsc.eworm.de/ISRG-Root-X2 \ upgrade.mikrotik.com/ISRG-Root-X1 DOMAINS_IPV4 = \ - 1.1.1.1/DigiCert-Global-Root-G2 \ + 1.1.1.1/SSL-com-Root-Certification-Authority-ECC \ 8.8.8.8/GTS-Root-R1 \ 9.9.9.9/DigiCert-Global-Root-G3 \ api.mullvad.net/ISRG-Root-X1 \ @@ -30,7 +30,7 @@ DOMAINS_IPV4 = \ www.dshield.org/GTS-Root-R4 \ www.spamhaus.org/GTS-Root-R4 DOMAINS_IPV6 = \ - [2606\:4700\:4700\:\:1111]/DigiCert-Global-Root-G2 \ + [2606\:4700\:4700\:\:1111]/SSL-com-Root-Certification-Authority-ECC \ [2001\:4860\:4860\:\:8888]/GTS-Root-R1 \ [2620\:fe\:\:9]/DigiCert-Global-Root-G3 \ ipv6.showipv6.de/ISRG-Root-X1 diff --git a/certs/SSL-com-Root-Certification-Authority-ECC.pem b/certs/SSL-com-Root-Certification-Authority-ECC.pem new file mode 100644 index 00000000..f1166839 --- /dev/null +++ b/certs/SSL-com-Root-Certification-Authority-ECC.pem @@ -0,0 +1,23 @@ +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- From ad455c8f1d011ba0bbfcfc25f5b5f7f722b2da51 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 15 Jan 2026 23:10:33 +0100 Subject: [PATCH 04/12] doc/netwatch-dns: cloudflare uses a new CA for certificates --- doc/netwatch-dns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/netwatch-dns.md b/doc/netwatch-dns.md index 23190b12..c81ca8c9 100644 --- a/doc/netwatch-dns.md +++ b/doc/netwatch-dns.md @@ -62,7 +62,7 @@ manually! Importing a certificate automatically is possible. You may want to find the [certificate name from browser](../CERTIFICATES.md). - /tool/netwatch/add comment="doh, doh-cert=DigiCert Global Root G2" host=1.1.1.1; + /tool/netwatch/add comment="doh, doh-cert=SSL.com Root Certification Authority ECC" host=1.1.1.1; /tool/netwatch/add comment="doh, doh-cert=DigiCert Global Root G3" host=9.9.9.9; /tool/netwatch/add comment="doh, doh-cert=GTS Root R1" host=8.8.8.8; From d673f0956c23f0ab30c19b28cf0090a0ddb6df27 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 16 Jan 2026 00:00:58 +0100 Subject: [PATCH 05/12] global-functions: $CertificateAvailable: get missing certificate... ... not the issued and available one. --- global-functions.rsc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/global-functions.rsc b/global-functions.rsc index 5c70a463..5d2a5044 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -150,9 +150,9 @@ :local CertVal [ /certificate/get [ find where common-name=$CommonName ] ]; :while (($CertVal->"akid") != "" && ($CertVal->"akid") != ($CertVal->"skid")) do={ :if ([ :len [ /certificate/find where skid=($CertVal->"akid") ] ] = 0) do={ - $LogPrint info $0 ("Certificate chain for '" . $CommonName . \ - "' is incomplete, missing '" . ([ $ParseKeyValueStore ($CertVal->"issuer") ]->"CN") . "'."); - :if ([ $CertificateDownload $CommonName ] = false) do={ + :local IssuerCN ([ $ParseKeyValueStore ($CertVal->"issuer") ]->"CN"); + $LogPrint info $0 ("Certificate chain for '" . $CommonName . "' is incomplete, missing '" . $IssuerCN . "'."); + :if ([ $CertificateDownload $IssuerCN ] = false) do={ :return false; } } From 0fee5cea3c6b14e0d612fb0ea28fa49967ce7e1a Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 16 Jan 2026 13:35:05 +0100 Subject: [PATCH 06/12] check-certificates: move the warning below check for key --- check-certificates.rsc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/check-certificates.rsc b/check-certificates.rsc index 1dd61299..88f144a2 100644 --- a/check-certificates.rsc +++ b/check-certificates.rsc @@ -197,16 +197,16 @@ 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; } + :if ([ $CertificateAvailable ([ $ParseKeyValueStore ($CertNewVal->"issuer") ]->"CN") "fetch" ] = false) do={ + $LogPrint warning $ScriptName ("The certificate chain is not available!"); + } + /ip/service/set certificate=($CertNewVal->"name") [ find where certificate=($CertVal->"name") ]; /ip/ipsec/identity/set certificate=($CertNewVal->"name") [ find where certificate=($CertVal->"name") ]; From 330a616406a2cf255236472f3b3ac8cc6d0ac02c Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 16 Jan 2026 13:39:25 +0100 Subject: [PATCH 07/12] check-certificates: abort renew if "new" certificate is older... ... and drop the condition on $CertRenewTime. --- check-certificates.rsc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/check-certificates.rsc b/check-certificates.rsc index 88f144a2..9aa11c10 100644 --- a/check-certificates.rsc +++ b/check-certificates.rsc @@ -194,9 +194,15 @@ :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 ]; + fingerprint!=[ :tostr ($CertVal->"fingerprint") ] ]; :local CertNewVal [ /certificate/get $CertNew ]; + :if (($CertVal->"expires-after") > ($CertNewVal->"expires-after")) do={ + /certificate/remove $CertNew; + $LogPrint warning $ScriptName ("Old certificate is newer than the new one. Aborting renew."); + :error false; + } + :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."); From 0fffb5198eafe53a02c48a701ec7309244be5242 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 16 Jan 2026 13:51:37 +0100 Subject: [PATCH 08/12] netwatch-dns: support multiple certificates Some services use certificates issued by differnt CA certificates, depending on geolocation. One example is dns.google, which may require either of 'GTS Root R1' or 'GTS Root R4'. /tool/netwatch/add comment="doh, dns, name=google-dns-ipv4, doh-cert=GTS Root R1:GTS Root R4" host=8.8.8.8 type=simple; --- netwatch-dns.rsc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/netwatch-dns.rsc b/netwatch-dns.rsc index 2edbdf8c..06a15f95 100644 --- a/netwatch-dns.rsc +++ b/netwatch-dns.rsc @@ -17,6 +17,7 @@ :local ScriptName [ :jobname ]; :global CertificateAvailable; + :global CharacterReplace; :global EitherOr; :global IsDNSResolving; :global LogPrint; @@ -103,10 +104,12 @@ } :foreach DohServer in=$DohServers do={ - :if ([ :len ($DohServer->"doh-cert") ] > 0) do={ - :if ([ $CertificateAvailable ($DohServer->"doh-cert") "fetch" ] = false || \ - [ $CertificateAvailable ($DohServer->"doh-cert") "dns" ] = false) do={ - $LogPrint warning $ScriptName ("Downloading certificate failed, trying without."); + :foreach DohCert in=[ :toarray [ $CharacterReplace ($DohServer->"doh-cert") ":" "," ] ] do={ + :if ([ :len $DohCert ] > 0) do={ + :if ([ $CertificateAvailable $DohCert "fetch" ] = false || \ + [ $CertificateAvailable $DohCert "dns" ] = false) do={ + $LogPrint warning $ScriptName ("Downloading certificate '" . $DohCert . "' failed, trying without."); + } } } From c0c1c5521eda80539bf26c99d212ab4fe8ba80af Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 16 Jan 2026 14:01:57 +0100 Subject: [PATCH 09/12] doc/netwatch-dns: include examples for dns.quad9.net & dns.google --- doc/netwatch-dns.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/netwatch-dns.md b/doc/netwatch-dns.md index c81ca8c9..41eb7592 100644 --- a/doc/netwatch-dns.md +++ b/doc/netwatch-dns.md @@ -55,6 +55,10 @@ resolves to the same address. /ip/dns/static/add name="cloudflare-dns.com" address=1.1.1.1; /tool/netwatch/add comment="doh" host=1.1.1.1; + /ip dns static add name=dns.quad9.net address=9.9.9.9; + /tool/netwatch/add comment="doh" host=9.9.9.9; + /ip/dns/static/add name=dns.google address=8.8.8.8; + /tool/netwatch/add comment="doh" host=8.8.8.8; Be aware that you have to keep the ip address in sync with real world manually! From ad310e6573c554dca3df3e1fa7dea264d6555bb6 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 16 Jan 2026 14:05:22 +0100 Subject: [PATCH 10/12] doc/netwatch-dns: always use the same order for examples --- doc/netwatch-dns.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/netwatch-dns.md b/doc/netwatch-dns.md index 41eb7592..286fe474 100644 --- a/doc/netwatch-dns.md +++ b/doc/netwatch-dns.md @@ -37,11 +37,11 @@ The DNS and DoH servers to be checked have to be added to netwatch with specific comment: /tool/netwatch/add comment="doh" host=1.1.1.1; - /tool/netwatch/add comment="dns" host=8.8.8.8; /tool/netwatch/add comment="doh, dns" host=9.9.9.9; + /tool/netwatch/add comment="dns" host=8.8.8.8; This will configure *cloudflare-dns* for DoH (`https://1.1.1.1/dnsquery`), and -*google-dns* and *quad-nine* for regular DNS (`8.8.8.8,9.9.9.9`) if up. +*quad-nine* and *google-dns* for regular DNS (`9.9.9.9,8.8.8.8`) if up. If *cloudflare-dns* is down the script will fall back to *quad-nine* for DoH. Giving a specific query url for DoH is possible: From 92759fcca51c20da39b2c44a90f84637d3d34748 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 16 Jan 2026 14:07:44 +0100 Subject: [PATCH 11/12] doc/netwatch-dns: give hint on multiple certificates --- doc/netwatch-dns.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/netwatch-dns.md b/doc/netwatch-dns.md index 286fe474..73829974 100644 --- a/doc/netwatch-dns.md +++ b/doc/netwatch-dns.md @@ -64,11 +64,13 @@ Be aware that you have to keep the ip address in sync with real world manually! Importing a certificate automatically is possible. You may want to find the -[certificate name from browser](../CERTIFICATES.md). +[certificate name from browser](../CERTIFICATES.md). Sometimes a service +randomly switches the CA used to issue the certificate, or it just depends +geolocation - give several certificate delimited with colon (`:`) then. /tool/netwatch/add comment="doh, doh-cert=SSL.com Root Certification Authority ECC" host=1.1.1.1; /tool/netwatch/add comment="doh, doh-cert=DigiCert Global Root G3" host=9.9.9.9; - /tool/netwatch/add comment="doh, doh-cert=GTS Root R1" host=8.8.8.8; + /tool/netwatch/add comment="doh, doh-cert=GTS Root R1:GTS Root R4" host=8.8.8.8; > ⚠️ **Warning**: Combining these techniques can cause some confusion and > troubles! Chances are that a service uses different certificates based From b52936e94686b183122d04a5668b54cd3fc4f480 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 16 Jan 2026 15:52:01 +0100 Subject: [PATCH 12/12] doc/netwatch-dns: mention ip address... ... which can be used for serveral services that have it in SAN. --- doc/netwatch-dns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/netwatch-dns.md b/doc/netwatch-dns.md index 73829974..75933645 100644 --- a/doc/netwatch-dns.md +++ b/doc/netwatch-dns.md @@ -74,7 +74,7 @@ geolocation - give several certificate delimited with colon (`:`) then. > ⚠️ **Warning**: Combining these techniques can cause some confusion and > troubles! Chances are that a service uses different certificates based -> on indicated server name. +> on indicated server name (or ip address). Sometimes using just one specific (possibly internal) DNS server may be desired, with fallback in case it fails. This is possible as well: