istio: tls.httpsRedirect doesn't work in Gateway resources

What I did: installed sample bookinfo app using Istio (via Helm chart from release-0.8 branch with istionightly:nightly-release-0.8 images) on GKE 1.9.6-gke.1, and tried using this Gateway:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - bookinfo.example.com
    tls:
      httpsRedirect: true
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - bookinfo.example.com
    tls:
      mode: SIMPLE
      serverCertificate: /etc/istio/istio-ingress-certs/tls.crt
      privateKey: /etc/istio/istio-ingress-certs/tls.key

Expected behavior: http request returns 302, https 200 Actual behavior: both http and https requests return 200

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 38 (9 by maintainers)

Most upvoted comments

The same issue here with a 0.8 cluster on 1.10.4 on GKE

I made the redirect work using protocol HTTP2 instead of just HTTP (Istio 1.2.0). Example from my helm chart:

---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: {{ .Chart.Name }}-gateway
  namespace: {{ .Release.Namespace }}
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
    - port:
        number: 80
        name: http-{{ .Chart.Name }}
        protocol: HTTP2 # <-- this is it!
      hosts:
      {{- range (pluck .Values.global.env .Values.ingress.hosts | first) }}
        - {{ .host | quote }}
      {{- end }}
      tls:
        httpsRedirect: true
    - port:
        number: 443
        name: https-{{ .Chart.Name }}
        protocol: HTTPS
      hosts:
      {{- range (pluck .Values.global.env .Values.ingress.hosts | first) }}
        - {{ .host | quote }}
      {{- end }}
      tls:
        credentialName: {{ .Values.ingress.istioCertServer }}
        mode: SIMPLE
        privateKey: sds
        serverCertificate: sds

I followed the following process to resolve this and have the redirect running currently:

I started by resetting the ingress IP and ports as it might have been the case that values were cleared between sessions.

https://istio.io/docs/tasks/traffic-management/ingress/#determining-the-ingress-ip-and-ports-when-using-an-external-load-balancer

I then followed the default setup for configuring the ingress gateway using the httpbin example until I was able to complete this curl:

https://istio.io/docs/tasks/traffic-management/ingress/#configuring-ingress-using-an-istio-gateway

curl -I -HHost:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/status/200

This confirmed that my ingress host and port values were set as well.

At this point I also had the httpbin service and deployment running.

All of this was done in a user created namespace with mutual tls.

I then tested this to ensure that tls redirect was working.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "httpbin.example.com"
    tls:
      httpsRedirect: true # sends 301 redirect for http requests

Once I confirmed that, I switched to my own gateway and virtual service files while using the prefixes from the httpbin virtual services to test the status responses.

To begin with, I set all hosts to “*” as desribed here:

https://istio.io/docs/tasks/traffic-management/ingress/#accessing-ingress-services-using-a-browser

This have me files like this which allowed my domain to have the https redirect:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: example-gateway
spec:
  selector:  
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
    tls:
      httpsRedirect: true # sends 301 redirect for http requests
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - "*"
    tls:
      mode: SIMPLE #enables HTTPS on this port
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
      privateKey: /etc/istio/ingressgateway-certs/tls.key


apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: example-virtual-service
spec:
  hosts:
  - "*"
  gateways:
  - example-gateway
  http:
  - match:
    - uri:
        prefix: /status
    - uri:
        prefix: /delay
    route:
    - destination:
        port:
          number: 8000
        host: httpbin

This was the first time that my domain had the redirect. I was then able to shift the host files away from using the catch all values and to using my specific domain. The final files were these which currently allow the redirect.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: example-gateway
spec:
  selector:  
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - example.com
    - www.example.com
    tls:
      httpsRedirect: true # sends 301 redirect for http requests
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - example.com
    - www.example.com
    tls:
      mode: SIMPLE #enables HTTPS on this port
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
      privateKey: /etc/istio/ingressgateway-certs/tls.key

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: example-virtual-service
spec:
  hosts:
  - example.com
  - www.example.com
  gateways:
  - example-gateway
  http:
  - match:
    - uri:
        prefix: "/"
    route:
    - destination:
        port:
          number: 80
        host: nginx-80-081618

Just tested this on the recently released 0.8.0, here are the results (using 1.9.7-gke.1 with either COS or ubuntu nodes):

  • With the configuration above, the response is now Recv failure: Connection reset by peer instead of 200 for http/80 requests
  • Changing httpsRedirect: true to httpsRedirect: false still responds with Recv failure: Connection reset by peer
  • Removing tls.httpsRedirect returns (as it should) 200

I believe this issue is caused by default gateway ‘istio-autogenerated-k8s-ingress’, which is installed by the chart. When I remove this gateway, https redirect on my custom gateway start to work as expected.