sds: additional support for symlink-based key rotation. (#13721)

There are a few limitations in our existing support for symlink-based
key rotation:

We don't atomically resolve symlinks, so a single snapshot might have
inconsistent symlink resolutions for different watched files.
Watches are on parent directories, e.g. for /foo/bar/baz on /foo/bar,
which doesn't support common key rotation schemes were /foo/new/baz
is rotated via a mv -Tf /foo/new /foo/bar.
The solution is to provide a structured WatchedDirectory for Secrets to
opt into when monitoring DataSources. SDS will used WatchedDirectory
to setup the inotify watch instead of the DataSource path. On update, it will
read key/cert twice, verifying file content hash consistency.

Risk level: Low (opt-in feature)
Testing: Unit and integration tests added.

Fixes #13663
Fixes #10979
Fixes #13370

Signed-off-by: Harvey Tuch <htuch@google.com>

Mirrored from https://github.com/envoyproxy/envoy @ 122257ef6ade0009feafc3c9142d480260fe069f
pull/623/head
data-plane-api(Azure Pipelines) 4 years ago
parent 690d6d5f0e
commit 85622be847
  1. 7
      envoy/config/core/v3/base.proto
  2. 10
      envoy/config/core/v4alpha/base.proto
  3. 37
      envoy/extensions/transport_sockets/tls/v3/common.proto
  4. 37
      envoy/extensions/transport_sockets/tls/v4alpha/common.proto

@ -313,6 +313,13 @@ message HeaderMap {
repeated HeaderValue headers = 1;
}
// A directory that is watched for changes, e.g. by inotify on Linux. Move/rename
// events inside this directory trigger the watch.
message WatchedDirectory {
// Directory path to watch.
string path = 1 [(validate.rules).string = {min_len: 1}];
}
// Data source consisting of either a file or an inline value.
message DataSource {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.DataSource";

@ -308,6 +308,16 @@ message HeaderMap {
repeated HeaderValue headers = 1;
}
// A directory that is watched for changes, e.g. by inotify on Linux. Move/rename
// events inside this directory trigger the watch.
message WatchedDirectory {
option (udpa.annotations.versioning).previous_message_type =
"envoy.config.core.v3.WatchedDirectory";
// Directory path to watch.
string path = 1 [(validate.rules).string = {min_len: 1}];
}
// Data source consisting of either a file or an inline value.
message DataSource {
option (udpa.annotations.versioning).previous_message_type = "envoy.config.core.v3.DataSource";

@ -128,16 +128,36 @@ message PrivateKeyProvider {
}
}
// [#next-free-field: 7]
// [#next-free-field: 8]
message TlsCertificate {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.TlsCertificate";
// The TLS certificate chain.
//
// If *certificate_chain* is a filesystem path, a watch will be added to the
// parent directory for any file moves to support rotation. This currently
// only applies to dynamic secrets, when the *TlsCertificate* is delivered via
// SDS.
config.core.v3.DataSource certificate_chain = 1;
// The TLS private key.
//
// If *private_key* is a filesystem path, a watch will be added to the parent
// directory for any file moves to support rotation. This currently only
// applies to dynamic secrets, when the *TlsCertificate* is delivered via SDS.
config.core.v3.DataSource private_key = 2 [(udpa.annotations.sensitive) = true];
// If specified, updates of file-based *certificate_chain* and *private_key*
// sources will be triggered by this watch. The certificate/key pair will be
// read together and validated for atomic read consistency (i.e. no
// intervening modification occurred between cert/key read, verified by file
// hash comparisons). This allows explicit control over the path watched, by
// default the parent directories of the filesystem paths in
// *certificate_chain* and *private_key* are watched if this field is not
// specified. This only applies when a *TlsCertificate* is delivered by SDS
// with references to filesystem paths.
config.core.v3.WatchedDirectory watched_directory = 7;
// BoringSSL private key method provider. This is an alternative to :ref:`private_key
// <envoy_api_field_extensions.transport_sockets.tls.v3.TlsCertificate.private_key>` field. This can't be
// marked as ``oneof`` due to API compatibility reasons. Setting both :ref:`private_key
@ -191,7 +211,7 @@ message TlsSessionTicketKeys {
[(validate.rules).repeated = {min_items: 1}, (udpa.annotations.sensitive) = true];
}
// [#next-free-field: 11]
// [#next-free-field: 12]
message CertificateValidationContext {
option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.auth.CertificateValidationContext";
@ -233,8 +253,21 @@ message CertificateValidationContext {
//
// See :ref:`the TLS overview <arch_overview_ssl_enabling_verification>` for a list of common
// system CA locations.
//
// If *trusted_ca* is a filesystem path, a watch will be added to the parent
// directory for any file moves to support rotation. This currently only
// applies to dynamic secrets, when the *CertificateValidationContext* is
// delivered via SDS.
config.core.v3.DataSource trusted_ca = 1;
// If specified, updates of a file-based *trusted_ca* source will be triggered
// by this watch. This allows explicit control over the path watched, by
// default the parent directory of the filesystem path in *trusted_ca* is
// watched if this field is not specified. This only applies when a
// *CertificateValidationContext* is delivered by SDS with references to
// filesystem paths.
config.core.v3.WatchedDirectory watched_directory = 11;
// An optional list of base64-encoded SHA-256 hashes. If specified, Envoy will verify that the
// SHA-256 of the DER-encoded Subject Public Key Information (SPKI) of the presented certificate
// matches one of the specified values.

@ -129,17 +129,37 @@ message PrivateKeyProvider {
}
}
// [#next-free-field: 7]
// [#next-free-field: 8]
message TlsCertificate {
option (udpa.annotations.versioning).previous_message_type =
"envoy.extensions.transport_sockets.tls.v3.TlsCertificate";
// The TLS certificate chain.
//
// If *certificate_chain* is a filesystem path, a watch will be added to the
// parent directory for any file moves to support rotation. This currently
// only applies to dynamic secrets, when the *TlsCertificate* is delivered via
// SDS.
config.core.v4alpha.DataSource certificate_chain = 1;
// The TLS private key.
//
// If *private_key* is a filesystem path, a watch will be added to the parent
// directory for any file moves to support rotation. This currently only
// applies to dynamic secrets, when the *TlsCertificate* is delivered via SDS.
config.core.v4alpha.DataSource private_key = 2 [(udpa.annotations.sensitive) = true];
// If specified, updates of file-based *certificate_chain* and *private_key*
// sources will be triggered by this watch. The certificate/key pair will be
// read together and validated for atomic read consistency (i.e. no
// intervening modification occurred between cert/key read, verified by file
// hash comparisons). This allows explicit control over the path watched, by
// default the parent directories of the filesystem paths in
// *certificate_chain* and *private_key* are watched if this field is not
// specified. This only applies when a *TlsCertificate* is delivered by SDS
// with references to filesystem paths.
config.core.v4alpha.WatchedDirectory watched_directory = 7;
// BoringSSL private key method provider. This is an alternative to :ref:`private_key
// <envoy_api_field_extensions.transport_sockets.tls.v4alpha.TlsCertificate.private_key>` field. This can't be
// marked as ``oneof`` due to API compatibility reasons. Setting both :ref:`private_key
@ -193,7 +213,7 @@ message TlsSessionTicketKeys {
[(validate.rules).repeated = {min_items: 1}, (udpa.annotations.sensitive) = true];
}
// [#next-free-field: 11]
// [#next-free-field: 12]
message CertificateValidationContext {
option (udpa.annotations.versioning).previous_message_type =
"envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext";
@ -235,8 +255,21 @@ message CertificateValidationContext {
//
// See :ref:`the TLS overview <arch_overview_ssl_enabling_verification>` for a list of common
// system CA locations.
//
// If *trusted_ca* is a filesystem path, a watch will be added to the parent
// directory for any file moves to support rotation. This currently only
// applies to dynamic secrets, when the *CertificateValidationContext* is
// delivered via SDS.
config.core.v4alpha.DataSource trusted_ca = 1;
// If specified, updates of a file-based *trusted_ca* source will be triggered
// by this watch. This allows explicit control over the path watched, by
// default the parent directory of the filesystem path in *trusted_ca* is
// watched if this field is not specified. This only applies when a
// *CertificateValidationContext* is delivered by SDS with references to
// filesystem paths.
config.core.v4alpha.WatchedDirectory watched_directory = 11;
// An optional list of base64-encoded SHA-256 hashes. If specified, Envoy will verify that the
// SHA-256 of the DER-encoded Subject Public Key Information (SPKI) of the presented certificate
// matches one of the specified values.

Loading…
Cancel
Save