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.
Before you begin
- Complete Set Up Ingress Controller and Gateway.
- You have
kubectlconfigured 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"By default, API7 Gateway enables SSL on container port 9443 and service port 443, so no additional configuration is required for this step.
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.crtGenerate 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.crtStep 3: Configure downstream HTTPS
Create a Kubernetes TLS secret:
kubectl create secret tls test-tls-secret \
--cert=server.crt \
--key=server.key \
--namespace=aicUpdate your Gateway manifest file. The example uses the SNI test.com:
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-configThe 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.yamlCreate a Kubernetes manifest file for TLS configuration. The example uses the SNI test.com:
apiVersion: apisix.apache.org/v2
kind: ApisixTls
metadata:
namespace: aic
name: test-tls
spec:
ingressClassName: apisix
hosts:
- test.com
secret:
name: test-tls-secret
namespace: aicApply the configuration to your cluster:
kubectl apply -f tls.yamlStep 4: Create a route
Create an example route that forwards all requests with the path /ip to the upstream service httpbin.org:
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: 80apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: quickstart-client-ip
spec:
ingressClassName: apisix
http:
- name: quickstart-client-ip
match:
paths:
- /ip
upstreams:
- name: httpbin-external-domainApply the configuration to your cluster:
kubectl apply -f httpbin-route.yamlValidate
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.crtStop the local port-forward process if it is still running:
kill %1 2>/dev/null || trueTroubleshoot
| Symptom | Cause | Fix |
|---|---|---|
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. |