Encrypt API gateway traffic on virtual machines
This topic describes how to make TLS certificates available to API gateways so that requests between the user and the gateway endpoint are encrypted.
Requirements
- Consul v1.15 or later is required to use the Consul API gateway on VMs
- Consul v1.19 or later is required to use the file system certificate configuration entry
- You must have a certificate and key from your CA
- A Consul cluster with service mesh enabled. Refer to
connect - Network connectivity between the machine deploying the API gateway and a Consul cluster agent or server
ACL requirements
If ACLs are enabled, you must present a token with the following permissions to configure Consul and deploy API gateways:
Refer Mesh Rules for additional information about configuring policies that enable you to interact with Consul API gateway configurations.
Define TLS certificates
- Create a file system certificate or inline certificate and specify the following fields:
Kind: Specifies the type of configuration entry. This must be set tofile-system-certificateorinline-certificate.Name: Specify the name in the API gateway listener configuration to bind the certificate to that listener.Certificate: Specifies the filepath to the certificate on the local system or the inline public certificate as plain text.PrivateKey: Specifies the filepath to private key on the local system or the inline private key to as plain text.
- Configure any additional fields necessary for your use case, such as the namespace or admin partition. Refer to the file system certificate configuration reference or inline certificate configuration reference for more information.
- Save the configuration.
Examples
The following example defines a certificate named my-certificate. API gateway configurations that specify inline-certificate in the Certificate.Kind field and my-certificate in the Certificate.Name field are able to use the certificate.
Kind = "inline-certificate"
Name = "my-certificate"
Certificate = <<EOF
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
EOF
PrivateKey = <<EOF
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
EOF
Deploy the configuration to Consul
Run the consul config write command to enable listeners to use the certificate. The following example writes a configuration called my-certificate.hcl:
$ consul config write my-certificate.hcl
Terminate TLS with Consul-managed certificates
You can configure the API gateway to terminate downstream TLS with its Consul service mesh leaf certificate instead of a certificate that you provide. Consul issues and rotates the leaf certificate automatically, so you do not need to create a file-system-certificate or inline-certificate configuration entry.
The leaf certificate is signed by the Consul service mesh certificate authority (CA). Clients that trust the CA root certificate can verify the gateway certificate without additional configuration.
Requirements for Consul-managed certificates
- Consul v2.1 or later
- A Consul cluster with service mesh enabled. Refer to
connect - To resolve services by name, clients must be able to query Consul DNS
Certificate DNS names
Consul adds DNS subject alternative names (SANs) to the leaf certificate so that clients can reach each service exposed by the gateway at its <service>.api-gateway.<domain> DNS name. Refer to API gateway service lookups for more information about how Consul registers these names.
The following table describes the wildcard SANs that the leaf certificate includes:
| Services targeted by routes | Wildcard SANs |
|---|---|
Services in the default namespace and default admin partition | *.api-gateway.<domain>*.api-gateway.<datacenter>.<domain> |
| Services in a non-default namespace Enterprise | *.api-gateway.<namespace>.<domain>*.api-gateway.<namespace>.<datacenter>.<domain> |
Services in the default namespace of a non-default admin partition Enterprise | *.api-gateway.<partition>.<domain>*.api-gateway.<partition>.<datacenter>.<domain> |
| Services in a non-default namespace of a non-default admin partition Enterprise | *.api-gateway.<namespace>.<partition>.<domain>*.api-gateway.<namespace>.<partition>.<datacenter>.<domain> |
Consul adds one set of wildcard SANs for each namespace and admin partition that contains a service targeted by a bound route.
The certificate also includes the following SANs:
- The
Hostnamevalue of each gateway listener, when set. - The
Hostnamesvalues of each HTTP route bound to the gateway. - The equivalent wildcard SANs for the
alt_domain, when configured.
When you add or remove routes, listeners, or hostnames, Consul reissues the leaf certificate with the updated SANs.
Enable Consul-managed TLS
Complete the following steps to terminate TLS with the gateway's leaf certificate:
Create an API gateway configuration entry and set
TLS.Enabledtotrue. Do not reference a certificate in the listenerTLS.Certificatesfield. The following example configures an HTTP listener on port8443:gateway.hcl
Kind = "api-gateway" Name = "my-gateway" TLS = { Enabled = true } Listeners = [ { Name = "my-https-listener" Port = 8443 Protocol = "http" } ]Apply the configuration entry.
$ consul config write gateway.hclBind an HTTP route or TCP route to the listener and create service intentions that allow traffic from the gateway to the destination service. Refer to Define API gateway routes on virtual machines for more information.
TLS.Enabled applies to every listener on the gateway. Certificates that you configure on a listener with TLS.Certificates or TLS.SDS take precedence for requests whose server name indication (SNI) matches the certificate hosts. The leaf certificate serves all other requests. When you configure a gateway-level TLS.SDS certificate, the SDS certificate remains the default certificate and the gateway does not serve the leaf certificate. Refer to TLS.Enabled in the API gateway configuration reference for more information.
Verify HTTPS traffic
Complete the following steps to verify that the gateway terminates HTTPS with a certificate that clients can trust:
Confirm that Consul mapped the service to the gateway. The output includes an entry for the service with
"GatewayKind": "api-gateway"and the listener port. Refer to API gateway service mapping for more information.$ curl --silent $CONSUL_HTTP_ADDR/v1/catalog/gateway-services/my-gateway \ | jq '[.[] | {Service: .Service.Name, GatewayKind, Port}]'Resolve the DNS name of the service that the route targets. The A record returns the address of each healthy gateway instance, and the SRV record returns the listener port. The following example resolves the
webservice:$ dig @127.0.0.1 -p 8600 web.api-gateway.consul A +short $ dig @127.0.0.1 -p 8600 web.api-gateway.consul SRV +shortRetrieve the active Consul service mesh CA root certificate. Refer to the
/connect/ca/rootsAPI endpoint for more information.$ curl --silent $CONSUL_HTTP_ADDR/v1/connect/ca/roots \ | jq --raw-output '.Roots[] | select(.Active) | .RootCert' > consul-ca.pemSend an HTTPS request to the service through the gateway and verify the certificate with the CA root certificate:
$ curl --cacert consul-ca.pem https://web.api-gateway.consul:8443The request succeeds without the
--insecureflag because the gateway certificate includes the*.api-gateway.consulSAN and chains to the Consul service mesh CA.