diff --git a/cmd/cloudflared/tunnel/cmd.go b/cmd/cloudflared/tunnel/cmd.go index 64e82978..52f68574 100644 --- a/cmd/cloudflared/tunnel/cmd.go +++ b/cmd/cloudflared/tunnel/cmd.go @@ -662,6 +662,12 @@ func tunnelFlags(shouldHide bool) []cli.Flag { EnvVars: []string{"TUNNEL_HOSTNAME"}, Hidden: shouldHide, }), + altsrc.NewStringFlag(&cli.StringFlag{ + Name: "http-host-header", + Usage: "Sets the HTTP Host header for the local webserver.", + EnvVars: []string{"TUNNEL_HTTP_HOST_HEADER"}, + Hidden: shouldHide, + }), altsrc.NewStringFlag(&cli.StringFlag{ Name: "origin-server-name", Usage: "Hostname on the origin server certificate.", diff --git a/cmd/cloudflared/tunnel/configuration.go b/cmd/cloudflared/tunnel/configuration.go index 31c3e43b..9fddcf7a 100644 --- a/cmd/cloudflared/tunnel/configuration.go +++ b/cmd/cloudflared/tunnel/configuration.go @@ -253,6 +253,7 @@ func prepareTunnelConfig( HTTPTransport: httpTransport, HeartbeatInterval: c.Duration("heartbeat-interval"), Hostname: hostname, + HTTPHostHeader: c.String("http-host-header"), IncidentLookup: origin.NewIncidentLookup(), IsAutoupdated: c.Bool("is-autoupdated"), IsFreeTunnel: isFreeTunnel, diff --git a/origin/tunnel.go b/origin/tunnel.go index 94b13deb..b86f2ab8 100644 --- a/origin/tunnel.go +++ b/origin/tunnel.go @@ -53,6 +53,7 @@ type TunnelConfig struct { HTTPTransport http.RoundTripper HeartbeatInterval time.Duration Hostname string + HTTPHostHeader string IncidentLookup IncidentLookup IsAutoupdated bool IsFreeTunnel bool @@ -447,12 +448,13 @@ func H1ResponseToH2Response(h1 *http.Response) (h2 []h2mux.Header) { } type TunnelHandler struct { - originUrl string - muxer *h2mux.Muxer - httpClient http.RoundTripper - tlsConfig *tls.Config - tags []tunnelpogs.Tag - metrics *TunnelMetrics + originUrl string + httpHostHeader string + muxer *h2mux.Muxer + httpClient http.RoundTripper + tlsConfig *tls.Config + tags []tunnelpogs.Tag + metrics *TunnelMetrics // connectionID is only used by metrics, and prometheus requires labels to be string connectionID string logger *log.Logger @@ -473,6 +475,7 @@ func NewTunnelHandler(ctx context.Context, } h := &TunnelHandler{ originUrl: originURL, + httpHostHeader: config.HTTPHostHeader, httpClient: config.HTTPTransport, tlsConfig: config.ClientTlsConfig, tags: config.Tags, @@ -566,6 +569,11 @@ func (h *TunnelHandler) createRequest(stream *h2mux.MuxedStream) (*http.Request, } func (h *TunnelHandler) serveWebsocket(stream *h2mux.MuxedStream, req *http.Request) (*http.Response, error) { + if h.httpHostHeader != "" { + req.Header.Set("Host", h.httpHostHeader) + req.Host = h.httpHostHeader + } + conn, response, err := websocket.ClientConnect(req, h.tlsConfig) if err != nil { return nil, err @@ -594,6 +602,11 @@ func (h *TunnelHandler) serveHTTP(stream *h2mux.MuxedStream, req *http.Request) // Request origin to keep connection alive to improve performance req.Header.Set("Connection", "keep-alive") + if h.httpHostHeader != "" { + req.Header.Set("Host", h.httpHostHeader) + req.Host = h.httpHostHeader + } + response, err := h.httpClient.RoundTrip(req) if err != nil { return nil, errors.Wrap(err, "Error proxying request to origin")