diff --git a/cmd/k8s-operator/depaware.txt b/cmd/k8s-operator/depaware.txt index d801c0285..38b8c4679 100644 --- a/cmd/k8s-operator/depaware.txt +++ b/cmd/k8s-operator/depaware.txt @@ -160,7 +160,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/ 💣 github.com/modern-go/reflect2 from github.com/json-iterator/go github.com/munnerz/goautoneg from k8s.io/kube-openapi/pkg/handler3+ github.com/opencontainers/go-digest from github.com/distribution/reference - github.com/pires/go-proxyproto from tailscale.com/ipn/ipnlocal + github.com/pires/go-proxyproto from tailscale.com/ipn/ipnlocal+ github.com/pkg/errors from github.com/evanphx/json-patch/v5+ github.com/pmezard/go-difflib/difflib from k8s.io/apimachinery/pkg/util/diff D github.com/prometheus-community/pro-bing from tailscale.com/wgengine/netstack diff --git a/cmd/k8s-proxy/k8s-proxy.go b/cmd/k8s-proxy/k8s-proxy.go index e00d43a94..38a86a5e0 100644 --- a/cmd/k8s-proxy/k8s-proxy.go +++ b/cmd/k8s-proxy/k8s-proxy.go @@ -50,6 +50,12 @@ import ( "tailscale.com/tsnet" ) +const ( + // proxyProtocolV2 enables PROXY protocol v2 to preserve original client + // connection info after TLS termination. + proxyProtocolV2 = 2 +) + func main() { encoderCfg := zap.NewProductionEncoderConfig() encoderCfg.EncodeTime = zapcore.RFC3339TimeEncoder @@ -441,24 +447,16 @@ func setServeConfig(ctx context.Context, lc *local.Client, cm *certs.CertManager if err != nil { return fmt.Errorf("error getting local client status: %w", err) } - serviceHostPort := ipn.HostPort(fmt.Sprintf("%s.%s:443", name.WithoutPrefix(), status.CurrentTailnet.MagicDNSSuffix)) + serviceSNI := fmt.Sprintf("%s.%s", name.WithoutPrefix(), status.CurrentTailnet.MagicDNSSuffix) serveConfig := ipn.ServeConfig{ - // Configure for the Service hostname. Services: map[tailcfg.ServiceName]*ipn.ServiceConfig{ name: { TCP: map[uint16]*ipn.TCPPortHandler{ 443: { - HTTPS: true, - }, - }, - Web: map[ipn.HostPort]*ipn.WebServerConfig{ - serviceHostPort: { - Handlers: map[string]*ipn.HTTPHandler{ - "/": { - Proxy: "http://localhost:80", - }, - }, + TCPForward: "localhost:80", + TerminateTLS: serviceSNI, + ProxyProtocol: proxyProtocolV2, }, }, }, diff --git a/k8s-operator/api-proxy/proxy.go b/k8s-operator/api-proxy/proxy.go index c4c651b1f..ff2e033af 100644 --- a/k8s-operator/api-proxy/proxy.go +++ b/k8s-operator/api-proxy/proxy.go @@ -12,20 +12,19 @@ import ( "encoding/json" "errors" "fmt" + "github.com/pires/go-proxyproto" + "go.uber.org/zap" "io" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/client-go/rest" + "k8s.io/client-go/transport" "net" "net/http" "net/http/httputil" "net/netip" "net/url" "strings" - "time" - - "go.uber.org/zap" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apiserver/pkg/endpoints/request" - "k8s.io/client-go/rest" - "k8s.io/client-go/transport" "tailscale.com/client/local" "tailscale.com/client/tailscale/apitype" "tailscale.com/envknob" @@ -38,6 +37,7 @@ import ( "tailscale.com/util/clientmetric" "tailscale.com/util/ctxkey" "tailscale.com/util/set" + "time" ) var ( @@ -163,10 +163,18 @@ func (ap *APIServerProxy) Run(ctx context.Context) error { } } else { var err error - proxyLn, err = net.Listen("tcp", "localhost:80") + baseLn, err := net.Listen("tcp", "localhost:80") if err != nil { return fmt.Errorf("could not listen on :80: %w", err) } + proxyLn = &proxyproto.Listener{ + Listener: baseLn, + ReadHeaderTimeout: 10 * time.Second, + ConnPolicy: proxyproto.ConnPolicyFunc(func(opts proxyproto.ConnPolicyOptions) (proxyproto.Policy, + error) { + return proxyproto.REQUIRE, nil + }), + } serve = ap.hs.Serve }