aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasil Dimov <vd@FreeBSD.org>2021-08-30 14:33:29 +0200
committerVasil Dimov <vd@FreeBSD.org>2021-11-24 12:44:05 +0100
commite53a8505dbb6f9deaae8ac82793a4fb760a1e0a6 (patch)
tree40507a94035ee59351b4a7008616b825a5b32ef6
parent9394964f6b9d1cf1220a4eca17ba18dc49ae876d (diff)
downloadbitcoin-e53a8505dbb6f9deaae8ac82793a4fb760a1e0a6.tar.xz
net: respect -onlynet= when making outbound connections
Do not make outbound connections to hosts which belong to a network which is restricted by `-onlynet`. This applies to hosts that are automatically chosen to connect to and to anchors. This does not apply to hosts given to `-connect`, `-addnode`, `addnode` RPC, dns seeds, `-seednodes`. Fixes https://github.com/bitcoin/bitcoin/issues/13378 Fixes https://github.com/bitcoin/bitcoin/issues/22647 Supersedes https://github.com/bitcoin/bitcoin/pull/22651
-rw-r--r--doc/i2p.md6
-rw-r--r--doc/release-notes.md6
-rw-r--r--doc/tor.md6
-rw-r--r--src/init.cpp33
-rw-r--r--src/torcontrol.cpp17
-rwxr-xr-xtest/functional/feature_proxy.py2
6 files changed, 45 insertions, 25 deletions
diff --git a/doc/i2p.md b/doc/i2p.md
index 5f631c11ca..ee650f3999 100644
--- a/doc/i2p.md
+++ b/doc/i2p.md
@@ -67,11 +67,7 @@ logging` for more information.
Make outgoing connections only to I2P addresses. Incoming connections are not
affected by this option. It can be specified multiple times to allow multiple
-network types, e.g. onlynet=ipv4, onlynet=ipv6, onlynet=onion, onlynet=i2p.
-
-Warning: if you use -onlynet with values other than onion, and the -onion or
--proxy option is set, then outgoing onion connections will still be made; use
--noonion or -onion=0 to disable outbound onion connections in this case.
+network types, e.g. onlynet=onion, onlynet=i2p.
I2P support was added to Bitcoin Core in version 22.0 and there may be fewer I2P
peers than Tor or IP ones. Therefore, using I2P alone without other networks may
diff --git a/doc/release-notes.md b/doc/release-notes.md
index 4483dee1dd..0095696b83 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -131,6 +131,12 @@ Updated settings
E.g. `-maxuploadtarget=500g`. No whitespace, +- or fractions allowed.
Default is `M` if no suffix provided. (#23249)
+- If `-proxy=` is given together with `-noonion` then the provided proxy will
+ not be set as a proxy for reaching the Tor network. So it will not be
+ possible to open manual connections to the Tor network for example with the
+ `addnode` RPC. To mimic the old behavior use `-proxy=` together with
+ `-onlynet=` listing all relevant networks except `onion`. (#22834)
+
Tools and Utilities
-------------------
diff --git a/doc/tor.md b/doc/tor.md
index 8dc82ca91e..9b0c40bad5 100644
--- a/doc/tor.md
+++ b/doc/tor.md
@@ -56,11 +56,7 @@ outgoing connections, but more is possible.
-onlynet=onion Make outgoing connections only to .onion addresses. Incoming
connections are not affected by this option. This option can be
specified multiple times to allow multiple network types, e.g.
- onlynet=ipv4, onlynet=ipv6, onlynet=onion, onlynet=i2p.
- Warning: if you use -onlynet with values other than onion, and
- the -onion or -proxy option is set, then outgoing onion
- connections will still be made; use -noonion or -onion=0 to
- disable outbound onion connections in this case.
+ onlynet=onion, onlynet=i2p.
In a typical situation, this suffices to run behind a Tor proxy:
diff --git a/src/init.cpp b/src/init.cpp
index a2060daf45..a3e97a98bd 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -441,7 +441,7 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-onion=<ip:port>", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-i2psam=<ip:port>", "I2P SAM proxy to reach I2P peers and accept I2P connections (default: none)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-i2pacceptincoming", "If set and -i2psam is also set then incoming I2P connections are accepted via the SAM proxy. If this is not set but -i2psam is set then only outgoing connections will be made to the I2P network. Ignored if -i2psam is not set. Listening for incoming I2P connections is done through the SAM proxy, not by binding to a local address and port (default: 1)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
- argsman.AddArg("-onlynet=<net>", "Make outgoing connections only through network <net> (" + Join(GetNetworkNames(), ", ") + "). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks. Warning: if it is used with non-onion networks and the -onion or -proxy option is set, then outbound onion connections will still be made; use -noonion or -onion=0 to disable outbound onion connections in this case.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
+ argsman.AddArg("-onlynet=<net>", "Make automatic outgoing connections only through network <net> (" + Join(GetNetworkNames(), ", ") + "). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-permitbaremultisig", strprintf("Relay non-P2SH multisig (default: %u)", DEFAULT_PERMIT_BAREMULTISIG), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
@@ -1315,11 +1315,12 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// Check for host lookup allowed before parsing any network related parameters
fNameLookup = args.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP);
+ proxyType onion_proxy;
+
bool proxyRandomize = args.GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE);
// -proxy sets a proxy for all outgoing network traffic
// -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default
std::string proxyArg = args.GetArg("-proxy", "");
- SetReachable(NET_ONION, false);
if (proxyArg != "" && proxyArg != "0") {
CService proxyAddr;
if (!Lookup(proxyArg, proxyAddr, 9050, fNameLookup)) {
@@ -1332,10 +1333,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
SetProxy(NET_IPV4, addrProxy);
SetProxy(NET_IPV6, addrProxy);
- SetProxy(NET_ONION, addrProxy);
SetProxy(NET_CJDNS, addrProxy);
SetNameProxy(addrProxy);
- SetReachable(NET_ONION, true); // by default, -proxy sets onion as reachable, unless -noonion later
+ onion_proxy = addrProxy;
}
// -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
@@ -1344,18 +1344,26 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
std::string onionArg = args.GetArg("-onion", "");
if (onionArg != "") {
if (onionArg == "0") { // Handle -noonion/-onion=0
- SetReachable(NET_ONION, false);
+ onion_proxy = proxyType{};
} else {
- CService onionProxy;
- if (!Lookup(onionArg, onionProxy, 9050, fNameLookup)) {
+ CService addr;
+ if (!Lookup(onionArg, addr, 9050, fNameLookup) || !addr.IsValid()) {
return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg));
}
- proxyType addrOnion = proxyType(onionProxy, proxyRandomize);
- if (!addrOnion.IsValid())
- return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg));
- SetProxy(NET_ONION, addrOnion);
- SetReachable(NET_ONION, true);
+ onion_proxy = proxyType{addr, proxyRandomize};
+ }
+ }
+
+ if (onion_proxy.IsValid()) {
+ SetProxy(NET_ONION, onion_proxy);
+ } else {
+ if (args.IsArgSet("-onlynet") && IsReachable(NET_ONION)) {
+ return InitError(
+ _("Outbound connections restricted to Tor (-onlynet=onion) but the proxy for "
+ "reaching the Tor network is not provided (no -proxy= and no -onion= given) or "
+ "it is explicitly forbidden (-onion=0)"));
}
+ SetReachable(NET_ONION, false);
}
for (const std::string& strAddr : args.GetArgs("-externalip")) {
@@ -1843,7 +1851,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
if (!Lookup(i2psam_arg, addr, 7656, fNameLookup) || !addr.IsValid()) {
return InitError(strprintf(_("Invalid -i2psam address or hostname: '%s'"), i2psam_arg));
}
- SetReachable(NET_I2P, true);
SetProxy(NET_I2P, proxyType{addr});
} else {
SetReachable(NET_I2P, false);
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index 55618a5c57..fdf1957bff 100644
--- a/src/torcontrol.cpp
+++ b/src/torcontrol.cpp
@@ -380,7 +380,22 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply&
CService resolved(LookupNumeric("127.0.0.1", 9050));
proxyType addrOnion = proxyType(resolved, true);
SetProxy(NET_ONION, addrOnion);
- SetReachable(NET_ONION, true);
+
+ const auto onlynets = gArgs.GetArgs("-onlynet");
+
+ const bool onion_allowed_by_onlynet{
+ !gArgs.IsArgSet("-onlynet") ||
+ std::any_of(onlynets.begin(), onlynets.end(), [](const auto& n) {
+ return ParseNetwork(n) == NET_ONION;
+ })};
+
+ if (onion_allowed_by_onlynet) {
+ // If NET_ONION is reachable, then the below is a noop.
+ //
+ // If NET_ONION is not reachable, then none of -proxy or -onion was given.
+ // Since we are here, then -torcontrol and -torpassword were given.
+ SetReachable(NET_ONION, true);
+ }
}
// Finally - now create the service
diff --git a/test/functional/feature_proxy.py b/test/functional/feature_proxy.py
index 7d9e5b70fc..fb0f6d7cb7 100755
--- a/test/functional/feature_proxy.py
+++ b/test/functional/feature_proxy.py
@@ -280,7 +280,7 @@ class ProxyTest(BitcoinTestFramework):
n3 = networks_dict(self.nodes[3].getnetworkinfo())
assert_equal(NETWORKS, n3.keys())
for net in NETWORKS:
- if net == NET_I2P:
+ if net == NET_I2P or net == NET_ONION:
expected_proxy = ''
else:
expected_proxy = f'[{self.conf3.addr[0]}]:{self.conf3.addr[1]}'