Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document SDS for ingress gateways #11164

Merged
merged 4 commits into from
Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 87 additions & 4 deletions website/content/docs/connect/config-entries/ingress-gateway.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -810,11 +810,29 @@ spec:
type: 'bool: false',
description: {
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 `true` 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:
"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 `true` 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: "Defines a set of parameters that 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 defined in this field are used as defaults for all listeners on the gateway.",
children: [
{
name: 'ClusterName',
type: 'string',
description: "Specifies the name of the SDS cluster from which Consul should retrieve certificates. This cluster must be [specified in the Gateway's bootstrap configuration](/docs/connect/gateways/ingress-gateway#sds).",
},
{
name: 'CertResource',
type: 'string',
description: "Specifies an SDS resource name. Consul will request the SDS resource name 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.",
},
],
},
],
},
{
Expand Down Expand Up @@ -843,8 +861,10 @@ spec:
{
name: 'Services',
type: 'array<IngressService>: <optional>',
description:
'A list of services to be exposed via this listener. For `tcp` listeners, only a single service is allowed.',
description: `A list of services to be exposed via this listener.
For \`tcp\` listeners, only a single service is allowed.
Each service must have a unique name. A namespace is also required for
Consul Enterprise.`,
children: [
{
name: 'Name',
Expand Down Expand Up @@ -896,6 +916,69 @@ spec:
that will be applied to responses from this service.
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: `Defines a set of parameters that configures the SDS source for the certificate for this specific service.
At least one custom host must be specified in \`Hosts\`.
The certificate retrieved from SDS will be served for 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 `true` 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 `true` to enable built-in TLS for this listener.<br><br>If TLS is enabled, then each host defined in the `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.",
},
},
{
name: 'SDS',
type: 'SDSConfig: <optional>',
description: "Defines a set of parameters that 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.",
},
],
},
],
},
],
Expand Down
214 changes: 213 additions & 1 deletion website/content/docs/connect/gateways/ingress-gateway.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,216 @@ 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
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 topic describes 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 following procedure describes how to configure an ingress gateway with TLS certificates from an SDS source. The instructions assume that you are familiar with Envoy configuration and the SDS protocol.

### Configure Static SDS Cluster(s)

Each Envoy proxy that makes up this Ingress Gateway must define one or more additional [static
clusters](/docs/connect/proxies/envoy#envoy_extra_static_clusters_json) when registering. These additional clusters define how Envoy should connect to the required SDS service(s). Defining extra clusters in Envoy's bootstrap configuration requires a manual registration of the Ingress Gateway with Consul proxy.
It's not possible to use the `-register` flag with `consul connect envoy -gateway=ingress` to automatically register the proxy in this case.

The cluster(s) must provide connection information and any necessary
authentication information such as mTLS credentials.

The following example will demonstrate how to use:
- 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. **Register the proxy service.**

The following Proxy Service Definition defines the additional cluster
configuration that will be provided 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
}
}
}
```

1. **Issue the following command to create the registration.**

```
consul services register public-ingress.hcl
```

The command must be executed against the Consul agent on the Envoy proxy's node.

#### Setup TLS Client Authentication for SDS

Configuration files similar to the following examples must be available on the
disk where the Envoy proxy will run. The actual certificates and keys referenced
in the configuration files must also be present.

1. **Configure TLS client authentication for SDS.**

The certificates and keys must be saved to the same disk where the Envoy
proxy will run. The following example files reference the PEM-encoded
certificate and key files to be used for TLS Client Authentication with the
SDS service (`sds-client-auth.{crt,key}`) and the certificate authority
certificate used to validate the SDS server's TLS credentials
(`sds-ca.crt`).

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. **Issue the following command to start Envoy.**

```bash
$ consul connect envoy -gateway=ingress -service public-ingress
```

### 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 = ["*"]
}
]

```

1. **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.