mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-03 09:56:38 -05:00
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
This commit is contained in:
parent
9394964f6b
commit
e53a8505db
6 changed files with 45 additions and 25 deletions
|
@ -67,11 +67,7 @@ logging` for more information.
|
||||||
|
|
||||||
Make outgoing connections only to I2P addresses. Incoming connections are not
|
Make outgoing connections only to I2P addresses. Incoming connections are not
|
||||||
affected by this option. It can be specified multiple times to allow multiple
|
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.
|
network types, e.g. 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.
|
|
||||||
|
|
||||||
I2P support was added to Bitcoin Core in version 22.0 and there may be fewer 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
|
peers than Tor or IP ones. Therefore, using I2P alone without other networks may
|
||||||
|
|
|
@ -131,6 +131,12 @@ Updated settings
|
||||||
E.g. `-maxuploadtarget=500g`. No whitespace, +- or fractions allowed.
|
E.g. `-maxuploadtarget=500g`. No whitespace, +- or fractions allowed.
|
||||||
Default is `M` if no suffix provided. (#23249)
|
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
|
Tools and Utilities
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|
|
@ -56,11 +56,7 @@ outgoing connections, but more is possible.
|
||||||
-onlynet=onion Make outgoing connections only to .onion addresses. Incoming
|
-onlynet=onion Make outgoing connections only to .onion addresses. Incoming
|
||||||
connections are not affected by this option. This option can be
|
connections are not affected by this option. This option can be
|
||||||
specified multiple times to allow multiple network types, e.g.
|
specified multiple times to allow multiple network types, e.g.
|
||||||
onlynet=ipv4, onlynet=ipv6, onlynet=onion, onlynet=i2p.
|
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.
|
|
||||||
|
|
||||||
In a typical situation, this suffices to run behind a Tor proxy:
|
In a typical situation, this suffices to run behind a Tor proxy:
|
||||||
|
|
||||||
|
|
33
src/init.cpp
33
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("-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("-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("-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("-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("-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);
|
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
|
// Check for host lookup allowed before parsing any network related parameters
|
||||||
fNameLookup = args.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP);
|
fNameLookup = args.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP);
|
||||||
|
|
||||||
|
proxyType onion_proxy;
|
||||||
|
|
||||||
bool proxyRandomize = args.GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE);
|
bool proxyRandomize = args.GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE);
|
||||||
// -proxy sets a proxy for all outgoing network traffic
|
// -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
|
// -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", "");
|
std::string proxyArg = args.GetArg("-proxy", "");
|
||||||
SetReachable(NET_ONION, false);
|
|
||||||
if (proxyArg != "" && proxyArg != "0") {
|
if (proxyArg != "" && proxyArg != "0") {
|
||||||
CService proxyAddr;
|
CService proxyAddr;
|
||||||
if (!Lookup(proxyArg, proxyAddr, 9050, fNameLookup)) {
|
if (!Lookup(proxyArg, proxyAddr, 9050, fNameLookup)) {
|
||||||
|
@ -1332,10 +1333,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
|
|
||||||
SetProxy(NET_IPV4, addrProxy);
|
SetProxy(NET_IPV4, addrProxy);
|
||||||
SetProxy(NET_IPV6, addrProxy);
|
SetProxy(NET_IPV6, addrProxy);
|
||||||
SetProxy(NET_ONION, addrProxy);
|
|
||||||
SetProxy(NET_CJDNS, addrProxy);
|
SetProxy(NET_CJDNS, addrProxy);
|
||||||
SetNameProxy(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
|
// -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
|
||||||
|
@ -1344,20 +1344,28 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
std::string onionArg = args.GetArg("-onion", "");
|
std::string onionArg = args.GetArg("-onion", "");
|
||||||
if (onionArg != "") {
|
if (onionArg != "") {
|
||||||
if (onionArg == "0") { // Handle -noonion/-onion=0
|
if (onionArg == "0") { // Handle -noonion/-onion=0
|
||||||
SetReachable(NET_ONION, false);
|
onion_proxy = proxyType{};
|
||||||
} else {
|
} else {
|
||||||
CService onionProxy;
|
CService addr;
|
||||||
if (!Lookup(onionArg, onionProxy, 9050, fNameLookup)) {
|
if (!Lookup(onionArg, addr, 9050, fNameLookup) || !addr.IsValid()) {
|
||||||
return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg));
|
return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg));
|
||||||
}
|
}
|
||||||
proxyType addrOnion = proxyType(onionProxy, proxyRandomize);
|
onion_proxy = proxyType{addr, proxyRandomize};
|
||||||
if (!addrOnion.IsValid())
|
|
||||||
return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg));
|
|
||||||
SetProxy(NET_ONION, addrOnion);
|
|
||||||
SetReachable(NET_ONION, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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")) {
|
for (const std::string& strAddr : args.GetArgs("-externalip")) {
|
||||||
CService addrLocal;
|
CService addrLocal;
|
||||||
if (Lookup(strAddr, addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid())
|
if (Lookup(strAddr, addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid())
|
||||||
|
@ -1843,7 +1851,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
if (!Lookup(i2psam_arg, addr, 7656, fNameLookup) || !addr.IsValid()) {
|
if (!Lookup(i2psam_arg, addr, 7656, fNameLookup) || !addr.IsValid()) {
|
||||||
return InitError(strprintf(_("Invalid -i2psam address or hostname: '%s'"), i2psam_arg));
|
return InitError(strprintf(_("Invalid -i2psam address or hostname: '%s'"), i2psam_arg));
|
||||||
}
|
}
|
||||||
SetReachable(NET_I2P, true);
|
|
||||||
SetProxy(NET_I2P, proxyType{addr});
|
SetProxy(NET_I2P, proxyType{addr});
|
||||||
} else {
|
} else {
|
||||||
SetReachable(NET_I2P, false);
|
SetReachable(NET_I2P, false);
|
||||||
|
|
|
@ -380,7 +380,22 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply&
|
||||||
CService resolved(LookupNumeric("127.0.0.1", 9050));
|
CService resolved(LookupNumeric("127.0.0.1", 9050));
|
||||||
proxyType addrOnion = proxyType(resolved, true);
|
proxyType addrOnion = proxyType(resolved, true);
|
||||||
SetProxy(NET_ONION, addrOnion);
|
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
|
// Finally - now create the service
|
||||||
|
|
|
@ -280,7 +280,7 @@ class ProxyTest(BitcoinTestFramework):
|
||||||
n3 = networks_dict(self.nodes[3].getnetworkinfo())
|
n3 = networks_dict(self.nodes[3].getnetworkinfo())
|
||||||
assert_equal(NETWORKS, n3.keys())
|
assert_equal(NETWORKS, n3.keys())
|
||||||
for net in NETWORKS:
|
for net in NETWORKS:
|
||||||
if net == NET_I2P:
|
if net == NET_I2P or net == NET_ONION:
|
||||||
expected_proxy = ''
|
expected_proxy = ''
|
||||||
else:
|
else:
|
||||||
expected_proxy = f'[{self.conf3.addr[0]}]:{self.conf3.addr[1]}'
|
expected_proxy = f'[{self.conf3.addr[0]}]:{self.conf3.addr[1]}'
|
||||||
|
|
Loading…
Add table
Reference in a new issue