mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-06 05:37:50 +02:00
Merge bitcoin/bitcoin#33414: tor: enable PoW defenses for automatically created hidden services
c68e3d2c57doc: add release notes for Tor PoW defenses (Vasil Dimov)4bae84c94adoc: add a hint to enable PoW defenses to manual hidden services (Vasil Dimov)4c6798a3d3tor: enable PoW defenses for automatically created hidden services (Vasil Dimov)fb993f7604tor, fuzz: reuse constants instead of duplicating (Vasil Dimov) Pull request description: Enable [PoW defenses](https://tpo.pages.torproject.net/onion-services/ecosystem/technology/security/pow/) for hidden services that we create via Tor Control using the [`ADD_ONION` command](https://spec.torproject.org/control-spec/commands.html#add_onion). The ability to do that has been added in [tor-0.4.9.2-alpha](02c1804446). Previous versions return a syntax error to the `ADD_ONION` command with `PoWDefensesEnabled=1`, so the approach here is to try with PoW and if we get syntax error, then retry without PoW. Also update `doc/tor.md` with a hint on enabling PoW on manually configured Tor hidden services. ACKs for top commit: willcl-ark: ACKc68e3d2c57fjahr: tACKc68e3d2c57sedited: ACKc68e3d2c57Tree-SHA512: 56f57bc770b89389c35a4c0bc2a28804d17b1479ecd4d9b764695d6c9d2994425aee759e71658d7b57088bbe43ce90b94fb972f66d79ef903e0c1a4d6c4562f3
This commit is contained in:
9
doc/release-notes-33414.md
Normal file
9
doc/release-notes-33414.md
Normal file
@@ -0,0 +1,9 @@
|
||||
Notable changes
|
||||
===============
|
||||
|
||||
P2P and network changes
|
||||
-----------------------
|
||||
|
||||
Tor hidden services that are created automatically by Bitcoin Core will have
|
||||
[PoW defenses](https://tpo.pages.torproject.net/onion-services/ecosystem/technology/security/pow/)
|
||||
enabled if the Tor daemon supports that. (#33414)
|
||||
@@ -181,6 +181,10 @@ Add these lines to your `/etc/tor/torrc` (or equivalent config file):
|
||||
|
||||
HiddenServiceDir /var/lib/tor/bitcoin-service/
|
||||
HiddenServicePort 8333 127.0.0.1:8334
|
||||
# If `tor --list-modules` shows "pow: yes", then enable PoW protection.
|
||||
# It is available in tor-0.4.8.1-alpha and newer when configured with
|
||||
# `./configure --enable-gpl`.
|
||||
HiddenServicePoWDefensesEnabled 1
|
||||
|
||||
The directory can be different of course, but virtual port numbers should be equal to
|
||||
your bitcoind's P2P listen port (8333 by default), and target addresses and ports
|
||||
|
||||
@@ -49,10 +49,13 @@ FUZZ_TARGET(torcontrol, .init = initialize_torcontrol)
|
||||
CallOneOf(
|
||||
fuzzed_data_provider,
|
||||
[&] {
|
||||
tor_control_reply.code = 250;
|
||||
tor_control_reply.code = TOR_REPLY_OK;
|
||||
},
|
||||
[&] {
|
||||
tor_control_reply.code = 510;
|
||||
tor_control_reply.code = TOR_REPLY_UNRECOGNIZED;
|
||||
},
|
||||
[&] {
|
||||
tor_control_reply.code = TOR_REPLY_SYNTAX_ERROR;
|
||||
},
|
||||
[&] {
|
||||
tor_control_reply.code = fuzzed_data_provider.ConsumeIntegral<int>();
|
||||
@@ -65,7 +68,10 @@ FUZZ_TARGET(torcontrol, .init = initialize_torcontrol)
|
||||
CallOneOf(
|
||||
fuzzed_data_provider,
|
||||
[&] {
|
||||
tor_controller.add_onion_cb(dummy_tor_control_connection, tor_control_reply);
|
||||
tor_controller.add_onion_cb(dummy_tor_control_connection, tor_control_reply, /*pow_was_enabled=*/true);
|
||||
},
|
||||
[&] {
|
||||
tor_controller.add_onion_cb(dummy_tor_control_connection, tor_control_reply, /*pow_was_enabled=*/false);
|
||||
},
|
||||
[&] {
|
||||
tor_controller.auth_cb(dummy_tor_control_connection, tor_control_reply);
|
||||
|
||||
@@ -53,9 +53,6 @@ const std::string DEFAULT_TOR_CONTROL = "127.0.0.1:" + ToString(DEFAULT_TOR_CONT
|
||||
static const int TOR_COOKIE_SIZE = 32;
|
||||
/** Size of client/server nonce for SAFECOOKIE */
|
||||
static const int TOR_NONCE_SIZE = 32;
|
||||
/** Tor control reply code. Ref: https://spec.torproject.org/control-spec/replies.html */
|
||||
static const int TOR_REPLY_OK = 250;
|
||||
static const int TOR_REPLY_UNRECOGNIZED = 510;
|
||||
/** For computing serverHash in SAFECOOKIE */
|
||||
static const std::string TOR_SAFE_SERVERKEY = "Tor safe cookie authentication server-to-controller hash";
|
||||
/** For computing clientHash in SAFECOOKIE */
|
||||
@@ -426,10 +423,20 @@ void TorController::get_socks_cb(TorControlConnection& _conn, const TorControlRe
|
||||
}
|
||||
}
|
||||
|
||||
void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlReply& reply)
|
||||
static std::string MakeAddOnionCmd(const std::string& private_key, const std::string& target, bool enable_pow)
|
||||
{
|
||||
// Note that the 'virtual' port is always the default port to avoid decloaking nodes using other ports.
|
||||
return strprintf("ADD_ONION %s%s Port=%i,%s",
|
||||
private_key,
|
||||
enable_pow ? " PoWDefensesEnabled=1" : "",
|
||||
Params().GetDefaultPort(),
|
||||
target);
|
||||
}
|
||||
|
||||
void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlReply& reply, bool pow_was_enabled)
|
||||
{
|
||||
if (reply.code == TOR_REPLY_OK) {
|
||||
LogDebug(BCLog::TOR, "ADD_ONION successful\n");
|
||||
LogDebug(BCLog::TOR, "ADD_ONION successful (PoW defenses %s)", pow_was_enabled ? "enabled" : "disabled");
|
||||
for (const std::string &s : reply.lines) {
|
||||
std::map<std::string,std::string> m = ParseTorReplyMapping(s);
|
||||
std::map<std::string,std::string>::iterator i;
|
||||
@@ -456,6 +463,12 @@ void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlRe
|
||||
// ... onion requested - keep connection open
|
||||
} else if (reply.code == TOR_REPLY_UNRECOGNIZED) {
|
||||
LogWarning("tor: Add onion failed with unrecognized command (You probably need to upgrade Tor)");
|
||||
} else if (pow_was_enabled && reply.code == TOR_REPLY_SYNTAX_ERROR) {
|
||||
LogDebug(BCLog::TOR, "ADD_ONION failed with PoW defenses, retrying without");
|
||||
_conn.Command(MakeAddOnionCmd(private_key, m_target.ToStringAddrPort(), /*enable_pow=*/false),
|
||||
[this](TorControlConnection& conn, const TorControlReply& reply) {
|
||||
add_onion_cb(conn, reply, /*pow_was_enabled=*/false);
|
||||
});
|
||||
} else {
|
||||
LogWarning("tor: Add onion failed; error code %d", reply.code);
|
||||
}
|
||||
@@ -477,9 +490,10 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply&
|
||||
private_key = "NEW:ED25519-V3"; // Explicitly request key type - see issue #9214
|
||||
}
|
||||
// Request onion service, redirect port.
|
||||
// Note that the 'virtual' port is always the default port to avoid decloaking nodes using other ports.
|
||||
_conn.Command(strprintf("ADD_ONION %s Port=%i,%s", private_key, Params().GetDefaultPort(), m_target.ToStringAddrPort()),
|
||||
std::bind_front(&TorController::add_onion_cb, this));
|
||||
_conn.Command(MakeAddOnionCmd(private_key, m_target.ToStringAddrPort(), /*enable_pow=*/true),
|
||||
[this](TorControlConnection& conn, const TorControlReply& reply) {
|
||||
add_onion_cb(conn, reply, /*pow_was_enabled=*/true);
|
||||
});
|
||||
} else {
|
||||
LogWarning("tor: Authentication failed");
|
||||
}
|
||||
|
||||
@@ -24,6 +24,11 @@ constexpr int DEFAULT_TOR_CONTROL_PORT = 9051;
|
||||
extern const std::string DEFAULT_TOR_CONTROL;
|
||||
static const bool DEFAULT_LISTEN_ONION = true;
|
||||
|
||||
/** Tor control reply code. Ref: https://spec.torproject.org/control-spec/replies.html */
|
||||
constexpr int TOR_REPLY_OK{250};
|
||||
constexpr int TOR_REPLY_UNRECOGNIZED{510};
|
||||
constexpr int TOR_REPLY_SYNTAX_ERROR{512}; //!< Syntax error in command argument
|
||||
|
||||
void StartTorControl(CService onion_service_target);
|
||||
void InterruptTorControl();
|
||||
void StopTorControl();
|
||||
@@ -138,7 +143,7 @@ public:
|
||||
/** Callback for GETINFO net/listeners/socks result */
|
||||
void get_socks_cb(TorControlConnection& conn, const TorControlReply& reply);
|
||||
/** Callback for ADD_ONION result */
|
||||
void add_onion_cb(TorControlConnection& conn, const TorControlReply& reply);
|
||||
void add_onion_cb(TorControlConnection& conn, const TorControlReply& reply, bool pow_was_enabled);
|
||||
/** Callback for AUTHENTICATE result */
|
||||
void auth_cb(TorControlConnection& conn, const TorControlReply& reply);
|
||||
/** Callback for AUTHCHALLENGE result */
|
||||
|
||||
Reference in New Issue
Block a user