BT
5 years ago
committed by
GitHub
16 changed files with 500 additions and 12 deletions
@ -1,10 +1,52 @@ |
|||
# Install docker via pip3 (within chroot) |
|||
|
|||
echo "Installing docker-compose from pip3, and also setting up the box folder structure" |
|||
|
|||
on_chroot << EOF |
|||
pip3 install docker-compose |
|||
cd /home/${FIRST_USER_NAME} |
|||
wget -qO- "https://raw.githubusercontent.com/lncm/thebox-compose-system/master/install-box.sh" | sh |
|||
chown -R ${FIRST_USER_NAME}:${FIRST_USER_NAME} /home/${FIRST_USER_NAME} |
|||
EOF |
|||
|
|||
# Maybe generate a compose file to use |
|||
echo "Docker stuff installed" >> $ROOTFS_DIR/home/$FIRST_USER_NAME/docker-compose.txt |
|||
# Maybe generate docker-compose file so we can use it |
|||
chmod 755 files/compose-service |
|||
|
|||
# These can be probabably removed |
|||
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 |
|||
|
|||
# Docker compose service |
|||
on_chroot << EOF |
|||
mkdir -p /etc/init.d |
|||
mkdir -p /etc/rc2.d |
|||
mkdir -p /etc/rc3.d |
|||
mkdir -p /etc/rc4.d |
|||
mkdir -p /etc/rc5.d |
|||
mkdir -p /etc/rc0.d |
|||
mkdir -p /etc/rc1.d |
|||
mkdir -p /etc/rc6.d |
|||
EOF |
|||
|
|||
echo "Copying the compose service to rootfs (etc/init.d)" |
|||
cp files/compose-service ${ROOTFS_DIR}/etc/init.d/umbrelbox |
|||
|
|||
on_chroot << EOF |
|||
cd /etc/rc2.d |
|||
ln -s /etc/init.d/umbrelbox S01umbrelbox |
|||
cd /etc/rc3.d |
|||
ln -s /etc/init.d/umbrelbox S01umbrelbox |
|||
cd /etc/rc4.d |
|||
ln -s /etc/init.d/umbrelbox S01umbrelbox |
|||
cd /etc/rc5.d |
|||
ln -s /etc/init.d/umbrelbox S01umbrelbox |
|||
cd /etc/rc0.d |
|||
ln -s /etc/init.d/umbrelbox K01umbrelbox |
|||
cd /etc/rc1.d |
|||
ln -s /etc/init.d/umbrelbox K01umbrelbox |
|||
cd /etc/rc6.d |
|||
ln -s /etc/init.d/umbrelbox K01umbrelbox |
|||
EOF |
|||
|
|||
echo "Docker stuff installed!" |
|||
|
|||
|
@ -0,0 +1,56 @@ |
|||
#!/bin/sh |
|||
|
|||
set -e |
|||
|
|||
### BEGIN INIT INFO |
|||
# Provides: docker-compose service |
|||
# Required-Start: $syslog $remote_fs docker |
|||
# Required-Stop: $syslog $remote_fs docker |
|||
# Should-Start: cgroupfs-mount cgroup-lite |
|||
# Should-Stop: cgroupfs-mount cgroup-lite |
|||
# Default-Start: 2 3 4 5 |
|||
# Default-Stop: 0 1 6 |
|||
# Short-Description: Starts docker-compose |
|||
# Description: Start docker-compose |
|||
### END INIT INFO |
|||
NAME="compose-service" |
|||
DESCRIPTION="Docker compose service" |
|||
SCRIPTNAME=/etc/init.d/$NAME |
|||
|
|||
case "$1" in |
|||
start) |
|||
if [ -f /home/umbrel/docker-compose.yml ]; then |
|||
sed -i 's/\${HOME}/\/home\/umbrel/g; ' /home/umbrel/docker-compose.yml |
|||
echo "Starting" |
|||
cd /home/umbrel |
|||
docker-compose up -d |
|||
exit 0 |
|||
else |
|||
echo "Docker-compose file doesn't exist" |
|||
exit 1 |
|||
fi |
|||
;; |
|||
stop) |
|||
if [ -f /home/umbrel/docker-compose.yml ]; then |
|||
sed -i 's/\${HOME}/\/home\/umbrel/g; ' /home/umbrel/docker-compose.yml |
|||
echo "Stopping docker" |
|||
cd /home/umbrel |
|||
docker-compose down |
|||
exit 0 |
|||
else |
|||
echo "Docker-compose file doesn't exist" |
|||
exit 1 |
|||
fi |
|||
;; |
|||
status) |
|||
echo "Status" |
|||
docker ps -a |
|||
exit 0 |
|||
;; |
|||
*) |
|||
echo "Either 'start', 'stop', or 'status'" |
|||
exit 1 |
|||
;; |
|||
esac |
|||
|
|||
exit 0 |
@ -0,0 +1,135 @@ |
|||
#!/usr/bin/env python3 |
|||
|
|||
''' |
|||
Copyright © 2018-2019 LNCM Contributors |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); |
|||
you may not use this file except in compliance with the License. |
|||
You may obtain a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
See the License for the specific language governing permissions and |
|||
limitations under the License. |
|||
|
|||
Documented logic |
|||
|
|||
1. Check if theres already a wallet. If there is, then exit. |
|||
2. Check for sesame.txt |
|||
3. If doesn't exist then check for whether we should save the password (save_password_control_file exists) or not |
|||
4. If sesame.txt exists import password in. |
|||
5. If sesame.txt doesn't exist ans we don't save the password,create a password and save it in temporary path as defined in temp_password_file_path |
|||
6. Now start the wallet creation. Look for a seed defined in seed_filename , if not existing then generate a wallet based on the seed by LND. |
|||
|
|||
''' |
|||
import base64, codecs, json, requests, os |
|||
import random, string |
|||
|
|||
# Generate seed |
|||
url = 'https://localhost:8080/v1/genseed' |
|||
# Initialize wallet |
|||
url2 = 'https://localhost:8080/v1/initwallet' |
|||
cert_path = '/home/umbrel/lnd/tls.cert' |
|||
seed_filename = '/home/umbrel/secrets/seed.txt' |
|||
|
|||
# save password control file (Add this file if we want to save passwords) |
|||
save_password_control_file = '/home/umbrel/.save_password' |
|||
# Create password for writing |
|||
temp_password_file_path = '/tmp/.password.txt' |
|||
|
|||
''' |
|||
Functions have 2 spaces |
|||
''' |
|||
def randompass(stringLength=10): |
|||
letters = string.ascii_letters |
|||
return ''.join(random.choice(letters) for i in range(stringLength)) |
|||
|
|||
def main(): |
|||
if not os.path.exists(save_password_control_file): |
|||
# Generate password but dont save it in usual spot |
|||
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/secrets/lnd-password.txt"): |
|||
# sesame file doesnt exist |
|||
password_str=randompass(stringLength=15) |
|||
if not os.path.exists(save_password_control_file): |
|||
# Use tempory file if there is a password control file there |
|||
temp_password_file = open(temp_password_file_path, "w") |
|||
temp_password_file.write(password_str) |
|||
temp_password_file.close() |
|||
else: |
|||
# Use sesame.txt if password_control_file exists |
|||
password_file = open("/home/umbrel/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/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) |
|||
if r.status_code == 200: |
|||
json_seed_creation = r.json() |
|||
json_seed_mnemonic = json_seed_creation['cipher_seed_mnemonic'] |
|||
json_enciphered_seed = json_seed_creation['enciphered_seed'] |
|||
seed_file = open(seed_filename, "w") |
|||
for word in json_seed_mnemonic: |
|||
seed_file.write(word + "\n") |
|||
seed_file.close() |
|||
data = { 'cipher_seed_mnemonic': json_seed_mnemonic, 'wallet_password': base64.b64encode(password_bytes).decode()} |
|||
# Data doesnt get set if cant create the seed but that is fine, handle it later |
|||
else: |
|||
# Seed exists |
|||
seed_file = open(seed_filename, "r") |
|||
seed_file_words = seed_file.readlines() |
|||
import_file_array = [] |
|||
for importword in seed_file_words: |
|||
import_file_array.append(importword.replace("\n", "")) |
|||
# Generate init wallet file from what was posted |
|||
data = { 'cipher_seed_mnemonic': import_file_array, 'wallet_password': base64.b64encode(password_bytes).decode()} |
|||
|
|||
# Step 2: Create wallet |
|||
try: |
|||
data |
|||
except NameError: |
|||
print("data isn't defined") |
|||
pass |
|||
else: |
|||
# Data is defined so proceed |
|||
r2 = requests.post(url2, verify=cert_path, data=json.dumps(data)) |
|||
if r2.status_code == 200: |
|||
# If create wallet was successful |
|||
print("Create wallet is successful") |
|||
else: |
|||
print("Create wallet is not successful") |
|||
|
|||
|
|||
''' |
|||
Main entrypoint function |
|||
|
|||
Testing creation notes: |
|||
rm /home/lncm/seed.txt |
|||
rm /media/important/important/lnd/sesame.txt |
|||
|
|||
docker stop compose_lndbox_1 ; rm -fr /media/important/important/lnd/data/chain/ ; docker start compose_lndbox_1 |
|||
''' |
|||
|
|||
if __name__ == '__main__': |
|||
if os.path.exists("/home/umbrel/lnd"): |
|||
if not os.path.exists("/home/umbrel/lnd/data/chain/bitcoin/mainnet/wallet.db"): |
|||
main() |
|||
else: |
|||
print('Wallet already exists! Please delete .lnd/data/chain and then restart LND') |
|||
else: |
|||
print('LND directory does not exist!') |
|||
|
|||
|
@ -0,0 +1,28 @@ |
|||
#!/usr/bin/env python3 |
|||
|
|||
import base64, codecs, json, requests |
|||
url = 'https://localhost:8080/v1/unlockwallet' |
|||
cert_path = '/home/umbrel/lnd/tls.cert' |
|||
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(), |
|||
} |
|||
|
|||
|
|||
def main(): |
|||
try: |
|||
r = requests.post(url, verify=cert_path, data=json.dumps(data)) |
|||
except: |
|||
# Silence connection errors when lnd is not running |
|||
pass |
|||
else: |
|||
try: |
|||
print(r.json()) |
|||
except: |
|||
# JSON will fail to decode when unlocked already since response is empty |
|||
pass |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
main() |
@ -1,4 +1,7 @@ |
|||
# Test out image |
|||
echo "Hello World" >> $ROOTFS_DIR/home/$FIRST_USER_NAME/hello.txt |
|||
# Save password (for createwallet script). |
|||
# We will remove this later when a more suitable secure system is finalized. |
|||
touch $ROOTFS_DIR/home/$FIRST_USER_NAME/.save_password |
|||
|
|||
echo "Executables directory" |
|||
mkdir -p $ROOTFS_DIR/home/$FIRST_USER_NAME/bin |
|||
|
|||
|
@ -1,5 +1,7 @@ |
|||
echo "Adding lncm to DOCKER group" |
|||
echo "Also fixing permissions on folders" |
|||
on_chroot << EOF |
|||
usermod -a -G docker $FIRST_USER_NAME |
|||
chown -R $FIRST_USER_NAME:$FIRST_USER_NAME /home/$FIRST_USER_NAME |
|||
EOF |
|||
|
|||
|
@ -0,0 +1,6 @@ |
|||
chmod 644 files/lnd.conf |
|||
echo "Copying lnd.conf to overwrite the existing LND.conf" |
|||
cp files/lnd.conf ${ROOTFS_DIR}/home/${FIRST_USER_NAME}/lnd/lnd.conf |
|||
on_chroot << EOF |
|||
chown -R ${FIRST_USER_NAME}:${FIRST_USER_NAME} /home/${FIRST_USER_NAME} |
|||
EOF |
@ -0,0 +1,38 @@ |
|||
[Application Options] |
|||
|
|||
listen=0.0.0.0:9735 |
|||
rpclisten=0.0.0.0:10009 |
|||
restlisten=0.0.0.0:8080 |
|||
maxpendingchannels=3 |
|||
minchansize=1337 |
|||
alias=Umbrel Node |
|||
color=#5351FB |
|||
|
|||
; Makes routing faster but have to use images built with experimental tag |
|||
[Routing] |
|||
routing.assumechanvalid=1 |
|||
|
|||
[Bitcoin] |
|||
; If the Bitcoin chain should be active. Atm, only a single chain can be |
|||
; active. |
|||
bitcoin.active=1 |
|||
bitcoin.mainnet=1 |
|||
; Use neutrino for now, but maybe it could be permanent and then switch |
|||
; to a full node once its working? |
|||
bitcoin.node=neutrino |
|||
bitcoin.defaultchanconfs=2 |
|||
|
|||
; Add neutrino peers |
|||
; TODO: umbrel to set up a neutrino peer to support umbrel nodes |
|||
[neutrino] |
|||
neutrino.addpeer=bb2.breez.technology |
|||
neutrino.addpeer=mainnet1-btcd.zaphq.io |
|||
neutrino.addpeer=mainnet2-btcd.zaphq.io |
|||
|
|||
[tor] |
|||
tor.active=1 |
|||
tor.control=9051 |
|||
tor.socks=9050 |
|||
tor.v3=1 |
|||
tor.dns=soa.nodes.lightning.directory:53 |
|||
|
@ -1,8 +0,0 @@ |
|||
echo "Install Python dependencies" |
|||
|
|||
## Add in any python dependencies within the chroot |
|||
on_chroot << EOF |
|||
pip3 install noma |
|||
EOF |
|||
|
|||
|
@ -0,0 +1,14 @@ |
|||
# TODO: configure username and password (internally) |
|||
|
|||
chmod 644 files/bitcoin.conf |
|||
mkdir ${ROOTFS_DIR}/home/${FIRST_USER_NAME}/bitcoin |
|||
cp files/bitcoin.conf ${ROOTFS_DIR}/home/${FIRST_USER_NAME}/bitcoin/bitcoin.conf |
|||
|
|||
echo "Downloading password utility" |
|||
cd ${ROOTFS_DIR}/home/${FIRST_USER_NAME}/bin |
|||
curl "https://raw.githubusercontent.com/bitcoin/bitcoin/master/share/rpcauth/rpcauth.py" 2>/dev/null 1>rpcauth.py |
|||
chmod 755 rpcauth.py |
|||
|
|||
on_chroot << EOF |
|||
chown -R ${FIRST_USER_NAME}:${FIRST_USER_NAME} /home/${FIRST_USER_NAME} |
|||
EOF |
@ -0,0 +1,32 @@ |
|||
onion=127.0.0.1:9050 |
|||
torcontrol=127.0.0.1:9051 |
|||
|
|||
server=1 |
|||
rest=1 |
|||
|
|||
# Some Pi optimizations |
|||
maxmempool=512 |
|||
maxconnections=40 |
|||
maxuploadtarget=5000 |
|||
|
|||
port=8333 |
|||
rpcport=8332 |
|||
|
|||
# Keep it pruned while we don't have a extenal drive to work with |
|||
prune=550 |
|||
|
|||
# When we have one we remove this |
|||
# Temporary solution while we don't have the drives |
|||
# txindex=1 |
|||
# blockfilterindex=1 |
|||
|
|||
peerbloomfilters=0 |
|||
addresstype=bech32 |
|||
avoidpartialspends=1 |
|||
logips=1 |
|||
logtimestamps=0 |
|||
logthreadnames=1 |
|||
nodebuglogfile=1 |
|||
|
|||
rpcbind=0.0.0.0 |
|||
|
@ -0,0 +1,6 @@ |
|||
# TODO: configure username and password (internally) |
|||
|
|||
chmod 644 files/torrc |
|||
mkdir -p ${ROOTFS_DIR}/etc/tor/ |
|||
echo "Overriding TORRC" |
|||
cp files/torrc ${ROOTFS_DIR}/etc/tor/torrc |
@ -0,0 +1,22 @@ |
|||
SocksPort 9050 # Default: Bind to localhost:9050 for local connections. |
|||
|
|||
Log notice syslog |
|||
Log debug file /var/log/tor/debug.log |
|||
|
|||
#RunAsDaemon 1 |
|||
|
|||
DataDirectory /var/lib/tor |
|||
ControlPort 9051 |
|||
# Use password Later when lnd supports it |
|||
#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C |
|||
CookieAuthentication 1 |
|||
|
|||
# Allow this for now |
|||
# TOR HOSTNAME |
|||
HiddenServiceDir /var/lib/tor/sshd |
|||
HiddenServicePort 22 127.0.0.1:22 |
|||
|
|||
HiddenServiceDir /var/lib/tor/web |
|||
HiddenServicePort 80 127.0.0.1:80 |
|||
|
|||
|
Loading…
Reference in new issue