Making ingress-gateway service listen only on port 443

Greeting all,

We’re currently running Istio version 1.7.6 and I’m trying to figure out the correct way to make the istio-gateway service listen only on the https port (=443), or at least not listen on port 80. I’ve tried adding

components:
  ingressGateways:
  - name: istio-ingressgateway
    enabled: true
    k8s:
      service:
        type: LoadBalancer
        ports:
        - name: https
          port: 443
          targetPort: 8443

to the IstioOperator setup but that causes the error

warn ads ADS:LDS: ACK ERROR router~10.244.5.10~istio-ingressgateway-65ffd7bdcf-h4bbq.istio-system~istio-system.svc.cluster.local-1883 Internal:Error adding/updating listener(s) 0.0.0.0_80: cannot bind '0.0.0.0:80': Permission denied
warning envoy config gRPC config for type.googleapis.com/envoy.config.listener.v3.Listener rejected: Error adding/updating listener(s) 0.0.0.0_80: cannot bind '0.0.0.0:80': Permission denied

which, presumably, is because the gateway is now running as non-root. I think this is because setting ports in the istio operator file also affects the istio-ingressgateway deployment, not just the public service. So I’m taking this to mean that I’m not really on the right track by manipulating the ports directly in this way. Is there some other, better, way to make the public service only listen on the https port?

/rycee

here is what we use to deploy istio ingress gateways on non default ports using the operator.

  ingressGateways:
  - name: istio-ingressgateway
    enabled: true
    k8s:
      env:
      - name: ISTIO_META_ROUTER_MODE
        value: "standard"
      service:
        ports:
        ## Default ports
        - port: 15021
          targetPort: 15021
          name: status-port
        - port: 8080
          targetPort: 8080
          name: http2
        - port: 8443
          targetPort: 8443
          name: https
        - port: 15443
          name: https-istio

There is also a second part to this though, when you create an Istio Gateway CRD and matching VirtualService you need to make sure it is also not on 80

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: echo-gw
spec:
  selector:
    app: echo-gateway
  servers:
    - port:
        number: 8443
        name: https
        protocol: HTTPS
      tls:
        mode: SIMPLE
        credentialName: echo-certs
      hosts:
        - "{{ .Hosts.Echo }}"
    - port:
        number: 8080
        name: http
        protocol: HTTP
      hosts:
        - "{{ .Hosts.Echo }}"

Thanks for the reply @nick_tetrate! We did something similar by putting http2 on a “hard to guess” non-standard port instead of port 80. But what we really would like to accomplish is to not have the port open at all. Our security people are upset with us having a non-encrypted port open, no matter whether any gateway is actually using it :confused:

That should be as simple as not exposing it in the ports list in the istiooperator CRD like this

  ingressGateways:
  - name: istio-ingressgateway
    enabled: true
    k8s:
      env:
      - name: ISTIO_META_ROUTER_MODE
        value: "standard"
      service:
        ports:
        - port: 15021
          targetPort: 15021
          name: status-port
        - port: 8443
          targetPort: 8443
          name: https

Yeah, that’s what I thought the code in my original post did. But then I got the cannot bind '0.0.0.0:80': Permission denied error in istiod and the newly started istio-ingressgateway hung.

I didn’t try with status-port included, though, is that one obligatory to include in the service? I will try tomorrow when I’m back at work. Many thanks for your help!

Switched to an ingressGateway very much like in the latest example but still encountered the problem. So I figured that the other suggestion about the Gateway CRD must be the key and indeed it was, found an old Gateway CRD that referenced port 80 in an unexpected namespace. Removed it and everything works just fine. Again, many thanks for your help @nick_tetrate!

1 Like