From 558735bc637f17bc0f85d43233b11559fae93d3a Mon Sep 17 00:00:00 2001 From: Maisem Ali Date: Mon, 13 Mar 2023 12:06:24 -0700 Subject: [PATCH] cmd/k8s-operator: require HTTPS to be enabled for AuthProxy Updates #5055 Signed-off-by: Maisem Ali --- cmd/k8s-operator/operator.go | 8 ++------ cmd/k8s-operator/proxy.go | 25 +++++++++++++++++++------ tsnet/tsnet.go | 2 +- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/cmd/k8s-operator/operator.go b/cmd/k8s-operator/operator.go index 82228f49f..be2e4790d 100644 --- a/cmd/k8s-operator/operator.go +++ b/cmd/k8s-operator/operator.go @@ -235,15 +235,11 @@ waitOnline: startlog.Infof("Startup complete, operator running") if shouldRunAuthProxy { - rc, err := rest.TransportFor(restConfig) + rt, err := rest.TransportFor(restConfig) if err != nil { startlog.Fatalf("could not get rest transport: %v", err) } - authProxyListener, err := s.Listen("tcp", ":443") - if err != nil { - startlog.Fatalf("could not listen on :443: %v", err) - } - go runAuthProxy(lc, authProxyListener, rc, zlog.Named("auth-proxy").Infof) + go runAuthProxy(s, rt, zlog.Named("auth-proxy").Infof) } if err := mgr.Start(signals.SetupSignalHandler()); err != nil { startlog.Fatalf("could not start manager: %v", err) diff --git a/cmd/k8s-operator/proxy.go b/cmd/k8s-operator/proxy.go index 94dde4809..847fdd559 100644 --- a/cmd/k8s-operator/proxy.go +++ b/cmd/k8s-operator/proxy.go @@ -5,10 +5,8 @@ package main import ( "context" - "crypto/tls" "fmt" "log" - "net" "net/http" "net/http/httputil" "net/url" @@ -17,6 +15,7 @@ import ( "tailscale.com/client/tailscale" "tailscale.com/client/tailscale/apitype" + "tailscale.com/tsnet" "tailscale.com/types/logger" ) @@ -41,11 +40,27 @@ func (h *authProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.rp.ServeHTTP(w, r) } -func runAuthProxy(lc *tailscale.LocalClient, ls net.Listener, rt http.RoundTripper, logf logger.Logf) { +// runAuthProxy runs an HTTP server that authenticates requests using the +// Tailscale LocalAPI and then proxies them to the Kubernetes API. +// It listens on :443 and uses the Tailscale HTTPS certificate. +// s will be started if it is not already running. +// rt is used to proxy requests to the Kubernetes API. +// +// It never returns. +func runAuthProxy(s *tsnet.Server, rt http.RoundTripper, logf logger.Logf) { + ln, err := s.ListenTLS("tcp", ":443") + if err != nil { + log.Fatalf("could not listen on :443: %v", err) + } u, err := url.Parse(fmt.Sprintf("https://%s:%s", os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT_HTTPS"))) if err != nil { log.Fatalf("runAuthProxy: failed to parse URL %v", err) } + + lc, err := s.LocalClient() + if err != nil { + log.Fatalf("could not get local client: %v", err) + } ap := &authProxy{ logf: logf, lc: lc, @@ -88,9 +103,7 @@ func runAuthProxy(lc *tailscale.LocalClient, ls net.Listener, rt http.RoundTripp Transport: rt, }, } - if err := http.Serve(tls.NewListener(ls, &tls.Config{ - GetCertificate: lc.GetCertificate, - }), ap); err != nil { + if err := http.Serve(ln, ap); err != nil { log.Fatalf("runAuthProxy: failed to serve %v", err) } } diff --git a/tsnet/tsnet.go b/tsnet/tsnet.go index 88b4f4d06..5bd9150d4 100644 --- a/tsnet/tsnet.go +++ b/tsnet/tsnet.go @@ -822,7 +822,7 @@ func (s *Server) ListenTLS(network, addr string) (net.Listener, error) { return nil, err } if len(st.CertDomains) == 0 { - return nil, errors.New("tsnet: you must enable HTTPS in the admin panel to proceed") + return nil, errors.New("tsnet: you must enable HTTPS in the admin panel to proceed. See https://tailscale.com/kb/1153/enabling-https/") } lc, err := s.LocalClient() // do local client first before listening.