diff --git a/rootfs/etc/nginx/lua/lua_ingress.lua b/rootfs/etc/nginx/lua/lua_ingress.lua index 6411af7c6f9e..bee1d3cbaf33 100644 --- a/rootfs/etc/nginx/lua/lua_ingress.lua +++ b/rootfs/etc/nginx/lua/lua_ingress.lua @@ -68,6 +68,16 @@ local function redirect_host() return host_port[1]; end +local function parse_x_forwarded_host() + local hosts, err = ngx_re_split(ngx.var.http_x_forwarded_host, ",") + if err then + ngx.log(ngx.ERR, string_format("could not parse variable: %s", err)) + return "" + end + + return hosts[1] +end + function _M.init_worker() randomseed() end @@ -96,10 +106,7 @@ function _M.rewrite(location_config) -- Obtain best http host if ngx.var.http_x_forwarded_host then - -- TODO(elvinefendi) https://github.com/kubernetes/ingress-nginx/issues/3790 can - -- be fixed here by splitting the value of ngx.var.http_x_forwarded_host by ',' - -- and taking the first portion - ngx.var.best_http_host = ngx.var.http_x_forwarded_host + ngx.var.best_http_host = parse_x_forwarded_host() end end diff --git a/test/e2e/settings/forwarded_headers.go b/test/e2e/settings/forwarded_headers.go index 4bbdf952f127..92fe6becc91d 100644 --- a/test/e2e/settings/forwarded_headers.go +++ b/test/e2e/settings/forwarded_headers.go @@ -54,6 +54,7 @@ var _ = framework.IngressNginxDescribe("X-Forwarded headers", func() { return strings.Contains(server, "server_name forwarded-headers") }) + By("ensuring single values are parsed correctly") resp, body, errs := gorequest.New(). Get(f.GetURL(framework.HTTP)). Set("Host", host). @@ -70,6 +71,22 @@ var _ = framework.IngressNginxDescribe("X-Forwarded headers", func() { Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-proto=myproto"))) Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-port=1234"))) Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-for=1.2.3.4"))) + + By("ensuring that first entry in X-Forwarded-Host is used as the best host") + resp, body, errs := gorequest.New(). + Get(f.GetURL(framework.HTTP)). + Set("Host", host). + Set("X-Forwarded-Port", "1234"). + Set("X-Forwarded-Proto", "myproto"). + Set("X-Forwarded-For", "1.2.3.4"). + Set("X-Forwarded-Host", "myhost.com, another.host,example.net"). + End() + + Expect(errs).Should(BeEmpty()) + Expect(resp.StatusCode).Should(Equal(http.StatusOK)) + Expect(body).Should(ContainSubstring(fmt.Sprintf("host=myhost.com"))) + Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-host=myhost.com, another.host,example.net"))) + }) It("should not trust X-Forwarded headers when setting is false", func() { host := "forwarded-headers"