After the gateway receives and accepts HTTPS traffic, the gateway terminates the TLS connection, and forwards the unencrypted HTTP request to the destination in the cluster.

Figure: HTTPS listener setup

Before you begin

  1. Set up Gloo Mesh Gateway in a single cluster.
  2. Install Bookinfo and other sample apps.
  3. The openssl version must be at least 1.1.

    1. Check your openssl version. If you see LibreSSL in the output, continue to the next step.
        openssl version
    2. Install the OpenSSL version (not LibreSSL). For example, you might use Homebrew.
        brew install openssl
    3. Review the output of the OpenSSL installation for the path of the binary file. You can choose to export the binary to your path, or call the entire path whenever the following steps use an openssl command.
      • For example, openssl might be installed along the following path: /usr/local/opt/openssl@3/bin/
      • To run commands, you can append the path so that your terminal uses this installed version of OpenSSL, and not the default LibreSSL. /usr/local/opt/openssl@3/bin/openssl req -new -newkey rsa:4096 -x509 -sha256 -days 3650...

Create self-signed TLS certificates

Create a self-signed root certificate that you use to sign a server certificate for the HTTPS/TLS listener on your gateway.

To create your own TLS certificate for a test environment, complete the following steps.

  1. Create a self-signed root certificate. The following command creates a root certificate that is valid for a year and that can serve any hostname. You use this certificate to sign the server certificate for the gateway later. For other command options, see the OpenSSL docs.
      # root cert
    openssl req -new -newkey rsa:4096 -x509 -sha256 \
        -days 365 -nodes -out root.crt -keyout root.key \
        -subj "/CN=*/O=root" \
        -addext "subjectAltName = DNS:*"
  2. Use the root certificate to sign the server certificate for the gateway.
      # server cert
    cat > "gateway.conf" <<EOF
    req_extensions = v3_req
    distinguished_name = req_distinguished_name
    [ v3_req ]
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage = clientAuth, serverAuth
    subjectAltName = @alt_names
    DNS = *
    openssl genrsa -out "gateway.key" 2048
    openssl req -new -key "gateway.key" -out gateway.csr -subj "/CN=*/O=root" -config "gateway.conf"
    openssl x509 -req \
      -days 3650 \
      -CA root.crt -CAkey root.key \
      -set_serial 0 \
      -in gateway.csr -out gateway.crt \
      -extensions v3_req -extfile "gateway.conf"

Set up an HTTPS/TLS listener

Configure your gateway with the server TLS certificate to start serving HTTPS traffic on your gateway.

  1. Create a Kubernetes secret to store the TLS certificate for the gateway. You create the secret in the same cluster and namespace that the Istio ingress gateway pod is deployed to. If you followed the Get started guide, the ingress gateway pod is deployed to the gloo-mesh-gateways namespace by default.

      kubectl create secret generic gw-ssl-1-secret \
    --from-file=tls.key=gateway.key \
    --from-file=tls.crt=gateway.crt \
    --dry-run=client -oyaml | kubectl apply -f- \
    --namespace gloo-mesh-gateways
  2. If you have ingress gateway proxies in multiple clusters or namespaces, repeat the previous step for each namespace in each cluster that an Istio ingress gateway pod is installed. The name of the secret must be the same in all clusters, although the secret can be in different namespaces as appropriate.

  3. Configure an HTTPS listener on your gateway. The following example adds the HTTPS listener to the virtual gateway resource that you created as part of the Get started guide guide. For more information about virtual gateways, see the API docs.

      kubectl apply -f - <<EOF
    kind: VirtualGateway
      name: istio-ingressgateway
      namespace: bookinfo
      - allowedRouteTables:
        - host: '*'
        http: {}
          number: 443
          mode: SIMPLE
          secretName: gw-ssl-1-secret
      - allowedRouteTables:
        - host: '*'
        http: {}
        httpsRedirect: true
          number: 80
      - selector:
            istio: ingressgateway
    Review the following table to understand this configuration.
    metadata.namespaceCreate the virtual gateway in a namespace that is in the same workspace as your ingress gateway.
    spec.listeners.allowedRouteTablesYou can specify the hostname that the certificates are valid for, or select the route tables to use.
    spec.listeners.portSelect the HTTPS port 443, or you could use the to select HTTPS.
    spec.listeners.tlsConfigure the TLS mode and secret to use to secure traffic. The SIMPLE TLS mode ensures that incoming TLS connections are terminated at the gateway, and that the unencrypted HTTP traffic is forwarded to the destination. Note that if you set up multiple gateways in multiple namespaces or clusters, each of those clusters and namespaces must have the TLS secret.
    spec.workloadsUse a workload selector label for the ingress gateway service that you want the virtual gateway to configure. In this example, you configure the Istio ingress gateway that you set up as part of the Get started guide.

Verify the secure connection

Now that you set up your TLS certificate for your domain, verify that HTTPS requests can be sent successfully.

  1. Save the external address of the ingress gateway. If you deployed your ingress gateway in a different namespace or with a different version, update the command.

  2. Send a request to the httpbin app on the domain. Verify that you see a successful TLS handshake, the server TLS certificate that you created earlier, and a 200 HTTP response code from the httpbin app.

      curl -vik -H "X-httpbin: true" --resolve "${INGRESS_GW_ADDRESS}"

    Example output:

      * Added to DNS cache
    * Hostname was found in DNS cache
    *   Trying
    * Connected to ( port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    *  CAfile: /etc/ssl/cert.pem
    *  CApath: none
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: CN=*; O=root
    *  start date: Dec 15 19:12:08 2023 GMT
    *  expire date: Dec 12 19:12:08 2033 GMT
    *  issuer: CN=*; O=root
    *  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Using Stream ID: 1 (easy handle 0x150012400)
    > GET /status/200 HTTP/2
    > Host:
    > user-agent: curl/7.77.0
    > accept: */*
    > x-httpbin: true
    * Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
    < HTTP/2 200 
    HTTP/2 200 
    < access-control-allow-credentials: true
    access-control-allow-credentials: true
    < access-control-allow-origin: *
    access-control-allow-origin: *
    < date: Fri, 15 Dec 2023 19:17:20 GMT
    date: Fri, 15 Dec 2023 19:17:20 GMT
    < content-length: 0
    content-length: 0
    < x-envoy-upstream-service-time: 0
    x-envoy-upstream-service-time: 0
    < server: istio-envoy
    server: istio-envoy

Verify HTTPS listeners in local test setups

If you test locally by using minikube or kind, or if you have insufficient permissions in your cloud platform, the load balancer service that exposes the Istio ingress gateway is not assigned an external IP address or hostname and remains in a <pending> state. You can follow the steps in this guide to verify that your HTTPS listener works.

Next steps

Now that you have the virtual gateway configured, you can add other Gloo Mesh Gateway resources to control traffic that is routed through the gateway.