mirror of
https://github.com/rootzoll/raspiblitz.git
synced 2025-02-25 07:07:46 +01:00
commit
aa486e3f05
24 changed files with 720 additions and 589 deletions
|
@ -14,7 +14,6 @@ if [ ${#autoNatDiscovery} -eq 0 ]; then autoNatDiscovery="off"; fi
|
|||
if [ ${#networkUPnP} -eq 0 ]; then networkUPnP="off"; fi
|
||||
if [ ${#touchscreen} -eq 0 ]; then touchscreen=0; fi
|
||||
if [ ${#lcdrotate} -eq 0 ]; then lcdrotate=0; fi
|
||||
if [ ${#letsencrypt} -eq 0 ]; then letsencrypt="off"; fi
|
||||
if [ ${#zerotier} -eq 0 ]; then zerotier="off"; fi
|
||||
|
||||
echo "map dropboxbackup to on/off"
|
||||
|
@ -78,7 +77,6 @@ OPTIONS+=(r 'LCD Rotate' ${lcdrotateMenu})
|
|||
OPTIONS+=(a 'Channel Autopilot' ${autoPilot})
|
||||
OPTIONS+=(k 'Accept Keysend' ${keysend})
|
||||
OPTIONS+=(n 'Testnet' ${chainValue})
|
||||
OPTIONS+=(c 'Let`s Encrypt Client' ${letsencrypt})
|
||||
OPTIONS+=(u 'LND Auto-Unlock' ${autoUnlock})
|
||||
OPTIONS+=(d 'StaticChannelBackup on DropBox' ${DropboxBackup})
|
||||
OPTIONS+=(e 'StaticChannelBackup on USB Drive' ${LocalBackup})
|
||||
|
@ -290,36 +288,6 @@ else
|
|||
echo "TOR Setting unchanged."
|
||||
fi
|
||||
|
||||
# Let's Encrypt process choice
|
||||
choice="off"; check=$(echo "${CHOICES}" | grep -c "c")
|
||||
if [ ${check} -eq 1 ]; then choice="on"; fi
|
||||
if [ "${letsencrypt}" != "${choice}" ]; then
|
||||
echo "Let's Encrypt Client Setting changed .."
|
||||
anychange=1
|
||||
/home/admin/config.scripts/bonus.letsencrypt.sh ${choice}
|
||||
errorOnInstall=$?
|
||||
if [ "${choice}" = "on" ]; then
|
||||
if [ ${errorOnInstall} -eq 0 ]; then
|
||||
msg="Successfully installed."
|
||||
else
|
||||
msg="Failed to install!"
|
||||
fi
|
||||
else
|
||||
if [ ${errorOnInstall} -eq 0 ]; then
|
||||
msg="Successfully removed."
|
||||
else
|
||||
msg="Failed to remove!"
|
||||
fi
|
||||
fi
|
||||
|
||||
dialog --backtitle "Additional Services" \
|
||||
--title "Let's Encrypt Client" \
|
||||
--infobox "\n${msg}" 5 40 ; sleep 3
|
||||
|
||||
else
|
||||
echo "Let's Encrypt Client Setting unchanged."
|
||||
fi
|
||||
|
||||
# LND Auto-Unlock
|
||||
choice="off"; check=$(echo "${CHOICES}" | grep -c "u")
|
||||
if [ ${check} -eq 1 ]; then choice="on"; fi
|
||||
|
|
|
@ -273,12 +273,12 @@ Please go to MAINMENU > SERVICES and activate KEYSEND first.
|
|||
exit 1;
|
||||
;;
|
||||
FULLY_NODED)
|
||||
appstoreLink="https://testflight.apple.com/join/PuFnSqgi"
|
||||
appstoreLink="https://apps.apple.com/us/app/fully-noded/id1436425586"
|
||||
/home/admin/config.scripts/blitz.lcd.sh qr ${appstoreLink}
|
||||
whiptail --title "Install Fully Noded on your iOS device" \
|
||||
--yes-button "continue" \
|
||||
--no-button "link as QR code" \
|
||||
--yesno "At the moment this app is in public beta testing:\n\n${appstoreLink}\n\nJoin testing and follow ALL instructions.\n\nWhen installed and started -> continue" 10 60
|
||||
--yesno "Download the app from the AppStore:\n\n${appstoreLink}\n\nWhen installed and started -> continue" 8 60
|
||||
if [ $? -eq 1 ]; then
|
||||
/home/admin/config.scripts/blitz.lcd.sh qr-console ${appstoreLink}
|
||||
fi
|
||||
|
|
|
@ -5,6 +5,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.3.0] - 2020-07-19
|
||||
### Added
|
||||
- add BlitzError Class
|
||||
|
||||
## [0.2.0] - 2020-05-23
|
||||
### Added
|
||||
- add write() to BlitzPy config Classes
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from .config import RaspiBlitzConfig, RaspiBlitzInfo
|
||||
|
||||
__all__ = [
|
||||
'RaspiBlitzConfig',
|
||||
'RaspiBlitzInfo',
|
||||
]
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from .config import RaspiBlitzConfig, RaspiBlitzInfo
|
||||
from .exceptions import BlitzError
|
||||
|
||||
__all__ = [
|
||||
'RaspiBlitzConfig',
|
||||
'RaspiBlitzInfo',
|
||||
'BlitzError'
|
||||
]
|
||||
|
|
16
home.admin/BlitzPy/blitzpy/exceptions.py
Normal file
16
home.admin/BlitzPy/blitzpy/exceptions.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
from datetime import datetime
|
||||
|
||||
TS_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
|
||||
|
||||
|
||||
class BlitzError(Exception):
|
||||
def __init__(self, short: str, details: dict = None, org: Exception = None):
|
||||
self.short: str = str(short)
|
||||
if details:
|
||||
self.details: dict = details
|
||||
self.details.update({'timestamp': datetime.utcnow().strftime(TS_FORMAT)})
|
||||
else:
|
||||
self.details = dict()
|
||||
self.details['timestamp'] = datetime.utcnow().strftime(TS_FORMAT)
|
||||
|
||||
self.org: Exception = org
|
|
@ -4,5 +4,5 @@
|
|||
# 3) we can import it into your module module
|
||||
"""
|
||||
|
||||
__version_info__ = ('0', '2', '0')
|
||||
__version_info__ = ('0', '3', '0')
|
||||
__version__ = '.'.join(__version_info__)
|
||||
|
|
BIN
home.admin/BlitzPy/dist/BlitzPy-0.3.0-py2.py3-none-any.whl
vendored
Normal file
BIN
home.admin/BlitzPy/dist/BlitzPy-0.3.0-py2.py3-none-any.whl
vendored
Normal file
Binary file not shown.
BIN
home.admin/BlitzPy/dist/BlitzPy-0.3.0.tar.gz
vendored
Normal file
BIN
home.admin/BlitzPy/dist/BlitzPy-0.3.0.tar.gz
vendored
Normal file
Binary file not shown.
|
@ -287,12 +287,15 @@ fi
|
|||
# BTCPAYSERVER
|
||||
if [ "${BTCPayServer}" = "on" ]; then
|
||||
|
||||
echo "Provisioning BTCPAYSERVER on TOR - run on after bootup script" >> ${logFile}
|
||||
#sudo sed -i "s/^message=.*/message='Setup BTCPay (takes time)'/g" ${infoFile}
|
||||
#sudo -u admin /home/admin/config.scripts/bonus.btcpayserver.sh on >> ${logFile} 2>&1
|
||||
echo "Provisioning BTCPAYSERVER on TOR - running setup" >> ${logFile}
|
||||
sudo sed -i "s/^message=.*/message='Setup BTCPay (takes time)'/g" ${infoFile}
|
||||
sudo -u admin /home/admin/config.scripts/bonus.btcpayserver.sh on >> ${logFile} 2>&1
|
||||
|
||||
#echo "Provisioning BTCPAYSERVER on TOR - run on after bootup script" >> ${logFile}
|
||||
# because BTCPAY server freezes during recovery .. it will get installed after reboot
|
||||
echo "sudo -u admin /home/admin/config.scripts/bonus.btcpayserver.sh on" >> /home/admin/setup.sh
|
||||
#echo "sudo -u admin /home/admin/config.scripts/bonus.btcpayserver.sh on" >> /home/admin/setup.sh
|
||||
#sudo chmod +x /home/admin/setup.sh >> ${logFile}
|
||||
#sudo ls -la /home/admin/setup.sh >> ${logFile}
|
||||
|
||||
else
|
||||
echo "Provisioning BTCPayServer - keep default" >> ${logFile}
|
||||
|
|
|
@ -58,6 +58,46 @@ if [ "${setupStep}" != "100" ]; then
|
|||
fi
|
||||
sudo chmod 777 ${infoFile}
|
||||
|
||||
################################
|
||||
# IDENTIFY CPU ARCHITECTURE
|
||||
################################
|
||||
|
||||
cpu="?"
|
||||
isARM=$(uname -m | grep -c 'arm')
|
||||
isAARCH64=$(uname -m | grep -c 'aarch64')
|
||||
isX86_64=$(uname -m | grep -c 'x86_64')
|
||||
if [ ${isARM} -gt 0 ]; then
|
||||
cpu="arm"
|
||||
elif [ ${isAARCH64} -gt 0 ]; then
|
||||
cpu="aarch64"
|
||||
elif [ ${isX86_64} -gt 0 ]; then
|
||||
cpu="x86_64"
|
||||
fi
|
||||
echo "cpu=${cpu}" >> $infoFile
|
||||
|
||||
################################
|
||||
# IDENTIFY BASEIMAGE
|
||||
################################
|
||||
|
||||
baseImage="?"
|
||||
isDietPi=$(uname -n | grep -c 'DietPi')
|
||||
isRaspbian=$(cat /etc/os-release 2>/dev/null | grep -c 'Raspbian')
|
||||
isArmbian=$(cat /etc/os-release 2>/dev/null | grep -c 'Debian')
|
||||
isUbuntu=$(cat /etc/os-release 2>/dev/null | grep -c 'Ubuntu')
|
||||
if [ ${isRaspbian} -gt 0 ]; then
|
||||
baseImage="raspbian"
|
||||
fi
|
||||
if [ ${isArmbian} -gt 0 ]; then
|
||||
baseImage="armbian"
|
||||
fi
|
||||
if [ ${isUbuntu} -gt 0 ]; then
|
||||
baseImage="ubuntu"
|
||||
fi
|
||||
if [ ${isDietPi} -gt 0 ]; then
|
||||
baseImage="dietpi"
|
||||
fi
|
||||
echo "baseimage=${baseImage}" >> $infoFile
|
||||
|
||||
# resetting start count files
|
||||
echo "SYSTEMD RESTART LOG: blockchain (bitcoind/litecoind)" > /home/admin/systemd.blockchain.log
|
||||
echo "SYSTEMD RESTART LOG: lightning (LND)" > /home/admin/systemd.lightning.log
|
||||
|
@ -142,9 +182,11 @@ if [ ${afterSetupScriptExists} -eq 1 ]; then
|
|||
# echo out script to journal logs
|
||||
sudo cat /home/admin/setup.sh
|
||||
# execute the after boot script
|
||||
sudo /home/admin/setup.sh
|
||||
echo "Logs in stored to: /home/admin/raspiblitz.recover.log"
|
||||
echo "\n***** RUNNING AFTER BOOT SCRIPT ******** " >> /home/admin/raspiblitz.recover.log
|
||||
sudo /home/admin/setup.sh >> /home/admin/raspiblitz.recover.log
|
||||
# delete the after boot script
|
||||
sudo rm /home/admin/setup.sh
|
||||
sudo rm /home/admin/setup.sh
|
||||
# reboot again
|
||||
echo "DONE wait 6 secs ... one more reboot needed ... "
|
||||
sudo shutdown -r now
|
||||
|
@ -536,46 +578,6 @@ else
|
|||
sudo chown admin:admin /mnt/hdd/app-data/subscriptions
|
||||
fi
|
||||
|
||||
################################
|
||||
# IDENTIFY CPU ARCHITECTURE
|
||||
################################
|
||||
|
||||
cpu="?"
|
||||
isARM=$(uname -m | grep -c 'arm')
|
||||
isAARCH64=$(uname -m | grep -c 'aarch64')
|
||||
isX86_64=$(uname -m | grep -c 'x86_64')
|
||||
if [ ${isARM} -gt 0 ]; then
|
||||
cpu="arm"
|
||||
elif [ ${isAARCH64} -gt 0 ]; then
|
||||
cpu="aarch64"
|
||||
elif [ ${isX86_64} -gt 0 ]; then
|
||||
cpu="x86_64"
|
||||
fi
|
||||
echo "cpu=${cpu}" >> $infoFile
|
||||
|
||||
################################
|
||||
# IDENTIFY BASEIMAGE
|
||||
################################
|
||||
|
||||
baseImage="?"
|
||||
isDietPi=$(uname -n | grep -c 'DietPi')
|
||||
isRaspbian=$(cat /etc/os-release 2>/dev/null | grep -c 'Raspbian')
|
||||
isArmbian=$(cat /etc/os-release 2>/dev/null | grep -c 'Debian')
|
||||
isUbuntu=$(cat /etc/os-release 2>/dev/null | grep -c 'Ubuntu')
|
||||
if [ ${isRaspbian} -gt 0 ]; then
|
||||
baseImage="raspbian"
|
||||
fi
|
||||
if [ ${isArmbian} -gt 0 ]; then
|
||||
baseImage="armbian"
|
||||
fi
|
||||
if [ ${isUbuntu} -gt 0 ]; then
|
||||
baseImage="ubuntu"
|
||||
fi
|
||||
if [ ${isDietPi} -gt 0 ]; then
|
||||
baseImage="dietpi"
|
||||
fi
|
||||
echo "baseimage=${baseImage}" >> $infoFile
|
||||
|
||||
################################
|
||||
# STRESSTEST RASPBERRY PI
|
||||
################################
|
||||
|
|
|
@ -12,7 +12,7 @@ from pathlib import Path
|
|||
import grpc
|
||||
import requests
|
||||
import toml
|
||||
from blitzpy import RaspiBlitzConfig
|
||||
from blitzpy import RaspiBlitzConfig, BlitzError
|
||||
from lndlibs import rpc_pb2 as lnrpc
|
||||
from lndlibs import rpc_pb2_grpc as rpcstub
|
||||
|
||||
|
@ -34,6 +34,12 @@ if len(sys.argv) <= 1 or sys.argv[1] == "-h" or sys.argv[1] == "help":
|
|||
print("# blitz.subscriptions.ip2tor.py ip-by-tor onionaddress")
|
||||
sys.exit(1)
|
||||
|
||||
# constants for standard services
|
||||
SERVICE_LND_REST_API = "LND-REST-API"
|
||||
SERVICE_LND_GRPC_API = "LND-GRPC-API"
|
||||
SERVICE_LNBITS = "LNBITS"
|
||||
SERVICE_BTCPAY = "BTCPAY"
|
||||
|
||||
#####################
|
||||
# BASIC SETTINGS
|
||||
#####################
|
||||
|
@ -69,17 +75,6 @@ else:
|
|||
is_testnet = False
|
||||
|
||||
|
||||
#####################
|
||||
# HELPER CLASSES
|
||||
#####################
|
||||
|
||||
class BlitzError(Exception):
|
||||
def __init__(self, errorShort, errorLong="", errorException=None):
|
||||
self.errorShort = str(errorShort)
|
||||
self.errorLong = str(errorLong)
|
||||
self.errorException = errorException
|
||||
|
||||
|
||||
#####################
|
||||
# HELPER FUNCTIONS
|
||||
#####################
|
||||
|
@ -90,9 +85,9 @@ def eprint(*args, **kwargs):
|
|||
|
||||
def handleException(e):
|
||||
if isinstance(e, BlitzError):
|
||||
eprint(e.errorLong)
|
||||
eprint(e.errorException)
|
||||
print("error='{0}'".format(e.errorShort))
|
||||
eprint(e.details)
|
||||
eprint(e.org)
|
||||
print("error='{0}'".format(e.short))
|
||||
else:
|
||||
eprint(e)
|
||||
print("error='{0}'".format(str(e)))
|
||||
|
@ -149,17 +144,17 @@ def apiGetHosts(session, shopurl):
|
|||
try:
|
||||
response = session.get(url)
|
||||
except Exception as e:
|
||||
raise BlitzError("failed HTTP request", url, e)
|
||||
raise BlitzError("failed HTTP request", {'url': url}, e)
|
||||
if response.status_code != 200:
|
||||
raise BlitzError("failed HTTP code", response.status_code, )
|
||||
raise BlitzError("failed HTTP code", {'status_code': response.status_code})
|
||||
|
||||
# parse & validate data
|
||||
try:
|
||||
jData = json.loads(response.content)
|
||||
except Exception as e:
|
||||
raise BlitzError("failed JSON parsing", response.content, e)
|
||||
raise BlitzError("failed JSON parsing", {'content': response.content}, e)
|
||||
if not isinstance(jData, list):
|
||||
raise BlitzError("hosts not list", response.content)
|
||||
raise BlitzError("hosts not list", {'content': response.content})
|
||||
for idx, hostEntry in enumerate(jData):
|
||||
try:
|
||||
# ignore if not offering tor bridge
|
||||
|
@ -187,7 +182,7 @@ def apiGetHosts(session, shopurl):
|
|||
# shorten names to 20 chars max
|
||||
hostEntry['name'] = hostEntry['name'][:20]
|
||||
except Exception as e:
|
||||
raise BlitzError("failed host entry pasring", str(hostEntry), e)
|
||||
raise BlitzError("failed host entry pasring", hostEntry, e)
|
||||
|
||||
hosts.append(hostEntry)
|
||||
|
||||
|
@ -210,11 +205,11 @@ def apiPlaceOrderNew(session, shopurl, hostid, toraddressWithPort):
|
|||
try:
|
||||
response = session.post(url, data=postData)
|
||||
except Exception as e:
|
||||
raise BlitzError("failed HTTP request", url, e)
|
||||
raise BlitzError("failed HTTP request", {'url': url}, e)
|
||||
if response.status_code == 420:
|
||||
raise BlitzError("forwarding this address was rejected", response.status_code)
|
||||
raise BlitzError("forwarding this address was rejected", {'status_code': response.status_code})
|
||||
if response.status_code != 201:
|
||||
raise BlitzError("failed HTTP code", response.status_code)
|
||||
raise BlitzError("failed HTTP code", {'status_code': response.status_code})
|
||||
|
||||
# parse & validate data
|
||||
try:
|
||||
|
@ -223,7 +218,7 @@ def apiPlaceOrderNew(session, shopurl, hostid, toraddressWithPort):
|
|||
print("error='MISSING ID'")
|
||||
return
|
||||
except Exception as e:
|
||||
raise BlitzError("failed JSON parsing", response.status_code, e)
|
||||
raise BlitzError("failed JSON parsing", {'status_code': response.status_code}, e)
|
||||
|
||||
return jData['id']
|
||||
|
||||
|
@ -235,11 +230,11 @@ def apiPlaceOrderExtension(session, shopurl, bridgeid):
|
|||
try:
|
||||
response = session.post(url)
|
||||
except Exception as e:
|
||||
raise BlitzError("failed HTTP request", url, e)
|
||||
raise BlitzError("failed HTTP request", {'url': url}, e)
|
||||
if response.status_code == 420:
|
||||
raise BlitzError("forwarding this address was rejected", response.status_code)
|
||||
raise BlitzError("forwarding this address was rejected", {'status_code': response.status_code})
|
||||
if response.status_code != 200 and response.status_code != 201:
|
||||
raise BlitzError("failed HTTP code", response.status_code)
|
||||
raise BlitzError("failed HTTP code", {'status_code': response.status_code})
|
||||
|
||||
# parse & validate data
|
||||
print("# parse")
|
||||
|
@ -249,12 +244,12 @@ def apiPlaceOrderExtension(session, shopurl, bridgeid):
|
|||
print("error='MISSING ID'")
|
||||
return
|
||||
except Exception as e:
|
||||
raise BlitzError("failed JSON parsing", response.content, e)
|
||||
raise BlitzError("failed JSON parsing", {'content': response.content}, e)
|
||||
|
||||
return jData['po_id']
|
||||
|
||||
|
||||
def apiGetOrder(session, shopurl, orderid):
|
||||
def apiGetOrder(session, shopurl, orderid) -> dict:
|
||||
print("# apiGetOrder")
|
||||
|
||||
# make HTTP request
|
||||
|
@ -262,19 +257,19 @@ def apiGetOrder(session, shopurl, orderid):
|
|||
try:
|
||||
response = session.get(url)
|
||||
except Exception as e:
|
||||
raise BlitzError("failed HTTP request", url, e)
|
||||
raise BlitzError("failed HTTP request", {'url': url}, e)
|
||||
if response.status_code != 200:
|
||||
raise BlitzError("failed HTTP code", response.status_code)
|
||||
raise BlitzError("failed HTTP code", {'status_code': response.status_code})
|
||||
|
||||
# parse & validate data
|
||||
try:
|
||||
jData = json.loads(response.content)
|
||||
if len(jData['item_details']) == 0:
|
||||
raise BlitzError("missing item", response.content)
|
||||
raise BlitzError("missing item", {'content': response.content})
|
||||
if len(jData['ln_invoices']) > 1:
|
||||
raise BlitzError("more than one invoice", response.content)
|
||||
raise BlitzError("more than one invoice", {'content': response.content})
|
||||
except Exception as e:
|
||||
raise BlitzError("failed JSON parsing", response.content, e)
|
||||
raise BlitzError("failed JSON parsing", {'content': response.content}, e)
|
||||
|
||||
return jData
|
||||
|
||||
|
@ -287,16 +282,16 @@ def apiGetBridgeStatus(session, shopurl, bridgeid):
|
|||
try:
|
||||
response = session.get(url)
|
||||
except Exception as e:
|
||||
raise BlitzError("failed HTTP request", url, e)
|
||||
raise BlitzError("failed HTTP request", {'url': url}, e)
|
||||
if response.status_code != 200:
|
||||
raise BlitzError("failed HTTP code", response.status_code)
|
||||
raise BlitzError("failed HTTP code", {'status_code': response.status_code})
|
||||
# parse & validate data
|
||||
try:
|
||||
jData = json.loads(response.content)
|
||||
if len(jData['id']) == 0:
|
||||
raise BlitzError("missing id", response.content)
|
||||
raise BlitzError("missing id", {'content': response.content})
|
||||
except Exception as e:
|
||||
raise BlitzError("failed JSON parsing", response.content, e)
|
||||
raise BlitzError("failed JSON parsing", {'content': response.content}, e)
|
||||
|
||||
return jData
|
||||
|
||||
|
@ -321,10 +316,10 @@ def lndDecodeInvoice(lnInvoiceString):
|
|||
|
||||
# validate results
|
||||
if response.num_msat <= 0:
|
||||
raise BlitzError("zero invoice not allowed", lnInvoiceString)
|
||||
raise BlitzError("zero invoice not allowed", {'invoice': lnInvoiceString})
|
||||
|
||||
except Exception as e:
|
||||
raise BlitzError("failed LND invoice decoding", lnInvoiceString, e)
|
||||
raise BlitzError("failed LND invoice decoding", {'invoice': lnInvoiceString}, e)
|
||||
|
||||
return response
|
||||
|
||||
|
@ -345,10 +340,10 @@ def lndPayInvoice(lnInvoiceString):
|
|||
|
||||
# validate results
|
||||
if len(response.payment_error) > 0:
|
||||
raise BlitzError(response.payment_error, lnInvoiceString)
|
||||
raise BlitzError(response.payment_error, {'invoice': lnInvoiceString})
|
||||
|
||||
except Exception as e:
|
||||
raise BlitzError("payment failed", lnInvoiceString, e)
|
||||
raise BlitzError("payment failed", {'invoice': lnInvoiceString}, e)
|
||||
|
||||
return response
|
||||
|
||||
|
@ -411,6 +406,8 @@ def shopOrder(shopUrl, hostid, servicename, torTarget, duration, msatsFirst, msa
|
|||
bridge = apiGetBridgeStatus(session, shopUrl, bridge_id)
|
||||
if bridge['status'] == "A":
|
||||
break
|
||||
if bridge['status'] == "R":
|
||||
break
|
||||
if loopCount > 120:
|
||||
raise BlitzError("timeout bridge not getting ready", bridge)
|
||||
|
||||
|
@ -430,6 +427,12 @@ def shopOrder(shopUrl, hostid, servicename, torTarget, duration, msatsFirst, msa
|
|||
if (secondsDelivered + 600) < int(duration):
|
||||
contract_breached = True
|
||||
warning_text = "delivered duration shorter than advertised"
|
||||
if bridge['status'] == "R":
|
||||
contract_breached = True
|
||||
try:
|
||||
warningTXT = "rejected: {0}".format(bridge['message'])
|
||||
except Exception as e:
|
||||
warningTXT = "rejected: n/a"
|
||||
|
||||
# create subscription data for storage
|
||||
subscription = dict()
|
||||
|
@ -437,7 +440,7 @@ def shopOrder(shopUrl, hostid, servicename, torTarget, duration, msatsFirst, msa
|
|||
subscription['id'] = bridge['id']
|
||||
subscription['name'] = servicename
|
||||
subscription['shop'] = shopUrl
|
||||
subscription['active'] = True
|
||||
subscription['active'] = not contract_breached
|
||||
subscription['ip'] = bridge_ip
|
||||
subscription['port'] = bridge_port
|
||||
subscription['duration'] = int(duration)
|
||||
|
@ -471,7 +474,7 @@ def shopOrder(shopUrl, hostid, servicename, torTarget, duration, msatsFirst, msa
|
|||
|
||||
except Exception as e:
|
||||
eprint(e)
|
||||
raise BlitzError("fail on subscription storage", str(subscription), e)
|
||||
raise BlitzError("fail on subscription storage", subscription, e)
|
||||
|
||||
print("# OK - BRIDGE READY: {0}:{1} -> {2}".format(bridge_ip, bridge_port, torTarget))
|
||||
return subscription
|
||||
|
@ -521,6 +524,13 @@ def subscriptionExtend(shopUrl, bridgeid, durationAdvertised, msatsNext, bridge_
|
|||
print("## Loop {0}".format(loopCount))
|
||||
try:
|
||||
bridge = apiGetBridgeStatus(session, shopUrl, bridgeid)
|
||||
if bridge['status'] == "R":
|
||||
contract_breached = True
|
||||
try:
|
||||
warningTXT = "rejected: {0}".format(bridge['message'])
|
||||
except Exception as e:
|
||||
warningTXT = "rejected: n/a"
|
||||
break
|
||||
if bridge['suspend_after'] != bridge_suspendafter:
|
||||
break
|
||||
except Exception as e:
|
||||
|
@ -562,7 +572,7 @@ def subscriptionExtend(shopUrl, bridgeid, durationAdvertised, msatsNext, bridge_
|
|||
|
||||
except Exception as e:
|
||||
eprint(e)
|
||||
raise BlitzError("fail on subscription storage", "", e)
|
||||
raise BlitzError("fail on subscription storage", org=e)
|
||||
|
||||
print("# BRIDGE GOT EXTENDED: {0} -> {1}".format(bridge_suspendafter, bridge['suspend_after']))
|
||||
|
||||
|
@ -648,7 +658,8 @@ Try again later, enter another address or cancel.
|
|||
choices=choices, title="Available Subscriptions")
|
||||
|
||||
# if user cancels
|
||||
if code != d.OK: sys.exit(0)
|
||||
if code != d.OK:
|
||||
sys.exit(0)
|
||||
|
||||
# get data of selected
|
||||
seletedIndex = int(tag)
|
||||
|
@ -696,7 +707,8 @@ More information on the service you can find under:
|
|||
height=30)
|
||||
|
||||
# if user AGREED break loop and continue with selected host
|
||||
if code == "extra": break
|
||||
if code == "extra":
|
||||
break
|
||||
|
||||
############################
|
||||
# PHASE 3: Make Subscription
|
||||
|
@ -713,18 +725,25 @@ More information on the service you can find under:
|
|||
|
||||
exitcode = 0
|
||||
|
||||
if (be.errorShort == "timeout on waiting for extending bridge" or
|
||||
be.errorShort == "fail on subscription storage" or
|
||||
be.errorShort == "invalid port" or
|
||||
be.errorShort == "timeout bridge not getting ready"):
|
||||
try:
|
||||
message = be.details['message']
|
||||
except KeyError:
|
||||
message = ""
|
||||
|
||||
if (be.short == "timeout on waiting for extending bridge" or
|
||||
be.short == "fail on subscription storage" or
|
||||
be.short == "invalid port" or
|
||||
be.short == "timeout bridge not getting ready"):
|
||||
|
||||
# error happened after payment
|
||||
exitcode = Dialog(dialog="dialog", autowidgetsize=True).msgbox('''
|
||||
You DID PAY the initial fee.
|
||||
But the service was not able to provide service.
|
||||
Subscription will be ignored.
|
||||
|
||||
Error: {0}
|
||||
'''.format(be.errorShort), title="Error on Subscription", extra_button=True, extra_label="Details")
|
||||
Message: {1}
|
||||
'''.format(be.short, message), title="Error on Subscription", extra_button=True, extra_label="Details")
|
||||
else:
|
||||
|
||||
# error happened before payment
|
||||
|
@ -732,8 +751,10 @@ Error: {0}
|
|||
You DID NOT PAY the initial fee.
|
||||
The service was not able to provide service.
|
||||
Subscription will be ignored.
|
||||
|
||||
Error: {0}
|
||||
'''.format(be.errorShort), title="Error on Subscription", extra_button=True, extra_label="Details")
|
||||
Message: {1}
|
||||
'''.format(be.short, message), title="Error on Subscription", extra_button=True, extra_label="Details")
|
||||
|
||||
# show more details (when user used extra button)
|
||||
if exitcode == Dialog.EXTRA:
|
||||
|
@ -741,13 +762,13 @@ Error: {0}
|
|||
print('###### ERROR DETAIL FOR DEBUG #######')
|
||||
print("")
|
||||
print("Error Short:")
|
||||
print(be.errorShort)
|
||||
print(be.short)
|
||||
print('Shop:')
|
||||
print(shopurl)
|
||||
print('Bridge:')
|
||||
print(str(host))
|
||||
print("Error Detail:")
|
||||
print(be.errorLong)
|
||||
print(be.details)
|
||||
print("")
|
||||
input("Press Enter to continue ...")
|
||||
|
||||
|
@ -770,7 +791,7 @@ Error: {0}
|
|||
sys.exit(1)
|
||||
|
||||
# if LND REST or LND GRPC service ... add bridge IP to TLS
|
||||
if servicename == "LND-REST-API" or servicename == "LND-GRPC-API":
|
||||
if blitzServiceName == SERVICE_LND_REST_API or blitzServiceName == SERVICE_LND_GRPC_API:
|
||||
os.system("sudo /home/admin/config.scripts/lnd.tlscert.sh ip-add {0}".format(subscription['ip']))
|
||||
os.system("sudo /home/admin/config.scripts/lnd.credentials.sh reset tls")
|
||||
os.system("sudo /home/admin/config.scripts/lnd.credentials.sh sync")
|
||||
|
@ -785,7 +806,7 @@ You may want to consider to cancel the subscription later.
|
|||
|
||||
# decide if https:// address
|
||||
protocol = ""
|
||||
if blitzServiceName == "LNBITS":
|
||||
if blitzServiceName == SERVICE_LNBITS:
|
||||
protocol = "https://"
|
||||
|
||||
# Give final result feedback to user
|
||||
|
@ -821,13 +842,11 @@ MAIN MENU > Manage Subscriptions > My Subscriptions
|
|||
# CREATE SSH DIALOG
|
||||
# use for ssh shell menu
|
||||
###############
|
||||
|
||||
if sys.argv[1] == "create-ssh-dialog":
|
||||
|
||||
def create_ssh_dialog():
|
||||
# check parameters
|
||||
try:
|
||||
if len(sys.argv) <= 4:
|
||||
raise BlitzError("incorrect parameters", "")
|
||||
raise BlitzError("incorrect parameters")
|
||||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
|
@ -839,17 +858,16 @@ if sys.argv[1] == "create-ssh-dialog":
|
|||
|
||||
sys.exit()
|
||||
|
||||
|
||||
###############
|
||||
# SHOP LIST
|
||||
# call from web interface
|
||||
###############
|
||||
|
||||
if sys.argv[1] == "shop-list":
|
||||
|
||||
def shop_list():
|
||||
# check parameters
|
||||
try:
|
||||
if len(sys.argv) <= 2:
|
||||
raise BlitzError("incorrect parameters", "")
|
||||
raise BlitzError("incorrect parameters")
|
||||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
|
@ -865,17 +883,16 @@ if sys.argv[1] == "shop-list":
|
|||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
##########################
|
||||
# SHOP ORDER
|
||||
# call from web interface
|
||||
##########################
|
||||
|
||||
if sys.argv[1] == "shop-order":
|
||||
|
||||
def shop_order():
|
||||
# check parameters
|
||||
try:
|
||||
if len(sys.argv) <= 8:
|
||||
raise BlitzError("incorrect parameters", "")
|
||||
raise BlitzError("incorrect parameters")
|
||||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
|
@ -900,13 +917,12 @@ if sys.argv[1] == "shop-order":
|
|||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
|
||||
#######################
|
||||
# SUBSCRIPTIONS LIST
|
||||
# call in intervals from background process
|
||||
#######################
|
||||
|
||||
if sys.argv[1] == "subscriptions-list":
|
||||
|
||||
def subscriptions_list():
|
||||
try:
|
||||
|
||||
if Path(SUBSCRIPTIONS_FILE).is_file():
|
||||
|
@ -921,15 +937,12 @@ if sys.argv[1] == "subscriptions-list":
|
|||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
#######################
|
||||
# SUBSCRIPTIONS RENEW
|
||||
# call in intervals from background process
|
||||
#######################
|
||||
|
||||
if sys.argv[1] == "subscriptions-renew":
|
||||
|
||||
def subscriptions_renew():
|
||||
print("# RUNNING subscriptions-renew")
|
||||
|
||||
# check parameters
|
||||
|
@ -976,16 +989,16 @@ if sys.argv[1] == "subscriptions-renew":
|
|||
subs = toml.load(SUBSCRIPTIONS_FILE)
|
||||
for sub in subs['subscriptions_ip2tor']:
|
||||
if sub['id'] == subscription['id']:
|
||||
sub['warning'] = "Exception on Renew: {0}".format(be.errorShort)
|
||||
if be.errorShort == "invoice bigger amount than advertised":
|
||||
sub['warning'] = "Exception on Renew: {0}".format(be.short)
|
||||
if be.short == "invoice bigger amount than advertised":
|
||||
sub['contract_breached'] = True
|
||||
sub['active'] = False
|
||||
with open(SUBSCRIPTIONS_FILE, 'w') as writer:
|
||||
writer.write(toml.dumps(subs))
|
||||
writer.close()
|
||||
break
|
||||
print("# BLITZERROR on subscriptions-renew of subscription index {0}: {1}".format(idx, be.errorShort))
|
||||
print("# {0}".format(be.errorShort))
|
||||
print("# BLITZERROR on subscriptions-renew of subscription index {0}: {1}".format(idx, be.short))
|
||||
print("# {0}".format(be.short))
|
||||
|
||||
except Exception as e:
|
||||
print("# EXCEPTION on subscriptions-renew of subscription index {0}".format(idx))
|
||||
|
@ -996,18 +1009,17 @@ if sys.argv[1] == "subscriptions-renew":
|
|||
|
||||
# output - not needed only for debug logs
|
||||
print("# DONE subscriptions-renew")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
#######################
|
||||
# SUBSCRIPTION CANCEL
|
||||
# call in intervalls from background process
|
||||
# call in intervals from background process
|
||||
#######################
|
||||
if sys.argv[1] == "subscription-cancel":
|
||||
|
||||
def subscription_cancel():
|
||||
# check parameters
|
||||
try:
|
||||
if len(sys.argv) <= 2:
|
||||
raise BlitzError("incorrect parameters", "")
|
||||
raise BlitzError("incorrect parameters")
|
||||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
|
@ -1032,30 +1044,28 @@ if sys.argv[1] == "subscription-cancel":
|
|||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
#######################
|
||||
# GET ADDRESS BY SERVICENAME
|
||||
# GET ADDRESS BY SERVICE NAME
|
||||
# gets called by other scripts to check if service has a ip2tor bridge address
|
||||
# output is bash key/value style so that it can be imported with source
|
||||
#######################
|
||||
if sys.argv[1] == "subscription-by-service":
|
||||
|
||||
def subscription_by_service():
|
||||
# check parameters
|
||||
try:
|
||||
if len(sys.argv) <= 2:
|
||||
raise BlitzError("incorrect parameters", "")
|
||||
raise BlitzError("incorrect parameters")
|
||||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
servicename = sys.argv[2]
|
||||
service_name = sys.argv[2]
|
||||
|
||||
try:
|
||||
if os.path.isfile(SUBSCRIPTIONS_FILE):
|
||||
os.system("sudo chown admin:admin {0}".format(SUBSCRIPTIONS_FILE))
|
||||
subs = toml.load(SUBSCRIPTIONS_FILE)
|
||||
for idx, sub in enumerate(subs['subscriptions_ip2tor']):
|
||||
if sub['active'] and sub['name'] == servicename:
|
||||
if sub['active'] and sub['name'] == service_name:
|
||||
print("type='{0}'".format(sub['type']))
|
||||
print("ip='{0}'".format(sub['ip']))
|
||||
print("port='{0}'".format(sub['port']))
|
||||
|
@ -1063,24 +1073,22 @@ if sys.argv[1] == "subscription-by-service":
|
|||
sys.exit(0)
|
||||
|
||||
print("error='not found'")
|
||||
sys.exit(0)
|
||||
|
||||
except Exception as e:
|
||||
handleException(e)
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(1)
|
||||
|
||||
#######################
|
||||
# GET IP BY ONIONADDRESS
|
||||
# GET IP BY ONION ADDRESS
|
||||
# gets called by other scripts to check if a onion address as a IP2TOR bridge
|
||||
# output is bash key/value style so that it can be imported with source
|
||||
#######################
|
||||
if sys.argv[1] == "ip-by-tor":
|
||||
|
||||
def ip_by_tor():
|
||||
# check parameters
|
||||
try:
|
||||
if len(sys.argv) <= 2:
|
||||
raise BlitzError("incorrect parameters", "")
|
||||
raise BlitzError("incorrect parameters")
|
||||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
|
@ -1100,12 +1108,41 @@ if sys.argv[1] == "ip-by-tor":
|
|||
sys.exit(0)
|
||||
|
||||
print("error='not found'")
|
||||
sys.exit(0)
|
||||
|
||||
except Exception as e:
|
||||
handleException(e)
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(1)
|
||||
|
||||
# unknown command
|
||||
print("# unknown command")
|
||||
def main():
|
||||
if sys.argv[1] == "create-ssh-dialog":
|
||||
create_ssh_dialog()
|
||||
|
||||
elif sys.argv[1] == "shop-list":
|
||||
shop_list()
|
||||
|
||||
elif sys.argv[1] == "shop-order":
|
||||
shop_order()
|
||||
|
||||
elif sys.argv[1] == "subscriptions-list":
|
||||
subscriptions_list()
|
||||
|
||||
elif sys.argv[1] == "subscriptions-renew":
|
||||
subscriptions_renew()
|
||||
|
||||
elif sys.argv[1] == "subscription-cancel":
|
||||
subscription_cancel()
|
||||
|
||||
elif sys.argv[1] == "subscription-by-service":
|
||||
subscription_by_service()
|
||||
|
||||
elif sys.argv[1] == "ip-by-tor":
|
||||
ip_by_tor()
|
||||
|
||||
else:
|
||||
# unknown command
|
||||
print("# unknown command")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -10,7 +10,7 @@ from pathlib import Path
|
|||
|
||||
import requests
|
||||
import toml
|
||||
from blitzpy import RaspiBlitzConfig
|
||||
from blitzpy import RaspiBlitzConfig,BlitzError
|
||||
|
||||
#####################
|
||||
# SCRIPT INFO
|
||||
|
@ -30,6 +30,12 @@ if len(sys.argv) <= 1 or sys.argv[1] == "-h" or sys.argv[1] == "help":
|
|||
print("# blitz.subscriptions.ip2tor.py subscription-cancel <id>")
|
||||
sys.exit(1)
|
||||
|
||||
# constants for standard services
|
||||
SERVICE_LND_REST_API = "LND-REST-API"
|
||||
SERVICE_LND_GRPC_API = "LND-GRPC-API"
|
||||
SERVICE_LNBITS = "LNBITS"
|
||||
SERVICE_BTCPAY = "BTCPAY"
|
||||
|
||||
#####################
|
||||
# BASIC SETTINGS
|
||||
#####################
|
||||
|
@ -49,6 +55,7 @@ if cfg.run_behind_tor:
|
|||
# HELPER CLASSES
|
||||
#####################
|
||||
|
||||
# ToDo(frennkie) replace this with updated BlitzError from blitzpy
|
||||
class BlitzError(Exception):
|
||||
def __init__(self, errorShort, errorLong="", errorException=None):
|
||||
self.errorShort = str(errorShort)
|
||||
|
@ -75,19 +82,19 @@ def handleException(e):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
def getsubdomain(fulldomainstring):
|
||||
return fulldomainstring.split('.')[0]
|
||||
def get_subdomain(fulldomain_str):
|
||||
return fulldomain_str.split('.')[0]
|
||||
|
||||
|
||||
############################
|
||||
# API Calls to DNS Servcies
|
||||
# API Calls to DNS Services
|
||||
############################
|
||||
|
||||
def duckDNSupdate(domain, token, ip):
|
||||
def duckdns_update(domain, token, ip):
|
||||
print("# duckDNS update IP API call for {0}".format(domain))
|
||||
|
||||
# make HTTP request
|
||||
url = "https://www.duckdns.org/update?domains={0}&token={1}&ip={2}".format(getsubdomain(domain), token, ip)
|
||||
url = "https://www.duckdns.org/update?domains={0}&token={1}&ip={2}".format(get_subdomain(domain), token, ip)
|
||||
try:
|
||||
response = session.get(url)
|
||||
if response.status_code != 200:
|
||||
|
@ -102,41 +109,33 @@ def duckDNSupdate(domain, token, ip):
|
|||
# PROCESS FUNCTIONS
|
||||
#####################
|
||||
|
||||
def subscriptionsNew(ip, dnsservice, id, token, target):
|
||||
# id needs to the full domain name
|
||||
def subscriptions_new(ip, dnsservice, id, token, target):
|
||||
# id needs to be the full domain name
|
||||
if id.find(".") == -1:
|
||||
raise BlitzError("not a fully qualified domainname", dnsservice_id)
|
||||
# ToDo(frennkie) dnsservice_id doesn't exit
|
||||
raise BlitzError("not a fully qualified domain name", dnsservice_id)
|
||||
|
||||
# check if id already exists
|
||||
if len(getSubscription(id)) > 0:
|
||||
if len(get_subscription(id)) > 0:
|
||||
raise BlitzError("id already exists", id)
|
||||
|
||||
# make sure lets encrypt client is installed
|
||||
os.system("/home/admin/config.scripts/bonus.letsencrypt.sh on")
|
||||
|
||||
# dyndns
|
||||
realip = ip
|
||||
real_ip = ip
|
||||
if ip == "dyndns":
|
||||
updateURL = ""
|
||||
update_url = ""
|
||||
if dnsservice == "duckdns":
|
||||
updateURL = "https://www.duckdns.org/update?domains={0}&token={1}".format(getsubdomain(domain), token, ip)
|
||||
subprocess.run(['/home/admin/config.scriprs/internet.dyndomain.sh', 'on', id, updateURL],
|
||||
# ToDo(frennkie) domain doesn't exit
|
||||
update_url = "https://www.duckdns.org/update?domains={0}&token={1}".format(get_subdomain(domain), token, ip)
|
||||
subprocess.run(['/home/admin/config.scriprs/internet.dyndomain.sh', 'on', id, update_url],
|
||||
stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||
realip = cfg.public_ip
|
||||
real_ip = cfg.public_ip
|
||||
|
||||
# update DNS with actual IP
|
||||
if dnsservice == "duckdns":
|
||||
duckDNSupdate(getsubdomain(id), token, realip)
|
||||
|
||||
# run the ACME script
|
||||
print("# Running letsencrypt ACME script ...")
|
||||
acmeResult = subprocess.Popen(
|
||||
["/home/admin/config.scripts/bonus.letsencrypt.sh", "issue-cert", dnsservice, id, token, target],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf8')
|
||||
out, err = acmeResult.communicate()
|
||||
if out.find("error=") > -1:
|
||||
time.sleep(6)
|
||||
raise BlitzError("letsancrypt acme failed", out)
|
||||
duckdns_update(get_subdomain(id), token, real_ip)
|
||||
|
||||
# create subscription data for storage
|
||||
subscription = dict()
|
||||
|
@ -172,30 +171,40 @@ def subscriptionsNew(ip, dnsservice, id, token, target):
|
|||
eprint(e)
|
||||
raise BlitzError("fail on subscription storage", str(subscription), e)
|
||||
|
||||
# run the ACME script
|
||||
print("# Running letsencrypt ACME script ...")
|
||||
acme_result = subprocess.Popen(
|
||||
["/home/admin/config.scripts/bonus.letsencrypt.sh", "issue-cert", dnsservice, id, token, target],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf8')
|
||||
out, err = acme_result.communicate()
|
||||
eprint(str(out))
|
||||
eprint(str(err))
|
||||
if out.find("error=") > -1:
|
||||
time.sleep(6)
|
||||
raise BlitzError("letsancrypt acme failed", out)
|
||||
|
||||
print("# OK - LETSENCRYPT DOMAIN IS READY")
|
||||
return subscription
|
||||
|
||||
|
||||
def subscriptionsCancel(id):
|
||||
# ToDo(frennkie) id is not used..
|
||||
|
||||
def subscriptions_cancel(s_id):
|
||||
os.system("sudo chown admin:admin {0}".format(SUBSCRIPTIONS_FILE))
|
||||
subs = toml.load(SUBSCRIPTIONS_FILE)
|
||||
newList = []
|
||||
removedCert = None
|
||||
new_list = []
|
||||
removed_cert = None
|
||||
for idx, sub in enumerate(subs['subscriptions_letsencrypt']):
|
||||
if sub['id'] != subscriptionID:
|
||||
newList.append(sub)
|
||||
if sub['id'] != s_id:
|
||||
new_list.append(sub)
|
||||
else:
|
||||
removedCert = sub
|
||||
subs['subscriptions_letsencrypt'] = newList
|
||||
removed_cert = sub
|
||||
subs['subscriptions_letsencrypt'] = new_list
|
||||
|
||||
# run the ACME script to remove cert
|
||||
if removedCert:
|
||||
acmeResult = subprocess.Popen(
|
||||
["/home/admin/config.scripts/bonus.letsencrypt.sh", "remove-cert", removedCert['id'],
|
||||
removedCert['target']], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf8')
|
||||
out, err = acmeResult.communicate()
|
||||
if removed_cert:
|
||||
acme_result = subprocess.Popen(
|
||||
["/home/admin/config.scripts/bonus.letsencrypt.sh", "remove-cert", removed_cert['id'],
|
||||
removed_cert['target']], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf8')
|
||||
out, err = acme_result.communicate()
|
||||
if out.find("error=") > -1:
|
||||
time.sleep(6)
|
||||
raise BlitzError("letsencrypt acme failed", out)
|
||||
|
@ -210,7 +219,7 @@ def subscriptionsCancel(id):
|
|||
# todo: deinstall letsencrypt if this was last subscription
|
||||
|
||||
|
||||
def getSubscription(subscriptionID):
|
||||
def get_subscription(subscription_id):
|
||||
try:
|
||||
|
||||
if Path(SUBSCRIPTIONS_FILE).is_file():
|
||||
|
@ -221,7 +230,7 @@ def getSubscription(subscriptionID):
|
|||
if "subscriptions_letsencrypt" not in subs:
|
||||
return []
|
||||
for idx, sub in enumerate(subs['subscriptions_letsencrypt']):
|
||||
if sub['id'] == subscriptionID:
|
||||
if sub['id'] == subscription_id:
|
||||
return sub
|
||||
return []
|
||||
|
||||
|
@ -229,7 +238,7 @@ def getSubscription(subscriptionID):
|
|||
return []
|
||||
|
||||
|
||||
def getDomainByIP(ip):
|
||||
def get_domain_by_ip(ip):
|
||||
# does subscriptin file exists
|
||||
if Path(SUBSCRIPTIONS_FILE).is_file():
|
||||
os.system("sudo chown admin:admin {0}".format(SUBSCRIPTIONS_FILE))
|
||||
|
@ -251,7 +260,7 @@ def getDomainByIP(ip):
|
|||
raise BlitzError("no match")
|
||||
|
||||
|
||||
def menuMakeSubscription():
|
||||
def menu_make_subscription():
|
||||
# late imports - so that rest of script can run also if dependency is not available
|
||||
from dialog import Dialog
|
||||
|
||||
|
@ -297,7 +306,7 @@ If you havent already go to https://duckdns.org
|
|||
title="DuckDNS Domain")
|
||||
subdomain = text.strip()
|
||||
subdomain = subdomain.split(' ')[0]
|
||||
subdomain = getsubdomain(subdomain)
|
||||
subdomain = get_subdomain(subdomain)
|
||||
domain = "{0}.duckdns.org".format(subdomain)
|
||||
os.system("clear")
|
||||
|
||||
|
@ -324,7 +333,7 @@ This looks not like a valid subdomain.
|
|||
if len(token) < 20:
|
||||
Dialog(dialog="dialog", autowidgetsize=True).msgbox('''
|
||||
This looks not like a valid token.
|
||||
''', title="Unvalid Input")
|
||||
''', title="Invalid Input")
|
||||
sys.exit(0)
|
||||
|
||||
else:
|
||||
|
@ -348,7 +357,7 @@ This looks not like a valid token.
|
|||
"\nChoose the kind of IP you want to use:",
|
||||
choices=choices, width=60, height=10, title="Select Service")
|
||||
|
||||
# if user chosses CANCEL
|
||||
# if user chooses CANCEL
|
||||
os.system("clear")
|
||||
if code != d.OK:
|
||||
sys.exit(0)
|
||||
|
@ -360,16 +369,16 @@ This looks not like a valid token.
|
|||
if tag == "IP2TOR":
|
||||
|
||||
# get all active IP2TOR subscriptions (just in case)
|
||||
ip2torSubs = []
|
||||
ip2tor_subs = []
|
||||
if Path(SUBSCRIPTIONS_FILE).is_file():
|
||||
os.system("sudo chown admin:admin {0}".format(SUBSCRIPTIONS_FILE))
|
||||
subs = toml.load(SUBSCRIPTIONS_FILE)
|
||||
for idx, sub in enumerate(subs['subscriptions_ip2tor']):
|
||||
if sub['active']:
|
||||
ip2torSubs.append(sub)
|
||||
ip2tor_subs.append(sub)
|
||||
|
||||
# when user has no IP2TOR subs yet
|
||||
if len(ip2torSubs) == 0:
|
||||
if len(ip2tor_subs) == 0:
|
||||
Dialog(dialog="dialog", autowidgetsize=True).msgbox('''
|
||||
You have no active IP2TOR subscriptions.
|
||||
Create one first and try again.
|
||||
|
@ -378,7 +387,7 @@ Create one first and try again.
|
|||
|
||||
# let user select a IP2TOR subscription
|
||||
choices = []
|
||||
for idx, sub in enumerate(ip2torSubs):
|
||||
for idx, sub in enumerate(ip2tor_subs):
|
||||
choices.append(("{0}".format(idx), "IP2TOR {0} {1}:{2}".format(sub['name'], sub['ip'], sub['port'])))
|
||||
|
||||
d = Dialog(dialog="dialog", autowidgetsize=True)
|
||||
|
@ -392,8 +401,8 @@ Create one first and try again.
|
|||
sys.exit(0)
|
||||
|
||||
# get the slected IP2TOR bridge
|
||||
ip2torSelect = ip2torSubs[int(tag)]
|
||||
ip = ip2torSelect["ip"]
|
||||
ip2tor_select = ip2tor_subs[int(tag)]
|
||||
ip = ip2tor_select["ip"]
|
||||
target = "tor"
|
||||
|
||||
elif tag == "DYNDNS":
|
||||
|
@ -419,13 +428,13 @@ Create one first and try again.
|
|||
if len(ip) == 0:
|
||||
Dialog(dialog="dialog", autowidgetsize=True).msgbox('''
|
||||
This looks not like a valid IP.
|
||||
''', title="Unvalid Input")
|
||||
''', title="Invalid Input")
|
||||
sys.exit(0)
|
||||
|
||||
# create the letsencrypt subscription
|
||||
try:
|
||||
os.system("clear")
|
||||
subscription = subscriptionsNew(ip, dnsservice, domain, token, target)
|
||||
subscription = subscriptions_new(ip, dnsservice, domain, token, target)
|
||||
|
||||
# success dialog
|
||||
Dialog(dialog="dialog", autowidgetsize=True).msgbox('''
|
||||
|
@ -453,19 +462,15 @@ Unknown Error happened - please report to developers:
|
|||
# CREATE SSH DIALOG
|
||||
# use for ssh shell menu
|
||||
###############
|
||||
def create_ssh_dialog():
|
||||
menu_make_subscription()
|
||||
|
||||
if sys.argv[1] == "create-ssh-dialog":
|
||||
menuMakeSubscription()
|
||||
|
||||
sys.exit()
|
||||
|
||||
##########################
|
||||
# SUBSCRIPTIONS NEW
|
||||
# call from web interface
|
||||
##########################
|
||||
|
||||
if sys.argv[1] == "subscription-new":
|
||||
|
||||
def subscription_new():
|
||||
# check parameters
|
||||
try:
|
||||
if len(sys.argv) <= 5:
|
||||
|
@ -484,7 +489,7 @@ if sys.argv[1] == "subscription-new":
|
|||
|
||||
# create the subscription
|
||||
try:
|
||||
subscription = subscriptionsNew(ip, dnsservice_type, dnsservice_id, dnsservice_token, target)
|
||||
subscription = subscriptions_new(ip, dnsservice_type, dnsservice_id, dnsservice_token, target)
|
||||
|
||||
# output json ordered bridge
|
||||
print(json.dumps(subscription, indent=2))
|
||||
|
@ -493,12 +498,11 @@ if sys.argv[1] == "subscription-new":
|
|||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
|
||||
#######################
|
||||
# SUBSCRIPTIONS LIST
|
||||
#######################
|
||||
|
||||
if sys.argv[1] == "subscriptions-list":
|
||||
|
||||
def subscriptions_list():
|
||||
try:
|
||||
|
||||
if Path(SUBSCRIPTIONS_FILE).is_file():
|
||||
|
@ -513,13 +517,11 @@ if sys.argv[1] == "subscriptions-list":
|
|||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
#######################
|
||||
# SUBSCRIPTION DETAIL
|
||||
#######################
|
||||
if sys.argv[1] == "subscription-detail":
|
||||
|
||||
def subscription_detail():
|
||||
# check parameters
|
||||
try:
|
||||
if len(sys.argv) <= 2:
|
||||
|
@ -527,22 +529,20 @@ if sys.argv[1] == "subscription-detail":
|
|||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
subscriptionID = sys.argv[2]
|
||||
subscription_id = sys.argv[2]
|
||||
try:
|
||||
sub = getSubscription(subscriptionID)
|
||||
sub = get_subscription(subscription_id)
|
||||
print(json.dumps(sub, indent=2))
|
||||
|
||||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
#######################
|
||||
# DOMAIN BY IP
|
||||
# to check if an ip has a domain mapping
|
||||
#######################
|
||||
if sys.argv[1] == "domain-by-ip":
|
||||
|
||||
def domain_by_ip():
|
||||
# check parameters
|
||||
try:
|
||||
if len(sys.argv) <= 2:
|
||||
|
@ -554,19 +554,17 @@ if sys.argv[1] == "domain-by-ip":
|
|||
ip = sys.argv[2]
|
||||
try:
|
||||
|
||||
domain = getDomainByIP(ip)
|
||||
domain = get_domain_by_ip(ip)
|
||||
print("domain='{0}'".format(domain))
|
||||
|
||||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
#######################
|
||||
# SUBSCRIPTION CANCEL
|
||||
#######################
|
||||
if sys.argv[1] == "subscription-cancel":
|
||||
|
||||
def subscription_cancel():
|
||||
# check parameters
|
||||
try:
|
||||
if len(sys.argv) <= 2:
|
||||
|
@ -574,13 +572,36 @@ if sys.argv[1] == "subscription-cancel":
|
|||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
subscriptionID = sys.argv[2]
|
||||
subscription_id = sys.argv[2]
|
||||
try:
|
||||
subscriptionsCancel(subscriptionID)
|
||||
subscriptions_cancel(subscription_id)
|
||||
except Exception as e:
|
||||
handleException(e)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
# unknown command
|
||||
print("# unknown command")
|
||||
def main():
|
||||
if sys.argv[1] == "create-ssh-dialog":
|
||||
create_ssh_dialog()
|
||||
|
||||
elif sys.argv[1] == "domain-by-ip":
|
||||
domain_by_ip()
|
||||
|
||||
elif sys.argv[1] == "subscriptions-list":
|
||||
subscriptions_list()
|
||||
|
||||
elif sys.argv[1] == "subscription-cancel":
|
||||
subscription_cancel()
|
||||
|
||||
elif sys.argv[1] == "subscription-detail":
|
||||
subscription_detail()
|
||||
|
||||
elif sys.argv[1] == "subscription-new":
|
||||
subscription_new()
|
||||
|
||||
else:
|
||||
# unknown command
|
||||
print("# unknown command")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -15,10 +15,10 @@ from blitzpy import RaspiBlitzConfig
|
|||
from dialog import Dialog
|
||||
|
||||
# constants for standard services
|
||||
LND_REST_API = "LND-REST-API"
|
||||
LND_GRPC_API = "LND-GRPC-API"
|
||||
LNBITS = "LNBITS"
|
||||
BTCPAY = "BTCPAY"
|
||||
SERVICE_LND_REST_API = "LND-REST-API"
|
||||
SERVICE_LND_GRPC_API = "LND-GRPC-API"
|
||||
SERVICE_LNBITS = "LNBITS"
|
||||
SERVICE_BTCPAY = "BTCPAY"
|
||||
|
||||
# load config
|
||||
cfg = RaspiBlitzConfig()
|
||||
|
@ -32,35 +32,38 @@ SUBSCRIPTIONS_FILE = "/mnt/hdd/app-data/subscriptions/subscriptions.toml"
|
|||
# HELPER FUNCTIONS
|
||||
#######################
|
||||
|
||||
# ToDo(frennkie) these are not being used!
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
|
||||
def parseDateIP2TORSERVER(datestr):
|
||||
return datetime.strptime(datestr, "%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
def parse_date_ip2tor(date_str):
|
||||
return datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
|
||||
|
||||
def secondsLeft(dateObj):
|
||||
return round((dateObj - datetime.utcnow()).total_seconds())
|
||||
def seconds_left(date_obj):
|
||||
return round((date_obj - datetime.utcnow()).total_seconds())
|
||||
|
||||
|
||||
#######################
|
||||
# SSH MENU FUNCTIONS
|
||||
#######################
|
||||
|
||||
def mySubscriptions():
|
||||
def my_subscriptions():
|
||||
# check if any subscriptions are available
|
||||
countSubscriptions = 0
|
||||
count_subscriptions = 0
|
||||
try:
|
||||
os.system("sudo chown admin:admin {0}".format(SUBSCRIPTIONS_FILE))
|
||||
subs = toml.load(SUBSCRIPTIONS_FILE)
|
||||
if 'subscriptions_ip2tor' in subs:
|
||||
countSubscriptions += len(subs['subscriptions_ip2tor'])
|
||||
count_subscriptions += len(subs['subscriptions_ip2tor'])
|
||||
if 'subscriptions_letsencrypt' in subs:
|
||||
countSubscriptions += len(subs['subscriptions_letsencrypt'])
|
||||
count_subscriptions += len(subs['subscriptions_letsencrypt'])
|
||||
except Exception as e:
|
||||
pass
|
||||
if countSubscriptions == 0:
|
||||
print(f"warning: {e}")
|
||||
|
||||
if count_subscriptions == 0:
|
||||
Dialog(dialog="dialog", autowidgetsize=True).msgbox('''
|
||||
You have no active or inactive subscriptions.
|
||||
''', title="Info")
|
||||
|
@ -69,36 +72,36 @@ You have no active or inactive subscriptions.
|
|||
# load subscriptions and make dialog choices out of it
|
||||
choices = []
|
||||
lookup = {}
|
||||
lookupIndex = 0
|
||||
lookup_index = 0
|
||||
subs = toml.load(SUBSCRIPTIONS_FILE)
|
||||
|
||||
# list ip2tor subscriptions
|
||||
if 'subscriptions_ip2tor' in subs:
|
||||
for sub in subs['subscriptions_ip2tor']:
|
||||
# remember subscription under lookupindex
|
||||
lookupIndex += 1
|
||||
lookup[str(lookupIndex)] = sub
|
||||
lookup_index += 1
|
||||
lookup[str(lookup_index)] = sub
|
||||
# add to dialog choices
|
||||
if sub['active']:
|
||||
activeState = "active"
|
||||
active_state = "active"
|
||||
else:
|
||||
activeState = "in-active"
|
||||
active_state = "in-active"
|
||||
name = "IP2TOR Bridge (P:{1}) for {0}".format(sub['name'], sub['port'])
|
||||
choices.append(("{0}".format(lookupIndex), "{0} ({1})".format(name.ljust(30), activeState)))
|
||||
choices.append(("{0}".format(lookup_index), "{0} ({1})".format(name.ljust(30), active_state)))
|
||||
|
||||
# list letsencrypt subscriptions
|
||||
if 'subscriptions_letsencrypt' in subs:
|
||||
for sub in subs['subscriptions_letsencrypt']:
|
||||
# remember subscription under lookupindex
|
||||
lookupIndex += 1
|
||||
lookup[str(lookupIndex)] = sub
|
||||
lookup_index += 1
|
||||
lookup[str(lookup_index)] = sub
|
||||
# add to dialog choices
|
||||
if sub['active']:
|
||||
activeState = "active"
|
||||
active_state = "active"
|
||||
else:
|
||||
activeState = "in-active"
|
||||
active_state = "in-active"
|
||||
name = "LETSENCRYPT {0}".format(sub['id'])
|
||||
choices.append(("{0}".format(lookupIndex), "{0} ({1})".format(name.ljust(30), activeState)))
|
||||
choices.append(("{0}".format(lookup_index), "{0} ({1})".format(name.ljust(30), active_state)))
|
||||
|
||||
# show menu with options
|
||||
d = Dialog(dialog="dialog", autowidgetsize=True)
|
||||
|
@ -111,15 +114,15 @@ You have no active or inactive subscriptions.
|
|||
if code != d.OK:
|
||||
return
|
||||
|
||||
# get data of selected subscrption
|
||||
selectedSub = lookup[str(tag)]
|
||||
# get data of selected subscription
|
||||
selected_sub = lookup[str(tag)]
|
||||
|
||||
# show details of selected
|
||||
d = Dialog(dialog="dialog", autowidgetsize=True)
|
||||
d.set_background_title("My Subscriptions")
|
||||
if selectedSub['type'] == "letsencrypt-v1":
|
||||
if len(selectedSub['warning']) > 0:
|
||||
selectedSub['warning'] = "\n{0}".format(selectedSub['warning'])
|
||||
if selected_sub['type'] == "letsencrypt-v1":
|
||||
if len(selected_sub['warning']) > 0:
|
||||
selected_sub['warning'] = "\n{0}".format(selected_sub['warning'])
|
||||
text = '''
|
||||
This is a LetsEncrypt subscription using the free DNS service
|
||||
{dnsservice}
|
||||
|
@ -135,17 +138,17 @@ The state of the subscription is: {active} {warning}
|
|||
The following additional information is available:
|
||||
{description}
|
||||
|
||||
'''.format(dnsservice=selectedSub['dnsservice_type'],
|
||||
domain=selectedSub['id'],
|
||||
ip=selectedSub['ip'],
|
||||
active="ACTIVE" if selectedSub['active'] else "NOT ACTIVE",
|
||||
warning=selectedSub['warning'],
|
||||
description=selectedSub['description']
|
||||
'''.format(dnsservice=selected_sub['dnsservice_type'],
|
||||
domain=selected_sub['id'],
|
||||
ip=selected_sub['ip'],
|
||||
active="ACTIVE" if selected_sub['active'] else "NOT ACTIVE",
|
||||
warning=selected_sub['warning'],
|
||||
description=selected_sub['description']
|
||||
)
|
||||
|
||||
elif selectedSub['type'] == "ip2tor-v1":
|
||||
if len(selectedSub['warning']) > 0:
|
||||
selectedSub['warning'] = "\n{0}".format(selectedSub['warning'])
|
||||
elif selected_sub['type'] == "ip2tor-v1":
|
||||
if len(selected_sub['warning']) > 0:
|
||||
selected_sub['warning'] = "\n{0}".format(selected_sub['warning'])
|
||||
text = '''
|
||||
This is a IP2TOR subscription bought on {initdate} at
|
||||
{shop}
|
||||
|
@ -161,26 +164,26 @@ The state of the subscription is: {active} {warning}
|
|||
|
||||
The following additional information is available:
|
||||
{description}
|
||||
'''.format(initdate=selectedSub['time_created'],
|
||||
shop=selectedSub['shop'],
|
||||
publicaddress="{0}:{1}".format(selectedSub['ip'], selectedSub['port']),
|
||||
toraddress=selectedSub['tor'],
|
||||
renewhours=(round(int(selectedSub['duration']) / 3600)),
|
||||
renewsats=(round(int(selectedSub['price_extension']) / 1000)),
|
||||
totalsats=(round(int(selectedSub['price_total']) / 1000)),
|
||||
active="ACTIVE" if selectedSub['active'] else "NOT ACTIVE",
|
||||
warning=selectedSub['warning'],
|
||||
description=selectedSub['description'],
|
||||
service=selectedSub['name']
|
||||
'''.format(initdate=selected_sub['time_created'],
|
||||
shop=selected_sub['shop'],
|
||||
publicaddress="{0}:{1}".format(selected_sub['ip'], selected_sub['port']),
|
||||
toraddress=selected_sub['tor'],
|
||||
renewhours=(round(int(selected_sub['duration']) / 3600)),
|
||||
renewsats=(round(int(selected_sub['price_extension']) / 1000)),
|
||||
totalsats=(round(int(selected_sub['price_total']) / 1000)),
|
||||
active="ACTIVE" if selected_sub['active'] else "NOT ACTIVE",
|
||||
warning=selected_sub['warning'],
|
||||
description=selected_sub['description'],
|
||||
service=selected_sub['name']
|
||||
)
|
||||
else:
|
||||
text = "no text?! FIXME"
|
||||
|
||||
if selectedSub['active']:
|
||||
extraLable = "CANCEL SUBSCRIPTION"
|
||||
if selected_sub['active']:
|
||||
extra_label = "CANCEL SUBSCRIPTION"
|
||||
else:
|
||||
extraLable = "DELETE SUBSCRIPTION"
|
||||
code = d.msgbox(text, title="Subscription Detail", ok_label="Back", extra_button=True, extra_label=extraLable,
|
||||
extra_label = "DELETE SUBSCRIPTION"
|
||||
code = d.msgbox(text, title="Subscription Detail", ok_label="Back", extra_button=True, extra_label=extra_label,
|
||||
width=75, height=30)
|
||||
|
||||
# user wants to delete this subscription
|
||||
|
@ -188,15 +191,15 @@ The following additional information is available:
|
|||
# api calls when canceling
|
||||
if code == "extra":
|
||||
os.system("clear")
|
||||
if selectedSub['type'] == "letsencrypt-v1":
|
||||
if selected_sub['type'] == "letsencrypt-v1":
|
||||
cmd = "python /home/admin/config.scripts/blitz.subscriptions.letsencrypt.py subscription-cancel {0}".format(
|
||||
selectedSub['id'])
|
||||
selected_sub['id'])
|
||||
print("# running: {0}".format(cmd))
|
||||
os.system(cmd)
|
||||
time.sleep(2)
|
||||
elif selectedSub['type'] == "ip2tor-v1":
|
||||
elif selected_sub['type'] == "ip2tor-v1":
|
||||
cmd = "python /home/admin/config.scripts/blitz.subscriptions.ip2tor.py subscription-cancel {0}".format(
|
||||
selectedSub['id'])
|
||||
selected_sub['id'])
|
||||
print("# running: {0}".format(cmd))
|
||||
os.system(cmd)
|
||||
time.sleep(2)
|
||||
|
@ -205,184 +208,188 @@ The following additional information is available:
|
|||
time.sleep(3)
|
||||
|
||||
# loop until no more subscriptions or user chooses CANCEL on subscription list
|
||||
mySubscriptions()
|
||||
my_subscriptions()
|
||||
|
||||
|
||||
#######################
|
||||
# SSH MENU
|
||||
#######################
|
||||
def main():
|
||||
#######################
|
||||
# SSH MENU
|
||||
#######################
|
||||
|
||||
choices = list()
|
||||
choices.append(("LIST", "My Subscriptions"))
|
||||
choices.append(("NEW1", "+ IP2TOR Bridge (paid)"))
|
||||
choices.append(("NEW2", "+ LetsEncrypt HTTPS Domain (free)"))
|
||||
|
||||
d = Dialog(dialog="dialog", autowidgetsize=True)
|
||||
d.set_background_title("RaspiBlitz Subscriptions")
|
||||
code, tag = d.menu(
|
||||
"\nCheck existing subscriptions or create new:",
|
||||
choices=choices, width=50, height=10, title="Subscription Management")
|
||||
|
||||
# if user chosses CANCEL
|
||||
if code != d.OK:
|
||||
sys.exit(0)
|
||||
|
||||
#######################
|
||||
# MANAGE SUBSCRIPTIONS
|
||||
#######################
|
||||
|
||||
if tag == "LIST":
|
||||
mySubscriptions()
|
||||
sys.exit(0)
|
||||
|
||||
###############################
|
||||
# NEW LETSENCRYPT HTTPS DOMAIN
|
||||
###############################
|
||||
|
||||
if tag == "NEW2":
|
||||
# run creating a new IP2TOR subscription
|
||||
os.system("clear")
|
||||
cmd = "python /home/admin/config.scripts/blitz.subscriptions.letsencrypt.py create-ssh-dialog"
|
||||
print("# running: {0}".format(cmd))
|
||||
os.system(cmd)
|
||||
sys.exit(0)
|
||||
|
||||
###############################
|
||||
# NEW IP2TOR BRIDGE
|
||||
###############################
|
||||
|
||||
|
||||
if tag == "NEW1":
|
||||
|
||||
# check if Blitz is running behind TOR
|
||||
cfg.reload()
|
||||
if not cfg.run_behind_tor.value:
|
||||
Dialog(dialog="dialog", autowidgetsize=True).msgbox('''
|
||||
The IP2TOR service just makes sense if you run
|
||||
your RaspiBlitz behind TOR.
|
||||
''', title="Info")
|
||||
sys.exit(1)
|
||||
|
||||
os.system("clear")
|
||||
print("please wait ..")
|
||||
|
||||
# check for which standard services already a active bridge exists
|
||||
lnd_rest_api = False
|
||||
lnd_grpc_api = False
|
||||
lnbits = False
|
||||
btcpay = False
|
||||
try:
|
||||
if os.path.isfile(SUBSCRIPTIONS_FILE):
|
||||
os.system("sudo chown admin:admin {0}".format(SUBSCRIPTIONS_FILE))
|
||||
subs = toml.load(SUBSCRIPTIONS_FILE)
|
||||
for sub in subs['subscriptions_ip2tor']:
|
||||
if not sub['active']:
|
||||
continue
|
||||
if sub['active'] and sub['name'] == LND_REST_API:
|
||||
lnd_rest_api = True
|
||||
if sub['active'] and sub['name'] == LND_GRPC_API:
|
||||
lnd_grpc_api = True
|
||||
if sub['active'] and sub['name'] == LNBITS:
|
||||
lnbits = True
|
||||
if sub['active'] and sub['name'] == BTCPAY:
|
||||
btcpay = True
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
# check if BTCPayserver is installed
|
||||
btcPayServer = False
|
||||
statusData = subprocess.run(['/home/admin/config.scripts/bonus.btcpayserver.sh', 'status'],
|
||||
stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||
if statusData.find("installed=1") > -1:
|
||||
btcPayServer = True
|
||||
|
||||
# ask user for which RaspiBlitz service the bridge should be used
|
||||
choices = list()
|
||||
choices.append(("REST", "LND REST API {0}".format("--> ALREADY BRIDGED" if lnd_rest_api else "")))
|
||||
choices.append(("GRPC", "LND gRPC API {0}".format("--> ALREADY BRIDGED" if lnd_grpc_api else "")))
|
||||
if cfg.lnbits:
|
||||
choices.append(("LNBITS", "LNbits Webinterface {0}".format("--> ALREADY BRIDGED" if lnd_grpc_api else "")))
|
||||
if btcPayServer:
|
||||
choices.append(("BTCPAY", "BTCPay Server Webinterface {0}".format("--> ALREADY BRIDGED" if btcpay else "")))
|
||||
choices.append(("SELF", "Create a custom IP2TOR Bridge"))
|
||||
choices.append(("LIST", "My Subscriptions"))
|
||||
choices.append(("NEW1", "+ IP2TOR Bridge (paid)"))
|
||||
choices.append(("NEW2", "+ LetsEncrypt HTTPS Domain (free)"))
|
||||
|
||||
d = Dialog(dialog="dialog", autowidgetsize=True)
|
||||
d.set_background_title("RaspiBlitz Subscriptions")
|
||||
code, tag = d.menu(
|
||||
"\nChoose RaspiBlitz Service to create Bridge for:",
|
||||
choices=choices, width=60, height=10, title="Select Service")
|
||||
"\nCheck existing subscriptions or create new:",
|
||||
choices=choices, width=50, height=10, title="Subscription Management")
|
||||
|
||||
# if user chosses CANCEL
|
||||
if code != d.OK:
|
||||
sys.exit(0)
|
||||
|
||||
servicename = None
|
||||
torAddress = None
|
||||
torPort = None
|
||||
if tag == "REST":
|
||||
# get TOR address for REST
|
||||
servicename = LND_REST_API
|
||||
torAddress = subprocess.run(['sudo', 'cat', '/mnt/hdd/tor/lndrest8080/hostname'],
|
||||
stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||
torPort = 8080
|
||||
if tag == "GRPC":
|
||||
# get TOR address for GRPC
|
||||
servicename = LND_GRPC_API
|
||||
torAddress = subprocess.run(['sudo', 'cat', '/mnt/hdd/tor/lndrpc10009/hostname'],
|
||||
stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||
torPort = 10009
|
||||
if tag == "LNBITS":
|
||||
# get TOR address for LNBits
|
||||
servicename = LNBITS
|
||||
torAddress = subprocess.run(['sudo', 'cat', '/mnt/hdd/tor/lnbits/hostname'],
|
||||
stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||
torPort = 443
|
||||
if tag == "BTCPAY":
|
||||
# get TOR address for BTCPAY
|
||||
servicename = BTCPAY
|
||||
torAddress = subprocess.run(['sudo', 'cat', '/mnt/hdd/tor/btcpay/hostname'],
|
||||
stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||
torPort = 443
|
||||
if tag == "SELF":
|
||||
servicename = "CUSTOM"
|
||||
try:
|
||||
# get custom TOR address
|
||||
code, text = d.inputbox(
|
||||
"Enter TOR Onion-Address:",
|
||||
height=10, width=60, init="",
|
||||
title="IP2TOR Bridge Target")
|
||||
text = text.strip()
|
||||
os.system("clear")
|
||||
if code != d.OK:
|
||||
sys.exit(0)
|
||||
if len(text) == 0:
|
||||
sys.exit(0)
|
||||
if text.find('.onion') < 0 or text.find(' ') > 0:
|
||||
print("Not a TOR Onion Address")
|
||||
time.sleep(3)
|
||||
sys.exit(0)
|
||||
torAddress = text
|
||||
# get custom TOR port
|
||||
code, text = d.inputbox(
|
||||
"Enter TOR Port Number:",
|
||||
height=10, width=40, init="80",
|
||||
title="IP2TOR Bridge Target")
|
||||
text = text.strip()
|
||||
os.system("clear")
|
||||
if code != d.OK:
|
||||
sys.exit(0)
|
||||
if len(text) == 0:
|
||||
sys.exit(0)
|
||||
torPort = int(text)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
time.sleep(3)
|
||||
#######################
|
||||
# MANAGE SUBSCRIPTIONS
|
||||
#######################
|
||||
|
||||
if tag == "LIST":
|
||||
my_subscriptions()
|
||||
sys.exit(0)
|
||||
|
||||
###############################
|
||||
# NEW LETSENCRYPT HTTPS DOMAIN
|
||||
###############################
|
||||
|
||||
if tag == "NEW2":
|
||||
# run creating a new IP2TOR subscription
|
||||
os.system("clear")
|
||||
cmd = "python /home/admin/config.scripts/blitz.subscriptions.letsencrypt.py create-ssh-dialog"
|
||||
print("# running: {0}".format(cmd))
|
||||
os.system(cmd)
|
||||
sys.exit(0)
|
||||
|
||||
###############################
|
||||
# NEW IP2TOR BRIDGE
|
||||
###############################
|
||||
|
||||
if tag == "NEW1":
|
||||
|
||||
# check if Blitz is running behind TOR
|
||||
cfg.reload()
|
||||
if not cfg.run_behind_tor.value:
|
||||
Dialog(dialog="dialog", autowidgetsize=True).msgbox('''
|
||||
The IP2TOR service just makes sense if you run
|
||||
your RaspiBlitz behind TOR.
|
||||
''', title="Info")
|
||||
sys.exit(1)
|
||||
|
||||
# run creating a new IP2TOR subscription
|
||||
os.system("clear")
|
||||
cmd = "python /home/admin/config.scripts/blitz.subscriptions.ip2tor.py create-ssh-dialog {0} {1} {2}".format(
|
||||
servicename, torAddress, torPort)
|
||||
print("# running: {0}".format(cmd))
|
||||
os.system(cmd)
|
||||
sys.exit(0)
|
||||
os.system("clear")
|
||||
print("please wait ..")
|
||||
|
||||
# check for which standard services already a active bridge exists
|
||||
lnd_rest_api = False
|
||||
lnd_grpc_api = False
|
||||
lnbits = False
|
||||
btcpay = False
|
||||
try:
|
||||
if os.path.isfile(SUBSCRIPTIONS_FILE):
|
||||
os.system("sudo chown admin:admin {0}".format(SUBSCRIPTIONS_FILE))
|
||||
subs = toml.load(SUBSCRIPTIONS_FILE)
|
||||
for sub in subs['subscriptions_ip2tor']:
|
||||
if not sub['active']:
|
||||
continue
|
||||
if sub['active'] and sub['name'] == SERVICE_LND_REST_API:
|
||||
lnd_rest_api = True
|
||||
if sub['active'] and sub['name'] == SERVICE_LND_GRPC_API:
|
||||
lnd_grpc_api = True
|
||||
if sub['active'] and sub['name'] == SERVICE_LNBITS:
|
||||
lnbits = True
|
||||
if sub['active'] and sub['name'] == SERVICE_BTCPAY:
|
||||
btcpay = True
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
# check if BTCPayServer is installed
|
||||
btc_pay_server = False
|
||||
status_data = subprocess.run(['/home/admin/config.scripts/bonus.btcpayserver.sh', 'status'],
|
||||
stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||
if status_data.find("installed=1") > -1:
|
||||
btc_pay_server = True
|
||||
|
||||
# ask user for which RaspiBlitz service the bridge should be used
|
||||
choices = list()
|
||||
choices.append(("REST", "LND REST API {0}".format("--> ALREADY BRIDGED" if lnd_rest_api else "")))
|
||||
choices.append(("GRPC", "LND gRPC API {0}".format("--> ALREADY BRIDGED" if lnd_grpc_api else "")))
|
||||
if cfg.lnbits:
|
||||
choices.append(("LNBITS", "LNbits Webinterface {0}".format("--> ALREADY BRIDGED" if lnbits else "")))
|
||||
if btc_pay_server:
|
||||
choices.append(("BTCPAY", "BTCPay Server Webinterface {0}".format("--> ALREADY BRIDGED" if btcpay else "")))
|
||||
choices.append(("SELF", "Create a custom IP2TOR Bridge"))
|
||||
|
||||
d = Dialog(dialog="dialog", autowidgetsize=True)
|
||||
d.set_background_title("RaspiBlitz Subscriptions")
|
||||
code, tag = d.menu(
|
||||
"\nChoose RaspiBlitz Service to create Bridge for:",
|
||||
choices=choices, width=60, height=10, title="Select Service")
|
||||
|
||||
# if user chosses CANCEL
|
||||
if code != d.OK:
|
||||
sys.exit(0)
|
||||
|
||||
service_name = None
|
||||
tor_address = None
|
||||
tor_port = None
|
||||
if tag == "REST":
|
||||
# get TOR address for REST
|
||||
service_name = SERVICE_LND_REST_API
|
||||
tor_address = subprocess.run(['sudo', 'cat', '/mnt/hdd/tor/lndrest8080/hostname'],
|
||||
stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||
tor_port = 8080
|
||||
if tag == "GRPC":
|
||||
# get TOR address for GRPC
|
||||
service_name = SERVICE_LND_GRPC_API
|
||||
tor_address = subprocess.run(['sudo', 'cat', '/mnt/hdd/tor/lndrpc10009/hostname'],
|
||||
stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||
tor_port = 10009
|
||||
if tag == "LNBITS":
|
||||
# get TOR address for LNBits
|
||||
service_name = SERVICE_LNBITS
|
||||
tor_address = subprocess.run(['sudo', 'cat', '/mnt/hdd/tor/lnbits/hostname'],
|
||||
stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||
tor_port = 443
|
||||
if tag == "BTCPAY":
|
||||
# get TOR address for BTCPAY
|
||||
service_name = SERVICE_BTCPAY
|
||||
tor_address = subprocess.run(['sudo', 'cat', '/mnt/hdd/tor/btcpay/hostname'],
|
||||
stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||
tor_port = 443
|
||||
if tag == "SELF":
|
||||
service_name = "CUSTOM"
|
||||
try:
|
||||
# get custom TOR address
|
||||
code, text = d.inputbox(
|
||||
"Enter TOR Onion-Address:",
|
||||
height=10, width=60, init="",
|
||||
title="IP2TOR Bridge Target")
|
||||
text = text.strip()
|
||||
os.system("clear")
|
||||
if code != d.OK:
|
||||
sys.exit(0)
|
||||
if len(text) == 0:
|
||||
sys.exit(0)
|
||||
if text.find('.onion') < 0 or text.find(' ') > 0:
|
||||
print("Not a TOR Onion Address")
|
||||
time.sleep(3)
|
||||
sys.exit(0)
|
||||
tor_address = text
|
||||
# get custom TOR port
|
||||
code, text = d.inputbox(
|
||||
"Enter TOR Port Number:",
|
||||
height=10, width=40, init="80",
|
||||
title="IP2TOR Bridge Target")
|
||||
text = text.strip()
|
||||
os.system("clear")
|
||||
if code != d.OK:
|
||||
sys.exit(0)
|
||||
if len(text) == 0:
|
||||
sys.exit(0)
|
||||
tor_port = int(text)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
time.sleep(3)
|
||||
sys.exit(1)
|
||||
|
||||
# run creating a new IP2TOR subscription
|
||||
os.system("clear")
|
||||
cmd = "python /home/admin/config.scripts/blitz.subscriptions.ip2tor.py create-ssh-dialog {0} {1} {2}".format(
|
||||
service_name, tor_address, tor_port)
|
||||
print("# running: {0}".format(cmd))
|
||||
os.system(cmd)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -128,6 +128,9 @@ elif [ "$1" = "1" ] || [ "$1" = "on" ]; then
|
|||
sudo systemctl enable nginx
|
||||
sudo systemctl start nginx
|
||||
|
||||
# create nginx app-data dir
|
||||
sudo mkdir /mnt/hdd/app-data/nginx/ 2>/dev/null
|
||||
|
||||
# general nginx settings
|
||||
if ! grep -Eq '^\s*server_names_hash_bucket_size.*$' /etc/nginx/nginx.conf; then
|
||||
# ToDo(frennkie) verify this
|
||||
|
@ -135,10 +138,22 @@ elif [ "$1" = "1" ] || [ "$1" = "on" ]; then
|
|||
fi
|
||||
|
||||
if [ ! -f /etc/ssl/certs/dhparam.pem ]; then
|
||||
#can take 5-10+ minutes on a Raspberry Pi 3
|
||||
echo "Running \"sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048\" next."
|
||||
echo "This can take 5-10 minutes on a Raspberry Pi 3 - please be patient!"
|
||||
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
|
||||
|
||||
# check if there is a user generated dhparam.pem on the HDD to use
|
||||
userFileExists=$(sudo ls /mnt/hdd/app-data/nginx/dhparam.pem 2>/dev/null | grep -c dhparam.pem)
|
||||
if [ ${userFileExists} -eq 0 ]; then
|
||||
# generate dhparam.pem - can take +10 minutes on a Raspberry Pi
|
||||
echo "Generating a complete new dhparam.pem"
|
||||
echo "Running \"sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048\" next."
|
||||
echo "This can take 5-10 minutes on a Raspberry Pi 3 - please be patient!"
|
||||
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
|
||||
sudo cp /etc/ssl/certs/dhparam.pem /mnt/hdd/app-data/nginx/dhparam.pem
|
||||
else
|
||||
# just copy the already user generated dhparam.pem into nginx
|
||||
echo "Copying the user generetad /mnt/hdd/app-data/nginx/dhparam.pem"
|
||||
sudo cp /mnt/hdd/app-data/nginx/dhparam.pem /etc/ssl/certs/dhparam.pem
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
sudo cp /home/admin/assets/nginx/snippets/* /etc/nginx/snippets/
|
||||
|
@ -178,8 +193,7 @@ elif [ "$1" = "1" ] || [ "$1" = "on" ]; then
|
|||
sudo apt-get install -y python3-jinja2
|
||||
sudo -H python3 -m pip install j2cli
|
||||
|
||||
# create nginx app-data dir and use LND cert by default
|
||||
sudo mkdir /mnt/hdd/app-data/nginx/ 2>/dev/null
|
||||
# use LND cert by default
|
||||
sudo ln -sf /mnt/hdd/lnd/tls.cert /mnt/hdd/app-data/nginx/tls.cert
|
||||
sudo ln -sf /mnt/hdd/lnd/tls.key /mnt/hdd/app-data/nginx/tls.key
|
||||
sudo ln -sf /mnt/hdd/lnd/tls.cert /mnt/hdd/app-data/nginx/tor_tls.cert
|
||||
|
|
|
@ -229,7 +229,7 @@ EOF
|
|||
# Hidden Service for BTC-RPC-explorer if Tor is active
|
||||
source /mnt/hdd/raspiblitz.conf
|
||||
if [ "${runBehindTor}" = "on" ]; then
|
||||
echo "# Creating Tor Hidden Service"
|
||||
# make sure to keep in sync with internet.tor.sh script
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh btc-rpc-explorer 80 3022 443 3023
|
||||
fi
|
||||
exit 0
|
||||
|
@ -261,6 +261,7 @@ if [ "$1" = "0" ] || [ "$1" = "off" ]; then
|
|||
|
||||
# Hidden Service if Tor is active
|
||||
if [ "${runBehindTor}" = "on" ]; then
|
||||
# make sure to keep in sync with internet.tor.sh script
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh off btc-rpc-explorer
|
||||
fi
|
||||
|
||||
|
|
|
@ -14,8 +14,12 @@ source /mnt/hdd/raspiblitz.conf
|
|||
source /home/admin/raspiblitz.info
|
||||
|
||||
if [ "$1" = "status" ]; then
|
||||
|
||||
if [ "${BTCPayServer}" = "on" ]; then
|
||||
echo "installed=1"
|
||||
|
||||
echo "switchedon=1"
|
||||
isInstalled=$(sudo ls /etc/systemd/system/btcpayserver.service 2>/dev/null | grep -c 'btcpayserver.service')
|
||||
echo "installed=${isInstalled}"
|
||||
|
||||
localIP=$(ip addr | grep 'state UP' -A2 | egrep -v 'docker0' | grep 'eth0\|wlan0' | tail -n1 | awk '{print $2}' | cut -f1 -d'/')
|
||||
echo "localIP='${localIP}'"
|
||||
|
@ -61,6 +65,7 @@ if [ "$1" = "status" ]; then
|
|||
fi
|
||||
|
||||
else
|
||||
echo "switchedon=0"
|
||||
echo "installed=0"
|
||||
fi
|
||||
exit 0
|
||||
|
@ -73,6 +78,17 @@ if [ "$1" = "menu" ]; then
|
|||
echo "# collecting status info ... (please wait)"
|
||||
source <(sudo /home/admin/config.scripts/bonus.btcpayserver.sh status)
|
||||
|
||||
if [ ${switchedon} -eq 0 ]; then
|
||||
whiptail --title " BTCPay Server " --msgbox "BTCPay Server is not activated." 7 36
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ${installed} -eq 0 ]; then
|
||||
whiptail --title " BTCPay Server " --msgbox "BTCPay Server needs to be re-installed.\nPress OK to start process." 8 45
|
||||
/home/admin/config.scripts/bonus.btcpayserver.sh on
|
||||
exit 0
|
||||
fi
|
||||
|
||||
text="Local Webrowser: https://${localIP}:${httpsPort}"
|
||||
|
||||
if [ ${#publicDomain} -gt 0 ]; then
|
||||
|
@ -162,7 +178,10 @@ BTC.lightning=type=lnd-rest;server=https://127.0.0.1:8080/;macaroonfilepath=/hom
|
|||
s="BTC.lightning=type=lnd-rest\;server=https\://127.0.0.1:8080/\;macaroonfilepath=/home/btcpay/admin.macaroon\;"
|
||||
sudo -u btcpay sed -i "s|^${s}certthumbprint=.*|${s}certthumbprint=$FINGERPRINT|g" /home/btcpay/.btcpayserver/Main/settings.config
|
||||
fi
|
||||
sudo systemctl restart btcpayserver
|
||||
|
||||
if [ "${state}" == "ready" ]; then
|
||||
sudo systemctl restart btcpayserver
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
@ -197,8 +216,7 @@ if [ "$1" = "1" ] || [ "$1" = "on" ]; then
|
|||
|
||||
# Hidden Service for BTCPay if Tor is active
|
||||
if [ "${runBehindTor}" = "on" ]; then
|
||||
# correct old Hidden Service with port
|
||||
sudo sed -i "s/^HiddenServicePort 80 127.0.0.1:23000/HiddenServicePort 80 127.0.0.1:23002/g" /etc/tor/torrc
|
||||
# make sure to keep in sync with internet.tor.sh script
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh btcpay 80 23002 443 23003
|
||||
fi
|
||||
|
||||
|
@ -322,7 +340,6 @@ if [ "$1" = "1" ] || [ "$1" = "on" ]; then
|
|||
# from the build.sh with path
|
||||
sudo -u btcpay /home/btcpay/dotnet/dotnet build -c Release NBXplorer/NBXplorer.csproj
|
||||
|
||||
|
||||
# create nbxplorer service
|
||||
echo "
|
||||
[Unit]
|
||||
|
@ -350,26 +367,27 @@ WantedBy=multi-user.target
|
|||
sudo systemctl daemon-reload
|
||||
# start to create settings.config
|
||||
sudo systemctl enable nbxplorer
|
||||
sudo systemctl start nbxplorer
|
||||
#sudo systemctl start nbxplorer
|
||||
|
||||
echo "Checking for nbxplorer config"
|
||||
while [ ! -f "/home/btcpay/.nbxplorer/Main/settings.config" ]
|
||||
do
|
||||
echo "Waiting for nbxplorer to start - CTRL+C to abort"
|
||||
sleep 10
|
||||
hasFailed=$(sudo systemctl status nbxplorer | grep -c "Active: failed")
|
||||
if [ ${hasFailed} -eq 1 ]; then
|
||||
echo "seems like starting nbxplorer service has failed - see: systemctl status nbxplorer"
|
||||
echo "maybe report here: https://github.com/rootzoll/raspiblitz/issues/214"
|
||||
fi
|
||||
done
|
||||
#echo "Checking for nbxplorer config"
|
||||
#while [ ! -f "/home/btcpay/.nbxplorer/Main/settings.config" ]
|
||||
# do
|
||||
# echo "Waiting for nbxplorer to start - CTRL+C to abort"
|
||||
# sleep 10
|
||||
# hasFailed=$(sudo systemctl status nbxplorer | grep -c "Active: failed")
|
||||
# if [ ${hasFailed} -eq 1 ]; then
|
||||
# echo "seems like starting nbxplorer service has failed - see: systemctl status nbxplorer"
|
||||
# echo "maybe report here: https://github.com/rootzoll/raspiblitz/issues/214"
|
||||
# fi
|
||||
#done
|
||||
|
||||
echo ""
|
||||
echo "***"
|
||||
echo "getting RPC credentials from the bitcoin.conf"
|
||||
RPC_USER=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep rpcuser | cut -c 9-)
|
||||
PASSWORD_B=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep rpcpassword | cut -c 13-)
|
||||
sudo mv /home/btcpay/.nbxplorer/Main/settings.config /home/btcpay/.nbxplorer/Main/settings.config.backup
|
||||
#sudo mv /home/btcpay/.nbxplorer/Main/settings.config /home/btcpay/.nbxplorer/Main/settings.config.backup
|
||||
sudo -u btcpay mkdir -p /home/btcpay/.nbxplorer/Main
|
||||
touch /home/admin/settings.config
|
||||
sudo chmod 600 /home/admin/settings.config || exit 1
|
||||
cat >> /home/admin/settings.config <<EOF
|
||||
|
@ -379,7 +397,14 @@ EOF
|
|||
|
||||
sudo mv /home/admin/settings.config /home/btcpay/.nbxplorer/Main/settings.config
|
||||
sudo chown btcpay:btcpay /home/btcpay/.nbxplorer/Main/settings.config
|
||||
sudo systemctl restart nbxplorer
|
||||
#sudo systemctl restart nbxplorer
|
||||
|
||||
if [ "${state}" == "ready" ]; then
|
||||
echo "Starting nbxplorer"
|
||||
sudo systemctl start nbxplorer
|
||||
else
|
||||
echo "Because the system is not 'ready' the service 'nbxplorer' will not be started at this point .. its enabled and will start on next reboot"
|
||||
fi
|
||||
|
||||
# BTCPayServer
|
||||
echo ""
|
||||
|
@ -420,28 +445,39 @@ WantedBy=multi-user.target
|
|||
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable btcpayserver
|
||||
sudo systemctl start btcpayserver
|
||||
|
||||
echo "Checking for btcpayserver config"
|
||||
while [ ! -f "/home/btcpay/.btcpayserver/Main/settings.config" ]
|
||||
do
|
||||
echo "Waiting for btcpayserver to start - CTRL+C to abort"
|
||||
sleep 10
|
||||
hasFailed=$(sudo systemctl status btcpayserver | grep -c "Active: failed")
|
||||
if [ ${hasFailed} -eq 1 ]; then
|
||||
echo "seems like starting btcpayserver service has failed - see: systemctl status btcpayserver"
|
||||
echo "maybe report here: https://github.com/rootzoll/raspiblitz/issues/214"
|
||||
fi
|
||||
done
|
||||
if [ "${state}" == "ready" ]; then
|
||||
echo "Starting btcpayserver"
|
||||
sudo systemctl start btcpayserver
|
||||
else
|
||||
echo "Because the system is not 'ready' the service 'btcpayserver' will not be started at this point .. its enabled and will start on next reboot"
|
||||
fi
|
||||
|
||||
#echo "Checking for btcpayserver config"
|
||||
#while [ ! -f "/home/btcpay/.btcpayserver/Main/settings.config" ]
|
||||
# do
|
||||
# echo "Waiting for btcpayserver to start - CTRL+C to abort"
|
||||
# sleep 10
|
||||
# hasFailed=$(sudo systemctl status btcpayserver | grep -c "Active: failed")
|
||||
# if [ ${hasFailed} -eq 1 ]; then
|
||||
# echo "seems like starting btcpayserver service has failed - see: systemctl status btcpayserver"
|
||||
# echo "maybe report here: https://github.com/rootzoll/raspiblitz/issues/214"
|
||||
# fi
|
||||
#done
|
||||
sudo -u btcpay mkdir -p /home/btcpay/.btcpayserver/Main/
|
||||
|
||||
/home/admin/config.scripts/bonus.btcpayserver.sh write-tls-macaroon
|
||||
|
||||
else
|
||||
echo "BTCPay Server is already installed."
|
||||
# start service
|
||||
echo "start service"
|
||||
sudo systemctl start nbxplorer 2>/dev/null
|
||||
sudo systemctl start btcpayserver 2>/dev/null
|
||||
|
||||
if [ "${state}" == "ready" ]; then
|
||||
# start service
|
||||
echo "start service"
|
||||
sudo systemctl start nbxplorer 2>/dev/null
|
||||
sudo systemctl start btcpayserver 2>/dev/null
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# setting value in raspi blitz config
|
||||
|
|
|
@ -239,10 +239,8 @@ EOF
|
|||
# Hidden Service for SERVICE if Tor is active
|
||||
source /mnt/hdd/raspiblitz.conf
|
||||
if [ "${runBehindTor}" = "on" ]; then
|
||||
echo "# --> correct old Hidden Service with port"
|
||||
sudo sed -i "s/^HiddenServicePort 25441 127.0.0.1:25441/HiddenServicePort 80 127.0.0.1:25441/g" /etc/tor/torrc
|
||||
sudo sed -i "s/^HiddenServicePort 25441 127.0.0.1:80/HiddenServicePort 443 127.0.0.1:25441/g" /etc/tor/torrc
|
||||
# port 25441 is HTTPS with self-signed cert
|
||||
# make sure to keep in sync with internet.tor.sh script
|
||||
# port 25441 is HTTPS with self-signed cert - specte only makes sense to be served over HTTPS
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh cryptoadvance-specter 443 25441
|
||||
fi
|
||||
exit 0
|
||||
|
|
|
@ -453,6 +453,7 @@ WantedBy=multi-user.target
|
|||
|
||||
# Hidden Service for electrs if Tor active
|
||||
if [ "${runBehindTor}" = "on" ]; then
|
||||
# make sure to keep in sync with internet.tor.sh script
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh electrs 50002 50002 50001 50001
|
||||
fi
|
||||
|
||||
|
|
|
@ -105,11 +105,6 @@ function acme_install() {
|
|||
|
||||
function refresh_certs_with_nginx() {
|
||||
|
||||
if [ ! -d "${ACME_CERT_HOME}" ]; then
|
||||
echo "# no cert directory to link: ${ACME_CERT_HOME}"
|
||||
return
|
||||
fi
|
||||
|
||||
# FIRST: SET ALL TO DEFAULT SELF SIGNED
|
||||
|
||||
echo "# default IP certs"
|
||||
|
@ -126,6 +121,11 @@ function refresh_certs_with_nginx() {
|
|||
|
||||
# SECOND: SET LETSENCRPYT CERTS FOR SUBSCRIPTIONS
|
||||
|
||||
if [ "${letsencrypt}" != "on" ]; then
|
||||
echo "# lets encrypt is off - so no certs replacements"
|
||||
return
|
||||
fi
|
||||
|
||||
certsDirectories=$(sudo ls ${ACME_CERT_HOME})
|
||||
directoryArray=(`echo "${certsDirectories}" | tr ' ' ' '`)
|
||||
for i in "${directoryArray[@]}"; do
|
||||
|
|
|
@ -184,7 +184,13 @@ if [ "$1" = "1" ] || [ "$1" = "on" ]; then
|
|||
cd /home/lnbits
|
||||
sudo -u lnbits git clone https://github.com/lnbits/lnbits.git
|
||||
cd /home/lnbits/lnbits
|
||||
sudo -u lnbits git checkout tags/raspiblitz
|
||||
if [ "$2" == "master" ]; then
|
||||
echo "# checking out master branch"
|
||||
sudo -u lnbits git checkout
|
||||
else
|
||||
echo "# checking out tag 'raspiblitz'"
|
||||
sudo -u lnbits git checkout tags/raspiblitz
|
||||
fi
|
||||
|
||||
# prepare .env file
|
||||
echo "# preparing env file"
|
||||
|
@ -246,7 +252,14 @@ WantedBy=multi-user.target
|
|||
EOF
|
||||
|
||||
sudo systemctl enable lnbits
|
||||
echo "# OK - service needs starting: sudo systemctl start lnbits"
|
||||
|
||||
source /home/admin/raspiblitz.info
|
||||
if [ "${state}" == "ready" ]; then
|
||||
echo "# OK - lnbits service is enabled, system is on ready so starting lnbits service"
|
||||
sudo systemctl start lnbits
|
||||
else
|
||||
echo "# OK - lnbits service is enabled, but needs reboot or manual starting: sudo systemctl start lnbits"
|
||||
fi
|
||||
|
||||
else
|
||||
echo "LNbits already installed."
|
||||
|
@ -274,6 +287,7 @@ EOF
|
|||
# Hidden Service if Tor is active
|
||||
source /mnt/hdd/raspiblitz.conf
|
||||
if [ "${runBehindTor}" = "on" ]; then
|
||||
# make sure to keep in sync with internet.tor.sh script
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh lnbits 80 5002 443 5003
|
||||
fi
|
||||
exit 0
|
||||
|
|
|
@ -200,8 +200,7 @@ EOF
|
|||
|
||||
# Hidden Service for RTL if Tor is active
|
||||
if [ "${runBehindTor}" = "on" ]; then
|
||||
echo "# Creating Tor Hidden Service"
|
||||
sudo sed -i "s/^HiddenServicePort 80 127.0.0.1:3000/HiddenServicePort 80 127.0.0.1:3002/g" /etc/tor/torrc
|
||||
# make sure to keep in sync with internet.tor.sh script
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh RTL 80 3002 443 3003
|
||||
fi
|
||||
exit 0
|
||||
|
|
|
@ -229,8 +229,7 @@ EOF
|
|||
|
||||
# Hidden Service for thunderhub if Tor is active
|
||||
if [ "${runBehindTor}" = "on" ]; then
|
||||
# correct old Hidden Service with port
|
||||
sudo sed -i "s/^HiddenServicePort 80 127.0.0.1:3001/HiddenServicePort 80 127.0.0.1:3012/g" /etc/tor/torrc
|
||||
# make sure to keep in sync with internet.tor.sh script
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh thunderhub 80 3012 443 3013
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -15,17 +15,24 @@ source /mnt/hdd/raspiblitz.conf
|
|||
|
||||
# delete a hidden service
|
||||
if [ "$1" == "off" ]; then
|
||||
|
||||
service="$2"
|
||||
if [ ${#service} -eq 0 ]; then
|
||||
echo "ERROR: service name is missing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# remove service paragraph
|
||||
sudo sed -i "/# Hidden Service for ${service}/,/^\s*$/{d}" /etc/tor/torrc
|
||||
# remove double lines
|
||||
awk 'NF > 0 {blank=0} NF == 0 {blank++} blank < 2' /etc/tor/torrc > .tmp && sudo mv .tmp /etc/tor/torrc
|
||||
|
||||
echo "# OK service is removed - restarting TOR ..."
|
||||
sudo chmod 644 /etc/tor/torrc
|
||||
sudo systemctl restart tor
|
||||
sleep 10
|
||||
echo "# Done"
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
service="$1"
|
||||
|
@ -59,38 +66,36 @@ if [ ${#toPort2} -gt 0 ]; then
|
|||
fi
|
||||
|
||||
if [ "${runBehindTor}" = "on" ]; then
|
||||
#check if the service is already present
|
||||
isHiddenService=$(sudo cat /etc/tor/torrc 2>/dev/null | grep -c $service)
|
||||
if [ ${isHiddenService} -eq 0 ]; then
|
||||
#check if the port is already forwarded
|
||||
alreadyThere=$(sudo cat /etc/tor/torrc 2>/dev/null | grep -c "\b127.0.0.1:$fromPort\b")
|
||||
if [ ${alreadyThere} -gt 0 ]; then
|
||||
echo "The port $fromPort is already forwarded. Check /etc/tor/torrc for the details."
|
||||
exit 1
|
||||
fi
|
||||
echo "
|
||||
|
||||
# delete any old entry for that servive
|
||||
sudo sed -i "/# Hidden Service for ${service}/,/^\s*$/{d}" /etc/tor/torrc
|
||||
|
||||
# make new entry for that service
|
||||
echo "
|
||||
# Hidden Service for $service
|
||||
HiddenServiceDir /mnt/hdd/tor/$service
|
||||
HiddenServiceVersion 3
|
||||
HiddenServicePort $toPort 127.0.0.1:$fromPort" | sudo tee -a /etc/tor/torrc
|
||||
# remove double lines
|
||||
sudo awk 'NF > 0 {blank=0} NF == 0 {blank++} blank < 2' /etc/tor/torrc > /mnt/hdd/temp/tmp && sudo mv /mnt/hdd/temp/tmp /etc/tor/torrc
|
||||
|
||||
# check and insert second port pair
|
||||
if [ ${#toPort2} -gt 0 ]; then
|
||||
alreadyThere=$(sudo cat /etc/tor/torrc 2>/dev/null | grep -c "\b127.0.0.1:$fromPort2\b")
|
||||
if [ ${alreadyThere} -gt 0 ]; then
|
||||
echo "The port $fromPort2 is already forwarded. Check the /etc/tor/torrc for the details."
|
||||
else
|
||||
echo "HiddenServicePort $toPort2 127.0.0.1:$fromPort2" | sudo tee -a /etc/tor/torrc
|
||||
fi
|
||||
# check and insert second port pair
|
||||
if [ ${#toPort2} -gt 0 ]; then
|
||||
alreadyThere=$(sudo cat /etc/tor/torrc 2>/dev/null | grep -c "\b127.0.0.1:$fromPort2\b")
|
||||
if [ ${alreadyThere} -gt 0 ]; then
|
||||
echo "The port $fromPort2 is already forwarded. Check the /etc/tor/torrc for the details."
|
||||
else
|
||||
echo "HiddenServicePort $toPort2 127.0.0.1:$fromPort2" | sudo tee -a /etc/tor/torrc
|
||||
fi
|
||||
# restart tor
|
||||
echo ""
|
||||
echo "Restarting Tor to activate the Hidden Service..."
|
||||
sudo systemctl restart tor
|
||||
sleep 10
|
||||
else
|
||||
echo "The Hidden Service for $service is already installed."
|
||||
fi
|
||||
|
||||
# restart tor
|
||||
echo ""
|
||||
echo "Restarting Tor to activate the Hidden Service..."
|
||||
sudo chmod 644 /etc/tor/torrc
|
||||
sudo systemctl restart tor
|
||||
sleep 10
|
||||
|
||||
# show the Hidden Service address
|
||||
TOR_ADDRESS=$(sudo cat /mnt/hdd/tor/$service/hostname)
|
||||
if [ -z "$TOR_ADDRESS" ]; then
|
||||
|
@ -106,13 +111,10 @@ HiddenServicePort $toPort 127.0.0.1:$fromPort" | sudo tee -a /etc/tor/torrc
|
|||
echo "The Tor Hidden Service address for $service is:"
|
||||
echo "$TOR_ADDRESS"
|
||||
echo "use with the port: $toPort"
|
||||
echo ""
|
||||
if [ ${#toPort2} -gt 0 ]; then
|
||||
alreadyThere=$(sudo cat /etc/tor/torrc 2>/dev/null | grep -c "\b127.0.0.1:$fromPort2\b")
|
||||
if [ ${alreadyThere} -eq 0 ]; then
|
||||
wasAdded=$(sudo cat /etc/tor/torrc 2>/dev/null | grep -c "\b127.0.0.1:$fromPort2\b")
|
||||
if [ ${wasAdded} -gt 0 ]; then
|
||||
echo "or the port: $toPort2"
|
||||
else
|
||||
echo "The port $fromPort2 is forwarded for another Hidden Service. Check the /etc/tor/torrc for the details."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
|
|
|
@ -365,16 +365,23 @@ EOF
|
|||
/home/admin/config.scripts/internet.hiddenservice.sh btc-rpc-explorer 80 3002
|
||||
fi
|
||||
if [ "${rtlWebinterface}" = "on" ]; then
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh RTL 80 3000
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh RTL 80 3002 443 3003
|
||||
fi
|
||||
if [ "${BTCPayServer}" = "on" ]; then
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh btcpay 80 23000
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh btcpay 80 23002 443 23003
|
||||
fi
|
||||
if [ "${ElectRS}" = "on" ]; then
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh electrs 50002 50002 50001 50001
|
||||
fi
|
||||
if [ "${LNBits}" = "on" ]; then
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh lnbits 80 5000
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh lnbits 80 5002 443 5003
|
||||
fi
|
||||
if [ "${thunderhub}" = "on" ]; then
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh thunderhub 80 3012 443 3013
|
||||
fi
|
||||
if [ "${specter}" = "on" ]; then
|
||||
# specter makes only sense to be served over https
|
||||
/home/admin/config.scripts/internet.hiddenservice.sh cryptoadvance-specter 443 25441
|
||||
fi
|
||||
|
||||
echo "OK - TOR is now ON"
|
||||
|
|
Loading…
Add table
Reference in a new issue