diff --git a/stage2/04-docker-compose/01-run.sh b/stage2/04-docker-compose/01-run.sh index c66ac4a..4fee0ed 100755 --- a/stage2/04-docker-compose/01-run.sh +++ b/stage2/04-docker-compose/01-run.sh @@ -11,6 +11,7 @@ chmod 755 files/compose-service cp files/docker-compose.yml ${ROOTFS_DIR}/home/${FIRST_USER_NAME}/docker-compose.yml cp files/umbrel-createwallet.py ${ROOTFS_DIR}/home/${FIRST_USER_NAME}/umbrel-createwallet.py cp files/umbrel-unlock.py ${ROOTFS_DIR}/home/${FIRST_USER_NAME}/umbrel-unlock.py +cp -fr files/build ${ROOTFS_DIR}/home/${FIRST_USER_NAME} # Docker compose service on_chroot << EOF diff --git a/stage2/04-docker-compose/files/build/lnd-unlock/Dockerfile b/stage2/04-docker-compose/files/build/lnd-unlock/Dockerfile new file mode 100644 index 0000000..33936c2 --- /dev/null +++ b/stage2/04-docker-compose/files/build/lnd-unlock/Dockerfile @@ -0,0 +1,11 @@ +FROM alpine:3.10 + +RUN apk add --no-cache curl jq + +RUN mkdir /lnd/ + +COPY unlock.sh /bin/unlock + +RUN chmod +x /bin/unlock + +ENTRYPOINT ["unlock"] diff --git a/stage2/04-docker-compose/files/build/lnd-unlock/unlock.sh b/stage2/04-docker-compose/files/build/lnd-unlock/unlock.sh new file mode 100755 index 0000000..69dd7d6 --- /dev/null +++ b/stage2/04-docker-compose/files/build/lnd-unlock/unlock.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +HOST=localhost:8080 +TLS_CERT=/lnd/tls.cert +MACAROON="$(xxd -p /run/secrets/lnd-admin | tr -d '\n')" +PASS="$(cat /run/secrets/lnd-password | tr -d '\n' | base64 | tr -d '\n')" +UNLOCK_PAYLOAD="$(jq -nc --arg wallet_password ${PASS} '{$wallet_password}')" + +lncurl() { + url_path=$1 + data=$2 + + curl --fail --silent --show-error \ + --cacert "${TLS_CERT}" \ + --header "Grpc-Metadata-macaroon: ${MACAROON}" \ + --data "${data}" \ + "https://${HOST}/v1/${url_path}" +} + +while true; do + # First make sure that port is open + while ! nc -z localhost 8080; do + >&2 echo "Waiting for ${HOST} port to open…" + sleep 3 + done + >&2 echo "Port ${HOST} is open" + + # Wait a bit more in case the port was just opened + sleep 1 + + >&2 echo "Trying ${HOST}/getinfo…" + INFO=$(lncurl getinfo) + if [ "$?" = "0" ]; then + >&2 echo "Response: ${INFO}" + alias="$(echo "${INFO}" | jq '.alias')" + >&2 echo "Wallet for ${alias} unlocked!" + exit 0 + fi + >&2 echo "${HOST}/getinfo FAILED, out=${INFO}" + + >&2 echo "Trying ${HOST}/unlockwallet…" + RESULT=$(lncurl unlockwallet "${UNLOCK_PAYLOAD}") + >&2 echo "${HOST}/unlockwallet completed with: exit-code=$?, out=${RESULT}" + + sleep 16 +done diff --git a/stage2/04-docker-compose/files/docker-compose.yml b/stage2/04-docker-compose/files/docker-compose.yml index 2ab437d..dfb3254 100644 --- a/stage2/04-docker-compose/files/docker-compose.yml +++ b/stage2/04-docker-compose/files/docker-compose.yml @@ -1,10 +1,51 @@ version: '3.7' +x-logging: &default-logging + driver: journald + options: + tag: "{{.Name}}" + +x-utility: &default-utility + image: "alpine:3.11" + logging: *default-logging + network_mode: host + services: + web: + image: nginx:1.17.8 + logging: *default-logging + volumes: + - ${HOME}/nginx:/etc/nginx + restart: on-failure + network_mode: host + bitcoin: + image: lncm/bitcoind:v0.19.0.1 + logging: *default-logging + volumes: + - ${HOME}/bitcoin:/root/.bitcoin + restart: on-failure + network_mode: host lnd: image: lncm/lnd:v0.8.0-experimental + logging: *default-logging volumes: - - /home/umbrel/lnd:/root/.lnd + - ${HOME}/lnd:/root/.lnd - /var/lib/tor:/var/lib/tor - /run/tor:/run/tor restart: on-failure + depends_on: [ bitcoin, web ] + network_mode: host + lnd-unlock: + build: ${HOME}/build/lnd-unlock/ + depends_on: [ lnd ] + logging: *default-logging + secrets: + - lnd-password + - lnd-admin + volumes: + - "${HOME}/lnd/tls.cert:/lnd/tls.cert:ro" network_mode: host +secrets: + lnd-password: + file: ${HOME}/secrets/lnd-password.txt + lnd-admin: + file: ${HOME}/lnd/data/chain/bitcoin/mainnet/admin.macaroon diff --git a/stage2/04-docker-compose/files/umbrel-createwallet.py b/stage2/04-docker-compose/files/umbrel-createwallet.py index 3617b26..6634520 100755 --- a/stage2/04-docker-compose/files/umbrel-createwallet.py +++ b/stage2/04-docker-compose/files/umbrel-createwallet.py @@ -53,7 +53,7 @@ def main(): password_str=randompass(stringLength=15) temp_password_file = open(temp_password_file_path, "w") # Check if there is an existing file, if not generate a random password - if not os.path.exists("/home/umbrel/lnd/sesame.txt"): + if not os.path.exists("/home/umbrel/secrets/lnd-password.txt"): # sesame file doesnt exist password_str=randompass(stringLength=15) if not os.path.exists(save_password_control_file): @@ -63,18 +63,17 @@ def main(): temp_password_file.close() else: # Use sesame.txt if password_control_file exists - password_file = open("/home/umbrel/lnd/sesame.txt","w") + password_file = open("/home/umbrel/lnd/secrets/lnd-password.txt","w") password_file.write(password_str) password_file.close() else: # Get password from file if sesame file already exists - password_str = open('/home/umbrel/lnd/sesame.txt', 'r').read().rstrip() - + password_str = open('/home/umbrel/secrets/lnd-password.txt', 'r').read().rstrip() + # Convert password to byte encoded password_bytes = str(password_str).encode('utf-8') - # Step 1 get seed from web or file - + # Send request to generate seed if seed file doesnt exist if not os.path.exists(seed_filename): r = requests.get(url, verify=cert_path) diff --git a/stage2/04-docker-compose/files/umbrel-unlock.py b/stage2/04-docker-compose/files/umbrel-unlock.py index 6da48e1..e69e71e 100755 --- a/stage2/04-docker-compose/files/umbrel-unlock.py +++ b/stage2/04-docker-compose/files/umbrel-unlock.py @@ -3,7 +3,7 @@ import base64, codecs, json, requests url = 'https://localhost:8080/v1/unlockwallet' cert_path = '/home/umbrel/lnd/tls.cert' -password_str = open('/home/umbrel/lnd/sesame.txt', 'r').read().rstrip() +password_str = open('/home/umbrel/secrets/lnd-password.txt', 'r').read().rstrip() password_bytes = str(password_str).encode('utf-8') data = { 'wallet_password': base64.b64encode(password_bytes).decode(),