Istio ingressgateway Returns 404 When Host Header has Port

Hello.

Istio: 1.7.4
Kubernetes: 1.19.3

Istio is returning a 404 when the Host header has the port included. This wasn’t the behavior I experienced on Istio 1.7.3. I can make curl requests where adding :443 to the host header returns a 404 . Seeing this behavior in Istio 1.7.4 but not 1.7.3.

Istio 1.7.4 Example:

$ curl https://moon-rancher-dev1-cluster.domain.com -H "Host: dev-easybake.domain.com" -I
HTTP/2 200
server: istio-envoy
date: Sat, 21 Nov 2020 01:20:08 GMT
content-type: text/html
content-length: 745
expires: Sat, 21 Nov 2020 01:20:07 GMT
cache-control: no-cache,no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0
x-service: easybake
last-modified: Saturday, 21-Nov-2020 01:20:08 GMT
accept-ranges: bytes
x-envoy-upstream-service-time: 0

$ curl https://moon-rancher-dev1-cluster.domain.com -H "Host: dev-easybake.domain.com:443" -I
HTTP/2 404
date: Sat, 21 Nov 2020 01:20:13 GMT
server: istio-envoy

Istio 1.7.3 Example:

$ curl https://moon-rancher-prod1-cluster.domain.com -H "Host: easybake.domain.com" -I
HTTP/2 200
server: istio-envoy
date: Sat, 21 Nov 2020 01:21:14 GMT
content-type: text/html
content-length: 745
expires: Sat, 21 Nov 2020 01:21:13 GMT
cache-control: no-cache,no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0
x-service: easybake
last-modified: Saturday, 21-Nov-2020 01:21:14 GMT
accept-ranges: bytes
x-envoy-upstream-service-time: 3

$ curl https://moon-rancher-prod1-cluster.domain.com -H "Host: easybake.domain.com:443" -I
HTTP/2 200
server: istio-envoy
date: Sat, 21 Nov 2020 01:21:17 GMT
content-type: text/html
content-length: 745
expires: Sat, 21 Nov 2020 01:21:16 GMT
cache-control: no-cache,no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0
x-service: easybake
last-modified: Saturday, 21-Nov-2020 01:21:17 GMT
accept-ranges: bytes
x-envoy-upstream-service-time: 4

The Envoy VirtualHost config is the same for both examples:

                "name": "dev-easybake.domain.com:443",
                "domains": [
                    "dev-easybake.domain.com",
                    "dev-easybake.domain.com:*"
                ],
                "name": "easybake.domain.com:443",
                "domains": [
                    "easybake.domain.com",
                    "easybake.domain.com:*"
                ],

I got the VirtualHost config from using istioctl against a ingressgateway pod in each cluster.

I tried to reproduce and could not. Can you provide the full config (VS/GW) and maybe large config dump? Also access logs would be useful (https://github.com/istio/istio/wiki/Troubleshooting-Istio has info)

If I recall correctly, Envoy does a simple string equality comparison between a request’s Host/authority header and the match strings specified in configuration.

Specifically, it doesn’t handle the optionality of the port number when the port number is the default port for the URI scheme (e.g., http vs. https), because it can’t–it doesn’t know the original scheme. (When Istio/Envoy is looking an HTTP request, it doesn’t know if the original scheme was http or https.)

Although the current HTTP spec says that the port number should be elided if it is the default port, earlier versions only said that it could be elided (not saying that it should be), so not all clients are going to behave the same way.