feat(client,membershipd): TLS on the HTTP control plane (H5)
Audit H5 (Alto, public). The control plane was signed but plaintext, so a network MITM could read all metadata (subjects, endpoints, public keys, sealed keys, blob hashes, the social graph) and drop requests. Signing gives integrity, not confidentiality. - membershipd serves the control plane over TLS (ListenAndServeTLS, MinVersion 1.2) with the same CA-signed cert as the data plane when --tls-cert is set; the fail-open guard already requires --bus-auth enforce alongside it. - The client gets a separate Options.CtrlTLS so the HTTP client pins the bus CA, independent of the NATS data-plane TLS. Connect now sets both planes' TLS from the one CA and REFUSES a plaintext http:// control-plane URL when a CA is provided, so metadata is never sent in the clear when TLS is expected. Connect's signature is unchanged; callers (worker/chat --ca, mobile NewSession) must pass an https:// control-plane URL when they pass a CA. Documented for the deploy step. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+19
-4
@@ -6,6 +6,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -139,10 +140,24 @@ func main() {
|
||||
}
|
||||
|
||||
go func() {
|
||||
log.Printf("HTTP control-plane API: http://%s", addr)
|
||||
log.Printf(" health: http://%s/healthz", addr)
|
||||
if err := httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Fatalf("http server: %v", err)
|
||||
var serveErr error
|
||||
if *tlsCert != "" {
|
||||
// Serve the control plane over TLS with the same CA-signed cert as the
|
||||
// data plane (audit H5): metadata (subjects, pubkeys, sealed keys, the
|
||||
// social graph) is no longer readable by a network MITM. The fail-open
|
||||
// guard already requires --bus-auth enforce alongside these flags.
|
||||
httpSrv.TLSConfig = &tls.Config{MinVersion: tls.VersionTLS12}
|
||||
log.Printf("HTTPS control-plane API: https://%s", addr)
|
||||
log.Printf(" health: https://%s/healthz", addr)
|
||||
log.Printf("control-plane TLS: ON (%s)", *tlsCert)
|
||||
serveErr = httpSrv.ListenAndServeTLS(*tlsCert, *tlsKey)
|
||||
} else {
|
||||
log.Printf("HTTP control-plane API: http://%s", addr)
|
||||
log.Printf(" health: http://%s/healthz", addr)
|
||||
serveErr = httpSrv.ListenAndServe()
|
||||
}
|
||||
if serveErr != nil && serveErr != http.ErrServerClosed {
|
||||
log.Fatalf("http server: %v", serveErr)
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user