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.
115 lines
4.1 KiB
TypeScript
115 lines
4.1 KiB
TypeScript
import { types as T, YAML } from "../deps.ts";
|
|
|
|
// 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
|
|
// can't know that external IP from inside the container, but we can
|
|
// publish the ports, the variant, and the TLS cert fingerprint + full
|
|
// 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) => {
|
|
const cfg = (await effects
|
|
.readFile({ volumeId: "main", path: "start9/config.yaml" })
|
|
.then((s: string) => YAML.parse(s))
|
|
.catch(() => ({}))) as any;
|
|
|
|
const stratumPort = cfg?.["stratum-port"] ?? 3333;
|
|
const tlsEnabled = cfg?.tls?.enabled === "enabled";
|
|
const tlsPort = cfg?.tls?.port ?? 3334;
|
|
const variant = cfg?.bitcoind?.type ?? "bitcoind";
|
|
const network = variant === "bitcoind-testnet" ? "testnet4" : "mainnet";
|
|
|
|
let fingerprint = "";
|
|
let certPem = "";
|
|
if (tlsEnabled) {
|
|
try {
|
|
fingerprint = (
|
|
await effects.readFile({
|
|
volumeId: "main",
|
|
path: "tls/fingerprint.txt",
|
|
})
|
|
).trim();
|
|
} catch {
|
|
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> = {
|
|
"Network": {
|
|
type: "string",
|
|
value: network,
|
|
description: "Bitcoin network Kamado is mining on.",
|
|
copyable: false,
|
|
qr: false,
|
|
masked: false,
|
|
},
|
|
"Stratum Port (plaintext)": {
|
|
type: "string",
|
|
value: String(stratumPort),
|
|
description:
|
|
"TCP port ckpool-solo listens on. Forward this from your router, or run simpleproxy on a LAN host, and point miners at stratum+tcp://<host>:<port>.",
|
|
copyable: true,
|
|
qr: false,
|
|
masked: false,
|
|
},
|
|
};
|
|
|
|
if (tlsEnabled) {
|
|
data["Stratum Port (TLS)"] = {
|
|
type: "string",
|
|
value: String(tlsPort),
|
|
description:
|
|
"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,
|
|
qr: false,
|
|
masked: false,
|
|
};
|
|
data["TLS Cert Fingerprint (SHA-256)"] = {
|
|
type: "string",
|
|
value: fingerprint,
|
|
description:
|
|
"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,
|
|
qr: false,
|
|
masked: false,
|
|
};
|
|
}
|
|
|
|
data["Worker Username"] = {
|
|
type: "string",
|
|
value: "<your-btc-address>[.<workername>]",
|
|
description:
|
|
"Configure each miner's stratum username as the Bitcoin address that should receive the block reward on a solve, optionally followed by .workername for dashboard labelling. Kamado refuses to authenticate workers whose username is not a valid address on the active network.",
|
|
copyable: false,
|
|
qr: false,
|
|
masked: false,
|
|
};
|
|
|
|
return {
|
|
result: {
|
|
version: 2,
|
|
data,
|
|
},
|
|
};
|
|
};
|