mirror of
https://github.com/cryptoadvance/specter-desktop.git
synced 2026-08-13 12:33:29 +02:00
Initial Tor integration option
This commit is contained in:
parent
07d8b10fba
commit
63a77be2d3
6 changed files with 148 additions and 2 deletions
3
.env_example
Normal file
3
.env_example
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# The cleartext password that was entered into:
|
||||
# $ tor --hash-password "your-tor-passphrase"
|
||||
TOR_PASSWORD=your-tor-passphrase
|
||||
9
.flaskenv
Normal file
9
.flaskenv
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
PORT=25441
|
||||
|
||||
# If you want to serve over a Tor hidden service, also set FLASK_ENV=production.
|
||||
# (The autoreloading in 'development' mode causes problems with the Tor connector)
|
||||
CONNECT_TOR=False
|
||||
|
||||
#FLASK_ENV=production
|
||||
FLASK_ENV=development
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -1 +1,5 @@
|
|||
*.pyc
|
||||
__pycache__
|
||||
*.pyc
|
||||
|
||||
.env
|
||||
.tor_service_key
|
||||
|
|
|
|||
15
server.py
15
server.py
|
|
@ -15,6 +15,12 @@ from specter import Specter, purposes, addrtypes
|
|||
from datetime import datetime
|
||||
import urllib
|
||||
|
||||
from pathlib import Path
|
||||
env_path = Path('.') / '.flaskenv'
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv(env_path)
|
||||
|
||||
|
||||
if getattr(sys, 'frozen', False):
|
||||
template_folder = os.path.join(sys._MEIPASS, 'templates')
|
||||
static_folder = os.path.join(sys._MEIPASS, 'static')
|
||||
|
|
@ -483,4 +489,11 @@ if __name__ == '__main__':
|
|||
if os.path.isfile(filename):
|
||||
extra_files.append(filename)
|
||||
|
||||
app.run(port=25441, debug=debug, extra_files=extra_files)
|
||||
if os.getenv('CONNECT_TOR', False):
|
||||
from tor import tor_util
|
||||
tor_util.run_on_hidden_service(app, port=os.getenv('PORT'), debug=debug, extra_files=extra_files)
|
||||
else:
|
||||
app.run(port=os.getenv('PORT'), debug=debug, extra_files=extra_files)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
80
tor/README.md
Normal file
80
tor/README.md
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
## Running Specter Desktop over a Tor hidden service
|
||||
Specter Desktop protects your security and privacy by running on a local server that only talks to your own bitcoin node. But what if you need to check a wallet balance or generate and sign transactions when you're away from your home network?
|
||||
|
||||
Configuring your router to let you VPN into your home network is probably the easiest solution.
|
||||
|
||||
But you can also make Specter Desktop available outside of your network via a Tor hidden service. A hidden service generates a secret .onion address that only you know and which can be accessed from a Tor browser from anywhere in the world. This does not require any port forwarding on your router.
|
||||
|
||||
### Security note
|
||||
Tor support, like Specter Desktop as a whole, should be treated as a work-in-progress that is not yet vetted as being fully secure.
|
||||
|
||||
### Install Tor service
|
||||
Install Tor on the same server that you'll be running Specter Desktop:
|
||||
* [Debian / Ubuntu](https://2019.www.torproject.org/docs/debian.html.en)
|
||||
* [macOS](https://2019.www.torproject.org/docs/tor-doc-osx.html.en)
|
||||
|
||||
### Configure Tor authentication
|
||||
```
|
||||
$ tor --hash-password "your-tor-passphrase"
|
||||
```
|
||||
That returns a password hash such as:
|
||||
```
|
||||
16:CE9058DA89498A4160373C70FF7FFF70CC2E20B6788FC48F5C35B2E85B
|
||||
```
|
||||
Update your `torrc` config file (usually `/etc/tor/torrc` or `/usr/local/etc/tor/torrc` on macOS Homebrew installs). Uncomment the `ControlPort` line as well as the `HashedControlPassword` line. Remember to paste in your own hashed password result from above.
|
||||
```
|
||||
## The port on which Tor will listen for local connections from Tor
|
||||
## controller applications, as documented in control-spec.txt.
|
||||
ControlPort 9051
|
||||
## If you enable the controlport, be sure to enable one of these
|
||||
## authentication methods, to prevent attackers from accessing it.
|
||||
HashedControlPassword 16:CE9058DA89498A4160373C70FF7FFF70CC2E20B6788FC48F5C35B2E85B
|
||||
#CookieAuthentication 1
|
||||
```
|
||||
|
||||
Restart the Tor service:
|
||||
* `sudo /etc/init.d/tor restart` on linux
|
||||
* `brew services restart tor` on macOS Homebrew installs
|
||||
|
||||
|
||||
### Configure Specter Desktop to connect to Tor
|
||||
Update the `.flaskenv` file in the project root. Set `CONNECT_TOR` to 'True' and set `FLASK_ENV` to 'production':
|
||||
```
|
||||
PORT=25441
|
||||
|
||||
# If you want to serve over a Tor hidden service, also set FLASK_ENV=production.
|
||||
# (The autoreloading in 'development' mode causes problems with the Tor connector)
|
||||
CONNECT_TOR=False
|
||||
|
||||
FLASK_ENV=production
|
||||
#FLASK_ENV=development
|
||||
```
|
||||
|
||||
### Specify Tor secrets
|
||||
The Tor password that we hashed above will need to be shared with Specter Desktop.
|
||||
|
||||
Copy the example `.env_example` file:
|
||||
```
|
||||
$ cp .env_example .env
|
||||
```
|
||||
|
||||
And then edit `.env` and specify `TOR_PASSWORD`:
|
||||
```
|
||||
# The cleartext password that was entered into:
|
||||
# $ tor --hash-password "your-tor-passphrase"
|
||||
TOR_PASSWORD=your-tor-passphrase
|
||||
```
|
||||
|
||||
### Launch with Tor
|
||||
Now just start Specter Desktop as usual:
|
||||
```
|
||||
$ python server.py
|
||||
```
|
||||
|
||||
Amongst the startup output you'll see:
|
||||
```
|
||||
* Connecting to tor
|
||||
Started a new hidden service with the address of abcd1234efgh5678.onion
|
||||
```
|
||||
|
||||
Point a Tor browser at that onion address and you will have (reasonably?) secure access to your Specter Desktop from anywhere in the world!
|
||||
37
tor/tor_util.py
Normal file
37
tor/tor_util.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import os
|
||||
import stem
|
||||
from stem.control import Controller
|
||||
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv() # Load the secrets from .env
|
||||
|
||||
|
||||
def run_on_hidden_service(app, port, debug, extra_files):
|
||||
with Controller.from_port() as controller:
|
||||
print(' * Connecting to tor')
|
||||
controller.authenticate(os.getenv('TOR_PASSWORD'))
|
||||
|
||||
key_path = os.path.expanduser('.tor_service_key')
|
||||
tor_service_id = None
|
||||
|
||||
if not os.path.exists(key_path):
|
||||
service = controller.create_ephemeral_hidden_service({80: port}, await_publication = True)
|
||||
tor_service_id = service.service_id
|
||||
print("Started a new hidden service with the address of %s.onion" % tor_service_id)
|
||||
|
||||
with open(key_path, 'w') as key_file:
|
||||
key_file.write('%s:%s' % (service.private_key_type, service.private_key))
|
||||
else:
|
||||
with open(key_path) as key_file:
|
||||
key_type, key_content = key_file.read().split(':', 1)
|
||||
|
||||
service = controller.create_ephemeral_hidden_service({80: port}, key_type = key_type, key_content = key_content, await_publication = True)
|
||||
tor_service_id = service.service_id
|
||||
print("Resumed %s.onion" % tor_service_id)
|
||||
|
||||
try:
|
||||
app.run(port=port, debug=debug, extra_files=extra_files)
|
||||
finally:
|
||||
if tor_service_id:
|
||||
print(" * Shutting down our hidden service")
|
||||
controller.remove_ephemeral_hidden_service(tor_service_id)
|
||||
Loading…
Add table
Add a link
Reference in a new issue