Browse Source
Co-authored-by: smolgrrr <smolgrrr@protonmail.com> Co-authored-by: nmfretz <nmfretz@gmail.com>main
Léo Haf
9 months ago
committed by
GitHub
9 changed files with 353 additions and 0 deletions
@ -0,0 +1,79 @@ |
|||
version: "3.7" |
|||
|
|||
services: |
|||
app_proxy: |
|||
environment: |
|||
APP_HOST: $APP_BITCOIN_KNOTS_IP |
|||
APP_PORT: 3005 |
|||
|
|||
server: |
|||
image: retropexx/umbrel-bitcoin-knots:v0.5.0@sha256:b19da8308ec9b6c66511d327f5fd2b64aa430a3da8ed3854e8e170274b11b624 |
|||
depends_on: [bitcoind] |
|||
restart: on-failure |
|||
volumes: |
|||
- ${APP_DATA_DIR}/data/app:/data # volume to persist advanced settings json |
|||
- ${APP_BITCOIN_KNOTS_DATA_DIR}:/bitcoin/.bitcoin # volume to persist umbrel-bitcoin.conf and bitcoin.conf |
|||
environment: |
|||
PORT: "3005" |
|||
BITCOIN_HOST: "${APP_BITCOIN_KNOTS_NODE_IP}" |
|||
RPC_PORT: "${APP_BITCOIN_KNOTS_INTERNAL_RPC_PORT}" |
|||
BITCOIN_RPC_PORT: "${APP_BITCOIN_KNOTS_INTERNAL_RPC_PORT}" |
|||
RPC_USER: "${APP_BITCOIN_KNOTS_RPC_USER}" |
|||
BITCOIN_RPC_USER: "${APP_BITCOIN_KNOTS_RPC_USER}" |
|||
RPC_PASSWORD: "${APP_BITCOIN_KNOTS_RPC_PASS}" |
|||
BITCOIN_RPC_PASSWORD: "${APP_BITCOIN_KNOTS_RPC_PASS}" |
|||
BITCOIN_RPC_HIDDEN_SERVICE: "${APP_BITCOIN_KNOTS_RPC_HIDDEN_SERVICE}" |
|||
BITCOIN_P2P_HIDDEN_SERVICE: "${APP_BITCOIN_KNOTS_P2P_HIDDEN_SERVICE}" |
|||
BITCOIN_P2P_PORT: "${APP_BITCOIN_KNOTS_P2P_PORT}" |
|||
DEVICE_DOMAIN_NAME: "${DEVICE_DOMAIN_NAME}" |
|||
BITCOIN_DEFAULT_NETWORK: "${BITCOIN_KNOTS_DEFAULT_NETWORK:-mainnet}" |
|||
# not needed |
|||
BITCOIN_INITIALIZE_WITH_CLEARNET_OVER_TOR: "${BITCOIN_INITIALIZE_WITH_CLEARNET_OVER_TOR:-unset}" |
|||
BITCOIND_IP: "${APP_BITCOIN_KNOTS_NODE_IP}" |
|||
TOR_PROXY_IP: "${APP_BITCOIN_KNOTS_TOR_PROXY_IP}" |
|||
TOR_PROXY_PORT: "9050" |
|||
TOR_PROXY_CONTROL_PORT: "9051" |
|||
TOR_PROXY_CONTROL_PASSWORD: "moneyprintergobrrr" |
|||
I2P_DAEMON_IP: "${APP_BITCOIN_KNOTS_I2P_DAEMON_IP}" |
|||
I2P_DAEMON_PORT: "7656" |
|||
networks: |
|||
default: |
|||
ipv4_address: $APP_BITCOIN_KNOTS_IP |
|||
|
|||
bitcoind: |
|||
image: retropexx/bitcoind:v25.1@sha256:4091eb570744d24f4234a0efc6d8b6aaf7de1c86d1a6e3077525d59bbd98336e |
|||
command: "${APP_BITCOIN_KNOTS_COMMAND}" |
|||
restart: unless-stopped |
|||
stop_grace_period: 15m30s |
|||
volumes: |
|||
- "${APP_BITCOIN_KNOTS_DATA_DIR}:/data/.bitcoin" |
|||
ports: |
|||
- "${APP_BITCOIN_KNOTS_P2P_PORT}:${APP_BITCOIN_KNOTS_INTERNAL_P2P_PORT}" |
|||
- "${APP_BITCOIN_KNOTS_RPC_PORT}:${APP_BITCOIN_KNOTS_INTERNAL_RPC_PORT}" |
|||
networks: |
|||
default: |
|||
ipv4_address: $APP_BITCOIN_KNOTS_NODE_IP |
|||
|
|||
tor: |
|||
image: getumbrel/tor:0.4.7.8@sha256:2ace83f22501f58857fa9b403009f595137fa2e7986c4fda79d82a8119072b6a |
|||
user: "1000:1000" |
|||
restart: on-failure |
|||
volumes: |
|||
- ${APP_DATA_DIR}/torrc:/etc/tor/torrc:ro |
|||
- ${TOR_DATA_DIR}:/data |
|||
environment: |
|||
HOME: "/tmp" |
|||
networks: |
|||
default: |
|||
ipv4_address: "${APP_BITCOIN_KNOTS_TOR_PROXY_IP}" |
|||
|
|||
i2pd_daemon: |
|||
image: purplei2p/i2pd:release-2.44.0@sha256:d154a599793c393cf9c91f8549ba7ece0bb40e5728e1813aa6dd4c210aa606f6 |
|||
user: "root" |
|||
command: --sam.enabled=true --sam.address=0.0.0.0 --sam.port=7656 --loglevel=error |
|||
restart: on-failure |
|||
volumes: |
|||
- ${APP_DATA_DIR}/data/i2pd:/home/i2pd/data |
|||
networks: |
|||
default: |
|||
ipv4_address: "${APP_BITCOIN_KNOTS_I2P_DAEMON_IP}" |
@ -0,0 +1,158 @@ |
|||
export APP_BITCOIN_KNOTS_IP="10.21.22.5" |
|||
export APP_BITCOIN_KNOTS_NODE_IP="10.21.21.7" |
|||
export APP_BITCOIN_KNOTS_TOR_PROXY_IP="10.21.22.12" |
|||
export APP_BITCOIN_KNOTS_I2P_DAEMON_IP="10.21.22.13" |
|||
|
|||
export APP_BITCOIN_KNOTS_DATA_DIR="${EXPORTS_APP_DIR}/data/bitcoin" |
|||
export APP_BITCOIN_KNOTS_RPC_PORT="9332" |
|||
export APP_BITCOIN_KNOTS_P2P_PORT="9333" |
|||
export APP_BITCOIN_KNOTS_TOR_PORT="9334" |
|||
export APP_BITCOIN_KNOTS_ZMQ_RAWBLOCK_PORT="48332" |
|||
export APP_BITCOIN_KNOTS_ZMQ_RAWTX_PORT="48333" |
|||
export APP_BITCOIN_KNOTS_ZMQ_HASHBLOCK_PORT="48334" |
|||
export APP_BITCOIN_KNOTS_ZMQ_SEQUENCE_PORT="48335" |
|||
export APP_BITCOIN_KNOTS_INTERNAL_RPC_PORT="8332" |
|||
export APP_BITCOIN_KNOTS_INTERNAL_P2P_PORT="8333" |
|||
export APP_BITCOIN_KNOTS_INTERNAL_tor_PORT="8334" |
|||
|
|||
BITCOIN_CHAIN="main" |
|||
BITCOIN_ENV_FILE="${EXPORTS_APP_DIR}/.env" |
|||
|
|||
{ |
|||
BITCOIN_APP_CONFIG_FILE="${EXPORTS_APP_DIR}/data/app/bitcoin-config.json" |
|||
if [[ -f "${BITCOIN_APP_CONFIG_FILE}" ]] |
|||
then |
|||
bitcoin_app_network=$(jq -r '.network' "${BITCOIN_APP_CONFIG_FILE}") |
|||
case $bitcoin_app_network in |
|||
"main") |
|||
BITCOIN_NETWORK="mainnet";; |
|||
"test") |
|||
BITCOIN_NETWORK="testnet";; |
|||
"signet") |
|||
BITCOIN_NETWORK="signet";; |
|||
"regtest") |
|||
BITCOIN_NETWORK="regtest";; |
|||
esac |
|||
fi |
|||
} > /dev/null || true |
|||
|
|||
if [[ ! -f "${BITCOIN_ENV_FILE}" ]]; then |
|||
if [[ -z "${BITCOIN_NETWORK}" ]]; then |
|||
BITCOIN_NETWORK="mainnet" |
|||
fi |
|||
|
|||
if [[ -z ${BITCOIN_RPC_USER+x} ]] || [[ -z ${BITCOIN_RPC_PASS+x} ]] || [[ -z ${BITCOIN_RPC_AUTH+x} ]]; then |
|||
BITCOIN_RPC_USER="umbrel" |
|||
BITCOIN_RPC_DETAILS=$("${EXPORTS_APP_DIR}/scripts/rpcauth.py" "${BITCOIN_RPC_USER}") |
|||
BITCOIN_RPC_PASS=$(echo "$BITCOIN_RPC_DETAILS" | tail -1) |
|||
BITCOIN_RPC_AUTH=$(echo "$BITCOIN_RPC_DETAILS" | head -2 | tail -1 | sed -e "s/^rpcauth=//") |
|||
fi |
|||
|
|||
echo "export APP_BITCOIN_KNOTS_NETWORK='${BITCOIN_NETWORK}'" > "${BITCOIN_ENV_FILE}" |
|||
echo "export APP_BITCOIN_KNOTS_RPC_USER='${BITCOIN_RPC_USER}'" >> "${BITCOIN_ENV_FILE}" |
|||
echo "export APP_BITCOIN_KNOTS_RPC_PASS='${BITCOIN_RPC_PASS}'" >> "${BITCOIN_ENV_FILE}" |
|||
echo "export APP_BITCOIN_KNOTS_RPC_AUTH='${BITCOIN_RPC_AUTH}'" >> "${BITCOIN_ENV_FILE}" |
|||
fi |
|||
|
|||
. "${BITCOIN_ENV_FILE}" |
|||
|
|||
# Make sure we don't persist the original value in .env if we have a more recent |
|||
# value from the app config |
|||
{ |
|||
if [[ ! -z ${BITCOIN_NETWORK+x} ]] && [[ "${BITCOIN_NETWORK}" ]] && [[ "${APP_BITCOIN_KNOTS_NETWORK}" ]] |
|||
then |
|||
APP_BITCOIN_KNOTS_NETWORK="${BITCOIN_NETWORK}" |
|||
fi |
|||
} > /dev/null || true |
|||
|
|||
if [[ "${APP_BITCOIN_KNOTS_NETWORK}" == "mainnet" ]]; then |
|||
BITCOIN_CHAIN="main" |
|||
elif [[ "${APP_BITCOIN_KNOTS_NETWORK}" == "testnet" ]]; then |
|||
BITCOIN_CHAIN="test" |
|||
# export APP_BITCOIN_RPC_PORT="18332" |
|||
# export APP_BITCOIN_P2P_PORT="18333" |
|||
# export APP_BITCOIN_TOR_PORT="18334" |
|||
elif [[ "${APP_BITCOIN_KNOTS_NETWORK}" == "signet" ]]; then |
|||
BITCOIN_CHAIN="signet" |
|||
# export APP_BITCOIN_RPC_PORT="38332" |
|||
# export APP_BITCOIN_P2P_PORT="38333" |
|||
# export APP_BITCOIN_TOR_PORT="38334" |
|||
elif [[ "${APP_BITCOIN_KNOTS_NETWORK}" == "regtest" ]]; then |
|||
BITCOIN_CHAIN="regtest" |
|||
# export APP_BITCOIN_RPC_PORT="18443" |
|||
# export APP_BITCOIN_P2P_PORT="18444" |
|||
# export APP_BITCOIN_TOR_PORT="18445" |
|||
else |
|||
echo "Warning (${EXPORTS_APP_ID}): Bitcoin Network '${APP_BITCOIN_KNOTS_NETWORK}' is not supported" |
|||
fi |
|||
|
|||
export BITCOIN_KNOTS_DEFAULT_NETWORK="${BITCOIN_CHAIN}" |
|||
|
|||
BIN_ARGS=() |
|||
# Commenting out options that are replaced by generated config file. We should migrate all these over in a future update. |
|||
# BIN_ARGS+=( "-chain=${BITCOIN_CHAIN}" ) |
|||
# BIN_ARGS+=( "-proxy=${TOR_PROXY_IP}:${TOR_PROXY_PORT}" ) |
|||
# BIN_ARGS+=( "-listen" ) |
|||
# BIN_ARGS+=( "-bind=0.0.0.0:${APP_BITCOIN_TOR_PORT}=onion" ) |
|||
# BIN_ARGS+=( "-bind=${APP_BITCOIN_NODE_IP}" ) |
|||
# BIN_ARGS+=( "-port=${APP_BITCOIN_P2P_PORT}" ) |
|||
# BIN_ARGS+=( "-rpcport=${APP_BITCOIN_RPC_PORT}" ) |
|||
BIN_ARGS+=( "-port=8333" ) |
|||
BIN_ARGS+=( "-rpcport=8332" ) |
|||
BIN_ARGS+=( "-rpcbind=${APP_BITCOIN_KNOTS_NODE_IP}" ) |
|||
BIN_ARGS+=( "-rpcbind=127.0.0.1" ) |
|||
BIN_ARGS+=( "-rpcallowip=${NETWORK_IP}/16" ) |
|||
BIN_ARGS+=( "-rpcallowip=127.0.0.1" ) |
|||
BIN_ARGS+=( "-rpcauth=\"${APP_BITCOIN_KNOTS_RPC_AUTH}\"" ) |
|||
BIN_ARGS+=( "-zmqpubrawblock=tcp://0.0.0.0:${APP_BITCOIN_KNOTS_ZMQ_RAWBLOCK_PORT}" ) |
|||
BIN_ARGS+=( "-zmqpubrawtx=tcp://0.0.0.0:${APP_BITCOIN_KNOTS_ZMQ_RAWTX_PORT}" ) |
|||
BIN_ARGS+=( "-zmqpubhashblock=tcp://0.0.0.0:${APP_BITCOIN_KNOTS_ZMQ_HASHBLOCK_PORT}" ) |
|||
BIN_ARGS+=( "-zmqpubsequence=tcp://0.0.0.0:${APP_BITCOIN_KNOTS_ZMQ_SEQUENCE_PORT}" ) |
|||
# BIN_ARGS+=( "-txindex=1" ) |
|||
# BIN_ARGS+=( "-blockfilterindex=1" ) |
|||
# BIN_ARGS+=( "-peerbloomfilters=1" ) |
|||
# BIN_ARGS+=( "-peerblockfilters=1" ) |
|||
# BIN_ARGS+=( "-rpcworkqueue=128" ) |
|||
|
|||
export APP_BITCOIN_KNOTS_COMMAND=$(IFS=" "; echo "${BIN_ARGS[@]}") |
|||
|
|||
# echo "${APP_BITCOIN_KNOTS_COMMAND}" |
|||
|
|||
rpc_hidden_service_file="${EXPORTS_TOR_DATA_DIR}/app-${EXPORTS_APP_ID}-rpc/hostname" |
|||
p2p_hidden_service_file="${EXPORTS_TOR_DATA_DIR}/app-${EXPORTS_APP_ID}-p2p/hostname" |
|||
export APP_BITCOIN_KNOTS_RPC_HIDDEN_SERVICE="$(cat "${rpc_hidden_service_file}" 2>/dev/null || echo "notyetset.onion")" |
|||
export APP_BITCOIN_KNOTS_P2P_HIDDEN_SERVICE="$(cat "${p2p_hidden_service_file}" 2>/dev/null || echo "notyetset.onion")" |
|||
|
|||
# electrs compatible network param |
|||
export APP_BITCOIN_KNOTS_NETWORK_ELECTRS=$APP_BITCOIN_KNOTS_NETWORK |
|||
if [[ "${APP_BITCOIN_KNOTS_NETWORK_ELECTRS}" = "mainnet" ]]; then |
|||
APP_BITCOIN_KNOTS_NETWORK_ELECTRS="bitcoin" |
|||
fi |
|||
|
|||
# We do not need this legacy bitcoin app logic because the Bitcoin Knots app was forked after advanced settings were introduced |
|||
|
|||
# { |
|||
# # Migrate settings for app updates differently to fresh installs |
|||
# BITCOIN_DATA_DIR="${EXPORTS_APP_DIR}/data/bitcoin" |
|||
# IS_POST_ADVANCED_SETTINGS_INSTALL_FILE_PATH="${EXPORTS_APP_DIR}/data/app/IS_POST_ADVANCED_SETTINGS_INSTALL" |
|||
|
|||
# # If no blocks directory exists, we write out a file to indicate that this is a fresh install. |
|||
# # This gets around the issue of the pre-start hook starting up the bitcoind container early for Tor HS creation |
|||
# # and creating the blocks directory. |
|||
# if [[ ! -d "${BITCOIN_DATA_DIR}/blocks" ]] && [[ ! -d "${BITCOIN_DATA_DIR}/testnet3/blocks" ]] && [[ ! -d "${BITCOIN_DATA_DIR}/regtest/blocks" ]] |
|||
# then |
|||
# touch "${IS_POST_ADVANCED_SETTINGS_INSTALL_FILE_PATH}" |
|||
# fi |
|||
|
|||
# APP_CONFIG_EXISTS="false" |
|||
# if [[ -f "${EXPORTS_APP_DIR}/data/app/bitcoin-config.json" ]] |
|||
# then |
|||
# APP_CONFIG_EXISTS="true" |
|||
# fi |
|||
|
|||
# if [[ ! -f "${IS_POST_ADVANCED_SETTINGS_INSTALL_FILE_PATH}" ]] && [[ "${APP_CONFIG_EXISTS}" = "false" ]] |
|||
# then |
|||
# # This app is not a fresh install, it's being updated, so preserve existing clearnet over Tor setting |
|||
# export BITCOIN_INITIALIZE_WITH_CLEARNET_OVER_TOR="true" |
|||
# fi |
|||
# } || true |
@ -0,0 +1,26 @@ |
|||
#!/usr/bin/env bash |
|||
|
|||
# Delay booting Bitcoin until the RPC and P2P Tor Hidden Services are ready |
|||
|
|||
HIDDEN_SERVICE_FILE="${TOR_DATA_DIR}/app-${APP_ID}-rpc/hostname" |
|||
|
|||
if [[ -f "${HIDDEN_SERVICE_FILE}" ]]; then |
|||
exit |
|||
fi |
|||
|
|||
"${UMBREL_ROOT}/scripts/app" compose "${APP_ID}" up --detach bitcoind |
|||
"${UMBREL_ROOT}/scripts/app" compose "${APP_ID}" up --detach tor |
|||
|
|||
echo "App: ${APP_ID} - Generating Tor Hidden Service..." |
|||
|
|||
for attempt in $(seq 1 100); do |
|||
if [[ -f "${HIDDEN_SERVICE_FILE}" ]]; then |
|||
echo "App: ${APP_ID} - Hidden service file created successfully!" |
|||
break |
|||
fi |
|||
sleep 0.1 |
|||
done |
|||
|
|||
if [[ ! -f "${HIDDEN_SERVICE_FILE}" ]]; then |
|||
echo "App: ${APP_ID} - Hidden service file wasn't created" |
|||
fi |
@ -0,0 +1,46 @@ |
|||
#!/usr/bin/env python3 |
|||
# Copyright (c) 2015-2018 The Bitcoin Core developers |
|||
# Distributed under the MIT software license, see the accompanying |
|||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. |
|||
|
|||
from argparse import ArgumentParser |
|||
from base64 import urlsafe_b64encode |
|||
from binascii import hexlify |
|||
from getpass import getpass |
|||
from os import urandom |
|||
|
|||
import hmac |
|||
|
|||
def generate_salt(size): |
|||
"""Create size byte hex salt""" |
|||
return hexlify(urandom(size)).decode() |
|||
|
|||
def generate_password(): |
|||
"""Create 32 byte b64 password""" |
|||
return urlsafe_b64encode(urandom(32)).decode('utf-8') |
|||
|
|||
def password_to_hmac(salt, password): |
|||
m = hmac.new(bytearray(salt, 'utf-8'), bytearray(password, 'utf-8'), 'SHA256') |
|||
return m.hexdigest() |
|||
|
|||
def main(): |
|||
parser = ArgumentParser(description='Create login credentials for a JSON-RPC user') |
|||
parser.add_argument('username', help='the username for authentication') |
|||
parser.add_argument('password', help='leave empty to generate a random password or specify "-" to prompt for password', nargs='?') |
|||
args = parser.parse_args() |
|||
|
|||
if not args.password: |
|||
args.password = generate_password() |
|||
elif args.password == '-': |
|||
args.password = getpass() |
|||
|
|||
# Create 16 byte hex salt |
|||
salt = generate_salt(16) |
|||
password_hmac = password_to_hmac(salt, args.password) |
|||
|
|||
print('String to be appended to bitcoin.conf:') |
|||
print('rpcauth={0}:{1}${2}'.format(args.username, salt, password_hmac)) |
|||
print('Your password:\n{0}'.format(args.password)) |
|||
|
|||
if __name__ == '__main__': |
|||
main() |
@ -0,0 +1,13 @@ |
|||
SocksPort 0.0.0.0:9050 |
|||
ControlPort 0.0.0.0:9051 |
|||
CookieAuthentication 1 |
|||
CookieAuthFileGroupReadable 1 |
|||
HashedControlPassword 16:39AF5EEFA4FC1D986022FDFB13663669FE50FB6DE9A3B4FE4FC7D82010 # moneyprintergobrrr |
|||
|
|||
# Bitcoin Core P2P Hidden Service |
|||
HiddenServiceDir /data/app-$APP_ID-p2p |
|||
HiddenServicePort $APP_BITCOIN_P2P_PORT $APP_BITCOIN_NODE_IP:$APP_BITCOIN_TOR_PORT |
|||
|
|||
# Bitcoin Core RPC Hidden Service |
|||
HiddenServiceDir /data/app-$APP_ID-rpc |
|||
HiddenServicePort $APP_BITCOIN_RPC_PORT $APP_BITCOIN_NODE_IP:$APP_BITCOIN_RPC_PORT |
@ -0,0 +1,31 @@ |
|||
manifestVersion: 1.1 |
|||
id: bitcoin-knots |
|||
category: bitcoin |
|||
name: Bitcoin Knots |
|||
version: "25.1" |
|||
tagline: Run your personal node powered by Bitcoin Knots |
|||
description: >- |
|||
Take control of your digital sovereignty by running a Bitcoin node that aligns with your needs and preferences. |
|||
Independently store and validate every single Bitcoin transaction with Bitcoin Knots. |
|||
|
|||
|
|||
⚠️ Bitcoin Knots does not yet automatically integrate with other apps in the Bitcoin ecosystem on Umbrel. |
|||
However, in a future umbrelOS update, users will be able to choose which Bitcoin Node app they want to use to connect with other apps. |
|||
|
|||
|
|||
Powered by Bitcoin Knots: https://bitcoinknots.org/ |
|||
developer: Léo Haf |
|||
website: https://bitcoinknots.org |
|||
dependencies: [] |
|||
repo: https://github.com/bitcoinknots/bitcoin.git |
|||
support: https://github.com/bitcoinknots/bitcoin/issues |
|||
port: 2105 |
|||
gallery: |
|||
- 1.jpg |
|||
- 2.jpg |
|||
- 3.jpg |
|||
path: "" |
|||
defaultPassword: "" |
|||
releaseNotes: "" |
|||
submitter: Léo Haf |
|||
submission: https://github.com/getumbrel/umbrel-apps/pull/953 |
Loading…
Reference in new issue