fix(net): answer TLS for the names a plugin exports - #4044
Conversation
0ff2643 made the vhost lookup exact: a name is served only if it has an entry of its own. It registered mDNS names as entries to match, but the loop that decides which names a host answers to still admitted only PublicDomain, PrivateDomain and Mdns. A hostname a URL plugin exported never got an entry, and the fallback to the port's `*` entry that used to cover it was gone, so every SSL .onion on an OS-terminated binding ended its handshake in `unrecognized name`. 0.4.0.1 still has the fallback and is unaffected. A plugin's name is served on the binding's assigned SSL port, since its provider forwards to the binding's bridge address whatever port the name advertises, and on the private leg whatever `public` the export carries. Its accept set is the binding's loopback and bridge SSL addresses alone: a plugin hostname has no gateways, and its provider connects from its own container. The regression never shipped, so the changelog amends the unreleased entry for the exact lookup rather than adding a Fixed line.
helix-a
left a comment
There was a problem hiding this comment.
One correctness issue in merging a plugin name with an existing private-domain entry; the standalone onion case looks correct.
Verification at 1250103a: all 12 net::net_controller::tests and all 44 net::vhost:: tests pass; the changed Rust file passes the pinned rustfmt check and git diff --check passes. An isolated Rust harness executing the unchanged named-vhost assembly and helpers reproduces the shared-name failure: plugin alone admits 10.0.3.1, but adding the private-domain row leaves only 192.0.2.10. Extending the accept set after entry lookup makes both cases pass. Native tests needed the generated build/env files staged at the legacy include path under shared-libs/build; that temporary directory was removed. I did not exercise this build on a StartOS VM.
…rows share A plugin name that is also a private domain on the same port shares one vhost entry with it. The private-domain row sorts first and made the entry, so the plugin-only bridge accept set was never applied and the provider's connection was rejected. Every named entry now starts from the binding's loopback and bridge SSL addresses, whatever row makes it. The named-vhost assembly moves into add_named_vhosts so the shared-name case has a regression test, and the ssl_vhost_private_ips doc comment the previous commit separated from its function goes back.
helix-a
left a comment
There was a problem hiding this comment.
Re-reviewed 832b816. The shared-name accept-set defect is fixed and covered through the production assembly helper. All 407 network tests and scoped formatting checks pass locally. No further correctness findings; VM verification remains unperformed.
Summary
On
master, an SSL.onionaddress on an OS-terminated binding fails its TLS handshake withunrecognized name. Every plugin-exported SSL hostname is affected; plaintext ones are not.0ff264313made the vhost lookup exact — "a name is served only if it has an entry of its own" — and registered mDNS names as entries to match. The loop innet_controller.rsthat decides which names a host answers to still admitted onlyPublicDomain | PrivateDomain | Mdns, so a hostname a URL plugin exported (HostnameMetadata::Plugin) never got an entry, and the fallback that used to cover it was gone. Released0.4.0.1is unaffected: its lookup still falls back to the port's*entry.named_vhost_legdecides the(port, leg)a name is served on. A plugin's name is served on the binding's assigned SSL port, because its provider forwards to the binding's bridge address whatever port the name itself advertises, and on the private leg whateverpublicthe export carries — that flag describes the URL, not how the connection arrives.ssl_vhost_internal_ips), whatever row creates it; gateway merges add to that. A plugin name has no gateways, so for it this is the whole accept set, and it holds when the name shares an entry with a private domain on the same port. Other services on the box reach any of the binding's names over the bridge the same way.add_named_vhosts, so it can be tested directly.Fixedline.Verification
a_plugin_name_is_served_on_the_bindings_ssl_port_over_internal_ips_alonecovers the helpers;every_named_vhost_accepts_the_bridge_even_when_names_share_an_entryruns the assembly for a plugin name, a private domain, a public domain, and a private domain and plugin name sharing one key. All 407net::tests pass; pinned rustfmt clean.0.4.0.2alpha VM (x86_64) with the Tor service, over the real Tor network against thestart-os/adminonion on port 443: with the.onionname as SNI the handshake ends inTLS alert, unrecognized name; the same onion and port with no SNI return HTTP 200. So the path Tor →10.0.3.1:443→ the TLS terminator → the UI is sound, and only the named entry was missing.Found while testing Start9Labs/tor-startos#39.