Configure Gateways to use Aspen Mesh minted certificates#
This guide describes the process of consuming Aspen Mesh certificates by Gateways to terminate TLS traffic coming from end user clients. By default, all Aspen Mesh generated certificates only include SPIFFE URI in SAN which is not compatible with end user clients like browsers or curl. Adding SAN entries in certificates enables you to terminate TLS traffic coming from browsers and other end user clients at Aspen Mesh gateways.
The functionality provided by Aspen Mesh will enable you to have your Certificate Authority (CA) certificates be used to sign certificates for TLS termination at your gateway. The key benefit of using this capability is that the lifecycle and rotations of this certificate will be managed by Aspen Mesh.
Prerequisites#
DNS name is configured to point to the cluster via A, ALIAS, or CNAME records
Setup#
Follow the instructions for enabling Mesh Workload Certificates with SAN DNS and URI entries.
Follow the instructions for Consuming Aspen Mesh certificates via Kubernetes Secrets API to enable Aspen Mesh Citadel.
Ensure that the ingress gateway chart has been deployed successfully to your cluster.
$ helm ls -A | grep 'istio-ingress'
Create or modify a
Service Accountin the namespace where your ingress gateway was deployed to include the following annotation, which includes the domain your gateway will serve:metadata: annotations: "certificate.aspenmesh.io/customFields": '{ "SAN": { "DNS": [ "YOUR_DOMAIN_HERE" ] } }'
Aspen Mesh Citadel will create a secret named
istio.<YOUR SERVICE ACCOUNT NAME>in that namespace.Add or modify your Gateway resource to reference this secret
apiVersion: networking.istio.io/v1alpha3 kind: Gateway ... - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE credentialName: istio.<YOUR SERVICE ACCOUNT NAME>
This secret’s lifecycle, including rotation, will be handled by Aspen Mesh Citadel.
Create or modify a VirtualService associated with the service you wish to expose and connect it to the Gateway resource. You can follow the example below for a step-by-step guide.
Example Deployment#
Here you will deploy a copy of the httpbin application from the samples directory found in the Aspen Mesh install
directory and expose it via the ingress gateway using the certificate generated from Aspen Mesh Citadel based on httpbin’s
Service Account. These steps assume that Aspen Mesh has been installed into the cluster and that the current directory
is the root of the extracted installation archive.
Note
This example assumes you have deployed your own CA certificates for use within the cluster and that Aspen Mesh Citadel has been enabled and deployed.
Create an
httpbinnamespace where thehttpbinapplication will be deployed:$ kubectl create namespace httpbin
Enable Istio Sidecar injection in the
httpbinnamespace$ kubectl label namespace httpbin istio-injection=enabled
Add to the namespace the label
ca.istio.io/overrideto have Aspen Mesh Citadel generate secrets for Service Accounts$ kubectl label --overwrite namespace httpbin ca.istio.io/override=true
Deploy the ingressgateway chart to the
httpbinnamespace$ helm install httpbin-ingress manifests/charts/gateways/istio-ingress \ --namespace httpbin --values <YOUR OVERRIDES>
Store the domain your gateway will serve as a variable within bash. Modify the value to your domain.
$ export MY_DOMAIN=YOUR_DOMAIN_HERE
Deploy the
httpbinapplication to thehttpbinnamespace. Note that service account has been augmented to provide certificate annotations.$ cat <<EOF | kubectl apply -n httpbin -f - apiVersion: v1 kind: ServiceAccount metadata: name: httpbin annotations: "certificate.aspenmesh.io/customFields": '{ "SAN": { "DNS": [ "$MY_DOMAIN" ] } }' --- apiVersion: v1 kind: Service metadata: name: httpbin labels: app: httpbin spec: ports: - name: http port: 8000 targetPort: 80 selector: app: httpbin --- apiVersion: apps/v1 kind: Deployment metadata: name: httpbin spec: replicas: 1 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: serviceAccountName: httpbin containers: - image: docker.io/kennethreitz/httpbin imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 80 EOF
Verify that the secret
istio.httpbinis created for the service accounthttpbinassociated with thehttpbindeployment:$ kubectl get secret istio.httpbin -n httpbin
NAME TYPE DATA AGE istio.httpbin istio.io/key-and-cert 3 1m
Verify that the certificate contains an extension for SAN using the domain you specified above:
$ kubectl get secret -n httpbin istio.httpbin -o yaml | \ yq r - 'data."cert"' | base64 --decode | openssl x509 -noout -text
Certificate: Data: ... X509v3 Subject Alternative Name: critical URI:spiffe://cluster.local/ns/httpbin/sa/httpbin, DNS:YOUR_DOMAIN_HEREDeploy the following Gateway and Virtual Service to your cluster to enable routing of traffic from the ingress gateway to the
httpbinworkload:$ cat <<EOF | kubectl apply -n httpbin -f - apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: httpbin-gateway spec: selector: istio: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE credentialName: istio.httpbin hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin spec: hosts: - "*" gateways: - httpbin-gateway http: - route: - destination: host: httpbin port: number: 8000 EOF
Fetch and store the ingress hostname that your ingressgateway is listening on so that we can send requests to the
httpbinapplication:$ export INGRESS_HOST=$(kubectl -n httpbin get service istio-ingressgateway \ -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
You can inspect the certificate presented by the ingress gateway using the
openssltool:$ echo | openssl s_client -showcerts -connect $INGRESS_HOST:443 2>/dev/null | \ openssl x509 -inform pem -noout -text
Certificate: Data: ... Validity Not Before: Nov 12 03:24:14 2020 GMT Not After : Nov 13 03:24:14 2020 GMT ... URI:spiffe://cluster.local/ns/httpbin/sa/httpbin, DNS:YOUR_DOMAIN_HERECongratulations, you’ve now setup Aspen Mesh to serve the managed
istio.httpbinsecret to clients of your gateway!