let the topology be pinned: trusted peer, outgoing switch, known nodes
Build docker image and push to registry.bitdeals.org / main-build-job (push) Successful in 1m50s
Build docker image and push to registry.bitdeals.org / main-build-job (push) Successful in 1m50s
A private Bitmessage contour cannot be assembled by letting the nodes find each other. The sybil check in connectionpool refuses a candidate whose /16 is already among the outbound connections, and every container of a compose project shares one /16 -- so each node keeps a single outbound connection to a randomly chosen peer, and the contour splits into components on some runs and not on others. Three variables make the topology explicit instead: BITMESSAGE_TRUSTED_PEER trustedpeer = host:port BITMESSAGE_SEND_OUTGOING sendoutgoingconnections = True/False BITMESSAGE_KNOWN_NODES host:port,... -> knownnodes.dat With them a star is one line of config per node: the hub takes SEND_OUTGOING=False and only accepts, the spokes take TRUSTED_PEER=<hub>:8444. Details worth knowing: - trustedpeer is absent from the stock keys.dat, so a substitution alone would be a silent no-op. The key is added the same way maxtotalconnections is, and it is added even when the value is empty -- that is how a node that was pinned before can be unpinned. Its anchors stop at "=" rather than "= ", because an empty value leaves no trailing space to match. - knownnodes.dat is rewritten on every start, not only when missing. "Only when missing" would never have fired: the image ships one, built by the `pybitmessage -t` run in the Dockerfile, and a named volume inherits it. Seeding it is also what stops the DNS bootstrap -- deserialising any peer that is neither a DEFAULT_NODE nor "self" raises knownNodesActual, and startBootstrappers only runs while that flag is down. - Both peer variables are validated here. PyBitmessage does check trustedpeer, but with a sys.exit() from a constructor in the network thread, which reads as a container that died for no stated reason.
This commit is contained in:
@@ -81,6 +81,9 @@ Container images are configured using parameters passed at runtime.
|
||||
|-e BITMESSAGE_STOPRESENDINGAFTERXDAYS|Stop resending unreceived message after X days. Default: `30`|
|
||||
|-e BITMESSAGE_APIVARIANT|provides xml or json-RPC API. Default: `legacy`|
|
||||
|-e BITMESSAGE_MAXTOTALCONNECTIONS|Cap on all connections at once, inbound and outbound together (`maxoutboundconnections` is 8, so this minus 8 is the inbound headroom). Default: `200`, the PyBitmessage stock value — lower it when the P2P port is published|
|
||||
|-e BITMESSAGE_TRUSTED_PEER|`host:port` of the one peer this node may connect out to; it dials nothing else. Default: empty — the node chooses its own peers. See Notes|
|
||||
|-e BITMESSAGE_SEND_OUTGOING|Whether the node dials out at all, `True` or `False`. Default: `True`. `False` gives a node that only accepts inbound connections — the hub of a private contour|
|
||||
|-e BITMESSAGE_KNOWN_NODES|Comma-separated `host:port` list, written into `knownnodes.dat` on every start in place of whatever was there. Default: empty — the file is left as it is. Also switches the DNS bootstrap off, see Notes|
|
||||
|
||||
# Notes
|
||||
|
||||
@@ -103,6 +106,23 @@ Container images are configured using parameters passed at runtime.
|
||||
published is found by the network on its own, as soon as it connects out —
|
||||
there is no host IP or DNS name to set anywhere. The one exception is a Tor
|
||||
hidden service, which needs an explicit `onionhostname`.
|
||||
- **A private contour needs its peers pinned, and a star to pin them into.**
|
||||
PyBitmessage refuses a candidate whose network group (the /16 for IPv4) is
|
||||
already represented among its outbound connections. Every container of one
|
||||
compose project lives in a single /16, so each node keeps exactly one outbound
|
||||
connection, to a peer it picked at random — which as often as not leaves the
|
||||
contour split into components. Give one node `BITMESSAGE_SEND_OUTGOING=False`
|
||||
so it becomes a hub that only accepts (the check looks at outbound connections
|
||||
only, so inbound are not capped by it), point the rest at it with
|
||||
`BITMESSAGE_TRUSTED_PEER=<hub-ip>:8444`, and objects travel spoke → hub →
|
||||
spokes. Use IP addresses, not service names: the sybil check parses the host
|
||||
as an IP, and the `addr` exchange between nodes carries IPs anyway.
|
||||
- **`BITMESSAGE_KNOWN_NODES` is what keeps a private contour private.** A node
|
||||
whose `knownnodes.dat` names a peer outside PyBitmessage's built-in default
|
||||
list stops asking `bootstrap8080.bitmessage.org` for more; without it even a
|
||||
pinned node resolves the public bootstrap host on every start. The file is
|
||||
rewritten on each start, so the variable, not the container's history, is what
|
||||
the node believes on boot.
|
||||
- **Publishing 8444 is a deliberate security trade-off.** The daemon runs on
|
||||
Python 2 and already parses untrusted data from its outbound peers, so an open
|
||||
port does not create that exposure — it changes *who* may connect, *when*, and
|
||||
|
||||
Reference in New Issue
Block a user