HTTPS redirect
Redirect HTTP traffic to HTTPS.
For more information, see the Kubernetes Gateway API documentation.
Before you begin
-
Follow the Get started guide to install kgateway.
-
Follow the Sample app guide to create an API gateway proxy with an HTTP listener and deploy the httpbin sample app.
-
Get the external address of the gateway and save it in an environment variable.
export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESS
kubectl port-forward deployment/http -n kgateway-system 8080:8080
Set up an HTTPS listener
-
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.
kubectl create secret tls -n kgateway-system https \ --key example_certs/gateway.key \ --cert example_certs/gateway.crt kubectl label secret https gateway=https --namespace kgateway-system
- Configure an HTTPS listener on the Gateway that you created earlier. Note that your Gateway now has two listeners,
http
andhttps
. You reference these listeners later in this guide to configure the HTTP to HTTPS redirect.kubectl apply -f- <<EOF kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: http namespace: kgateway-system spec: gatewayClassName: kgateway listeners: - protocol: HTTP port: 8080 name: http allowedRoutes: namespaces: from: All - name: https port: 443 protocol: HTTPS tls: mode: Terminate certificateRefs: - name: https kind: Secret allowedRoutes: namespaces: from: All EOF
Redirect HTTP traffic to HTTPS
-
Create an HTTPRoute for the httpbin app that sets up a
RequestRedirect
filter. By using thehttps
scheme, you instruct the Gateway to redirect HTTP traffic to HTTPS and send back a 301 HTTP response code to the client.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-https-redirect namespace: httpbin labels: example: httpbin-route gateway: https spec: parentRefs: - name: http namespace: kgateway-system sectionName: http hostnames: - redirect.example rules: - filters: - type: RequestRedirect requestRedirect: scheme: https statusCode: 301 EOF
Setting Description spec.parentRefs.name
spec.parentRefs.namespace
The name and namespace of the Gateway resource that serves the route. In this example, you use the Gateway that you set up earlier. spec.parentRefs.sectionName
The Gateway listener to bind this route to. In this example, you want to apply the HTTPS redirect to all traffic that is sent to the HTTP listener on the Gateway. spec.hostnames
The hostname for which you want to apply the redirect. spec.rules.filters.type
The type of filter that you want to apply to incoming requests. In this example, the RequestRedirect
is used.spec.rules.filters.requestRedirect.scheme
The type of redirect that you want to apply. The https
scheme redirects all incoming HTTP traffic to HTTPS.spec.rules.filters.requestRedirect.statusCode
The HTTP status code that you want to return to the client in case of a redirect. For a permanent redirect, use the 301 HTTP status code. -
Create another HTTPRoute for the httpbin app that routes incoming HTTPS traffic to the httpbin app. Note that you bind this HTTPRoute to the HTTPS listener on your gateway by using
sectionName: https
.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-https namespace: httpbin labels: example: httpbin-route gateway: https spec: parentRefs: - name: http namespace: kgateway-system sectionName: https hostnames: - redirect.example rules: - backendRefs: - name: httpbin port: 8000 EOF
-
Send an HTTP request to the httpbin app on the
redirect.example
domain. Verify that you get back a 301 HTTP response code and that your redirect location showshttps://redirect.example:8080/status/200
.curl -vik http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: redirect.example"
curl -vik localhost:8080/status/200 -H "host: redirect.example"
Example output:
* Mark bundle as not supporting multiuse < HTTP/1.1 301 Moved Permanently HTTP/1.1 301 Moved Permanently < location: https://redirect.example:8080/status/200 location: https://redirect.example:8080/status/200 < date: Mon, 06 Nov 2024 01:48:12 GMT date: Mon, 06 Nov 2024 01:48:12 GMT < server: envoy server: envoy < content-length: 0 content-length: 0
-
Send an HTTPS request to the httpbin app on the
redirect.example
domain. Verify that you get back a 200 HTTP response code and that you can see a successful TLS handshake with the gateway.curl -vik https://$INGRESS_GW_ADDRESS:443/status/200 -H "host: redirect.example"
-
Port-forward the gateway proxy service on port 8443.
kubectl port-forward svc/http -n kgateway-system 8443:443
-
Send an HTTPS request to the
redirect.example
domain.curl -vik --connect-to redirect.example:443:localhost:8443 https://redirect.example/status/200
Example output:
* ALPN: curl offers h2,http/1.1 * (304) (OUT), TLS handshake, Client hello (1): * (304) (IN), TLS handshake, Server hello (2): * (304) (IN), TLS handshake, Unknown (8): * (304) (IN), TLS handshake, Certificate (11): * (304) (IN), TLS handshake, CERT verify (15): * (304) (IN), TLS handshake, Finished (20): * (304) (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF * ALPN: server did not agree on a protocol. Uses default. * Server certificate: * subject: CN=*; O=any domain * start date: Mar 14 13:37:22 2025 GMT * expire date: Mar 14 13:37:22 2026 GMT * issuer: O=any domain; CN=* * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. * using HTTP/1.x > GET /status/200 HTTP/1.1 > Host: redirect.example > User-Agent: curl/8.7.1 > Accept: */* > * Request completely sent off < HTTP/1.1 200 OK HTTP/1.1 200 OK ...
-
Cleanup
You can remove the resources that you created in this guide.-
Remove the HTTPRoutes for the httpbin app and the Kubernetes secret that holds the TLS certificate and key.
kubectl delete httproute,secret -A -l gateway=https
-
Remove the example_certs directory that stores your TLS credentials.
rm -rf example_certs
-
Remove the HTTPS listener from your Gateway.
kubectl apply -f- <<EOF kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: http namespace: kgateway-system spec: gatewayClassName: kgateway listeners: - protocol: HTTP port: 8080 name: http allowedRoutes: namespaces: from: All EOF