For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
BackendTLS
Originate a one-way TLS connection from the Gateway to a backend.
Warning
About one-way TLS
When you configure a TLS listener on your Gateway, the Gateway typically terminates incoming TLS traffic and forwards the unencrypted traffic to the backend service. However, you might have a service that only accepts TLS connections, or you want to forward traffic to a secured backend service that is external to the cluster.
You can use the Kubernetes Gateway API BackendTLSPolicy to configure TLS origination from the Gateway to a service in the cluster. This policy supports simple, one-way TLS use cases.
About this guide
In this guide, you learn how to originate one-way TLS connections for the following services:
- In-cluster service: An NGINX server that is configured with a self-signed TLS certificate and deployed to the same cluster as the Gateway. You use a BackendTLSPolicy to originate TLS connections to NGINX.
- External service: The
httpbin.orghostname, which represents an external service that you want to originate a TLS connection to. You use a BackendTLSPolicy resource to originate TLS connections to that hostname.
Before you begin
Follow the Get started guide to install agentgateway.
Follow the Sample app guide to create a 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.
Tip
Kind cluster? Kind does not support
LoadBalancerservices by default. To use this option with a Kind cluster, install and runcloud-provider-kind.export INGRESS_GW_ADDRESS=$(kubectl get svc -n agentgateway-system agentgateway-proxy -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESS
In-cluster service
Deploy an NGINX server in your cluster that is configured for TLS traffic. Then, instruct the gateway proxy to terminate TLS traffic at the gateway and originate a new TLS connection from the gateway proxy to the NGINX server.
Create sample certificates
Create a CA and a server certificate for the example.com hostname. If you already have your own certificates such as from a CA provider, update the steps accordingly.
Warning
Self-signed certificates are used for demonstration purposes. Do not use self-signed certificates in production environments. Instead, use certificates that are issued from a trusted Certificate Authority.
Create the
example_certsdirectory and navigate to this directory.mkdir -p example_certs && cd example_certsCreate self-signed certificates for the Certificate Authority (CA) that you later use to sign the server certificate.
# Create CA private key openssl genrsa -out ca-key.pem 2048 # Create CA certificate (valid for 1 year) openssl req -new -x509 -days 365 -key ca-key.pem -out ca-cert.pem \ -subj "/CN=Test CA/O=Test Org"Create a server certificate for the
example.comhostname that is signed by the CA that you created in the previous step.# Create server private key openssl genrsa -out server-key.pem 2048 # Create server certificate signing request openssl req -new -key server-key.pem -out server.csr \ -subj "/CN=example.com/O=Test Org" # Create server certificate signed by CA (valid for 1 year) openssl x509 -req -days 365 -in server.csr -CA ca-cert.pem -CAkey ca-key.pem \ -CAcreateserial -out server-cert.pem \ -extensions v3_req -extfile <(echo "[v3_req]"; \ echo "basicConstraints=CA:FALSE"; \ echo "keyUsage=digitalSignature,keyEncipherment"; \ echo "extendedKeyUsage=serverAuth"; \ echo "subjectAltName=DNS:example.com,DNS:*.example.com")
Deploy the sample app
Deploy an NGINX server that serves HTTPS traffic. The NGINX server presents the server certificate, and the gateway proxy later uses the CA certificate to verify it.
Store the server certificate and key in a Kubernetes secret that the NGINX server mounts.
kubectl create secret tls nginx-server-cert \ --cert=server-cert.pem \ --key=server-key.pem \ -n agentgateway-systemDeploy the NGINX server and a Service that exposes it on HTTPS port 8443.
kubectl apply -f- <<EOF apiVersion: v1 kind: ConfigMap metadata: name: nginx-conf namespace: agentgateway-system labels: app: nginx data: nginx.conf: | events {} http { server { listen 443 ssl; server_name example.com; ssl_certificate /etc/nginx/certs/tls.crt; ssl_certificate_key /etc/nginx/certs/tls.key; location / { return 200 "hello from nginx\n"; } } } --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: agentgateway-system labels: app: nginx spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: nginx template: metadata: labels: app.kubernetes.io/name: nginx spec: containers: - name: nginx image: nginx:stable ports: - containerPort: 443 name: https-web-svc volumeMounts: - name: nginx-conf mountPath: /etc/nginx/nginx.conf subPath: nginx.conf - name: server-cert mountPath: /etc/nginx/certs readOnly: true volumes: - name: nginx-conf configMap: name: nginx-conf - name: server-cert secret: secretName: nginx-server-cert --- apiVersion: v1 kind: Service metadata: name: nginx namespace: agentgateway-system labels: app: nginx spec: selector: app.kubernetes.io/name: nginx ports: - protocol: TCP port: 8443 targetPort: https-web-svc name: https EOF
Verify that the NGINX server is running.
kubectl get pods -l app.kubernetes.io/name=nginx -n agentgateway-systemExample output:
NAME READY STATUS RESTARTS AGE nginx-7c8f9d5b4c-x2vlq 1/1 Running 0 9s
Originate TLS connections
Create a BackendTLSPolicy for the NGINX workload.
Create a Kubernetes ConfigMap that has the CA certificate the Gateway uses to verify the NGINX server. The CA certificate must be in the
ca.crtkey.kubectl create configmap ca \ --from-file=ca.crt=ca-cert.pem \ -n agentgateway-systemCreate the TLS policy. Note that to use the BackendTLSPolicy, you must have the experimental channel of the Kubernetes Gateway API version 1.4 or later.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: BackendTLSPolicy metadata: name: tls-policy namespace: agentgateway-system labels: app: nginx spec: targetRefs: - group: "" kind: Service name: nginx validation: hostname: "example.com" caCertificateRefs: - group: "" kind: ConfigMap name: ca EOFReview the following table to understand this configuration. For more information, see the Kubernetes Gateway API docs.
Setting Description targetRefsThe service that you want the Gateway to originate a TLS connection to, such as the NGINX server.
Agentgateway proxies: Even if you use a Backend for selector-based destinations, you still need to target the backing Service and thesectionNameof the port that you want the policy to apply to.validation.hostnameThe hostname that matches the NGINX server certificate. The gateway verifies this hostname against the Subject Alternative Names (SANs) or Common Name (CN) in the server certificate. validation.caCertificateRefsThe ConfigMap that has the CA certificate used to verify the backend, in a ca.crtkey. For the NGINX deployment in this guide, use the CA that signed the NGINX server certificate.Create an HTTPRoute that routes traffic to the NGINX server on the
example.comhostname and HTTPS port 8443. Note that the parent Gateway is the samplehttpGateway resource that you created before you began.kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: nginx-route namespace: agentgateway-system labels: app: nginx spec: parentRefs: - name: agentgateway-proxy namespace: agentgateway-system hostnames: - "example.com" rules: - backendRefs: - name: nginx port: 8443 EOFSend a request to the NGINX server and verify that you get back a 200 HTTP response code.
curl -vi http://$INGRESS_GW_ADDRESS:80/ -H "host: example.com:80"Example output:
* Host localhost:8080 was resolved. * IPv6: ::1 * IPv4: 127.0.0.1 * Trying [::1]:8080... * Connected to localhost (::1) port 8080 > GET / HTTP/1.1 > Host: example.com:8080 > User-Agent: curl/8.7.1 > Accept: */* > * Request completely sent off < HTTP/1.1 200 OK HTTP/1.1 200 OKThe HTTPRoute forwards the request to the NGINX server on port 8443, and the NGINX server accepts only TLS on that port. A 200 response means that the gateway proxy originated a TLS connection to the backend successfully. Without a valid BackendTLSPolicy and CA certificate, requests fail with
invalid peer certificate: UnknownIssuer.
External service
Set up an AgentgatewayBackend resource that represents your external service. Then, use a BackendTLSPolicy to instruct the gateway proxy to originate a TLS connection from the gateway proxy to the external service.
Create an AgentgatewayBackend resource that represents your external service. In this example, you use a static backend that routes traffic to the
httpbin.orgsite. Make sure to include the HTTPS port 443 so that traffic is routed to this port.kubectl apply -f- <<EOF apiVersion: agentgateway.dev/v1alpha1 kind: AgentgatewayBackend metadata: name: httpbin-org namespace: agentgateway-system spec: static: host: httpbin.org port: 443 EOFCreate a TLS policy that originates a TLS connection to the AgentgatewayBackend that you created in the previous step. To originate the TLS connection, you use known trusted CA certificates.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: BackendTLSPolicy metadata: name: httpbin-org namespace: agentgateway-system spec: targetRefs: - name: httpbin-org kind: AgentgatewayBackend group: agentgateway.dev validation: hostname: httpbin.org wellKnownCACertificates: System EOFCreate an HTTPRoute that rewrites traffic on the
httpbin-external.exampledomain to thehttpbin.orghostname and routes traffic to your Backend.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-org namespace: agentgateway-system spec: parentRefs: - name: agentgateway-proxy namespace: agentgateway-system hostnames: - "httpbin-external.example" rules: - matches: - path: type: PathPrefix value: /anything backendRefs: - name: httpbin-org kind: AgentgatewayBackend group: agentgateway.dev filters: - type: URLRewrite urlRewrite: hostname: httpbin.org EOFSend a request to the
httpbin-external.exampledomain. Verify that the host is rewritten tohttps://httpbin.org/anythingand that you get back a 200 HTTP response code.curl -vi http://$INGRESS_GW_ADDRESS:80/anything -H "host: httpbin-external.example"Example output:
< HTTP/1.1 200 OK HTTP/1.1 200 OK ... { "args": {}, "data": "", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Host": "httpbin.org", "User-Agent": "curl/8.7.1", "X-Amzn-Trace-Id": "Root=1-6881126a-03bfc90450805b9703e66e78", "X-Envoy-Expected-Rq-Timeout-Ms": "15000", "X-Envoy-External-Address": "10.0.X.XXX" }, "json": null, "method": "GET", "origin": "10.0.X.XXX, 3.XXX.XXX.XXX", "url": "https://httpbin.org/anything" }
Cleanup
You can remove the resources that you created in this guide.In-cluster service
kubectl delete deployment,service,backendtlspolicy,configmap,httproute -A -l app=nginx
kubectl delete secret nginx-server-cert -n agentgateway-system --ignore-not-found
kubectl delete configmap ca -n agentgateway-system --ignore-not-foundRemove the certificates that you created.
cd .. && rm -rf example_certsExternal service
Delete the resources that you created.
kubectl delete httproute httpbin-org -n agentgateway-system
kubectl delete backendtlspolicy httpbin-org -n agentgateway-system
kubectl delete AgentgatewayBackend httpbin-org -n agentgateway-system