Skip to content

rbac: add support for SNI based permissions#4662

Merged
mattklein123 merged 6 commits into
envoyproxy:masterfrom
venilnoronha:rbac-sni
Oct 12, 2018
Merged

rbac: add support for SNI based permissions#4662
mattklein123 merged 6 commits into
envoyproxy:masterfrom
venilnoronha:rbac-sni

Conversation

@venilnoronha
Copy link
Copy Markdown
Member

Description: This PR adds support for SNI based permissions by matching over a
connection's requested server name.
Risk Level: Low
Testing: Added 4 additional tests
Docs Changes: N/A
Release Notes: Added a note about this feature
Fixes #4515

Comment thread docs/root/intro/version_history.rst Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be a reference as well?

Copy link
Copy Markdown
Member

@rshriram rshriram left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick turn around. We need exact/prefix/regex matches for the SNI, similar to the string match constructs supported by the header matchers in rbac.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a string equals function? For SNI specifically, we need prefix matches at lest. (like *.example.com) that matches foo.example.com and so on.. Didn't RBAC have some exact/prefix/regex match construct for strings/

Comment thread test/extensions/filters/common/rbac/matchers_test.cc Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we potentially call this "requested_server_name_indication" to be super clear about what this is (or similar)? (With more detail in the comment about TLS, etc.)? WDYT?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about requested_sni_server_name?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about just SNI instead of all the workarounds?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

End users understand SNI much more than "requested server name". And in this PR, this requested server name is spilling into end user config, where we are better of using commonly known terms than the "technically" right term.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we made name change from SNI to server names in FilterChainMatch, so it is not TLS specific? If here we're going to match same thing it shouldn't refer SNI directly. ref: #3454
cc @ggreenway @PiotrSikora

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct. It was named this way so that it could also apply to HTTP Host header, or any other similar field in another protocol.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh? RBAC already has dedicated fields for HTTP host. The fact that this specific thing applies to the SNI value presented in the ClientHello message means we need to be very explicit about what server name this refers to. If consistency is needed, then we need to stick with requested_Server_name. But as @mattklein123 points out, its still confusing, because there are one too many server names :).
How about tls_server_name ? Very little scope for confusion. I really don't want to give people the impression that this could also be a HTTP host header, as it receives separate treatment in RBAC.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we keep requested_server_name, my ask is that we make the documentation much more explicit. Basically call out that this is typically set via TLS SNI, and then explain how it might be set some other way (Listener filter, other?). Thank you.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it could apply to HTTP Host header, but definitely similar field in another protocol. Any listener filter extension may set that. TLS inspector is the only one setting that here, but we may have other. +1 to https://github.com/envoyproxy/envoy/pull/4662/files#r224160788 make documentation explicit.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 92e54f4.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the expectation is that this only applies to SNI, then this code could do the wrong thing, depending on your configured filter chain:

  • If you don't explicitly add the tls_inspector filter, and you don't have any FilterChainMatch matching on servername, this field will be empty
  • A different listener filter could set this to something other than the SNI value
  • This could be a non-TLS connection, in which case there is no SNI value.

Given all this, I think you should document exactly what this is filtering on. Link to the docs on how requestedServerName() is set, give an example for how to set this up for TLS, and note that some filter chain configurations could lead to different results.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 92e54f4.

Comment thread api/envoy/config/rbac/v2alpha/rbac.proto Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it could apply to HTTP Host header, but definitely similar field in another protocol. Any listener filter extension may set that. TLS inspector is the only one setting that here, but we may have other. +1 to https://github.com/envoyproxy/envoy/pull/4662/files#r224160788 make documentation explicit.

This commit adds support for SNI based permissions by matching over a
connection's requested server name.

Signed-off-by: Venil Noronha <veniln@vmware.com>
This commit replaces the existing string based SNI field with
StringMatcher which provides much more flexibility for matching
patterns.

Signed-off-by: Venil Noronha <veniln@vmware.com>
#include "common/http/header_utility.h"
#include "common/network/cidr_range.h"

#include "absl/strings/str_replace.h"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not used.

@venilnoronha
Copy link
Copy Markdown
Member Author

Docs are on their way...

This commit adds notes about how the requested_server_name field behaves
in different situations.

Signed-off-by: Venil Noronha <veniln@vmware.com>
Comment thread test/extensions/filters/common/rbac/matchers_test.cc
const Envoy::Http::HeaderMap&,
const envoy::api::v2::core::Metadata&) const {
absl::string_view requested_server_name = connection.requestedServerName();
if (!requested_server_name.empty()) { // test for null string_view
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this needed? isn't "" a string?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of tests fail if this isn't in place.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because you only passing the data() to StringMatcher::match, but this is still wrong. string_view doesn't have to be null terminated, so the string you passed in to Matcher could be longer than the string_view.

Can you change StringMatcher::match to take absl::string_view instead? That would avoid a copy too.

Comment thread test/extensions/filters/common/rbac/matchers_test.cc
This commit adds tests cases to verify the RBAC filter behavior when the
configured and a connection's requested server name is non/empty.

Signed-off-by: Venil Noronha <veniln@vmware.com>
const Envoy::Http::HeaderMap&,
const envoy::api::v2::core::Metadata&) const {
absl::string_view requested_server_name = connection.requestedServerName();
if (!requested_server_name.empty()) { // test for null string_view
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because you only passing the data() to StringMatcher::match, but this is still wrong. string_view doesn't have to be null terminated, so the string you passed in to Matcher could be longer than the string_view.

Can you change StringMatcher::match to take absl::string_view instead? That would avoid a copy too.

This commit updates the StringMatcher implementation to take
absl::string_view inputs in place of the previous std::string& input for
no-copy matching.

Signed-off-by: Venil Noronha <veniln@vmware.com>
@venilnoronha
Copy link
Copy Markdown
Member Author

venilnoronha commented Oct 11, 2018

@lizan I've addressed the StringMatcher::match change in cce67a7.

lizan
lizan previously approved these changes Oct 11, 2018
Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Mostly comments on comments. @ggreenway can you also take another pass?

// * A listener filter may overwrite a connection's requested server name
// within Envoy.
//
// Please refer to `this FAQ <https://www.envoyproxy.io/docs/envoy/latest/faq/sni>`_
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using an absolute URL here can you ref link to the faq page?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed all comments in 0e2ad38.

// match, this permission would match.
Permission not_rule = 8;

// The requested TLS SNI server name from the client's connection request.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per below this is not necessarily TLS SNI. Should it be something like:

"The request server from the client's connection request. This is typically TLS SNI." (Or something like that?)

// a TLS connection's requested SNI server name will be treated as if it
// wasn't present.
//
// * A listener filter may overwrite a connection's requested server name
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Link to listener filter arch docs?

Comment thread docs/root/intro/version_history.rst Outdated
* http: no longer adding whitespace when appending X-Forwarded-For headers. **Warning**: this is not
compatible with 1.7.0 builds prior to `9d3a4eb4ac44be9f0651fcc7f87ad98c538b01ee <https://github.com/envoyproxy/envoy/pull/3610>`_.
See `#3611 <https://github.com/envoyproxy/envoy/issues/3611>`_ for details.
* rbac: added support for :ref:`TLS SNI based <envoy_api_field_config.rbac.v2alpha.Permission.requested_server_name>` permissions.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TLS SNI might be too specific per other comment? Make more general/clear?

};

/**
* Perform a match against the requested TLS SNI server name.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about specificity.

This commit updates the comments related to the newly introduced
requested_server_name configuration to more closely match its behavior.

Signed-off-by: Venil Noronha <veniln@vmware.com>
Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants