Browse Source

cmd/k8s-operator: require HTTPS to be enabled for AuthProxy

Updates #5055

Signed-off-by: Maisem Ali <[email protected]>
Maisem Ali 3 years ago
parent
commit
558735bc63
3 changed files with 22 additions and 13 deletions
  1. 2 6
      cmd/k8s-operator/operator.go
  2. 19 6
      cmd/k8s-operator/proxy.go
  3. 1 1
      tsnet/tsnet.go

+ 2 - 6
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)

+ 19 - 6
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)
 	}
 }

+ 1 - 1
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.