Simple HTTPS/TLS
Use virtual gateways and set up TLS certificates for your gateway to serve HTTPS traffic.
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.
Before you begin
This guide assumes that you use the same names for components like clusters, workspaces, and namespaces as in the getting started. If you have different names, make sure to update the sample configuration files in this guide.
- Set up Gloo Mesh Gateway in a single cluster.
- Install Bookinfo and other sample apps.
- TheThe default
openssl
version that is included in macOS is LibreSSL, which does not work with these instructions. Make sure that you have the OpenSSL version ofopenssl
, not LibreSSL.openssl
version must be at least 1.1.- Check your
openssl
version. If you see LibreSSL in the output, continue to the next step.openssl version
- Install the OpenSSL version (not LibreSSL). For example, you might use Homebrew.
brew install openssl
- 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...
- For example,
- Check your
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.
In production environments, you might have a TLS certificate and key pair from a certificate management tool that you use. In this case, continue with Set up an HTTPS/TLS listener.
To create your own TLS certificate for a test environment, complete the following steps.
- 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:*"
- Use the root certificate to sign the server certificate for the gateway.
# server cert cat > "gateway.conf" <<EOF [req] req_extensions = v3_req distinguished_name = req_distinguished_name [req_distinguished_name] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [alt_names] DNS = * EOF 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.
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
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.
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.
Review the following table to understand this configuration.kubectl apply -f - <<EOF apiVersion: networking.gloo.solo.io/v2 kind: VirtualGateway metadata: name: istio-ingressgateway namespace: bookinfo spec: listeners: - allowedRouteTables: - host: '*' http: {} port: number: 443 tls: mode: SIMPLE secretName: gw-ssl-1-secret - allowedRouteTables: - host: '*' http: {} httpsRedirect: true port: number: 80 workloads: - selector: labels: istio: ingressgateway EOF
Setting Description metadata.namespace Create the virtual gateway in a namespace that is in the same workspace as your ingress gateway. spec.listeners.allowedRouteTables You can specify the hostname that the certificates are valid for, or select the route tables to use. spec.listeners.port Select the HTTPS port 443, or you could use the port.name
to select HTTPS.spec.listeners.tls Configure 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.workloads Use 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. When you apply this custom resource to your cluster, Gloo Mesh Gateway automatically checks the configuration against validation rules and value constraints. You can also run a pre-admission validation check by using themeshctl x validate resources
command. For more information, see the resource validation overview and the CLI command reference.
Verify the secure connection
Now that you set up your TLS certificate for your domain, verify that HTTPS requests can be sent successfully.
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.
export INGRESS_GW_ADDRESS=$(kubectl get svc -n gloo-mesh-gateways istio-ingressgateway -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESS
Send a request to the httpbin app on the
https.example.com
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 "www.example.com:443:${INGRESS_GW_ADDRESS}" https://www.example.com:443/status/200
Example output:
* Added www.example.com:443:34.86.217.21 to DNS cache * Hostname www.example.com was found in DNS cache * Trying 34.86.217.21:443... * Connected to www.example.com (34.86.217.21) 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: www.example.com > 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.
- Process and route traffic through the virtual gateway with route tables, such as by using header matching, redirects, or direct responses.
- Explore traffic management, security, and resiliency policies that you can apply to your routes and upstream services. For example, you might apply the proxy protocol policy to your API Gateway so that it preserves connection information such as the originating client IP address.