Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: Automatically create hidden service, listen on Tor #6639

Merged
merged 5 commits into from Nov 12, 2015

Conversation

laanwj
Copy link
Member

@laanwj laanwj commented Sep 4, 2015

Discussion in #6586.

Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket API, to create and destroy 'ephemeral' hidden services programmatically.
https://stem.torproject.org/api/control.html#stem.control.Controller.create_ephemeral_hidden_service

This means that if Tor is running (and proper authorization is available), bitcoin automatically creates a hidden service to listen on, without user manual configuration. This will positively affect the number of available .onion nodes.

  • When the node is started, connect to Tor through control socket
  • Send ADD_ONION command
  • First time:
    • Make it create a hidden service key
    • Save the key in the data directory for later usage
  • Make it redirect port 8333 to the local port 8333 (or whatever port we're listening on).
  • Keep control socket connection open for as long node is running. The hidden service will
    (by default) automatically go away when the connection is closed.

Adds command line options:

  • -listenonion Automatically create Tor hidden service (default: 1)
  • -torcontrol=<ip>:<port> "Tor control port to use if onion listening enabled (default: 127.0.0.1:9051)

TODO:

@laanwj laanwj added the P2P label Sep 4, 2015
@jgarzik
Copy link
Contributor

jgarzik commented Sep 15, 2015

I like the feature - concept ACK

Trying to think through whether there are edge cases that persuade us to default this 'off' Leaning towards default-on as presented.

@dcousens
Copy link
Contributor

dcousens commented Sep 16, 2015

concept ACK

1 similar comment
@btcdrak
Copy link
Contributor

btcdrak commented Sep 23, 2015

concept ACK

@sipa
Copy link
Member

sipa commented Sep 26, 2015

2015-09-26 00:03:11 [tor] Using COOKIE authentication, reading cookie authentication from /var/run/tor/control.authcookie
2015-09-26 00:03:11 [tor] Authentication cookie not found, is inaccessible, or is not exactly 64 bytes

I have ControlPort 9051 and CookieAuthentication in torrc.

@pstratem
Copy link
Contributor

pstratem commented Sep 26, 2015

Check the permissions
On Sep 25, 2015 5:07 PM, "Pieter Wuille" notifications@github.com wrote:

2015-09-26 00:03:11 [tor] Using COOKIE authentication, reading cookie
authentication from /var/run/tor/control.authcookie
2015-09-26 00:03:11 [tor] Authentication cookie not found, is
inaccessible, or is not exactly 64 bytes

I have ControlPort 9051 and CookieAuthentication in torrc.


Reply to this email directly or view it on GitHub
#6639 (comment).

@laanwj
Copy link
Member Author

laanwj commented Oct 2, 2015

@sipa the check was broken, the cookie is 32 bytes not 64. That said, we should have a more specific error message.

if (f == NULL)
return false;
if (fwrite(data.data(), 1, data.size(), f) != data.size())
return false;
Copy link
Member

@theuni theuni Oct 2, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

false case needs fclose too

Copy link
Member Author

@laanwj laanwj Oct 2, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops good catch

@theuni
Copy link
Member

theuni commented Oct 2, 2015

Can the shutdown detection be changed to work like the httpserver? ie Init calls InterruptTorControl() which starts the immediate shutdown process?


bool TorControlConnection::Disconnect()
{
if (b_conn)
Copy link
Member

@theuni theuni Oct 2, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to undo the AddLocal here?

@theuni
Copy link
Member

theuni commented Oct 2, 2015

(Not for this PR) Looks like it'd be pretty simple to add support for connecting via Unix socket (/var/run/tor/control) as well.

@theuni
Copy link
Member

theuni commented Oct 2, 2015

Concept ACK. This looks like a great feature.

@laanwj
Copy link
Member Author

laanwj commented Oct 3, 2015

@cfields

Can the shutdown detection be changed to work like the httpserver? ie Init calls InterruptTorControl() which starts the immediate shutdown process?

Yes, that sounds better. I have not done this before because it means making the libevent instance thread-safe - Interrupt happens from a different thread. But as we need multi-threaded libevent anyway from the http server that's a bad reason.

(Not for this PR) Looks like it'd be pretty simple to add support for connecting via Unix socket (/var/run/tor/control) as well.

Good idea.

@laanwj
Copy link
Member Author

laanwj commented Oct 3, 2015

Ok: addressed all of @theuni's comments (apart from the UNIX socket, which we can add later).
Still have SAFECOOKIE auth support on my TODO list above, it is superior to COOKIE (no potential exposure of data), and COOKIE will eventually be deprecated.
This does require use of HMAC-SHA256. Luckily we have an implementation of that for BIP32, so I think it's doable.

Edit: done

laanwj and others added 2 commits Nov 10, 2015
Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket
API, to create and destroy 'ephemeral' hidden services programmatically.
https://stem.torproject.org/api/control.html#stem.control.Controller.create_ephemeral_hidden_service

This means that if Tor is running (and proper authorization is available),
bitcoin automatically creates a hidden service to listen on, without user
manual configuration. This will positively affect the number of available
.onion nodes.

- When the node is started, connect to Tor through control socket
- Send `ADD_ONION` command
- First time:
    - Make it create a hidden service key
    - Save the key in the data directory for later usage
- Make it redirect port 8333 to the local port 8333 (or whatever port we're listening on).
- Keep control socket connection open for as long node is running. The hidden service will
  (by default) automatically go away when the connection is closed.
@laanwj
Copy link
Member Author

laanwj commented Nov 10, 2015

Also mentioned in release notes now.

@petertodd
Copy link
Contributor

petertodd commented Nov 10, 2015

ACK

Tests done:

  • Restart reuses cached onion private key
  • SAFECOOKIE auth
  • HASHEDPASSWORD auth
  • Onion advertisement stops with tor disconnects
  • Onion advertisement starts when tor restarted

@sipa
Copy link
Member

sipa commented Nov 11, 2015

No code review, did a weak test (it correctly reports my Tor version is too old).

@MarcoFalke
Copy link
Member

MarcoFalke commented Nov 11, 2015

That's great! I will try to look into this soon.

@petertodd
Copy link
Contributor

petertodd commented Nov 11, 2015

utACK squashme commits

service = CService(service_id+".onion", GetListenPort(), false);
LogPrintf("tor: Got service ID %s, advertizing service %s\n", service_id, service.ToString());
if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) {
LogPrint("tor", "tor: Cached service private key to %s\n", GetPrivateKeyFile());
Copy link
Member

@MarcoFalke MarcoFalke Nov 11, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: "Wrote service key..."?

Copy link
Member

@MarcoFalke MarcoFalke Nov 11, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, mind to pass this file through

contrib/devtools/clang-format.py clang-format src/torcontrol.cpp?

Copy link
Member

@MarcoFalke MarcoFalke Nov 12, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MarcoFalke
Copy link
Member

MarcoFalke commented Nov 11, 2015

Somehow I can set up a -onlynet=onion node and connect to it (sometimes) but it never established outgoing connections:

2015-11-11 22:05:45 tor: ADD_ONION succesful
2015-11-11 22:05:45 tor: Got service ID moheur3skn7jbca4, advertizing service moheur3skn7jbca4.onion:18333
2015-11-11 22:05:45 tor: Cached service private key to /home/test/.bitcoin/testnet3/onion_private_key
2015-11-11 22:05:45 AddLocal(moheur3skn7jbca4.onion:18333,4)
2015-11-11 22:05:46 Cannot connect to t6xj6wilh4ytvcs7.onion:18333: unsupported network
2015-11-11 22:05:46 Cannot connect to 4azvkpo55qaskhjl.onion:18333: unsupported network
2015-11-11 22:05:47 Cannot connect to nkf5e6b7pl4jfd4a.onion:18333: unsupported network
2015-11-11 22:05:48 Cannot connect to 4zhkir2ofl7orfom.onion:18333: unsupported network

@gits7r
Copy link

gits7r commented Nov 11, 2015

you are mistaking. it's -onlynet=tor . you confuse onion with -onion=127.0.0.1:9050 where you instruct bitcoin to use that socks5 proxy to connect to onion peers (from tor network). While -onlynet=tor will make sure you connect only to onion (Tor) peers, -onion=xxx will only provide a gateway for these peers but connect to other kind of peers also.

@MarcoFalke
Copy link
Member

MarcoFalke commented Nov 12, 2015

Then, why does -? doesn't even mention tor?

  -onlynet=<net>
       Only connect to nodes in network <net> (ipv4, ipv6 or onion)

@laanwj
Copy link
Member Author

laanwj commented Nov 12, 2015

onlynet=onion should work. But is unrelated to this pull. Did you pass a proxy?

@MarcoFalke
Copy link
Member

MarcoFalke commented Nov 12, 2015

I tried with and without proxy:
bitcoin/src/bitcoind -debug=tor -onlynet=onion -proxy=127.0.0.1:9050 -listen=1 -torpassword=bar

But maybe my VPS provider is blocking tor...

@laanwj
Copy link
Member Author

laanwj commented Nov 12, 2015

They could, but that whouldn't result in errors like

2015-11-11 22:05:46 Cannot connect to t6xj6wilh4ytvcs7.onion:18333: unsupported network

Instead you'd get proxy errors. It's not using the proxy, why is that (again, this is seemingly unrleated to this pull, maybe file a new issue)

laanwj added 2 commits Nov 12, 2015
- Force AUTHCOOKIE size to be 32 bytes: This provides protection against
  an attack where a process pretends to be Tor and uses the cookie
  authentication method to nab arbitrary files such as the
  wallet
- torcontrol logging
- fix cookie auth
- add HASHEDPASSWORD auth, fix fd leak when fwrite() fails
- better error reporting when cookie file is not ok
- better init/shutdown flow
- stop advertizing service when disconnected from tor control port
- COOKIE->SAFECOOKIE auth
@laanwj laanwj force-pushed the 2015_08_tor_hs_v2 branch 2 times, most recently from 944fcca to 58ef0ff Compare Nov 12, 2015
- add new data directory files for 0.12 to doc/files.md
- mention torcontrol in doc/tor.md
@laanwj laanwj merged commit 58ef0ff into bitcoin:master Nov 12, 2015
laanwj added a commit that referenced this pull request Nov 12, 2015
58ef0ff doc: update docs for Tor listening (Wladimir J. van der Laan)
68ccdc4 doc: Mention Tor listening in release notes (Wladimir J. van der Laan)
09c1ae1 torcontrol improvements and fixes (Wladimir J. van der Laan)
2f796e5 Better error message if Tor version too old (Peter Todd)
8f4e67f net: Automatically create hidden service, listen on Tor (Wladimir J. van der Laan)
@MarcoFalke
Copy link
Member

MarcoFalke commented Nov 12, 2015

tested ACK 58ef0ff

@bitcoin bitcoin locked as resolved and limited conversation to collaborators Dec 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants