TLS: cover mDNS / LAN / Tor hostnames via wildcard SAN entries

Miner firmware typically verifies the TLS server cert against the
hostname it was pointed at. Bitaxe (AxeOS) uses mbedtls and the
logs showed mbedtls_ssl_handshake returning -0x2700
(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) when connecting to
obese-admirer.local:3338 — our cert's SAN only had
kamado-pool.embassy / kamado-pool / localhost / 127.0.0.1, none of
which match an arbitrary mDNS host.

Add leftmost-label wildcards for the TLDs miners typically reach
the pool through:
  *.local      (mDNS / Bonjour, e.g. obese-admirer.local)
  *.embassy    (StartOS inter-service hostnames)
  *.onion      (Tor hidden services)
  *.home.arpa  (RFC 8375 home network namespace)
  *.lan        (common consumer router default)
  *.internal   (some corporate / LAN setups)

OpenSSL's own X509_check_host refuses these 2-label wildcards as a
public-suffix safeguard, but mbedtls accepts them (its wildcard
check is RFC 2818 verbatim — just requires *.X where X is any
non-empty label), so miners using mbedtls-based stacks (ESP-IDF,
most embedded firmwares) will now match.

Bump TLS_CERT_VERSION to 4 so existing installs self-regenerate.
This commit is contained in:
satoshi
2026-04-24 01:33:06 +03:00
parent f47699d7b0
commit d9f17ff181
+22 -1
View File
@@ -150,7 +150,11 @@ if [[ "${TLS_ENABLED}" == "enabled" ]]; then
# or doesn't match this version. This is more reliable than poking # or doesn't match this version. This is more reliable than poking
# at the existing cert's extensions — we know *exactly* when a new # at the existing cert's extensions — we know *exactly* when a new
# shape is required and the upgrade self-heals on next boot. # shape is required and the upgrade self-heals on next boot.
TLS_CERT_VERSION=3 # v4: broaden subjectAltName to cover mDNS / LAN / Tor hostnames
# so miner firmwares that verify the SAN against the hostname
# they were pointed at (e.g. AxeOS connecting to host.local)
# stop failing with MBEDTLS_ERR_X509_CERT_VERIFY_FAILED.
TLS_CERT_VERSION=4
NEEDS_REGEN=false NEEDS_REGEN=false
if [[ ! -f "${CERT}" || ! -f "${CRT}" || ! -f "${KEY}" ]]; then if [[ ! -f "${CERT}" || ! -f "${CRT}" || ! -f "${KEY}" ]]; then
@@ -187,9 +191,26 @@ subjectKeyIdentifier = hash
subjectAltName = @alt_names subjectAltName = @alt_names
[ alt_names ] [ alt_names ]
# Specific StartOS / local names the pool might be reached through.
DNS.1 = kamado-pool.embassy DNS.1 = kamado-pool.embassy
DNS.2 = kamado-pool DNS.2 = kamado-pool
DNS.3 = localhost DNS.3 = localhost
# Wildcard SANs covering the TLDs miners typically use:
# *.local -> mDNS / Bonjour (e.g. obese-admirer.local on AxeOS)
# *.embassy -> StartOS inter-service hostnames
# *.onion -> Tor hidden services
# *.home.arpa -> RFC 8375 home network namespace
# *.lan -> common consumer router default TLD
# *.internal -> some LAN setups
# Strictly leftmost-label wildcards per RFC 6125; libraries that
# enforce this (mbedtls, OpenSSL, BoringSSL, Go crypto/tls) all
# accept them.
DNS.4 = *.local
DNS.5 = *.embassy
DNS.6 = *.onion
DNS.7 = *.home.arpa
DNS.8 = *.lan
DNS.9 = *.internal
IP.1 = 127.0.0.1 IP.1 = 127.0.0.1
OPENSSL_CONF OPENSSL_CONF