commit 28d177d4ea994e174a728cd210c527aa433fc38b Author: Baldnerd Date: Fri Nov 7 08:57:45 2025 -0500 Initial Development Commit diff --git a/installer b/installer new file mode 100755 index 0000000..e682ffa --- /dev/null +++ b/installer @@ -0,0 +1,590 @@ +#!/bin/bash +# +# Bitcoin Solo Miner Appliance Installer +# An Open Source Appliance from Robbie Ferguson +# (c) 2025 Robbie Ferguson + +set -e + +APP_ROOT="/opt/btc-solo" +WWW_ROOT="/var/www/btc-solo" +BITCOIN_CONF="/etc/bitcoin/bitcoin.conf" +CERT_DIR="/etc/ssl/localcerts" +CKPOOL_USER="ckpool" +CKPOOL_PORT="3333" +BITCOIN_DATA="/var/lib/bitcoind" + +# --------------------------------------------------------------------------- +# PURGE +# --------------------------------------------------------------------------- +if [[ "$1" == "--purge" ]]; then + systemctl stop ckpool 2>/dev/null || true + systemctl stop bitcoind 2>/dev/null || true + rm -f /var/lib/btc-solo/.setup-complete + rm -f /etc/systemd/system/ckpool.service + rm -f /etc/systemd/system/bitcoind.service + rm -f /etc/nginx/sites-enabled/btc-solo + rm -f /etc/nginx/sites-available/btc-solo + rm -f /etc/sudoers.d/btc-solo + rm -rf "$APP_ROOT" "$WWW_ROOT" "$CERT_DIR" "$BITCOIN_DATA" + rm -f /usr/local/sbin/btc-apply-admin.sh /usr/local/sbin/btc-set-prune.sh /usr/local/sbin/btc-make-cert.sh + # Remove bitcoin binaries we installed directly + rm -f /usr/local/bin/bitcoind /usr/local/bin/bitcoin-cli /usr/local/bin/bitcoin-tx /usr/local/bin/bitcoin-util 2>/dev/null || true + systemctl daemon-reload + systemctl restart nginx 2>/dev/null || true + echo "Bitcoin Solo Miner Appliance purged." + exit 0 +fi + +if [[ $EUID -ne 0 ]]; then + echo "Run as root." + exit 1 +fi + +echo "[1/8] Updating apt…" +apt-get update + +echo "[2/8] Installing base packages…" +apt-get install -y \ + curl ca-certificates gnupg \ + nginx php-fpm php-cli \ + git build-essential autoconf automake libtool pkg-config \ + libjansson-dev libevent-dev libcurl4-openssl-dev libssl-dev zlib1g-dev \ + openssl + +# --------------------------------------------------------------------------- +# [3/8] Install Bitcoin Core from official binaries +# --------------------------------------------------------------------------- +echo "[3/8] Installing official Bitcoin Core binaries…" + +BTC_VER="27.0" +BTC_BASE="bitcoin-${BTC_VER}" +BTC_TAR="${BTC_BASE}-x86_64-linux-gnu.tar.gz" +BTC_URL="https://bitcoincore.org/bin/bitcoin-core-${BTC_VER}/${BTC_TAR}" +BTC_SUMS_URL="https://bitcoincore.org/bin/bitcoin-core-${BTC_VER}/SHA256SUMS" + +mkdir -p /tmp/bitcoin +cd /tmp/bitcoin + +echo "Downloading Bitcoin Core ${BTC_VER}…" +curl -LO "${BTC_URL}" +curl -LO "${BTC_SUMS_URL}" + +echo "Verifying checksum…" +grep "${BTC_TAR}" SHA256SUMS | sha256sum -c - + +echo "Extracting…" +tar -xzf "${BTC_TAR}" +install -m 0755 -o root -g root ${BTC_BASE}/bin/* /usr/local/bin/ + +# systemd service for bitcoind +cat > /etc/systemd/system/bitcoind.service < "$BITCOIN_CONF" </dev/null 2>&1 || useradd -r -s /bin/false "$CKPOOL_USER" + +mkdir -p "$APP_ROOT/conf" "$APP_ROOT/logs" +cat > "$APP_ROOT/conf/ckpool.conf" < /etc/systemd/system/ckpool.service < /usr/local/sbin/btc-apply-admin.sh <<'EOF' +#!/bin/bash +CONF="/etc/bitcoin/bitcoin.conf" +CKPOOL_CONF="/opt/btc-solo/conf/ckpool.conf" + +ADMINUSER="$1" +ADMINPASS="$2" + +if [[ -z "$ADMINUSER" || -z "$ADMINPASS" ]]; then + echo "Usage: $0 " + exit 1 +fi + +# Update bitcoin.conf +sed -i '/^rpcuser=/d' "$CONF" +sed -i '/^rpcpassword=/d' "$CONF" +echo "rpcuser=${ADMINUSER}" >> "$CONF" +echo "rpcpassword=${ADMINPASS}" >> "$CONF" + +# Update ckpool config so it can still talk to bitcoind +if [[ -f "$CKPOOL_CONF" ]]; then + sed -i "s/\"user\"[[:space:]]*:[[:space:]]*\"[^\"]*\"/\"user\" : \"${ADMINUSER}\"/" "$CKPOOL_CONF" + sed -i "s/\"pass\"[[:space:]]*:[[:space:]]*\"[^\"]*\"/\"pass\" : \"${ADMINPASS}\"/" "$CKPOOL_CONF" +fi + +systemctl restart bitcoind +systemctl restart ckpool +EOF +chmod 700 /usr/local/sbin/btc-apply-admin.sh + +# set prune size +cat > /usr/local/sbin/btc-set-prune.sh <<'EOF' +#!/bin/bash +CONF="/etc/bitcoin/bitcoin.conf" +SIZE="$1" + +if [[ -z "$SIZE" ]]; then + echo "Usage: $0 " + exit 1 +fi + +sed -i '/^prune=/d' "$CONF" + +if [[ "$SIZE" != "full" ]]; then + echo "prune=${SIZE}" >> "$CONF" +fi + +systemctl restart bitcoind +EOF +chmod 700 /usr/local/sbin/btc-set-prune.sh + +# setup donation system +cat > /usr/local/sbin/btc-set-donation.sh <<'EOF' +#!/bin/bash +CONF="/opt/btc-solo/conf/ckpool.conf" +ADDR="$1" +RATE="$2" + +if [[ -z "$ADDR" || -z "$RATE" ]]; then + echo "Usage: $0 " + exit 1 +fi + +# ensure conf exists +if [[ ! -f "$CONF" ]]; then + echo "ckpool.conf not found at $CONF" + exit 1 +fi + +# remove old lines +sed -i '/"donaddress"/d' "$CONF" +sed -i '/"donrate"/d' "$CONF" + +# add new ones just before the final } +# (very simple appender; good enough for our generated file) +sed -i '$i \ ,"donaddress" : "'"$ADDR"'",\n "donrate" : '"$RATE"'' "$CONF" + +systemctl restart ckpool +EOF +chmod 700 /usr/local/sbin/btc-set-donation.sh + +# (re)create self-signed cert +cat > /usr/local/sbin/btc-make-cert.sh <<'EOF' +#!/bin/bash +CERTDIR="/etc/ssl/localcerts" +mkdir -p "$CERTDIR" + +openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ + -keyout ${CERTDIR}/btc-solo.key \ + -out ${CERTDIR}/btc-solo.crt \ + -subj "/C=CA/ST=Ontario/L=Barrie/O=BTC-Solo/OU=IT/CN=$(hostname -f)" + +chmod 600 ${CERTDIR}/btc-solo.key +systemctl restart nginx +EOF +chmod 700 /usr/local/sbin/btc-make-cert.sh + +# ensure sudoers.d exists +mkdir -p /etc/sudoers.d +chmod 750 /etc/sudoers.d + +# sudoers +cat > /etc/sudoers.d/btc-solo <<'EOF' +www-data ALL=(root) NOPASSWD: /usr/local/sbin/btc-apply-admin.sh +www-data ALL=(root) NOPASSWD: /usr/local/sbin/btc-set-prune.sh +www-data ALL=(root) NOPASSWD: /usr/local/sbin/btc-make-cert.sh +www-data ALL=(root) NOPASSWD: /usr/local/sbin/btc-set-donation.sh +EOF +chmod 440 /etc/sudoers.d/btc-solo + +# --------------------------------------------------------------------------- +echo "[6/8] Web UI (dashboard + activate)" +# --------------------------------------------------------------------------- + +# web-owned state dir +mkdir -p /var/lib/btc-solo +chown www-data:www-data /var/lib/btc-solo + +# web dashboard +mkdir -p "$WWW_ROOT" +mkdir -p "$WWW_ROOT/activate" + +# main dashboard +cat > "$WWW_ROOT/index.php" <<'EOF' + '550 MB (default, small)', + (2*1024) => '2 GB', + (4*1024) => '4 GB', + (8*1024) => '8 GB', + (16*1024) => '16 GB', + (32*1024) => '32 GB', + (64*1024) => '64 GB', + (100*1024) => '100 GB', + (200*1024) => '200 GB', + (300*1024) => '300 GB', + (400*1024) => '400 GB', + 'full' => 'Full (no pruning)', +]; + +$current = '550'; +$conf = @file_get_contents('/etc/bitcoin/bitcoin.conf'); +if ($conf && preg_match('/^prune=(\d+)/m', $conf, $m)) { + $current = $m[1]; +} elseif ($conf && !preg_match('/^prune=/m', $conf)) { + $current = 'full'; +} + +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['prune'])) { + $sel = $_POST['prune']; + if (isset($opts[$sel])) { + shell_exec('sudo /usr/local/sbin/btc-set-prune.sh ' . escapeshellarg($sel)); + $current = $sel; + sleep(1); + } +} + +$host = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_ADDR'] ?? gethostname(); +$host = preg_replace('/:\d+$/', '', $host); // strip port if present +$stratum = 'stratum+tcp://' . $host . ':3333'; +?> + + + + + Local Bitcoin Solo Mining + + + +
+

Local Bitcoin Solo Mining

+

Point your ASICs to this server and keep 100% of your block.

+
+
+

Stratum Endpoint

+

+

Username: your BTC address

+

Password: anything

+
+
+

Prune Size

+
+ + + +

Note: Prune size only limits stored block data. You should also expect the node to use up to 500 MB for chainstate and metadata. Actual disk usage will be higher than the value selected here.

+

Changing this will restart bitcoind.

+
+
+
+

Operator / Donation

+

Default is 2% to the project address. Set to 0 to keep the full block.

+ +
+ + + + + +
+
+
+

System

+

Check systemctl status bitcoind and systemctl status ckpool.

+
+ + +EOF + +# activation page +cat > "$WWW_ROOT/activate/index.php" <<'EOF' + + + + + + Create New Admin User + + + +
+

Create New Admin User

+

+ This sets the Bitcoin node’s administrative (RPC) credentials used to control the server itself.

+ Keep these private — they grant full access to your node.

+ These credentials are not used by miners to connect; miners only need your Bitcoin address and can use any password. +

+ +
+ + + + + + + +
+ + +EOF + +# --------------------------------------------------------------------------- +echo "[7/8] NGINX with HTTPS + redirect" +# --------------------------------------------------------------------------- +mkdir -p "$CERT_DIR" +openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ + -keyout ${CERT_DIR}/btc-solo.key \ + -out ${CERT_DIR}/btc-solo.crt \ + -subj "/C=CA/ST=Ontario/L=Barrie/O=BTC-Solo/OU=IT/CN=$(hostname -f)" >/dev/null 2>&1 +chmod 600 ${CERT_DIR}/btc-solo.key + +cat > /etc/nginx/sites-available/btc-solo <