Add documentation for SDS support in ingress gateways.

pull/11164/head
Paul Banks 2021-09-28 13:31:42 +01:00
parent d866e51bd4
commit fcfedfdb5d
2 changed files with 295 additions and 4 deletions

View File

@ -810,11 +810,29 @@ spec:
type: 'bool: false', type: 'bool: false',
description: { description: {
hcl: hcl:
"Set this configuration to enable TLS for every listener on the gateway.<br><br>If TLS is enabled, then each host defined in the `Host` field will be added as a DNSSAN to the gateway's x509 certificate.", "Set this configuration to enable built-in TLS for every listener on the gateway.<br><br>If TLS is enabled, then each host defined in each service's `Hosts` fields will be added as a DNSSAN to the gateway's x509 certificate.",
yaml: yaml:
"Set this configuration to enable TLS for every listener on the gateway.<br><br>If TLS is enabled, then each host defined in the `host` field will be added as a DNSSAN to the gateway's x509 certificate.", "Set this configuration to enable built-in TLS for every listener on the gateway.<br><br>If TLS is enabled, then each host defined in each service's `hosts` fields will be added as a DNSSAN to the gateway's x509 certificate.",
}, },
}, },
{
name: 'SDS',
yaml: false,
type: 'SDSConfig: <optional>',
description: "Configures the gateway to load TLS certificates from an external SDS service. See [SDS](/docs/connect/gateways/ ingress-gateway#sds) for more details on usage.<br><br>SDS properties set here will be used as defaults for all listeners on the gateway.",
children: [
{
name: 'ClusterName',
type: 'string',
description: "The SDS cluster name to connect to to retrieve certificates. This cluster must be [specified in the Gateway's bootstrap configuration](/docs/connect/gateways/ingress-gateway#sds).",
},
{
name: 'CertResource',
type: 'string',
description: "The SDS resource name to request when fetching the certificate from the SDS service. Setting this causes all listeners to be served exclusively over TLS with this certificate unless overridden by listener-specific TLS configuration.",
},
],
},
], ],
}, },
{ {
@ -843,8 +861,9 @@ spec:
{ {
name: 'Services', name: 'Services',
type: 'array<IngressService>: <optional>', type: 'array<IngressService>: <optional>',
description: description: `A list of services to be exposed via this listener.
'A list of services to be exposed via this listener. For `tcp` listeners, only a single service is allowed.', For \`tcp\` listeners, only a single service is allowed.
Each service must have a unique name (and namespace in Enterprise).`,
children: [ children: [
{ {
name: 'Name', name: 'Name',
@ -896,6 +915,69 @@ spec:
that will be applied to responses from this service. that will be applied to responses from this service.
This cannot be used with a \`tcp\` listener.`, This cannot be used with a \`tcp\` listener.`,
}, },
{
name: 'TLS',
yaml: false,
type: 'ServiceTLSConfig: <optional>',
description: 'TLS configuration for this service.',
children: [
{
name: 'SDS',
type: 'SDSConfig: <optional>',
description: `Configures the SDS source for the certificate for this specific service.
At least one custom host must be specified in \`Hosts\`.
This certificate will be served to all requests identifying one of the
\`Hosts\` values in the TLS Server Name Indication (SNI) header.`,
children: [
{
name: 'ClusterName',
type: 'string',
description: "The SDS cluster name to connect to to retrieve certificates. This cluster must be [specified in the Gateway's bootstrap configuration](/docs/connect/gateways/ingress-gateway#sds).",
},
{
name: 'CertResource',
type: 'string',
description: "The SDS resource name to request when fetching the certificate from the SDS service.",
},
],
},
],
},
],
},
{
name: 'TLS',
yaml: false,
type: 'TLSConfig: <optional>',
description: 'TLS configuration for this listener.',
children: [
{
name: 'Enabled',
type: 'bool: false',
description: {
hcl:
"Set this configuration to enable built-in TLS for this listener.<br><br>If TLS is enabled, then each host defined in each service's `Hosts` field will be added as a DNSSAN to the gateway's x509 certificate. Note that even hosts from other listeners with TLS disabled will be added.",
yaml:
"Set this configuration to enable built-in TLS for this listener.<br><br>If TLS is enabled, then each host defined in the `hosta` field will be added as a DNSSAN to the gateway's x509 certificate. Note that even hosts from other listeners with TLS disabled will be added.",
},
},
{
name: 'SDS',
type: 'SDSConfig: <optional>',
description: "Configures the listener to load TLS certificates from an external SDS service. See [SDS](/docs/connect/gateways/ ingress-gateway#sds) for more details on usage.<br><br>SDS properties set here will be used as defaults for all services on this listener.",
children: [
{
name: 'ClusterName',
type: 'string',
description: "The SDS cluster name to connect to to retrieve certificates. This cluster must be [specified in the Gateway's bootstrap configuration](/docs/connect/gateways/ingress-gateway#sds).",
},
{
name: 'CertResource',
type: 'string',
description: "The SDS resource name to request when fetching the certificate from the SDS service.",
},
],
},
], ],
}, },
], ],

View File

@ -69,3 +69,212 @@ must also provide `agent:read` for its node's name in order to discover the agen
~> [Configuration entries](/docs/agent/config-entries) are global in scope. A configuration entry for a gateway name applies ~> [Configuration entries](/docs/agent/config-entries) are global in scope. A configuration entry for a gateway name applies
across all federated Consul datacenters. If ingress gateways in different Consul datacenters need to route to different across all federated Consul datacenters. If ingress gateways in different Consul datacenters need to route to different
sets of services within their datacenter then the ingress gateways **must** be registered with different names. sets of services within their datacenter then the ingress gateways **must** be registered with different names.
<!-- Add a "permalink" anchor here since this title is long and may be edited
but we need to deep-link to it elsewhere -->
<a name="sds"></a>
## Custom TLS Certificates via Secret Discovery Service (SDS)
~> **Advanced Topic!** This is a low-level feature designed for developers
building integrations with custom TLS management solutions.
Consul 1.11 added support for Ingress Gateways to serve TLS certificates to
inbound traffic that are sourced from an external service. The external service
must implement Envoy's [gRPC Secret Discovery
Service](https://www.envoyproxy.io/docs/envoy/latest/configuration/security/secret)
(or SDS) API.
The steps below are necessary to fully configure an Ingress Gateway with TLS
certificates from an SDS source. They assume the operator is familiar with Envoy
configuration and the SDS protocol.
### 1. Configure Static SDS Cluster(s).
Each Ingress Gateway Envoy instance must have one or more additional [static
clusters](/docs/connect/proxies/envoy#envoy_extra_static_clusters_json) defined
when registering the ingress gateway to specify how to connect to the external
service. This requires a manual registration of the Ingress Gateway proxy rather
than relying on `-register` flag to `consul connect envoy -gateway=ingress`.
The cluster(s) must provide connection information and any necessary
authentication information such as mTLS credentials.
In this example we will show:
- A DNS name to discover the SDS service addresses
- Local certificate files for TLS client authentication with the SDS server
(the certificates are assumed to be created and managed by some other
process)
#### 1.1 Registering the Proxy Service
The following Proxy Service Definition defines the bootstrap overrides needed to
add this configuration to Envoy when it starts. With this TLS configuration,
Envoy will detect changes to the certificate and key files on disk so an
external process may maintain and rotate them without needing an Envoy restart.
```hcl
// public-ingress.hcl
Services {
Name = "public-ingress"
Kind = "ingress-gateway"
Proxy {
Config {
envoy_extra_static_clusters_json = <<EOF
{
"name": "sds-cluster",
"connect_timeout": "5s",
"http2_protocol_options": {},
"type": "LOGICAL_DNS",
"transport_socket": {
"name":"tls",
"typed_config": {
"@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
"common_tls_context":{
"tls_certificate_sds_secret_configs": [
{
"name":"tls_sds",
"sds_config":{
"path":"/certs/sds-auth-cert.json"
}
}
],
"validation_context_sds_secret_config": {
"name":"validation_context_sds",
"sds_config":{
"path":"/certs/sds-validation.json"
}
}
}
}
},
"load_assignment": {
"cluster_name": "sds-cluster",
"endpoints": [
{
"lb_endpoints": [
{
"endpoint": {
"address": {
"socket_address": {
"address": "sds-server.svc.cluster.local",
"port_value": 8080,
}
}
}
}
]
}
]
}
}
EOF
}
}
}
```
**Run `consul services register public-ingress.hcl`** to create the
registration. This must be run on the node where the Envoy proxy is going to run
to register the proxy with the local Consul agent.
#### 1.2 Setup TLS Client Authentication for SDS
This configuration relies on files like the following being present on disk
where the Envoy proxy will run, along with the actual certificates and keys
referenced.
* `sds-client-auth.{crt,key}` are the PEM-encoded certificate and key
files to be used for TLS Client Authentication with the SDS service.
* `sds-ca.crt` is the Certificate Authority certificate used to validate the the
SDS server's TLS credentials.
Please refer to [Envoy's
documentation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/bootstrap/bootstrap)
for more details on this configuration and other possible authentication
options.
```json
// /certs/sds-auth-cert.json
{
"resources": [
{
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",
"name": "tls_sds",
"tls_certificate": {
"certificate_chain": {
"filename": "/certs/sds-client-auth.crt"
},
"private_key": {
"filename": "/certs/sds-client-auth.key"
}
}
}
]
}
```
```json
// /certs/sds-validation.json
{
"resources": [
{
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",
"name": "validation_context_sds",
"validation_context": {
"trusted_ca": {
"filename": "/certs/sds-ca.crt"
}
}
}
]
}
```
#### 1.3 Start Envoy
**Start Envoy** with:
```bash
$ consul connect envoy -gateway=ingress -service public-ingress
```
### 2. Configure the Ingress Gateway to use certificates from SDS
SDS certificates may now be configured in the `ingress-gateway` Config Entry.
The following example shows a single default certificate and key being used for
all listeners.
```hcl
// public-ingress-cfg.hcl
Kind = "ingress-gateway"
Name = "public-ingress"
TLS {
SDS {
# This must match the name of the static cluster from step #1
ClusterName = "sds-cluster"
# This is the name of the certificate resource to load.
CertResource = "example.com-public-cert"
}
}
Listeners = [
{
Port = 8443
Protocol = "http"
Services = ["*"]
}
]
```
Run `consul config write public-ingress-cfg.hcl` to write this configuration.
The Envoy instance will now start a listener on port 8443 and attempt to fetch
the TLS certificate named from the SDS server.
Separate certificates may be loaded per listener or per-service with hostname
(SNI) switching. See the [Config Entry
reference](/docs/connect/config-entries/ingress-gateway) for more details.