Serve custom TLS certificates from an external service

This is an advanced topic that describes how to configure ingress gateways to serve TLS certificates sourced from an external service to inbound traffic using secret discovery service (SDS). SDS is a low-level feature designed for developers building integrations with custom TLS management solutions. For instructions on more common ingress gateway implementations, refer to Implement an ingress gateway.

Overview

The following process describes the general procedure for configuring ingress gateways to serve TLS certificates sourced from external services:

  1. Configure static SDS clusters in the ingress gateway service definition.
  2. Register the service definition.
  3. Configure TLS client authentication
  4. Start Envoy.
  5. Configure SDS settings in an ingress gateway configuration entry.
  6. Register the ingress gateway configuration entry with Consul.

Requirements

ACL requirements

If ACLs are enabled, you must present a token when registering ingress gateways that grant the following permissions:

  • service:write for the ingress gateway’s service name
  • service:read for all services in the ingress gateway’s configuration entry
  • node:read for all nodes of the services in the ingress gateway’s configuration entry.

These privileges authorize the token to route communications to other services in the mesh. If the Consul client agent on the gateway’s node is not configured to use the default gRPC port, 8502, then the gateway’s token must also provide agent:read for its node’s name in order to discover the agent’s gRPC port. gRPC is used to expose Envoy’s xDS API to Envoy proxies.

Configure static SDS clusters

You must define one or more additional static clusters in the ingress gateway service definition for each Envoy proxy associated with the gateway. The additional clusters define how Envoy should connect to the required SDS services.

Configure the static clusters in the Proxy.Config.envoy_envoy_extra_static_clusters_json parameter in the service definition.

The clusters must provide connection information and any necessary authentication information, such as mTLS credentials.

You must manually register the ingress gateway with Consul proxy to define extra clusters in Envoy’s bootstrap configuration. You can not use the -register flag with consul connect envoy -gateway=ingress to automatically register the proxy to define static clusters.

In the following example, the public-ingress gateway includes a static cluster named sds-cluster that specifies paths to the SDS certificate and SDS certification validation files:

public-ingress-service.hcl

  1. Services {
  2. Name = "public-ingress"
  3. Kind = "ingress-gateway"
  4. Proxy {
  5. Config {
  6. envoy_extra_static_clusters_json = <<EOF
  7. {
  8. "name": "sds-cluster",
  9. "connect_timeout": "5s",
  10. "http2_protocol_options": {},
  11. "type": "LOGICAL_DNS",
  12. "transport_socket": {
  13. "name":"tls",
  14. "typed_config": {
  15. "@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
  16. "common_tls_context":{
  17. "tls_certificate_sds_secret_configs": [
  18. {
  19. "name":"tls_sds",
  20. "sds_config":{
  21. "path":"/certs/sds-auth-cert.json"
  22. }
  23. }
  24. ],
  25. "validation_context_sds_secret_config": {
  26. "name":"validation_context_sds",
  27. "sds_config":{
  28. "path":"/certs/sds-validation.json"
  29. }
  30. }
  31. }
  32. }
  33. },
  34. "load_assignment": {
  35. "cluster_name": "sds-cluster",
  36. "endpoints": [
  37. {
  38. "lb_endpoints": [
  39. {
  40. "endpoint": {
  41. "address": {
  42. "socket_address": {
  43. "address": "sds-server.svc.cluster.local",
  44. "port_value": 8080,
  45. }
  46. }
  47. }
  48. }
  49. ]
  50. }
  51. ]
  52. }
  53. }
  54. EOF
  55. }
  56. }
  57. }

Refer to the Envoy documentation for details about configuration parameters for SDS clusters.

Register the ingress gateway service definition

Issue the consul services register command on the Consul agent on the Envoy proxy’s node to register the service. The following example command registers an ingress gateway proxy from a public-ingress.hcl file:

  1. $ consul services register public-ingress.hcl

Refer to Register services and health checks for additional information about registering services in Consul.

Configure TLS client authentication

Store TLS client authentication files, certificate files, and keys on disk where the Envoy proxy runs and ensure that they are available to Consul. Refer to the Envoy documentation for details on configuring authentication files.

The following example specifies certificate chain:

certs/sds-auth-cert.json

  1. {
  2. "resources": [
  3. {
  4. "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",
  5. "name": "tls_sds",
  6. "tls_certificate": {
  7. "certificate_chain": {
  8. "filename": "/certs/sds-client-auth.crt"
  9. },
  10. "private_key": {
  11. "filename": "/certs/sds-client-auth.key"
  12. }
  13. }
  14. }
  15. ]
  16. }

The following example specifies the validation context:

/certs/sds-validation.json

  1. {
  2. "resources": [
  3. {
  4. "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",
  5. "name": "validation_context_sds",
  6. "validation_context": {
  7. "trusted_ca": {
  8. "filename": "/certs/sds-ca.crt"
  9. }
  10. }
  11. }
  12. ]
  13. }

Start Envoy

Issue the consul connect envoy command to bootstrap Envoy. The following example starts Envoy and registers it as a service called public-ingress:

  1. $ ​​consul connect envoy -gateway=ingress -service public-ingress

Refer to Consul Connect Envoy for additional information about using the consul connect envoy command.

Define an ingress gateway configuration entry

Create an ingress gateway configuration entry that enables the gateway to use certificates from SDS. The configuration entry also maps downstream ingress listeners to upstream services. Configure the following fields:

  • Kind: Set the value to ingress-gateway.
  • Name: Consul applies the configuration entry settings to ingress gateway proxies with names that match the Name field.
  • TLS: The main TLS parameter for the configuration entry holds the SDS configuration. You can also specify TLS configurations per listener and per service.
  • Listeners: Specify one or more listeners.
    • Listeners.Port: Specify a port for the listener. Each listener is uniquely identified by its port number.
    • Listeners.Protocol: The default protocol is tcp, but you must specify the protocol used by the services you want to allow traffic from.
    • Listeners.Services: The Services field contains the services that you want to expose to upstream services. The field contains several options and sub-configurations that enable granular control over ingress traffic, such as health check and TLS configurations.

For Consul Enterprise service meshes, you may also need to configure the Partition and Namespace fields for the gateway and for each exposed service.

Refer to Ingress gateway configuration entry reference for details about the supported parameters.

The following example directs Consul to retrieve example.com-public-cert certificates from an SDS cluster named sds-cluster and serve them to all listeners:

public-ingress-cfg.hcl

  1. Kind = "ingress-gateway"
  2. Name = "public-ingress"
  3. TLS {
  4. SDS {
  5. ClusterName = "sds-cluster"
  6. CertResource = "example.com-public-cert"
  7. }
  8. }
  9. Listeners = [
  10. {
  11. Port = 8443
  12. Protocol = "http"
  13. Services = ["*"]
  14. }
  15. ]

Register the ingress gateway configuration entry

You can register the configuration entry using the consul config command or by calling the /config API endpoint. Refer to How to Use Configuration Entries for details about applying configuration entries.

The following example registers an ingress gateway configuration entry named public-ingress-cfg.hcl that is stored on the local system:

  1. $ consul config write public-ingress-cfg.hcl

The Envoy instance starts a listener on the port specified in the configuration entry and fetches the TLS certificate named from the SDS server.