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

external authorization: set the SNI value from server name if it isn't available on the connection/socket #34100

Merged
merged 22 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5429cca
Set the SNI value from the TLS inspector server name if it isn't avai…
marc-barry May 12, 2024
425e5ed
Address comments. Adjust setTLSSession() to handle both cases.
marc-barry May 14, 2024
aec9ee1
Update setTLSSession() function signature.
marc-barry May 14, 2024
9602555
Add Envoy namespace.
marc-barry May 14, 2024
7da868f
Change setTLSSession() to accept a Envoy::Network::Connection referen…
marc-barry May 14, 2024
f39531b
Address compilation issues.
marc-barry May 14, 2024
5fdc9e6
Adjust existing tests function call counts as the code was changed re…
marc-barry May 14, 2024
4ec74e9
Add test for the SNI being set by the connections server name when th…
marc-barry May 14, 2024
4cc43cc
Fix test name.
marc-barry May 14, 2024
661ee1a
Adjust test.
marc-barry May 14, 2024
16f7b2c
Fix test.
marc-barry May 14, 2024
53a346d
requestedServerName() is correctly called three times for the test.
marc-barry May 14, 2024
97baa0a
Bump CI.
marc-barry May 14, 2024
23d16bd
Add test for createHttpCheck() setting the TLS session SNI from the s…
marc-barry May 15, 2024
6ee761e
Fix test compilation.
marc-barry May 15, 2024
084f8c2
Update checks.
marc-barry May 15, 2024
d7e9e73
Create new createHttpCheck() test.
marc-barry May 15, 2024
3c9552b
Confirm requestedServerName() calls.
marc-barry May 15, 2024
27748dc
Add check for request attributes SNI value being equal to server name…
marc-barry May 15, 2024
e7e9e28
Fix tests.
marc-barry May 15, 2024
28da14d
Remove redundant test.
marc-barry May 15, 2024
9cd3f27
Update changelogs/current.yaml.
marc-barry May 15, 2024
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
5 changes: 5 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ bug_fixes:
change: |
Fix BalsaParser resetting state too early, guarded by default-true
``envoy.reloadable_features.http1_balsa_delay_reset``.
- area: ext_authz
change: |
Set the SNI value from the requested server name if it isn't available on the connection/socket. This applies when
``include_tls_session`` is true. The requested server name is set on a connection when filters such as the TLS
inspector are used.

removed_config_or_runtime:
# *Normally occurs at the end of the* :ref:`deprecation period <deprecated>`
Expand Down
18 changes: 12 additions & 6 deletions source/extensions/filters/common/ext_authz/check_request_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,14 @@ void CheckRequestUtils::setAttrContextRequest(

void CheckRequestUtils::setTLSSession(
envoy::service::auth::v3::AttributeContext::TLSSession& session,
const Ssl::ConnectionInfoConstSharedPtr ssl_info) {
if (!ssl_info->sni().empty()) {
const Envoy::Network::Connection& connection) {
const Ssl::ConnectionInfoConstSharedPtr ssl_info = connection.ssl();
if (ssl_info != nullptr && !ssl_info->sni().empty()) {
const std::string server_name(ssl_info->sni());
session.set_sni(server_name);
} else if (!connection.requestedServerName().empty()) {
const std::string server_name(connection.requestedServerName());
session.set_sni(server_name);
}
}

Expand All @@ -248,6 +252,7 @@ void CheckRequestUtils::createHttpCheck(
// *cb->connection(), callbacks->streamInfo() and callbacks->decodingBuffer() are not qualified as
// const.
auto* cb = const_cast<Envoy::Http::StreamDecoderFilterCallbacks*>(callbacks);

setAttrContextPeer(*attrs->mutable_source(), *cb->connection(), service, false,
include_peer_certificate);
setAttrContextPeer(*attrs->mutable_destination(), *cb->connection(), EMPTY_STRING, true,
Expand All @@ -256,8 +261,8 @@ void CheckRequestUtils::createHttpCheck(
cb->decodingBuffer(), headers, max_request_bytes, pack_as_bytes,
encode_raw_headers, allowed_headers_matcher, disallowed_headers_matcher);

if (include_tls_session && cb->connection()->ssl() != nullptr) {
setTLSSession(*attrs->mutable_tls_session(), cb->connection()->ssl());
if (include_tls_session) {
setTLSSession(*attrs->mutable_tls_session(), *cb->connection());
}
(*attrs->mutable_destination()->mutable_labels()) = destination_labels;
// Fill in the context extensions and metadata context.
Expand All @@ -280,8 +285,9 @@ void CheckRequestUtils::createTcpCheck(
include_peer_certificate);
setAttrContextPeer(*attrs->mutable_destination(), cb->connection(), server_name, true,
include_peer_certificate);
if (include_tls_session && cb->connection().ssl() != nullptr) {
setTLSSession(*attrs->mutable_tls_session(), cb->connection().ssl());

if (include_tls_session) {
setTLSSession(*attrs->mutable_tls_session(), cb->connection());
}
(*attrs->mutable_destination()->mutable_labels()) = destination_labels;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class CheckRequestUtils {
bool encode_raw_headers, const MatcherSharedPtr& allowed_headers_matcher,
const MatcherSharedPtr& disallowed_headers_matcher);
static void setTLSSession(envoy::service::auth::v3::AttributeContext::TLSSession& session,
const Ssl::ConnectionInfoConstSharedPtr ssl_info);
const Envoy::Network::Connection& connection);
static std::string getHeaderStr(const Envoy::Http::HeaderEntry* entry);
static Envoy::Http::HeaderMap::Iterate fillHttpHeaders(const Envoy::Http::HeaderEntry&, void*);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,11 @@ class CheckRequestUtilsTest : public testing::Test {

EXPECT_EQ(want_tls_session != nullptr, request.attributes().has_tls_session());
if (want_tls_session != nullptr) {
EXPECT_EQ(want_tls_session->sni(), request.attributes().tls_session().sni());
if (!want_tls_session->sni().empty()) {
EXPECT_EQ(want_tls_session->sni(), request.attributes().tls_session().sni());
} else {
EXPECT_EQ(requested_server_name_, request.attributes().tls_session().sni());
}
}
}

Expand Down Expand Up @@ -223,10 +227,10 @@ TEST_F(CheckRequestUtilsTest, TcpPeerCertificate) {
// Verify that createTcpCheck populates the tls session details correctly.
TEST_F(CheckRequestUtilsTest, TcpTlsSession) {
envoy::service::auth::v3::CheckRequest request;
EXPECT_CALL(net_callbacks_, connection()).Times(5).WillRepeatedly(ReturnRef(connection_));
EXPECT_CALL(net_callbacks_, connection()).Times(4).WillRepeatedly(ReturnRef(connection_));
connection_.stream_info_.downstream_connection_info_provider_->setRemoteAddress(addr_);
connection_.stream_info_.downstream_connection_info_provider_->setLocalAddress(addr_);
EXPECT_CALL(Const(connection_), ssl()).Times(4).WillRepeatedly(Return(ssl_));
EXPECT_CALL(Const(connection_), ssl()).Times(3).WillRepeatedly(Return(ssl_));
EXPECT_CALL(*ssl_, uriSanPeerCertificate()).WillOnce(Return(std::vector<std::string>{"source"}));
EXPECT_CALL(*ssl_, uriSanLocalCertificate())
.WillOnce(Return(std::vector<std::string>{"destination"}));
Expand All @@ -240,6 +244,29 @@ TEST_F(CheckRequestUtilsTest, TcpTlsSession) {
EXPECT_EQ(want_tls_session.sni(), request.attributes().tls_session().sni());
}

// Verify that createTcpCheck populates the tls session details correctly from the connection when
// TLS session information isn't present.
TEST_F(CheckRequestUtilsTest, TcpTlsSessionNoSessionSni) {
envoy::service::auth::v3::CheckRequest request;
EXPECT_CALL(net_callbacks_, connection()).Times(4).WillRepeatedly(ReturnRef(connection_));
connection_.stream_info_.downstream_connection_info_provider_->setRemoteAddress(addr_);
connection_.stream_info_.downstream_connection_info_provider_->setLocalAddress(addr_);
EXPECT_CALL(connection_, requestedServerName())
.Times(3)
.WillRepeatedly(Return(requested_server_name_));
EXPECT_CALL(Const(connection_), ssl()).Times(3).WillRepeatedly(Return(ssl_));
EXPECT_CALL(*ssl_, uriSanPeerCertificate()).WillOnce(Return(std::vector<std::string>{"source"}));
EXPECT_CALL(*ssl_, uriSanLocalCertificate())
.WillOnce(Return(std::vector<std::string>{"destination"}));
envoy::service::auth::v3::AttributeContext_TLSSession want_tls_session;
EXPECT_CALL(*ssl_, sni()).WillOnce(ReturnRef(want_tls_session.sni()));

CheckRequestUtils::createTcpCheck(&net_callbacks_, request, false, true,
Protobuf::Map<std::string, std::string>());
EXPECT_TRUE(request.attributes().has_tls_session());
EXPECT_EQ(requested_server_name_, request.attributes().tls_session().sni());
}

// Verify that createHttpCheck's dependencies are invoked when it's called.
// Verify that check request object has no request data.
// Verify that a client supplied EnvoyAuthPartialBody will not affect the
Expand Down Expand Up @@ -691,11 +718,11 @@ TEST_F(CheckRequestUtilsTest, CheckAttrContextPeerCertificate) {
// Verify that the SNI is populated correctly.
TEST_F(CheckRequestUtilsTest, CheckAttrContextPeerTLSSession) {
EXPECT_CALL(callbacks_, connection())
.Times(4)
.Times(3)
.WillRepeatedly(Return(OptRef<const Network::Connection>{connection_}));
connection_.stream_info_.downstream_connection_info_provider_->setRemoteAddress(addr_);
connection_.stream_info_.downstream_connection_info_provider_->setLocalAddress(addr_);
EXPECT_CALL(Const(connection_), ssl()).Times(4).WillRepeatedly(Return(ssl_));
EXPECT_CALL(Const(connection_), ssl()).Times(3).WillRepeatedly(Return(ssl_));
EXPECT_CALL(callbacks_, streamId()).WillOnce(Return(0));
EXPECT_CALL(callbacks_, decodingBuffer()).WillOnce(Return(buffer_.get()));
EXPECT_CALL(callbacks_, streamInfo()).WillOnce(ReturnRef(req_info_));
Expand All @@ -715,11 +742,14 @@ TEST_F(CheckRequestUtilsTest, CheckAttrContextPeerTLSSession) {
// Verify that the SNI is populated correctly.
TEST_F(CheckRequestUtilsTest, CheckAttrContextPeerTLSSessionWithoutSNI) {
EXPECT_CALL(callbacks_, connection())
.Times(4)
.Times(3)
.WillRepeatedly(Return(OptRef<const Network::Connection>{connection_}));
connection_.stream_info_.downstream_connection_info_provider_->setRemoteAddress(addr_);
connection_.stream_info_.downstream_connection_info_provider_->setLocalAddress(addr_);
EXPECT_CALL(Const(connection_), ssl()).Times(4).WillRepeatedly(Return(ssl_));
EXPECT_CALL(Const(connection_), ssl()).Times(3).WillRepeatedly(Return(ssl_));
EXPECT_CALL(connection_, requestedServerName())
.Times(2)
.WillRepeatedly(Return(requested_server_name_));
EXPECT_CALL(callbacks_, streamId()).WillOnce(Return(0));
EXPECT_CALL(callbacks_, decodingBuffer()).WillOnce(Return(buffer_.get()));
EXPECT_CALL(callbacks_, streamInfo()).WillOnce(ReturnRef(req_info_));
Expand Down
Loading