protocol: enrollment links carry the public name, not the endpoint
Sharing port 443 between the admin UI and the control plane forces two hostnames — one port and one name is one certificate, and the two need different ones. That difference had been leaking into every enrollment link, so an operator handed out fmr-1.echo-lot.app when the thing they and their users know is fmr.echo-lot.app. The link now carries the public name and the app asks GET /v1/discover where to actually connect. The endpoint is plumbing: it exists to select a certificate, and nobody needs to see it. Discovery hands out an address and never a pin. The pin stays in the link. Fetching it over an ordinary TLS connection would make pinning worth exactly what the certificate authorities are worth, and pinning is there to survive one the operator does not control — a root injected by corporate device management, say, which is unremarkable on the networks this tool gets pointed at. With the pin pre-shared, an intercepted discovery can only send a device somewhere the pin will not match: an outage, not a compromise. Optional on both sides. A server that does not answer, or a link that already names the control endpoint, works unchanged — enrollment must not start failing because a lookup did. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
a720e84411
commit
082a2314ef
@@ -150,6 +150,17 @@ func mintEnrollToken(cfg *config.Config, note string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// controlURL is the address devices connect to: the hostname that selects the pinned certificate.
|
||||
//
|
||||
// Falls back to the public URL when no separate control hostname is configured, so a server that
|
||||
// does not share the admin port keeps answering discovery with something usable.
|
||||
func controlURL(cfg *config.Config) string {
|
||||
if cfg.ControlHostname == "" {
|
||||
return cfg.PublicControlURL
|
||||
}
|
||||
return "https://" + cfg.ControlHostname
|
||||
}
|
||||
|
||||
func serve(cfg *config.Config) error {
|
||||
slog.Info("echolot-server starting", "version", Version, "mode",
|
||||
map[bool]string{true: "container", false: "native"}[cfg.Docker],
|
||||
@@ -350,6 +361,10 @@ func serve(cfg *config.Config) error {
|
||||
ClientSecret: cfg.OIDCClientSecret,
|
||||
Secure: adminSecure,
|
||||
EnrollLink: ctl.EnrollmentLink,
|
||||
// Where devices should connect, for /v1/discover. Derived from the control hostname so it
|
||||
// cannot drift from the name that actually selects the pinned certificate.
|
||||
ControlURL: controlURL(cfg),
|
||||
ServerName: cfg.Name,
|
||||
SelfTest: func() any { return selftestPtr.Load() },
|
||||
Version: Version,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user