net: Tor service target port collides when running multiple nodes, making bitcoind error out #31133

issue laanwj openend this issue on October 22, 2024
  1. laanwj commented at 2:59 pm on October 22, 2024: member

    Various people have reported this on IRC after the 28.0 release, but have not created a GH issue, so i’m creating one.

    To be able to distinguish incoming localhost connections from connections on the Tor hidden (onion) service, we automatically create a separate “Tor service target” P2P port. This port is always opened, even if -listenonion=0, because the user might manually configure a Tor hidden service and wants the same behavior.

    DefaultOnionServiceTarget() creates the CService for the Tor service target port. This number is fixed in the chainparams to 8334 for mainnet, on localhost.

    Normally, this is no problem. However a common scenario is to run multiple bitcoin nodes on one machine (usually for testing) with different P2P and RPC ports. In this case, they will all try to bind to port 8334 and the latter ones will fail. This problem has existed since the Tor service port was introduced, however it became visible in v0.28 with #22729. After that PR it becomes a crash issue. (it was a problem before because multiple bitcoind instances would try to bind on port 8334 while ignoring failures, but still have the wrong internal knowledge that they bound on port 8334, passing this to Tor. So all of Tor’s connections would go to the first node)

    The current suggested workaround is to manually set -bind=.... This removes the automatic onion binds (although explicit -bind=.....=onion can be used to create new ones). i have tagged this issue with milestone 28.1 as it could be considered a regression and would be nice to have this automatically work again (especially in cases where the user doesn’t care about Tor, like in regtest harnesses).

    Various ideas to resolve this have been discussed, among which:

    1. Revert #22729: i strongly dislike this, as it would only bury the problem again. Explicit failures are always better than having to debug silent loss of functionality.
    2. Instead of hardcoding port 8334, make it P2P_port + 1: When overriding the -port, the Tor service target port changes at the same time. This resolves the problem automatically, except in the edge case where the different bitcoind instances’ P2P ports are specified very closely together (and maybe it’s just better to avoid that in the first place).
    3. Disable the Tor service port binding when -listenonion=0: This avoids the problem when the user doesn’t care about Onion binds, however it means that an extra option has to be set, it’s still not nice automatic behavior. Might as well set -bind= then.
    4. Disable the Tor service port binding when -regtest: In case of regtest, it’s uncommon to care about Tor. However not always; this would interfere with out own tests when we want to test interaction with Tor. It also doesn’t solve the issue in case of sigtest/mainnet.

    (some more, from @mzumsande in #31134)

    1. Do nothing and tell affected users to switch to -bind - maybe even deprecate -port
    2. if -port is given, don’t attempt to bind to the default onion port
    3. disable the automatic tor binding silently if the port is already used

    i personally prefer 2. It keeps the current behavior, except when port is overridden, and doesn’t require any special workarounds.

  2. laanwj added the label P2P on Oct 22, 2024
  3. laanwj added this to the milestone 28.1 on Oct 22, 2024
  4. fanquake commented at 3:00 pm on October 22, 2024: member
  5. mzumsande commented at 4:47 pm on October 22, 2024: contributor

    I do think that keeping -port around would be helpful, especially for users less knowledgeable about networking, who aren’t sure which address to put in an equivalent -bind command.

    I also like option 2, provided that the behavior will be well-documented, so that users specifying -port values for multiple nodes don’t pick consecutive ones by accident (which would then again lead to collisions). Otherwise I don’t see a downside.

    I would also be ok with option 6, if I specify a port like that I probably wouldn’t necessarily expect another bind to a fixed port for onion.

  6. Christewart commented at 4:53 pm on October 22, 2024: contributor
    I’m in the camp of deprecating and then removing the -port setting. It seems we should should just get people to migrate to bind. Is -port strictly a subset of -bind functionality? If so it seems simplifying the config options would make sense.
  7. vasild commented at 9:29 am on October 23, 2024: contributor

    I am in favor of 2. (port+1) or 5. (do nothing) in the short term, for 28.1.

    For long term, maybe deprecate and remove port= (yes, I think it is a subset of bind=, somebody correct me if I am wrong) in favor of bind=...:port. I agree that port= is “helpful, especially for users less knowledgeable about networking”, maybe to resolve that extend the syntax of bind= to allow bind=*:8333. That is used in at least Apache configs: <VirtualHost *:80>.

  8. mzumsande commented at 6:02 pm on November 5, 2024: contributor
    I opened #31223 to move this forward (it seems to be consensus that we should fix this either now or not at all).
  9. mzumsande commented at 8:54 pm on November 8, 2024: contributor

    (yes, I think it is a subset of bind=, somebody correct me if I am wrong)

    As far as I understand it, one difference is that -bind disables self-discovery of addresses because connOptions.bind_on_any will not be set - whereas -port will work together with bind-on-any. So if you want to use Discover() together with a non-default port, -port is the only option.

  10. vasild commented at 1:40 pm on November 12, 2024: contributor

    Right! Looks like for Discover() to run -discover must be enabled and -bind not used. It is tough to explain what a config like -discover=1 -bind=1.2.3.4:5555 would do. Seems that this is another thing that can be simplified.

    Edit: I mean that -discover=1 -bind=1.2.3.4:5555 will behave differently compared to -discover=0 -bind=1.2.3.4:5555 in a way that I find tough to explain.

    Also, this has another flaw: bind_on_any will be false if -bind=0.0.0.0:5555 is used, but it should really be true :-/

  11. mzumsande commented at 7:21 pm on November 14, 2024: contributor

    Also, this has another flaw: bind_on_any will be false if -bind=0.0.0.0:5555 is used, but it should really be true :-/

    I agree, setting bind_on_any (and thus making Discover() possible unless disabled) if the user specified bind-on-all explicitly via -bind=0.0.0.0 seems like a bug that should be fixed in master, regardless of this issue.

  12. vasild commented at 8:55 am on November 15, 2024: contributor
    Opened #31293 just that we don’t forget about it.

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-11 06:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me