From 5a25a1c50daffe75e4f1a962d6155ee48cee46cd Mon Sep 17 00:00:00 2001 From: Andrew Burke <31974658+atburke@users.noreply.github.com> Date: Tue, 26 Apr 2022 10:46:04 -0700 Subject: [PATCH] Ignore HTTP_PROXY for reverse tunnels (#11990) This change disables the HTTP_PROXY support for reverse tunnel connections, as introduced in #10209. This is for backwards compatibility. --- api/client/webclient/webclient.go | 23 ++++++++++++++--------- api/client/webclient/webclient_test.go | 16 ++++++++++++++++ lib/reversetunnel/agent.go | 2 +- lib/reversetunnel/transport.go | 2 +- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/api/client/webclient/webclient.go b/api/client/webclient/webclient.go index 4ac5bd05f47ab..56417fe9c5936 100644 --- a/api/client/webclient/webclient.go +++ b/api/client/webclient/webclient.go @@ -57,6 +57,8 @@ type Config struct { // ExtraHeaders is a map of extra HTTP headers to be included in // requests. ExtraHeaders map[string]string + // IgnoreHTTPProxy disables support for HTTP proxying when true. + IgnoreHTTPProxy bool } // CheckAndSetDefaults checks and sets defaults @@ -77,16 +79,19 @@ func newWebClient(cfg *Config) (*http.Client, error) { if err := cfg.CheckAndSetDefaults(); err != nil { return nil, trace.Wrap(err) } - return &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - RootCAs: cfg.Pool, - InsecureSkipVerify: cfg.Insecure, - }, - Proxy: func(req *http.Request) (*url.URL, error) { - return httpproxy.FromEnvironment().ProxyFunc()(req.URL) - }, + transport := http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: cfg.Insecure, + RootCAs: cfg.Pool, }, + } + if !cfg.IgnoreHTTPProxy { + transport.Proxy = func(req *http.Request) (*url.URL, error) { + return httpproxy.FromEnvironment().ProxyFunc()(req.URL) + } + } + return &http.Client{ + Transport: &transport, }, nil } diff --git a/api/client/webclient/webclient_test.go b/api/client/webclient/webclient_test.go index 746b5b5674e34..3c171da45d581 100644 --- a/api/client/webclient/webclient_test.go +++ b/api/client/webclient/webclient_test.go @@ -329,3 +329,19 @@ func TestNewWebClientNoProxy(t *testing.T) { require.Contains(t, err.Error(), "lookup fakedomain.example.com") require.Contains(t, err.Error(), "no such host") } + +func TestNewWebClientIgnoreProxy(t *testing.T) { + t.Setenv("HTTPS_PROXY", "fakeproxy.example.com:9999") + client, err := newWebClient(&Config{ + Context: context.Background(), + ProxyAddr: "localhost:3080", + IgnoreHTTPProxy: true, + }) + require.NoError(t, err) + //nolint:bodyclose + resp, err := client.Get("https://fakedomain.example.com") + require.Error(t, err, "GET unexpectedly succeeded: %+v", resp) + require.NotContains(t, err.Error(), "proxyconnect") + require.Contains(t, err.Error(), "lookup fakedomain.example.com") + require.Contains(t, err.Error(), "no such host") +} diff --git a/lib/reversetunnel/agent.go b/lib/reversetunnel/agent.go index 9ad0f26d0ed48..76dfd23f5a21e 100644 --- a/lib/reversetunnel/agent.go +++ b/lib/reversetunnel/agent.go @@ -265,7 +265,7 @@ func (a *Agent) getHostCheckers() ([]ssh.PublicKey, error) { func (a *Agent) getReverseTunnelDetails() *reverseTunnelDetails { pd := reverseTunnelDetails{TLSRoutingEnabled: false} resp, err := webclient.Find( - &webclient.Config{Context: a.ctx, ProxyAddr: a.Addr.Addr, Insecure: lib.IsInsecureDevMode()}) + &webclient.Config{Context: a.ctx, ProxyAddr: a.Addr.Addr, Insecure: lib.IsInsecureDevMode(), IgnoreHTTPProxy: true}) if err != nil { // If TLS Routing is disabled the address is the proxy reverse tunnel diff --git a/lib/reversetunnel/transport.go b/lib/reversetunnel/transport.go index 56360955a2696..349dddd9db0f2 100644 --- a/lib/reversetunnel/transport.go +++ b/lib/reversetunnel/transport.go @@ -92,7 +92,7 @@ func (t *TunnelAuthDialer) DialContext(ctx context.Context, _, _ string) (net.Co // Check if t.ProxyAddr is ProxyWebPort and remote Proxy supports TLS ALPNSNIListener. resp, err := webclient.Find( - &webclient.Config{Context: ctx, ProxyAddr: addr.Addr, Insecure: t.InsecureSkipTLSVerify}) + &webclient.Config{Context: ctx, ProxyAddr: addr.Addr, Insecure: t.InsecureSkipTLSVerify, IgnoreHTTPProxy: true}) if err != nil { // If TLS Routing is disabled the address is the proxy reverse tunnel // address thus the ping call will always fail.