HTTPS
Set up an HTTPS listener on your API gateway to secure access to your apps.
Before you begin
Follow the Get started guide to install Gloo Gateway, set up a gateway resource, and deploy the httpbin sample app.
Make sure that you have the OpenSSL version of openssl, not LibreSSL. The 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
Decide whether to set up an HTTP listener inline on the Gateway resource or as a separate ListenerSet resource. Note that ListenerSets are an experimental feature in the upstream Kubernetes Gateway API project, and subject to change. For more information, see the Listener overview.
Create a TLS certificate
Create a directory to store your TLS credentials in.
mkdir example_certs
Create a self-signed root certificate. The following command creates a root certificate that is valid for a year and 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 -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=any domain/CN=*' -keyout example_certs/root.key -out example_certs/root.crt
Use the root certificate to sign the gateway certificate.
openssl req -out example_certs/gateway.csr -newkey rsa:2048 -nodes -keyout example_certs/gateway.key -subj "/CN=*/O=any domain" openssl x509 -req -sha256 -days 365 -CA example_certs/root.crt -CAkey example_certs/root.key -set_serial 0 -in example_certs/gateway.csr -out example_certs/gateway.crt
Create a Kubernetes secret to store your server TLS certificate. You create the secret in the same cluster and namespace that the gateway is deployed to. Optionally, you can label the secret to make it easier to refer to later.
kubectl create secret tls -n gloo-system https \ --key example_certs/gateway.key \ --cert example_certs/gateway.crt kubectl label secret https gateway=https --namespace gloo-system
Set up an HTTPS listener
Create a gateway resource and configure an HTTPS listener.
Verify that the status of the gateway shows
ACCEPTED
.kubectl get gateway/https -n gloo-system -o yaml
Create an HTTP route for the httpbin app and add it to the HTTPS gateway that you created.
Verify that the HTTPRoute is applied successfully.
kubectl get httproute/httpbin-https -n httpbin -o yaml
Example output: Notice in the
status
section that the parentRef is either the Gateway or the ListenerSet, depending on how you attached the HTTPRoute.... status: parents: - conditions: - lastTransitionTime: "2025-04-29T20:48:51Z" message: "" observedGeneration: 3 reason: Accepted status: "True" type: Accepted - lastTransitionTime: "2025-04-29T20:48:51Z" message: "" observedGeneration: 3 reason: ResolvedRefs status: "True" type: ResolvedRefs controllerName: solo.io/gloo-gateway parentRef: group: gateway.networking.x-k8s.io kind: XListenerSet name: https-listenerset namespace: gloo-system
Verify that the listener now has a route attached.
Get the external address of the gateway and save it in an environment variable. Note that it might take a few seconds for the gateway address to become available.
Send a request to the httpbin app and verify that you see the TLS handshake and you get back a 200 HTTP response code.
Example output:
* 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=gateway * start date: Nov 5 01:54:04 2023 GMT * expire date: Nov 2 01:54:04 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 0x15200e800) > GET /status/200 HTTP/2 > Host: https.example.com > user-agent: curl/7.77.0 > accept: */* > * Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)! < HTTP/2 200 HTTP/2 200 ...
Cleanup
You can optionally remove the resources that you set up as part of this guide.Remove the routing resources for the HTTPS route, including the Kubernetes secret that holds the TLS certificate and key.
Remove the
example_certs
directory that stores your TLS credentials.rm -rf example_certs