Browse Source

ipn/ipnlocal: [serve/funnel] use actual SrcAddr as X-Forwarded-For (#7600)

The reverse proxy was sending the ingressd IPv6 down as the
X-Forwarded-For. This update uses the actual remote addr.

Updates tailscale/corp#9914

Signed-off-by: Shayne Sweeney <[email protected]>
shayne 2 years ago
parent
commit
3177ccabe5
1 changed files with 19 additions and 11 deletions
  1. 19 11
      ipn/ipnlocal/serve.go

+ 19 - 11
ipn/ipnlocal/serve.go

@@ -439,18 +439,26 @@ func (b *LocalBackend) proxyHandlerForBackend(backend string) (*httputil.Reverse
 	if err != nil {
 		return nil, fmt.Errorf("invalid url %s: %w", targetURL, err)
 	}
-	rp := httputil.NewSingleHostReverseProxy(u)
-	rp.Transport = &http.Transport{
-		DialContext: b.dialer.SystemDial,
-		TLSClientConfig: &tls.Config{
-			InsecureSkipVerify: insecure,
+	rp := &httputil.ReverseProxy{
+		Rewrite: func(r *httputil.ProxyRequest) {
+			r.SetURL(u)
+			r.Out.Host = r.In.Host
+			if c, ok := r.Out.Context().Value(serveHTTPContextKey{}).(*serveHTTPContext); ok {
+				r.Out.Header.Set("X-Forwarded-For", c.SrcAddr.Addr().String())
+			}
+		},
+		Transport: &http.Transport{
+			DialContext: b.dialer.SystemDial,
+			TLSClientConfig: &tls.Config{
+				InsecureSkipVerify: insecure,
+			},
+			// Values for the following parameters have been copied from http.DefaultTransport.
+			ForceAttemptHTTP2:     true,
+			MaxIdleConns:          100,
+			IdleConnTimeout:       90 * time.Second,
+			TLSHandshakeTimeout:   10 * time.Second,
+			ExpectContinueTimeout: 1 * time.Second,
 		},
-		// Values for the following parameters have been copied from http.DefaultTransport.
-		ForceAttemptHTTP2:     true,
-		MaxIdleConns:          100,
-		IdleConnTimeout:       90 * time.Second,
-		TLSHandshakeTimeout:   10 * time.Second,
-		ExpectContinueTimeout: 1 * time.Second,
 	}
 	return rp, nil
 }