Make TOR optional, add info in welcome page, ability for notifier to bypass

This commit is contained in:
kexkey
2019-11-08 16:03:14 -05:00
committed by kexkey
parent 477c93468f
commit 58b80e1d3b
16 changed files with 130 additions and 27 deletions

View File

@@ -6,5 +6,9 @@
{
"name": "Opentimestamps client",
"value": "otsclient"
},
{
"name": "Tor Hidden Service/Gateway",
"value": "tor"
}
]

View File

@@ -466,6 +466,13 @@ module.exports = class App {
const optional_features = [];
const optional_features_data = {
tor: {
networks: ['cyphernodenet', 'cyphernodeappsnet'],
docker: "cyphernode/tor:" + this.config.docker_versions['cyphernode/tor'],
extra: {
hostname: 'tor_hostname_placeholder',
}
},
otsclient: {
docker: "cyphernode/otsclient:" + this.config.docker_versions['cyphernode/otsclient']
},

View File

@@ -19,6 +19,6 @@ module.exports = {
];
},
templates: function( props ) {
return [ 'torrc' ];
return [ 'torrc', 'curlcfg' ];
}
};

View File

@@ -69,7 +69,7 @@ module.exports = {
message: prefix()+'Custom path for traefik data?'+utils.getHelp('traefik_datapath_custom'),
},
{
when: installerDocker,
when: (props)=>{ return installerDocker(props) && props.features.indexOf('tor') !== -1 },
type: 'list',
name: 'tor_datapath',
default: utils.getDefault( 'tor_datapath' ),
@@ -98,7 +98,7 @@ module.exports = {
message: prefix()+'Where do you want to store your tor data?'+utils.getHelp('tor_datapath'),
},
{
when: (props)=>{ return installerDocker(props) && (props.tor_datapath === '_custom') },
when: (props)=>{ return installerDocker(props) && props.features.indexOf('tor') !== -1 && props.otsclient_datapath === '_custom' },
type: 'input',
name: 'tor_datapath_custom',
default: utils.getDefault( 'tor_datapath_custom' ),

View File

@@ -33,8 +33,7 @@
"proxy_datapath",
"traefik_datapath",
"traefik_http_port",
"traefik_https_port",
"tor_datapath"
"traefik_https_port"
],
"allOf": [
{
@@ -126,6 +125,24 @@
"otsclient_datapath"
]
}
},
{
"if": {
"properties": {
"features": {
"contains": {
"enum": [
"tor"
]
}
}
}
},
"then": {
"required": [
"tor_datapath"
]
}
}
],
"properties": {
@@ -164,13 +181,15 @@
"type": "string",
"enum": [
"lightning",
"otsclient"
"otsclient",
"tor"
],
"title": "The feature",
"default": "",
"examples": [
"lightning",
"otsclient"
"otsclient",
"tor"
]
}
},

View File

@@ -15,9 +15,12 @@ txindex=1
zmqpubrawblock=tcp://0.0.0.0:18501
zmqpubrawtx=tcp://0.0.0.0:18502
<% if ( features.indexOf('tor') !== -1 ) { %>
#tor
#proxy=127.0.0.1:9050
#listen=1
proxy=tor:9050
onlynet=onion
listen=1
<% } %>
maxmempool=64
dbcache=64

View File

@@ -7,7 +7,10 @@ PROXY_DATAPATH=<%= proxy_datapath %>
GATEKEEPER_DATAPATH=<%= gatekeeper_datapath %>
GATEKEEPER_PORT=<%= gatekeeper_port %>
TRAEFIK_DATAPATH=<%= traefik_datapath %>
FEATURE_TOR=<%= (features.indexOf('tor') != -1)?'true':'false' %>
<% if ( features.indexOf('tor') !== -1 ) { %>
TOR_DATAPATH=<%= tor_datapath %>
<% } %>
DOCKER_MODE=<%= docker_mode %>
RUN_AS_USER=<%= run_as_different_user?username:'' %>
CLEANUP=<%= installer_cleanup?'true':'false' %>

View File

@@ -73,6 +73,9 @@ services:
<% if ( features.indexOf('otsclient') !== -1 ) { %>
- "<%= otsclient_datapath %>:/proxy/otsfiles"
<% } %>
<% if ( features.indexOf('tor') !== -1 ) { %>
- "<%= tor_datapath %>:/proxy/tor"
<% } %>
networks:
- cyphernodenet
restart: always
@@ -119,6 +122,8 @@ services:
notifier:
image: cyphernode/notifier:<%= notifier_version %>
command: $USER ./startnotifier.sh
volumes:
- "<%= tor_datapath %>/curlcfg:/notifier/curlcfg"
networks:
- cyphernodenet
- cyphernodeappsnet
@@ -233,6 +238,7 @@ services:
# placement:
# constraints: [node.hostname==dev]
<% if ( features.indexOf('tor') !== -1 ) { %>
##########################
# TOR #
##########################
@@ -251,6 +257,7 @@ services:
# deploy:
# placement:
# constraints: [node.hostname==dev]
<% } %>
<% if ( features.indexOf('lightning') !== -1 && lightning_implementation === 'c-lightning' ) { %>
##########################

View File

@@ -100,7 +100,7 @@ checknotifier() {
local response
local returncode
response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"web\",\"url\":\"http://proxy:8888/helloworld\"}")
response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"web\",\"url\":\"http://proxy:8888/helloworld\",\"torbypass\":true}")
returncode=$?
[ "${returncode}" -ne "0" ] && return 115
http_code=$(echo "${response}" | jq -r ".http_code")
@@ -124,6 +124,18 @@ checkots() {
return 0
}
checktor() {
echo -en "\r\n\e[1;36mTesting TOR... " > /dev/console
local rc
rc=$(curl -s -o /dev/null -w "%{http_code}" --socks5-hostname tor:9050 http://expyuzz4wqqyqhjn.onion/)
[ "${rc}" -ne "200" ] && return 250
echo -e "\e[1;36mTOR rocks!" > /dev/console
return 0
}
checkbitcoinnode() {
echo -en "\r\n\e[1;36mTesting Bitcoin... " > /dev/console
local rc
@@ -161,12 +173,12 @@ checkservice() {
while :
do
outcome=0
for container in gatekeeper proxy proxycron broker notifier pycoin <%= (features.indexOf('otsclient') != -1)?'otsclient ':'' %>bitcoin <%= (features.indexOf('lightning') != -1)?'lightning ':'' %>; do
for container in gatekeeper proxy proxycron broker notifier pycoin <%= (features.indexOf('otsclient') != -1)?'otsclient ':'' %><%= (features.indexOf('tor') != -1)?'tor ':'' %>bitcoin <%= (features.indexOf('lightning') != -1)?'lightning ':'' %>; do
echo -e " \e[0;32mVerifying \e[0;33m${container}\e[0;32m..." > /dev/console
(ping -c 10 ${container} 2> /dev/null | grep "0% packet loss" > /dev/null) &
eval ${container}=$!
done
for container in gatekeeper proxy proxycron broker notifier pycoin <%= (features.indexOf('otsclient') != -1)?'otsclient ':'' %>bitcoin <%= (features.indexOf('lightning') != -1)?'lightning ':'' %>; do
for container in gatekeeper proxy proxycron broker notifier pycoin <%= (features.indexOf('otsclient') != -1)?'otsclient ':'' %><%= (features.indexOf('tor') != -1)?'tor ':'' %>bitcoin <%= (features.indexOf('lightning') != -1)?'lightning ':'' %>; do
eval wait '$'${container} ; returncode=$? ; outcome=$((${outcome} + ${returncode}))
eval c_${container}=${returncode}
done
@@ -185,10 +197,11 @@ checkservice() {
# { "name": "proxycron", "active":true },
# { "name": "pycoin", "active":true },
# { "name": "otsclient", "active":true },
# { "name": "tor", "active":true },
# { "name": "bitcoin", "active":true },
# { "name": "lightning", "active":true },
# ]
for container in gatekeeper proxy proxycron broker notifier pycoin <%= (features.indexOf('otsclient') != -1)?'otsclient ':'' %>bitcoin <%= (features.indexOf('lightning') != -1)?'lightning ':'' %>; do
for container in gatekeeper proxy proxycron broker notifier pycoin <%= (features.indexOf('otsclient') != -1)?'otsclient ':'' %><%= (features.indexOf('tor') != -1)?'tor ':'' %>bitcoin <%= (features.indexOf('lightning') != -1)?'lightning ':'' %>; do
[ -n "${result}" ] && result="${result},"
result="${result}{\"name\":\"${container}\",\"active\":"
eval "returncode=\$c_${container}"
@@ -245,6 +258,7 @@ feature_status() {
# { "name": "proxycron", "active":true },
# { "name": "pycoin", "active":true },
# { "name": "otsclient", "active":true },
# { "name": "tor", "active":true },
# { "name": "bitcoin", "active":true },
# { "name": "lightning", "active":true },
# ],
@@ -252,6 +266,7 @@ feature_status() {
# { "name": "gatekeeper", "working":true },
# { "name": "pycoin", "working":true },
# { "name": "otsclient", "working":true },
# { "name": "tor", "working":true },
# { "name": "bitcoin", "working":true },
# { "name": "lightning", "working":true },
# ]
@@ -285,6 +300,7 @@ fi
# { "name": "gatekeeper", "working":true },
# { "name": "pycoin", "working":true },
# { "name": "otsclient", "working":true },
# { "name": "tor", "working":true },
# { "name": "bitcoin", "working":true },
# { "name": "lightning", "working":true },
# ]
@@ -366,6 +382,23 @@ finalreturncode=$((${returncode} | ${finalreturncode}))
result="${result}$(feature_status ${returncode} 'OTSclient error!')}"
<% } %>
<% if (features.indexOf('tor') != -1) { %>
#############################
# TOR #
#############################
result="${result},{\"coreFeature\":false, \"name\":\"tor\",\"working\":"
status=$(echo "{${containers}}" | jq ".containers[] | select(.name == \"tor\") | .active")
if [[ "${workingproxy}" = "true" && "${status}" = "true" ]]; then
timeout_feature checktor
returncode=$?
else
returncode=1
fi
finalreturncode=$((${returncode} | ${finalreturncode}))
result="${result}$(feature_status ${returncode} 'TOR error!')}"
<% } %>
#############################
# BITCOIN #
#############################

View File

@@ -0,0 +1,3 @@
<% if ( features.indexOf('tor') !== -1 ) { %>
socks5-hostname=tor:9050
<% } %>

View File

@@ -4,7 +4,8 @@
"docker_versions": {},
"features": [
"lightning",
"otsclient"
"otsclient",
"tor"
],
"net": "testnet",
"use_xpub": true,

3
dist/setup.sh vendored
View File

@@ -398,6 +398,7 @@ install_docker() {
copy_file $cyphernodeconf_filepath/traefik/htpasswd $TRAEFIK_DATAPATH/htpasswd 1 $SUDO_REQUIRED
if [[ $FEATURE_TOR == true ]]; then
if [ ! -d $TOR_DATAPATH ]; then
step " create $TOR_DATAPATH"
sudo_if_required mkdir -p $TOR_DATAPATH/hidden_service
@@ -406,6 +407,8 @@ install_docker() {
fi
copy_file $cyphernodeconf_filepath/tor/torrc $TOR_DATAPATH/torrc 1 $SUDO_REQUIRED
copy_file $cyphernodeconf_filepath/tor/curlcfg $TOR_DATAPATH/curlcfg 1 $SUDO_REQUIRED
fi
if [ ! -d $PROXY_DATAPATH ]; then

View File

@@ -44,6 +44,7 @@ Current components in Cyphernode:
- Bitcoin: Bitcoin Core node. Cyphernode uses a watching wallet for watchers (no funds) and a spending wallet for spending. Mandatory component, but optionally part of Cyphernode installation, as we can use an already running Bitcoin Core node.
- Lightning: optional. C-Lightning node. The LN node will use the Bitcoin node for its tasks.
- OTSclient: optional. Used to stamp hashes on the Bitcoin blockchain.
- TOR: optional. Used to serve traefik as a HiddenService as well as Internet Gateway.
Future components:

View File

@@ -75,6 +75,7 @@ echo "arch_docker=$arch_docker\n"
image "gatekeeper" "api_auth_docker/" ${arch_docker} \
&& image "proxycron" "cron_docker/" ${arch_docker} \
&& image "otsclient" "otsclient_docker/" ${arch_docker} \
&& image "tor" "tor_docker/" ${arch_docker} \
&& image "proxy" "proxy_docker/" ${arch_docker} \
&& image "notifier" "notifier_docker/" ${arch_docker} \
&& image "pycoin" "pycoin_docker/" ${arch_docker} \
@@ -89,6 +90,7 @@ image "gatekeeper" "api_auth_docker/" ${arch_docker} \
manifest "gatekeeper" \
&& manifest "proxycron" \
&& manifest "otsclient" \
&& manifest "tor" \
&& manifest "proxy" \
&& manifest "notifier" \
&& manifest "pycoin" \

View File

@@ -8,6 +8,7 @@ web() {
local msg=${1}
local url
local body
local torbypass
local returncode
local response
local result
@@ -28,7 +29,15 @@ web() {
trace "[web] no body, GET request"
fi
response=$(curl_it "${url}" "${body}")
torbypass=$(echo ${msg} | jq -e ".torbypass")
# jq -e will have a return code of 1 if the supplied tag is null.
if [ "$?" -ne "0" ]; then
# torbypass tag null
torbypass=false
fi
trace "[web] torbypass=${torbypass}"
response=$(curl_it "${url}" "${body}", "${torbypass}")
returncode=$?
trace_rc ${returncode}
@@ -42,17 +51,24 @@ curl_it() {
local url=$(echo "${1}" | tr -d '"')
local data=${2}
local torbypass=${3}
local returncode
local response
local rnd=$(dd if=/dev/urandom bs=5 count=1 | xxd -pc 5)
if [ "${torbypass}" = "true" ]; then
torbypass=""
else
torbypass="-K curlcfg"
fi
if [ -n "${data}" ]; then
trace "[curl_it] curl -o webresponse-${rnd} -m 20 -w \"%{http_code}\" -H \"Content-Type: application/json\" -H \"X-Forwarded-Proto: https\" -d \"${data}\" -k ${url}"
rc=$(curl -o webresponse-${rnd} -m 20 -w "%{http_code}" -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -d "${data}" -k ${url})
trace "[curl_it] curl ${torbypass} -o webresponse-${rnd} -m 20 -w \"%{http_code}\" -H \"Content-Type: application/json\" -H \"X-Forwarded-Proto: https\" -d \"${data}\" -k ${url}"
rc=$(curl ${torbypass} -o webresponse-${rnd} -m 20 -w "%{http_code}" -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -d "${data}" -k ${url})
returncode=$?
else
trace "[curl_it] curl -o webresponse-$$ -m 20 -w \"%{http_code}\" -k ${url}"
rc=$(curl -o webresponse-${rnd} -m 20 -w "%{http_code}" -k ${url})
trace "[curl_it] curl ${torbypass} -o webresponse-$$ -m 20 -w \"%{http_code}\" -k ${url}"
rc=$(curl ${torbypass} -o webresponse-${rnd} -m 20 -w "%{http_code}" -k ${url})
returncode=$?
fi
trace "[curl_it] HTTP return code=${rc}"

View File

@@ -79,7 +79,8 @@ main() {
installation_info)
# GET http://192.168.111.152:8080/info
if [ -f "$DB_PATH/info.json" ]; then
response=$( cat "$DB_PATH/info.json" )
# Replace tor_hostname_placeholder with actual tor hostname from tor file
response=$(sed "s/tor_hostname_placeholder/`tr -d '\n\r' < tor/hidden_service/hostname`/g" "$DB_PATH/info.json")
else
response='{ "error": "missing installation data" }'
fi