Properties screen: expose stratum ports, TLS fingerprint, worker format
Entrypoint persists the generated TLS cert fingerprint so the properties script can read it from the main volume. The screen shows the active network, plaintext and TLS stratum ports, the SHA-256 fingerprint for miner pinning, and the worker username format (BTC address plus optional worker label).
This commit is contained in:
@@ -134,6 +134,7 @@ if [[ "${TLS_ENABLED}" == "enabled" ]]; then
|
||||
chmod 600 "${TLS_DIR}/stratum.key" "${CERT}"
|
||||
fi
|
||||
FINGERPRINT=$(openssl x509 -in "${TLS_DIR}/stratum.crt" -noout -fingerprint -sha256 | cut -d= -f2)
|
||||
printf '%s\n' "${FINGERPRINT}" > "${TLS_DIR}/fingerprint.txt"
|
||||
echo "kamado-entrypoint: stratum TLS SHA256 fingerprint: ${FINGERPRINT}"
|
||||
|
||||
STUNNEL_CONF=/etc/stunnel/stratum.conf
|
||||
|
||||
@@ -1,22 +1,91 @@
|
||||
import { types as T, YAML } from "../deps.ts";
|
||||
|
||||
const noProps: T.ExpectedExports.properties = async () => {
|
||||
// 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 so the
|
||||
// user has everything they need to configure their miner.
|
||||
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 = "";
|
||||
if (tlsEnabled) {
|
||||
try {
|
||||
fingerprint = (
|
||||
await effects.readFile({
|
||||
volumeId: "main",
|
||||
path: "tls/fingerprint.txt",
|
||||
})
|
||||
).trim();
|
||||
} catch {
|
||||
fingerprint = "(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. Miners must disable cert verification (self-signed cert) and connect with stratum+ssl://<host>:<port>.",
|
||||
copyable: true,
|
||||
qr: false,
|
||||
masked: false,
|
||||
};
|
||||
data["TLS Cert Fingerprint (SHA-256)"] = {
|
||||
type: "string",
|
||||
value: fingerprint,
|
||||
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.",
|
||||
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: {
|
||||
"Dashboard": {
|
||||
type: "string",
|
||||
value:
|
||||
"Open the Kamado web UI from the Services page for live stats.",
|
||||
description: "Kamado exposes everything through the web dashboard.",
|
||||
copyable: false,
|
||||
qr: false,
|
||||
masked: false,
|
||||
},
|
||||
},
|
||||
data,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const properties = noProps;
|
||||
|
||||
Reference in New Issue
Block a user