Docs
Ingress ControllerManage traffic and APIsTraffic ManagementTLS and mTLSConfigure HTTPS Between Client and Gateway

Configure HTTPS Between Client and Gateway

Learn how to use APISIX or API7 Ingress Controller to configure the gateway to accept HTTPS traffic from clients.

Applies to:API7 Ingress Controller (drives API7 Gateway)APISIX Ingress Controller (drives Apache APISIX)

Goal

Configure the gateway to accept HTTPS requests from clients and route them to an upstream service.

HTTPS

Client

APISIX / API7 Gateway

Upstream Service

HTTPS

Client

APISIX / API7 Gateway

Upstream Service

Before you begin

  • Complete Set Up Ingress Controller and Gateway.
  • You have kubectl configured against the cluster used in the setup guide.
  • You have OpenSSL installed to create the test CA and server certificate.
  • Choose a free local port for the gateway HTTPS port-forward. The examples use 9443.

Set the variables this guide uses:

export TLS_SNI="test.com"
export GATEWAY_SERVICE_NAME="apisix-gateway"   # your gateway's Service name in namespace aic
export GATEWAY_HTTPS_PORT="9443"

Steps

Step 1: Enable SSL on the gateway

Ensure that your gateway has enabled SSL.

helm upgrade apisix apisix/apisix \
  --set "apisix.ssl.enabled=true" \
  --set "apisix.ssl.containerPort=9443"

Step 2: Generate the test CA and server certificate

Generate the certificate authority (CA) key and certificate:

openssl genrsa -out ca.key 2048 && \
  openssl req -new -sha256 -key ca.key -out ca.csr -subj "/CN=ROOTCA" && \
  openssl x509 -req -days 36500 -sha256 -extensions v3_ca -signkey ca.key -in ca.csr -out ca.crt

Generate the key and certificate with the common name ${TLS_SNI} for the gateway, and sign with the CA certificate:

openssl genrsa -out server.key 2048 && \
  openssl req -new -sha256 -key server.key -out server.csr -subj "/CN=${TLS_SNI}" && \
  openssl x509 -req -days 36500 -sha256 -extensions v3_req \
  -CA ca.crt -CAkey ca.key -CAserial ca.srl -CAcreateserial \
  -in server.csr -out server.crt

Step 3: Configure downstream HTTPS

Create a Kubernetes TLS secret:

kubectl create secret tls test-tls-secret \
  --cert=server.crt \
  --key=server.key \
  --namespace=aic

Update your Gateway manifest file. The example uses the SNI test.com:

gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  namespace: aic
  name: apisix
spec:
  gatewayClassName: apisix
  listeners:
    - name: http
      protocol: HTTP
      port: 80
    - name: https
      protocol: HTTPS
      port: 443
      hostname: test.com
      tls:
        certificateRefs:
          - kind: Secret
            group: ""
            name: test-tls-secret
  infrastructure:
    parametersRef:
      group: apisix.apache.org
      kind: GatewayProxy
      name: apisix-config

The port in the Gateway listener is required but ignored. This is due to limitations in the data plane: it cannot dynamically open new ports. Since the Ingress Controller does not manage the data plane deployment, it cannot automatically update the configuration or restart the data plane to apply port changes.

Apply the configuration to your cluster:

kubectl apply -f gateway.yaml

Step 4: Create a route

Create an example route that forwards all requests with the path /ip to the upstream service httpbin.org:

httpbin-route.yaml
apiVersion: v1
kind: Service
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  type: ExternalName
  externalName: httpbin.org
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: quickstart-client-ip
spec:
  parentRefs:
  - name: apisix
  rules:
  - matches:
    - path:
        type: Exact
        value: /ip
    backendRefs:
    - name: httpbin-external-domain
      port: 80

Apply the configuration to your cluster:

kubectl apply -f httpbin-route.yaml

Validate

Forward the gateway's SSL port to your local machine:

kubectl port-forward -n aic "svc/${GATEWAY_SERVICE_NAME}" "${GATEWAY_HTTPS_PORT}:443" &

Since the certificate is valid only for the CN ${TLS_SNI}, use ${TLS_SNI} as the gateway's domain name. Send a request to the route:

curl -ikv --resolve "${TLS_SNI}:${GATEWAY_HTTPS_PORT}:127.0.0.1" "https://${TLS_SNI}:${GATEWAY_HTTPS_PORT}/ip"

Expected: a TLS handshake completes and the response contains HTTP/2 200.

Roll back / Clean up

Delete the manifests and secret created in this guide:

kubectl delete -f httpbin-route.yaml
kubectl delete -f gateway.yaml
kubectl delete -f tls.yaml
kubectl delete secret test-tls-secret -n aic
rm -f ca.key ca.crt ca.csr ca.srl server.key server.csr server.crt

Stop the local port-forward process if it is still running:

kill %1 2>/dev/null || true

Troubleshoot

SymptomCauseFix
curl cannot resolve or connect to the gateway.The gateway Service name or port-forward is wrong, or SSL is not enabled.Verify GATEWAY_SERVICE_NAME matches your gateway Service and that the product path in Step 1 enabled SSL.
curl reports a certificate error.The certificate CN does not match the requested SNI, or the server certificate was not signed by the CA the client trusts.Confirm TLS_SNI is the value used in the OpenSSL -subj and the Gateway/ApisixTls hosts/hostname, and that you included --cacert ca.crt if verifying the server.
The route returns 404.The HTTPRoute or ApisixRoute is not reconciled, or it does not match the requested path.Check that the route parentRefs resolve and that the path is /ip.