init: Configure reachable networks before we start the RPC server #32539

pull pinheadmz wants to merge 3 commits into bitcoin:master from pinheadmz:rpcallowip-rfc4193 changing 3 files +49 −26
  1. pinheadmz commented at 7:58 pm on May 16, 2025: member

    Closes #32433

    MaybeFlipIPv6toCJDNS() relies on g_reachable_nets to distinguish between CJDNS addresses and other IPv6 addresses. In particular, RFC4193 address or “Unique Local Address” with the L-bit unset also begins with the fc prefix. #32433 highlights a use case for these addresses that have nothing to do with CJDNS.

    On master we don’t parse init flags like -cjdnsreachable until after the HTTP server has started, causing conflicts with -rpcallowip because CJDNS doesn’t support subnets.

    This PR ensures that NET_CJDNS is only present in the reachable networks list if set by -cjdnsreachable before -rpcallowip is checked. If it is set all fc addresses are assumed to be CJDNS, can not have subnets, and can’t be set for -rpcallowip.

    I also noted this specific parameter interaction in the init help as well as the error message if configured incorrectly.

    This can be tested locally:

    bitcoind -regtest -rpcallowip=fc00:dead:beef::/64 -rpcuser=u -rpcpassword=p

    On master this will just throw an error that doesn’t even mention IPv6 at all.

    On the branch, this will succeed and can be tested by adding the ULA to a local interface.

    On linux: sudo ip -6 addr add fc00:dead:beef::1/64 dev lo

    On macos: sudo ifconfig lo0 inet6 fc00:dead:beef::1/128 add

    then: curl -v -g -6 --interface fc00:dead:beef::1 u:p@[::1]:18443 --data '{"method":"getblockcount"}'

    If the rpcallowip option is removed, the RPC request will fail to authorize.

    Finally, adding -cjdnsreachable to the start up command will throw an error and specify the incompatibility:

    RFC4193 is allowed only if -cjdnsreachable=0.

  2. init: Configure reachable networks before we start the RPC server
    We need to determine if CJDNS is reachable before we parse any IPv6
    addresses (for example, by the -rpcallowip setting) or an RFC4193
    address might get flipped to CJDNS, which can not be used with subnets
    f728b6b111
  3. config: Explain RFC4193 and CJDNS interaction in help and init error c02bd3c187
  4. test: ensure -rpcallowip is compatible with RFC4193 12ff4be9c7
  5. DrahtBot commented at 7:58 pm on May 16, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32539.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK tapcrafter, ryanofsky

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

  6. DrahtBot added the label CI failed on May 17, 2025
  7. DrahtBot removed the label CI failed on May 17, 2025
  8. in src/httpserver.cpp:230 in c02bd3c187 outdated
    226@@ -227,7 +227,7 @@ static bool InitHTTPAllowList()
    227         const CSubNet subnet{LookupSubNet(strAllow)};
    228         if (!subnet.IsValid()) {
    229             uiInterface.ThreadSafeMessageBox(
    230-                Untranslated(strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow)),
    231+                Untranslated(strprintf("Invalid -rpcallowip subnet specification: %s. Valid values are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0), a network/CIDR (e.g. 1.2.3.4/24), all ipv4 (0.0.0.0/0), or all ipv6 (::/0). RFC4193 is allowed only if -cjdnsreachable=0.", strAllow)),
    


    tapcrafter commented at 4:43 pm on May 17, 2025:
    I’m aware brevity is probably prioritized here. But I didn’t recognize RFC4193 just from its number, so had to look it up. What about “RFC4193 style IPv6 ULA addresses are only allowed…”?
  9. tapcrafter commented at 4:52 pm on May 17, 2025: none

    tACK 12ff4be9c724c752fe67835419be3ff4d0e65990

    Current error message on master (7710a31f0cb69a04529f39840196826d0b9770ab):

     0$ bitcoind -regtest -rpcallowip=fc00:dead:beef::/64 -rpcuser=u -rpcpassword=p
     1
     22025-05-17T16:24:29Z Command-line arg: regtest=""
     32025-05-17T16:24:29Z Command-line arg: rpcallowip="fc00:dead:beef::/64"
     42025-05-17T16:24:29Z Command-line arg: rpcpassword=****
     52025-05-17T16:24:29Z Command-line arg: rpcuser=****
     6...
     72025-05-17T16:24:29Z [error] Invalid -rpcallowip subnet specification: fc00:cafe:babe::/64. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).
     8Error: Invalid -rpcallowip subnet specification: fc00:dead:beef::/64. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).
     92025-05-17T16:24:29Z [error] Unable to start HTTP server. See debug log for details.
    10Error: Unable to start HTTP server. See debug log for details.
    

    Output on 12ff4be9c724c752fe67835419be3ff4d0e65990

     0$ bitcoind -regtest -rpcallowip=fc00:dead:beef::/64 -rpcbind=fc00:dead:beef::1 -cjdnsreachable -onlynet=cjdns -rpcuser=u -rpcpassword=p
     1
     22025-05-17T16:33:57Z Command-line arg: cjdnsreachable=""
     32025-05-17T16:33:57Z Command-line arg: onlynet="cjdns"
     42025-05-17T16:33:57Z Command-line arg: regtest=""
     52025-05-17T16:33:57Z Command-line arg: rpcallowip="fc00:dead:beef::/64"
     62025-05-17T16:33:57Z Command-line arg: rpcbind="fc00:dead:beef::1"
     72025-05-17T16:33:57Z Command-line arg: rpcpassword=****
     82025-05-17T16:33:57Z Command-line arg: rpcuser=****
     9...
    102025-05-17T16:33:57Z [error] Invalid -rpcallowip subnet specification: fc00:dead:beef::/64. Valid values are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0), a network/CIDR (e.g. 1.2.3.4/24), all ipv4 (0.0.0.0/0), or all ipv6 (::/0). RFC4193 is allowed only if -cjdnsreachable=0.
    11Error: Invalid -rpcallowip subnet specification: fc00:dead:beef::/64. Valid values are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0), a network/CIDR (e.g. 1.2.3.4/24), all ipv4 (0.0.0.0/0), or all ipv6 (::/0). RFC4193 is allowed only if -cjdnsreachable=0.
    

    Removing the -rpcallowip flag does then result in the request being denied as expected:

    0$ curl -v -g -6 --interface fc00:dead:beef::1 'u:p@[::1]:18443' --data '{"method":"getblockcount"}'
    1
    2...
    3HTTP/1.1 403 Forbidden
    4...
    

    Using a non-RFC4193 local address

    Starting bitcoind with a fd00 local address works without issue:

    0$ bitcoind -regtest -rpcallowip=fd00:dead:beef::/64 -rpcbind=fd00:dead:beef::1234 -cjdnsreachable -onlynet=cjdns -rpcuser=u -rpcpassword=p
    1
    2$ curl -v -g -6 --interface fd00:dead:beef::1234 'u:p@[fd00:dead:beef::1234]:18443' --data '{"method":"getblockcount"}'
    3
    4...
    5HTTP/1.1 200 OK
    6...
    7</details>
    
  10. ryanofsky approved
  11. ryanofsky commented at 5:10 pm on May 20, 2025: contributor

    Code review ACK 12ff4be9c724c752fe67835419be3ff4d0e65990

    Did not look closely how the RPC binding code works, but the only code change here is moving g_reachable_nets initialization earlier in the InitAppMain function, which makes sense and is safe. There is also a new test and documentation.

    Since the g_reachable_nets code has to move anyway, it could be make sense to move it into an InitReachableNets(args) or similar helper function so AppInitMain could be simpler. But not important, and maybe having a single function is better.


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: 2025-05-25 18:12 UTC

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