Summary
Support http(s)://<domain>.<pk>.dmsg (and, later, .skynet) as a first-class service/deployment URL format in services-config.json and the resolving proxy — alongside the existing dmsg://<pk>:<port> form — so Host-routed, mesh-fronted HTTP services can be addressed and aliased by name.
Context
We've put the skycoin node + explorer + blog behind Caddy on two prod hosts (*.theskywirenetwork.net and *.skycoin.com), with the host visor forwarding Caddy's :80 over dmsg/skynet (cli skynet port add 80). Two ways to reach a service over the mesh:
dmsg://<pk>:<port> — a direct per-service port forward. TCP-level. Identity = the forwarding visor's PK (or the service's own, if it runs a dmsg client).
http://<domain>.<pk>.dmsg — Host-routed through the visor's :80 forward + Caddy. One ingress fans many services out by Host, and inherits Caddy features (routing, compression, transform logging, header injection). HTTP-level.
Live state (verified)
- Direct forwards are up on both hosts (
dmsg://<pk>:6420 node, :8081 explorer, :8082 blog). dmsg://<pk>:6420/api/v1/health → 200.
- Port 80 is also forwarded (
caddy-websites), so the .dmsg Host-routed form is reachable — except it currently returns 404.
The concrete gap (.dmsg, near-term)
.dmsg is valid today because it rides the dmsg-server tier, which already aggregates client connections (the deployment box holds ~server-count sessions, not ~client-count). No new infrastructure is required.
But: curl of http://node.skycoin.com.<pk>.dmsg/api/v1/health through the resolving proxy returns 404. It's a Caddy 404 (the dmsg transport reaches Caddy) — the resolving proxy presents Host: node.skycoin.com.<pk>.dmsg, which matches no Caddy site block, and the client cannot override it (a forced bare Host: header still 404'd → the proxy owns the Host).
Fix: the resolving proxy (dmsgweb) should rewrite the forwarded Host to strip the .<pk>.dmsg suffix, presenting the bare <domain>, so Host-based backends (Caddy/nginx/…) route correctly. Small and self-contained. After that:
services-config.json accepts http(s)://<domain>.<pk>.dmsg as a service address form.
- The resolving proxy can alias service names to it (as it does for
dmsg:// deployment services today).
The gated part (.skynet, future)
.skynet is not ready and should be tracked as its own effort. It would use direct transports/routes, for which there is no aggregation tier — O(N) clients each dialing 1–2 deployment boxes does not scale (the exact fan-in problem dmsg servers solve for .dmsg). Making .skynet viable needs a relay/aggregation tier for the skynet control plane (e.g. dmsg server-to-server forwarding, and/or distributed relay across reward-eligible public nodes). Plumbing .dmsg addressing now sets up the config/resolver machinery so .skynet later becomes a transport swap rather than new plumbing.
Design notes (the two addressing models)
dmsg://pk:port binds identity to the endpoint PK (service's own key if it's a dmsg client, else the forwarding visor). End-to-end Noise auth to that key.
http://domain.pk.dmsg binds identity to the forwarding visor; <domain> is an (unauthenticated) routing hint for Host fan-out. The HTTP level is what lets a service without its own dmsg client still learn the authenticated caller PK — via visor-injected X-Skywire-Remote-PK on a trusted loopback listener (strip-then-set, fail-closed; trust by destination, never source-IP).
- Do not stack a visor port-forward on top of a service that keeps its own dmsg client → double dmsg-transit. It's either/or per service.
Proposed work
- Resolving proxy: strip
.<pk>.dmsg (.skynet) suffix from Host when forwarding (present bare <domain>). — unblocks .dmsg Host-routing.
services-config.json + resolver: accept and alias http(s)://<domain>.<pk>.dmsg service URLs.
- (later, separate)
.skynet support, gated on a skynet aggregation/relay tier.
- (optional design) per-service trusted-auth loopback port +
X-Skywire-Remote-PK injection, for PK-authz without a per-service dmsg client.
Summary
Support
http(s)://<domain>.<pk>.dmsg(and, later,.skynet) as a first-class service/deployment URL format inservices-config.jsonand the resolving proxy — alongside the existingdmsg://<pk>:<port>form — so Host-routed, mesh-fronted HTTP services can be addressed and aliased by name.Context
We've put the skycoin node + explorer + blog behind Caddy on two prod hosts (
*.theskywirenetwork.netand*.skycoin.com), with the host visor forwarding Caddy's:80over dmsg/skynet (cli skynet port add 80). Two ways to reach a service over the mesh:dmsg://<pk>:<port>— a direct per-service port forward. TCP-level. Identity = the forwarding visor's PK (or the service's own, if it runs a dmsg client).http://<domain>.<pk>.dmsg— Host-routed through the visor's:80forward + Caddy. One ingress fans many services out byHost, and inherits Caddy features (routing, compression, transform logging, header injection). HTTP-level.Live state (verified)
dmsg://<pk>:6420node,:8081explorer,:8082blog).dmsg://<pk>:6420/api/v1/health→ 200.caddy-websites), so the.dmsgHost-routed form is reachable — except it currently returns 404.The concrete gap (
.dmsg, near-term).dmsgis valid today because it rides the dmsg-server tier, which already aggregates client connections (the deployment box holds ~server-count sessions, not ~client-count). No new infrastructure is required.But:
curlofhttp://node.skycoin.com.<pk>.dmsg/api/v1/healththrough the resolving proxy returns 404. It's a Caddy 404 (the dmsg transport reaches Caddy) — the resolving proxy presentsHost: node.skycoin.com.<pk>.dmsg, which matches no Caddy site block, and the client cannot override it (a forced bareHost:header still 404'd → the proxy owns the Host).Fix: the resolving proxy (dmsgweb) should rewrite the forwarded
Hostto strip the.<pk>.dmsgsuffix, presenting the bare<domain>, so Host-based backends (Caddy/nginx/…) route correctly. Small and self-contained. After that:services-config.jsonacceptshttp(s)://<domain>.<pk>.dmsgas a service address form.dmsg://deployment services today).The gated part (
.skynet, future).skynetis not ready and should be tracked as its own effort. It would use direct transports/routes, for which there is no aggregation tier — O(N) clients each dialing 1–2 deployment boxes does not scale (the exact fan-in problem dmsg servers solve for.dmsg). Making.skynetviable needs a relay/aggregation tier for the skynet control plane (e.g. dmsg server-to-server forwarding, and/or distributed relay across reward-eligible public nodes). Plumbing.dmsgaddressing now sets up the config/resolver machinery so.skynetlater becomes a transport swap rather than new plumbing.Design notes (the two addressing models)
dmsg://pk:portbinds identity to the endpoint PK (service's own key if it's a dmsg client, else the forwarding visor). End-to-end Noise auth to that key.http://domain.pk.dmsgbinds identity to the forwarding visor;<domain>is an (unauthenticated) routing hint for Host fan-out. The HTTP level is what lets a service without its own dmsg client still learn the authenticated caller PK — via visor-injectedX-Skywire-Remote-PKon a trusted loopback listener (strip-then-set, fail-closed; trust by destination, never source-IP).Proposed work
.<pk>.dmsg(.skynet) suffix fromHostwhen forwarding (present bare<domain>). — unblocks.dmsgHost-routing.services-config.json+ resolver: accept and aliashttp(s)://<domain>.<pk>.dmsgservice URLs..skynetsupport, gated on a skynet aggregation/relay tier.X-Skywire-Remote-PKinjection, for PK-authz without a per-service dmsg client.