Browse Source

expose whirlpool api as a hidden service

use-env-var-docker
kenshin-samourai 5 years ago
parent
commit
d3457f81cd
  1. 34
      doc/DOCKER_advanced_setups.md
  2. 8
      docker/my-dojo/conf/docker-whirlpool.conf.tpl
  3. 1
      docker/my-dojo/docker-compose.yaml
  4. 10
      docker/my-dojo/dojo.sh
  5. 13
      docker/my-dojo/install/install-scripts.sh
  6. 13
      docker/my-dojo/install/upgrade-scripts.sh
  7. 1
      docker/my-dojo/nginx/Dockerfile
  8. 15
      docker/my-dojo/nginx/whirlpool.conf
  9. 9
      docker/my-dojo/overrides/whirlpool.install.yaml
  10. 7
      docker/my-dojo/tor/restart.sh
  11. 11
      docker/my-dojo/whirlpool/Dockerfile
  12. 2
      docker/my-dojo/whirlpool/restart.sh
  13. 178
      docker/my-dojo/whirlpool/wait-for-it.sh

34
doc/DOCKER_advanced_setups.md

@ -124,7 +124,7 @@ nano ./conf/docker-node.conf
This setup allows to install and run a [Whirlpool client](https://github.com/Samourai-Wallet/whirlpool-client-cli) inside MyDojo. This setup allows to install and run a [Whirlpool client](https://github.com/Samourai-Wallet/whirlpool-client-cli) inside MyDojo.
Note: In order to interact with the Whirlpool client, you'll need to install the [Whirlpool GUI application]((https://github.com/Samourai-Wallet/whirlpool-gui)) on a computer (either the machine running MyDojo or any computer connected to your LAN). The client can be configured and controlled through a REST API exposed as a Tor hidden service.
### Procedure ### ### Procedure ###
@ -138,14 +138,15 @@ nano ./conf/docker-whirlpool.conf
# #
# Set the value of WHIRLPOOL_INSTALL to "on" # Set the value of WHIRLPOOL_INSTALL to "on"
# If you plan to run whirlpool-gui on a machine than isn't the machine running MyDojo, set the value of WHIRLPOOL_RPC_EXTERNAL_IP with the IP address of the machine hosting MyDojo. Do not use the public IP address of the machine, use its address on your LAN (192.168.xXX.xxx). ## Save and exit nano
# Save and exit nano
# #
``` ```
### Initialization with Whirlppol GUI ### ### Installation of Whirlppol GUI ###
The [Whirlpool GUI application]((https://github.com/Samourai-Wallet/whirlpool-gui)) provides a graphical interface for your Whirlpool client.
These steps describe how to connect the Whirlpool GUI application ([whirlpool-gui](https://github.com/Samourai-Wallet/whirlpool-gui/releases)) to your Whirlpool client. These steps describe how to install the Whirlpool GUI application how a computer and how to connect it to your Whirlpool client.
**Requirements** **Requirements**
@ -154,17 +155,32 @@ These steps describe how to connect the Whirlpool GUI application ([whirlpool-gu
- Whirlpool client has been activated in MyDojo, - Whirlpool client has been activated in MyDojo,
- Your Samourai Wallet is paired to MyDojo, - Your Samourai Wallet is paired to MyDojo,
- MyDojo is running. - MyDojo is running.
- Tor browser is installed on the computer that will run the Whirlpool GUI application.
**Procedure** **Procedure**
- Retrieve the onion address of the API provided by your Whirlpool client
```
# Open a terminal console on the computer hosting your Dojo
# Retrieve the onion address of the Whirlpool API
./dojo.sh onion
``` ```
# Install the Whirlpool GUI application on a computer and launch it.
- Install and configure the Whirlpool GUI application
```
# If needed, install Tor browser on the computer that will run the Whirlpool GUI application
# Install the Whirlpool GUI application on the computer and launch it.
# Select 'Connect to remote CLI'. # Select 'Connect to remote CLI'.
# Insert the value of WHIRLPOOL_RPC_EXTERNAL_IP in the first block # Insert the onion address of the Whirlpool API, **prefixed by HTTP**, in the first block
# For example, you should insert `https://172.30.1.8` if WHIRLPOOL_RPC_EXTERNAL_IP is set to `172.30.1.8` # Set the port to 80
# Keep the Port 8899 and API pairing key BLANK. Click 'Connect'. # Let the API pairing key BLANK.
# Click 'Connect'.
# Paste the pairing payload from your mobile device when prompted: # Paste the pairing payload from your mobile device when prompted:
# Select the Samourai Wallet Menu (3 dots top right), # Select the Samourai Wallet Menu (3 dots top right),

8
docker/my-dojo/conf/docker-whirlpool.conf.tpl

@ -5,11 +5,3 @@
# Install and run an instance of whirlpool-cli inside Docker # Install and run an instance of whirlpool-cli inside Docker
# Value: on | off # Value: on | off
WHIRLPOOL_INSTALL=off WHIRLPOOL_INSTALL=off
# IP address used to expose the RPC API of whirlpool-cli to external apps
# Warning: Do not expose your RPC API to internet!
# Recommended value:
# if whirlpool-gui runs on the machine hosting dojo: 172.30.1.8 (default)
# otherwise: IP address on the LAN of the machine running dojo
# Type: string
WHIRLPOOL_RPC_EXTERNAL_IP=172.30.1.8

1
docker/my-dojo/docker-compose.yaml

@ -81,6 +81,7 @@ services:
env_file: env_file:
- ./.env - ./.env
- ./conf/docker-explorer.conf - ./conf/docker-explorer.conf
- ./conf/docker-whirlpool.conf
- ./conf/docker-tor.conf - ./conf/docker-tor.conf
restart: always restart: always
command: /restart.sh command: /restart.sh

10
docker/my-dojo/dojo.sh

@ -23,7 +23,6 @@ source_file "$DIR/.env"
# Export some variables for compose # Export some variables for compose
export BITCOIND_RPC_EXTERNAL_IP export BITCOIND_RPC_EXTERNAL_IP
export WHIRLPOOL_RPC_EXTERNAL_IP
# Select YAML files # Select YAML files
select_yaml_files() { select_yaml_files() {
@ -315,10 +314,6 @@ upgrade() {
# Load env vars for compose files # Load env vars for compose files
source_file "$DIR/conf/docker-bitcoind.conf" source_file "$DIR/conf/docker-bitcoind.conf"
export BITCOIND_RPC_EXTERNAL_IP export BITCOIND_RPC_EXTERNAL_IP
if [ "$WHIRLPOOL_INSTALL" == "on" ]; then
source_file "$DIR/conf/docker-whirlpool.conf"
export WHIRLPOOL_RPC_EXTERNAL_IP
fi
# Rebuild the images (with or without cache) # Rebuild the images (with or without cache)
if [ $noCache -eq 0 ]; then if [ $noCache -eq 0 ]; then
eval "docker-compose $yamlFiles build --no-cache" eval "docker-compose $yamlFiles build --no-cache"
@ -346,6 +341,11 @@ onion() {
V3_ADDR=$( docker exec -it tor cat /var/lib/tor/hsv3dojo/hostname ) V3_ADDR=$( docker exec -it tor cat /var/lib/tor/hsv3dojo/hostname )
echo "Maintenance Tool hidden service address = $V3_ADDR" echo "Maintenance Tool hidden service address = $V3_ADDR"
if [ "$WHIRLPOOL_INSTALL" == "on" ]; then
V3_ADDR_WHIRLPOOL=$( docker exec -it tor cat /var/lib/tor/hsv3whirlpool/hostname )
echo "Whirlpool API hidden service address = $V3_ADDR_WHIRLPOOL"
fi
if [ "$BITCOIND_INSTALL" == "on" ]; then if [ "$BITCOIND_INSTALL" == "on" ]; then
V2_ADDR_BTCD=$( docker exec -it tor cat /var/lib/tor/hsv2bitcoind/hostname ) V2_ADDR_BTCD=$( docker exec -it tor cat /var/lib/tor/hsv2bitcoind/hostname )
echo "bitcoind hidden service address = $V2_ADDR_BTCD" echo "bitcoind hidden service address = $V2_ADDR_BTCD"

13
docker/my-dojo/install/install-scripts.sh

@ -12,6 +12,12 @@ else
source ./conf/docker-explorer.conf.tpl source ./conf/docker-explorer.conf.tpl
fi fi
if [ -f ./conf/docker-whirlpool.conf ]; then
source ./conf/docker-whirlpool.conf
else
source ./conf/docker-whirlpool.conf.tpl
fi
if [ -f ./conf/docker-common.conf ]; then if [ -f ./conf/docker-common.conf ]; then
source ./conf/docker-common.conf source ./conf/docker-common.conf
else else
@ -86,6 +92,13 @@ init_config_files() {
fi fi
echo "Initialized dojo-explorer.conf (nginx)" echo "Initialized dojo-explorer.conf (nginx)"
if [ "$WHIRLPOOL_INSTALL" == "on" ]; then
cp ./nginx/whirlpool.conf ./nginx/dojo-whirlpool.conf
else
cp /dev/null ./nginx/dojo-ewhirlpool.conf
fi
echo "Initialized dojo-whirlpool.conf (nginx)"
# Initialize config files for nginx and the maintenance tool # Initialize config files for nginx and the maintenance tool
if [ "$COMMON_BTC_NETWORK" == "testnet" ]; then if [ "$COMMON_BTC_NETWORK" == "testnet" ]; then
cp ./nginx/testnet.conf ./nginx/dojo.conf cp ./nginx/testnet.conf ./nginx/dojo.conf

13
docker/my-dojo/install/upgrade-scripts.sh

@ -12,6 +12,12 @@ else
source ./conf/docker-explorer.conf.tpl source ./conf/docker-explorer.conf.tpl
fi fi
if [ -f ./conf/docker-whirlpool.conf ]; then
source ./conf/docker-whirlpool.conf
else
source ./conf/docker-whirlpool.conf.tpl
fi
source ./conf/docker-bitcoind.conf source ./conf/docker-bitcoind.conf
# Confirm upgrade operation # Confirm upgrade operation
@ -71,6 +77,13 @@ update_config_files() {
fi fi
echo "Initialized dojo-explorer.conf (nginx)" echo "Initialized dojo-explorer.conf (nginx)"
if [ "$WHIRLPOOL_INSTALL" == "on" ]; then
cp ./nginx/whirlpool.conf ./nginx/dojo-whirlpool.conf
else
cp /dev/null ./nginx/dojo-ewhirlpool.conf
fi
echo "Initialized dojo-whirlpool.conf (nginx)"
if [ "$COMMON_BTC_NETWORK" == "testnet" ]; then if [ "$COMMON_BTC_NETWORK" == "testnet" ]; then
cp ./nginx/testnet.conf ./nginx/dojo.conf cp ./nginx/testnet.conf ./nginx/dojo.conf
echo "Initialized dojo.conf (nginx)" echo "Initialized dojo.conf (nginx)"

1
docker/my-dojo/nginx/Dockerfile

@ -10,6 +10,7 @@ RUN mkdir -p "$LOGS_DIR" && \
COPY ./nginx.conf /etc/nginx/nginx.conf COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./dojo.conf /etc/nginx/sites-enabled/dojo.conf COPY ./dojo.conf /etc/nginx/sites-enabled/dojo.conf
COPY ./dojo-explorer.conf /etc/nginx/sites-enabled/dojo-explorer.conf COPY ./dojo-explorer.conf /etc/nginx/sites-enabled/dojo-explorer.conf
COPY ./dojo-whirlpool.conf /etc/nginx/sites-enabled/dojo-whirlpool.conf
# Copy wait-for script # Copy wait-for script
COPY ./wait-for /wait-for COPY ./wait-for /wait-for

15
docker/my-dojo/nginx/whirlpool.conf

@ -0,0 +1,15 @@
server {
listen 8898;
server_name _;
resolver 127.0.0.11 valid=30s;
location / {
set $upstream http://whirlpool:8898;
proxy_pass $upstream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

9
docker/my-dojo/overrides/whirlpool.install.yaml

@ -9,18 +9,13 @@ services:
env_file: env_file:
- ./.env - ./.env
- ./conf/docker-common.conf - ./conf/docker-common.conf
- ./conf/docker-node.conf
- ./conf/docker-whirlpool.conf - ./conf/docker-whirlpool.conf
restart: always restart: always
command: "/wait-for-it.sh nginx:80 --timeout=720 --strict -- /restart.sh" command: /restart.sh
expose: expose:
- "8899" - "8898"
ports:
- "${WHIRLPOOL_RPC_EXTERNAL_IP}:8899:8899"
volumes: volumes:
- data-whirlpool:/home/whirlpool - data-whirlpool:/home/whirlpool
depends_on:
- nginx
networks: networks:
whirlnet: whirlnet:
ipv4_address: 172.30.1.8 ipv4_address: 172.30.1.8

7
docker/my-dojo/tor/restart.sh

@ -32,6 +32,13 @@ if [ "$EXPLORER_INSTALL" == "on" ]; then
tor_options+=(--HiddenServiceDirGroupReadable 1) tor_options+=(--HiddenServiceDirGroupReadable 1)
fi fi
if [ "$WHIRLPOOL_INSTALL" == "on" ]; then
tor_options+=(--HiddenServiceDir /var/lib/tor/hsv3whirlpool)
tor_options+=(--HiddenServiceVersion 3)
tor_options+=(--HiddenServicePort "80 172.29.1.3:8898")
tor_options+=(--HiddenServiceDirGroupReadable 1)
fi
if [ "$TOR_USE_BRIDGES" == "on" ]; then if [ "$TOR_USE_BRIDGES" == "on" ]; then
tor_options+=(--ClientTransportPlugin "obfs4 exec /usr/local/bin/obfs4proxy") tor_options+=(--ClientTransportPlugin "obfs4 exec /usr/local/bin/obfs4proxy")
tor_options+=(--UseBridges 1) tor_options+=(--UseBridges 1)

11
docker/my-dojo/whirlpool/Dockerfile

@ -71,15 +71,8 @@ RUN chown whirlpool:whirlpool /restart.sh && \
chmod u+x /restart.sh && \ chmod u+x /restart.sh && \
chmod g+x /restart.sh chmod g+x /restart.sh
# Copy wait-for-it script # Expose HTTP API port
COPY ./wait-for-it.sh /wait-for-it.sh EXPOSE 8898
RUN chown whirlpool:whirlpool /wait-for-it.sh && \
chmod u+x /wait-for-it.sh && \
chmod g+x /wait-for-it.sh
# Expose API port
EXPOSE 8899
# Switch to user whirlpool # Switch to user whirlpool
USER whirlpool USER whirlpool

2
docker/my-dojo/whirlpool/restart.sh

@ -3,6 +3,8 @@ set -e
whirlpool_options=( whirlpool_options=(
--listen --listen
--cli.api.http-enable=true
--cli.api.http-port=8898
--cli.dojo.enabled=true --cli.dojo.enabled=true
--cli.tor=true --cli.tor=true
--cli.torConfig.executable=/usr/local/bin/tor --cli.torConfig.executable=/usr/local/bin/tor

178
docker/my-dojo/whirlpool/wait-for-it.sh

@ -1,178 +0,0 @@
#!/usr/bin/env bash
# Use this script to test if a given TCP host/port are available
WAITFORIT_cmdname=${0##*/}
echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
usage()
{
cat << USAGE >&2
Usage:
$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST Host or IP under test
-p PORT | --port=PORT TCP port under test
Alternatively, you specify the host and port as host:port
-s | --strict Only execute subcommand if the test succeeds
-q | --quiet Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit 1
}
wait_for()
{
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
else
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
fi
WAITFORIT_start_ts=$(date +%s)
while :
do
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
WAITFORIT_result=$?
else
(echo > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
WAITFORIT_result=$?
fi
if [[ $WAITFORIT_result -eq 0 ]]; then
WAITFORIT_end_ts=$(date +%s)
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
break
fi
sleep 1
done
return $WAITFORIT_result
}
wait_for_wrapper()
{
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
else
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
fi
WAITFORIT_PID=$!
trap "kill -INT -$WAITFORIT_PID" INT
wait $WAITFORIT_PID
WAITFORIT_RESULT=$?
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
fi
return $WAITFORIT_RESULT
}
# process arguments
while [[ $# -gt 0 ]]
do
case "$1" in
*:* )
WAITFORIT_hostport=(${1//:/ })
WAITFORIT_HOST=${WAITFORIT_hostport[0]}
WAITFORIT_PORT=${WAITFORIT_hostport[1]}
shift 1
;;
--child)
WAITFORIT_CHILD=1
shift 1
;;
-q | --quiet)
WAITFORIT_QUIET=1
shift 1
;;
-s | --strict)
WAITFORIT_STRICT=1
shift 1
;;
-h)
WAITFORIT_HOST="$2"
if [[ $WAITFORIT_HOST == "" ]]; then break; fi
shift 2
;;
--host=*)
WAITFORIT_HOST="${1#*=}"
shift 1
;;
-p)
WAITFORIT_PORT="$2"
if [[ $WAITFORIT_PORT == "" ]]; then break; fi
shift 2
;;
--port=*)
WAITFORIT_PORT="${1#*=}"
shift 1
;;
-t)
WAITFORIT_TIMEOUT="$2"
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
shift 2
;;
--timeout=*)
WAITFORIT_TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
WAITFORIT_CLI=("$@")
break
;;
--help)
usage
;;
*)
echoerr "Unknown argument: $1"
usage
;;
esac
done
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
echoerr "Error: you need to provide a host and port to test."
usage
fi
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
# check to see if timeout is from busybox?
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
WAITFORIT_ISBUSY=1
WAITFORIT_BUSYTIMEFLAG="-t"
else
WAITFORIT_ISBUSY=0
WAITFORIT_BUSYTIMEFLAG=""
fi
if [[ $WAITFORIT_CHILD -gt 0 ]]; then
wait_for
WAITFORIT_RESULT=$?
exit $WAITFORIT_RESULT
else
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
wait_for_wrapper
WAITFORIT_RESULT=$?
else
wait_for
WAITFORIT_RESULT=$?
fi
fi
if [[ $WAITFORIT_CLI != "" ]]; then
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
exit $WAITFORIT_RESULT
fi
exec "${WAITFORIT_CLI[@]}"
else
exit $WAITFORIT_RESULT
fi
Loading…
Cancel
Save