Properties: expose full stratum TLS cert PEM for miners with custom-CA
AxeOS / Bitaxe firmware verifies the stratum TLS cert against Espressif's bundled Mozilla CA store. A self-signed cert never matches anything in that bundle, so the handshake fails with mbedtls_ssl_handshake -0x3000 (fatal alert) and the miner shows "Failed to verify certificate". The firmware does, however, expose a "Stratum SSL Cert" field where a custom CA / trusted root can be pasted — that's the supported way to use TLS with a self-signed pool cert. Read tls/stratum.crt from the main volume and surface the full PEM (BEGIN/END markers included) as a copyable property. Update the TLS port and fingerprint descriptions to point users at the new field with a clear "paste this into your miner's TLS settings" explanation, instead of the previous wording that implied disabling cert verification was the only path.
This commit is contained in:
@@ -3,8 +3,11 @@ import { types as T, YAML } from "../deps.ts";
|
|||||||
// StartOS does not forward raw TCP on the LAN interface, so stratum is
|
// StartOS does not forward raw TCP on the LAN interface, so stratum is
|
||||||
// reached via a router forward or a simpleproxy on another host. We
|
// reached via a router forward or a simpleproxy on another host. We
|
||||||
// can't know that external IP from inside the container, but we can
|
// can't know that external IP from inside the container, but we can
|
||||||
// publish the ports, the variant, and the TLS cert fingerprint so the
|
// publish the ports, the variant, and the TLS cert fingerprint + full
|
||||||
// user has everything they need to configure their miner.
|
// PEM so the user has everything they need to configure their miner —
|
||||||
|
// including miners (e.g. AxeOS / Bitaxe) whose firmware verifies
|
||||||
|
// against a CA bundle and only accepts custom roots when the user
|
||||||
|
// pastes the cert in directly.
|
||||||
export const properties: T.ExpectedExports.properties = async (effects) => {
|
export const properties: T.ExpectedExports.properties = async (effects) => {
|
||||||
const cfg = (await effects
|
const cfg = (await effects
|
||||||
.readFile({ volumeId: "main", path: "start9/config.yaml" })
|
.readFile({ volumeId: "main", path: "start9/config.yaml" })
|
||||||
@@ -18,6 +21,7 @@ export const properties: T.ExpectedExports.properties = async (effects) => {
|
|||||||
const network = variant === "bitcoind-testnet" ? "testnet4" : "mainnet";
|
const network = variant === "bitcoind-testnet" ? "testnet4" : "mainnet";
|
||||||
|
|
||||||
let fingerprint = "";
|
let fingerprint = "";
|
||||||
|
let certPem = "";
|
||||||
if (tlsEnabled) {
|
if (tlsEnabled) {
|
||||||
try {
|
try {
|
||||||
fingerprint = (
|
fingerprint = (
|
||||||
@@ -29,6 +33,16 @@ export const properties: T.ExpectedExports.properties = async (effects) => {
|
|||||||
} catch {
|
} catch {
|
||||||
fingerprint = "(not yet generated — start the service once)";
|
fingerprint = "(not yet generated — start the service once)";
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
certPem = (
|
||||||
|
await effects.readFile({
|
||||||
|
volumeId: "main",
|
||||||
|
path: "tls/stratum.crt",
|
||||||
|
})
|
||||||
|
).trim();
|
||||||
|
} catch {
|
||||||
|
certPem = "(not yet generated — start the service once)";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const data: Record<string, T.PackagePropertyObject["value"] | any> = {
|
const data: Record<string, T.PackagePropertyObject["value"] | any> = {
|
||||||
@@ -56,7 +70,7 @@ export const properties: T.ExpectedExports.properties = async (effects) => {
|
|||||||
type: "string",
|
type: "string",
|
||||||
value: String(tlsPort),
|
value: String(tlsPort),
|
||||||
description:
|
description:
|
||||||
"TCP port stunnel listens on for TLS stratum. Miners must disable cert verification (self-signed cert) and connect with stratum+ssl://<host>:<port>.",
|
"TCP port stunnel listens on for TLS stratum. Connect miners with stratum+ssl://<host>:<port>. The cert is self-signed — miners that verify against a CA bundle (AxeOS / Bitaxe) need either the full PEM (below) pasted in as a custom root, the SHA-256 fingerprint pinned, or TLS verification disabled, depending on what the firmware exposes.",
|
||||||
copyable: true,
|
copyable: true,
|
||||||
qr: false,
|
qr: false,
|
||||||
masked: false,
|
masked: false,
|
||||||
@@ -65,7 +79,16 @@ export const properties: T.ExpectedExports.properties = async (effects) => {
|
|||||||
type: "string",
|
type: "string",
|
||||||
value: fingerprint,
|
value: fingerprint,
|
||||||
description:
|
description:
|
||||||
"Pin this fingerprint on your miner if its firmware supports it. The certificate is self-signed and regenerated only if you delete tls/stratum.* in the data volume.",
|
"SHA-256 fingerprint of the stratum TLS cert. Use this for fingerprint pinning on miner firmwares that support it. Changes only when the cert is regenerated (delete tls/stratum.* in the data volume to force a new one).",
|
||||||
|
copyable: true,
|
||||||
|
qr: false,
|
||||||
|
masked: false,
|
||||||
|
};
|
||||||
|
data["TLS Certificate (PEM)"] = {
|
||||||
|
type: "string",
|
||||||
|
value: certPem,
|
||||||
|
description:
|
||||||
|
"Full self-signed stratum certificate in PEM format. Paste this into your miner's TLS settings as a custom CA / trusted root (AxeOS exposes a 'Stratum SSL Cert' field for exactly this). Includes -----BEGIN/END CERTIFICATE----- markers; copy the whole block.",
|
||||||
copyable: true,
|
copyable: true,
|
||||||
qr: false,
|
qr: false,
|
||||||
masked: false,
|
masked: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user