-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Feature untrusted client certs #9172
Feature untrusted client certs #9172
Conversation
api/envoy/api/v2/route/route.proto
Outdated
@@ -349,6 +349,9 @@ message RouteMatch { | |||
message TlsContextMatchOptions { | |||
// If specified, the route will match against whether or not a certificate is presented. | |||
google.protobuf.BoolValue presented = 1; | |||
|
|||
// If specified, the route will match against whether or not a certificate is validated. | |||
google.protobuf.BoolValue validated = 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we make this an enum (and deprecate the old way of doing this).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These fields are used for route matching, and are effectively a tribool - true/false/not-defined
eg: for 'validated', by default we don't route based on validation status, unless specifically set to true / false, example snippet from previous PR #8248 :
"routes": [
{
"match": { "prefix": "/", "credentials": { "validated": false } },
"route": {
"cluster": "venue-edge-access-control",
...
}
},
{
"match": { "prefix": "/", "credentials": { "validated": true },
"headers": [ { "name": ":authority", "prefix_match": "service-actual-target-service" }
]
},
"route": {
"cluster": "service-actual-target-service"
}
}
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack. Is there a reason they are BoolValue
other than history? What is the default value? If it's false, I suggest leaving a [#next-major-version: change type to bool]
for both of these fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default is that it is not specified so will not be routed against. It is only routed against if specified in the configuration. This is why we've used a BoolValue (like a tribool). Is there another recommended way of defining this?
@@ -301,11 +302,20 @@ void SslSocket::shutdownSsl() { | |||
} | |||
} | |||
|
|||
SslSocketInfo::SslSocketInfo(bssl::UniquePtr<SSL> ssl, ContextImplSharedPtr ctx) | |||
: ssl_(std::move(ssl)) { | |||
SSL_set_ex_data(ssl_.get(), ctx->sslCustomDataIndex(), &(this->certificate_validation_status_)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not thrilled to have more ex_data exposed into SSL library later for this. Can we consolidate this with existing SSL_set_app_data
by defining a new interface for that purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently the set_app_data is on the ssl context for ContextImpl, and there exists a set_app_data on the SSL socket in the tls_inspector, so we weren't going to change that.
Because we're using this to be able to provide extra data related to the SSL connection, we've created an SslExtendedSocketInfo class that can be used/extended to pass this information through.
Let me know what you think of this approach (included in the latest commits).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lizan can you please give this change a re-review when you get a chance, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently the set_app_data is on the ssl context for ContextImpl, and there exists a set_app_data on the SSL socket in the tls_inspector, so we weren't going to change that.
Because we're using this to be able to provide extra data related to the SSL connection, we've created an SslExtendedSocketInfo class that can be used/extended to pass this information through.
Let me know what you think of this approach (included in the latest commits).
The SSL_CTX_set_app_data
set ContextImpl
which is not in the same scope, and TLS inspector SSL
object is not leaked into here.
The only existing SSL_set_app_data
is also to provide extra data related to SSL connection for transport socket options here, I meant to refactor these two into one interface and do SSL_set_app_data
once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we do this refactor as a subsequent PR - I'm happy to pick this up.
because this may be a bit of a tricky refactor to combine the multiple pieces of info 'cleanly'.
we've got the ContextImpl's const Network::TransportSocketOptions* options
being set via SSL_set_app_data
by the ContextImpl but only if (options && !options->verifySubjectAltNameListOverride().empty())
when the SslSocket is created,
and then the SslSocketInfo
::SslExtendedSocketInfo
member being set via SSL_set_ex_data
when the SslSocket
is subsequently moved to be owned by the constructed SslSocketInfo
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lizan Can we re-open this PR please - or do we need to create another PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we do this refactor as a subsequent PR - I'm happy to pick this up.
because this may be a bit of a tricky refactor to combine the multiple pieces of info 'cleanly'.
we've got the ContextImpl'sconst Network::TransportSocketOptions* options
being set viaSSL_set_app_data
by the ContextImpl but onlyif (options && !options->verifySubjectAltNameListOverride().empty())
when the SslSocket is created,
and then theSslSocketInfo
::SslExtendedSocketInfo
member being set viaSSL_set_ex_data
when theSslSocket
is subsequently moved to be owned by the constructedSslSocketInfo
.
Since this PR is relatively large, so sure, can you file an issue for this and assign yourself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I've created issue: #9867 , but don't appear to have the power to assign myself - can you assign it to me please.
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
not stale @jimini-lumox is just offline for a little while. pinging to keep this fresh... |
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
This pull request has been automatically closed because it has not had activity in the last 14 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you merge master again to fix merge conflicts? Otherwise LGTM once you filed the refactor issue.
Thanks, master merged & built. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also add a line to version_history.rst?
@@ -535,6 +535,7 @@ class TlsContextMatchCriteria { | |||
virtual ~TlsContextMatchCriteria() = default; | |||
|
|||
virtual const absl::optional<bool>& presented() const PURE; | |||
virtual const absl::optional<bool>& validated() const PURE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add comment to this class and methods?
@@ -6,6 +6,8 @@ Version history | |||
* config: use type URL to select an extension whenever the config type URL (or its previous versions) uniquely identify a typed extension, see :ref:`extension configuration <config_overview_extension_configuration>`. | |||
* retry: added a retry predicate that :ref:`rejects hosts based on metadata. <envoy_api_field_route.RetryPolicy.retry_host_predicate>` | |||
* upstream: changed load distribution algorithm when all priorities enter :ref:`panic mode<arch_overview_load_balancing_panic_threshold>`. | |||
* router: added the ability to match a route based on whether a downstream TLS connection certificate has been |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: alphabetical order
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
93632da
to
a0b1c3a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you fix DCO? Feel free to squash all commit into one and force-push if that's needed.
Needs another merge for version_history, thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 quick API/docs question. Thank you!
/wait
@@ -353,6 +353,9 @@ message RouteMatch { | |||
message TlsContextMatchOptions { | |||
// If specified, the route will match against whether or not a certificate is presented. | |||
google.protobuf.BoolValue presented = 1; | |||
|
|||
// If specified, the route will match against whether or not a certificate is validated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the default here? Can you clarify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If not specified, then the validated status (true or false) will not be considered for route matching - it's the same behaviour as the 'presented' field above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK can you do me a favor and clarify the docs both here and above that no value means not considered at all, a set value checks that state, etc. Feel free to phrase however you want but it was a bit unclear to me from a quick doc read. Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated it, let me know if it's ok. Thanks.
4e5b30f
to
378f043
Compare
I seem to have broken a bunch of things when trying to fix the DCO error - and don't think I can recover it in my branch. |
@jimini-lumox if you can squash all into one commit and force push it to same branch it will fix. You don't need another PR but just a force push. |
Signed-off-by: Michael Hargreaves <mik.hargreaves@gmail.com>
378f043
to
928bd25
Compare
@lizan I've fixed the DCO issues with a squashed forced push. Thanks |
Defer merge to @mattklein123 for doc check. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Description: Add the ability to pass through and route 'untrusted' certificates.
This is a resurrection of PR #8248 with latest master merged, & changes to ssl-context routing merged, as requested in #8248.
The original PR covered two requirements:
Allowing certs that fail validation.
Request peer certs when there is nothing to validate against.
Support routing based on client credential validation status.
By default the client validation rules are unchanged.
Additional validation context options:
// Specify the certificate validation to be performed: VERIFY_TRUST_CHAIN(default), ACCEPT_UNTRUSTED, NOT_VERIFIED.
TrustChainVerification verify_certificate_trust_chain;
Added Routing support based on whether the client certificate was validated or not.
Risk Level: Medium
Testing: Manual and unit tests
Docs Changes: API proto changes
Release Notes: N/A