fix: enforce HTTP/1.1 ALPN in relay server proxy and update health endpoint

Removed the unused ALPN parameter from serveHTTP function and updated the proxy logic to explicitly require "http/1.1" ALPN for connections, ensuring compatibility and security by restricting to HTTP/1.1 protocol. Also changed the health check endpoint from "/health" to "/healthz" for consistency.

lemon-mint committed Oct 29, 2025 at 15:51 UTC c37a17ed09955c9d9e3db1b1dc30f97c607b39f6
2 files changed +10 -5
cmd/relay-server/main.go
+1 -1
@@ -53,7 +53,7 @@ func runServer(cmd *cobra.Command, args []string) error {
53 defer serv.Stop()
54
55 // Admin UI + per-peer HTTP proxy
56 - httpSrv := serveHTTP(ctx, fmt.Sprintf(":%d", flagPort), serv, cred.ID(), flagBootstraps, flagALPN, stop)
56 + httpSrv := serveHTTP(ctx, fmt.Sprintf(":%d", flagPort), serv, cred.ID(), flagBootstraps, stop)
57
58 <-ctx.Done()
59 log.Info().Msg("[server] shutting down...")
cmd/relay-server/view.go
+9 -4
@@ -9,6 +9,7 @@ import (
9 "net/http"
10 "net/http/httputil"
11 "net/url"
12 + "slices"
13 "strings"
14 "sync"
15 "time"
@@ -22,7 +23,7 @@ import (
23 )
24
25 // serveHTTP builds the HTTP mux and returns the server.
25 -func serveHTTP(ctx context.Context, addr string, serv *relaydns.RelayServer, nodeID string, bootstraps []string, alpn string, cancel context.CancelFunc) *http.Server {
26 +func serveHTTP(_ context.Context, addr string, serv *relaydns.RelayServer, nodeID string, bootstraps []string, cancel context.CancelFunc) *http.Server {
27 if addr == "" {
28 addr = ":0"
29 }
@@ -107,7 +108,11 @@ func serveHTTP(ctx context.Context, addr string, serv *relaydns.RelayServer, nod
108 http.Error(w, "lease not found or no ALPN registered", http.StatusNotFound)
109 return
110 }
110 - targetALPN := alpns[0] // Use the first ALPN
111 +
112 + if !slices.Contains(alpns, "http/1.1") {
113 + http.Error(w, "no http/1.1 ALPN registered", http.StatusNotFound)
114 + return
115 + }
116
117 // Temporary credential for this proxy connection
118 cred := sdk.NewCredential()
@@ -123,7 +128,7 @@ func serveHTTP(ctx context.Context, addr string, serv *relaydns.RelayServer, nod
128 proxy := httputil.NewSingleHostReverseProxy(target)
129 proxy.Transport = &http.Transport{
130 DialContext: func(c context.Context, network, address string) (net.Conn, error) {
126 - conn, err := client.Dial(cred, leaseID, targetALPN)
131 + conn, err := client.Dial(cred, leaseID, "http/1.1")
132 if err != nil {
133 return nil, err
134 }
@@ -186,7 +191,7 @@ func serveHTTP(ctx context.Context, addr string, serv *relaydns.RelayServer, nod
191 }
192 })
193
189 - mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
194 + mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
195 type info struct {
196 Status string `json:"status"`
197 }