diff --git a/include/istio/control/http/check_data.h b/include/istio/control/http/check_data.h index fc8d204aa88..01f7d2d4c0a 100644 --- a/include/istio/control/http/check_data.h +++ b/include/istio/control/http/check_data.h @@ -47,6 +47,9 @@ class CheckData { // Returns true if connection is mutual TLS enabled. virtual bool IsMutualTLS() const = 0; + // Get requested server name, SNI in case of TLS + virtual std::string GetRequestedServerName() const = 0; + // These headers are extracted into top level attributes. // This is for standard HTTP headers. It supports both HTTP/1.1 and HTTP2 // They can be retrieved at O(1) speed by environment (Envoy). diff --git a/include/istio/control/tcp/check_data.h b/include/istio/control/tcp/check_data.h index 991b6f8d421..6bb5edf2210 100644 --- a/include/istio/control/tcp/check_data.h +++ b/include/istio/control/tcp/check_data.h @@ -37,6 +37,9 @@ class CheckData { // Returns true if connection is mutual TLS enabled. virtual bool IsMutualTLS() const = 0; + // Get requested server name, SNI in case of TLS + virtual std::string GetRequestedServerName() const = 0; + // Get downstream tcp connection id. virtual std::string GetConnectionId() const = 0; }; diff --git a/include/istio/utils/attribute_names.h b/include/istio/utils/attribute_names.h index d7c00fd3bb2..9dad877a20a 100644 --- a/include/istio/utils/attribute_names.h +++ b/include/istio/utils/attribute_names.h @@ -65,6 +65,7 @@ struct AttributeName { static const char kConnectionSendTotalBytes[]; static const char kConnectionDuration[]; static const char kConnectionMtls[]; + static const char kConnectionRequestedServerName[]; static const char kConnectionId[]; // Record TCP connection status: open, continue, close static const char kConnectionEvent[]; diff --git a/src/envoy/http/mixer/check_data.cc b/src/envoy/http/mixer/check_data.cc index 4726a4be7ae..64cc1fcd972 100644 --- a/src/envoy/http/mixer/check_data.cc +++ b/src/envoy/http/mixer/check_data.cc @@ -77,6 +77,14 @@ std::map CheckData::GetRequestHeaders() const { bool CheckData::IsMutualTLS() const { return Utils::IsMutualTLS(connection_); } +std::string CheckData::GetRequestedServerName() const { + if (connection_) { + return std::string(connection_->requestedServerName()); + } + + return ""; +} + bool CheckData::FindHeaderByType(HttpCheckData::HeaderType header_type, std::string* value) const { switch (header_type) { diff --git a/src/envoy/http/mixer/check_data.h b/src/envoy/http/mixer/check_data.h index b03c3a1e7f2..b41d05547f7 100644 --- a/src/envoy/http/mixer/check_data.h +++ b/src/envoy/http/mixer/check_data.h @@ -41,6 +41,7 @@ class CheckData : public ::istio::control::http::CheckData, std::map GetRequestHeaders() const override; bool IsMutualTLS() const override; + std::string GetRequestedServerName() const override; bool FindHeaderByType( ::istio::control::http::CheckData::HeaderType header_type, diff --git a/src/envoy/tcp/mixer/filter.cc b/src/envoy/tcp/mixer/filter.cc index 128e06ef715..944e2b1ce6f 100644 --- a/src/envoy/tcp/mixer/filter.cc +++ b/src/envoy/tcp/mixer/filter.cc @@ -157,6 +157,10 @@ bool Filter::IsMutualTLS() const { return Utils::IsMutualTLS(&filter_callbacks_->connection()); } +std::string Filter::GetRequestedServerName() const { + return std::string(filter_callbacks_->connection().requestedServerName()); +} + bool Filter::GetDestinationIpPort(std::string* str_ip, int* port) const { if (filter_callbacks_->upstreamHost() && filter_callbacks_->upstreamHost()->address()) { diff --git a/src/envoy/tcp/mixer/filter.h b/src/envoy/tcp/mixer/filter.h index 2fa8b8fe382..ed1f9685714 100644 --- a/src/envoy/tcp/mixer/filter.h +++ b/src/envoy/tcp/mixer/filter.h @@ -53,6 +53,7 @@ class Filter : public Network::Filter, bool GetSourceIpPort(std::string* str_ip, int* port) const override; bool GetSourceUser(std::string* user) const override; bool IsMutualTLS() const override; + std::string GetRequestedServerName() const override; // ReportData virtual functions. bool GetDestinationIpPort(std::string* str_ip, int* port) const override; diff --git a/src/istio/control/http/attributes_builder.cc b/src/istio/control/http/attributes_builder.cc index 7acdff379cd..e39537c696a 100644 --- a/src/istio/control/http/attributes_builder.cc +++ b/src/istio/control/http/attributes_builder.cc @@ -157,6 +157,12 @@ void AttributesBuilder::ExtractCheckAttributes(CheckData *check_data) { builder.AddBool(utils::AttributeName::kConnectionMtls, check_data->IsMutualTLS()); + std::string requested_server_name = check_data->GetRequestedServerName(); + if (!requested_server_name.empty()) { + builder.AddString(utils::AttributeName::kConnectionRequestedServerName, + requested_server_name); + } + builder.AddTimestamp(utils::AttributeName::kRequestTime, std::chrono::system_clock::now()); diff --git a/src/istio/control/http/attributes_builder_test.cc b/src/istio/control/http/attributes_builder_test.cc index d1475f734b9..26a319440ff 100644 --- a/src/istio/control/http/attributes_builder_test.cc +++ b/src/istio/control/http/attributes_builder_test.cc @@ -89,6 +89,12 @@ attributes { bool_value: true } } +attributes { + key: "connection.requested_server_name" + value { + string_value: "www.google.com" + } +} attributes { key: "source.principal" value { @@ -286,6 +292,8 @@ TEST(AttributesBuilderTest, TestCheckAttributes) { EXPECT_CALL(mock_data, IsMutualTLS()).WillOnce(Invoke([]() -> bool { return true; })); + EXPECT_CALL(mock_data, GetRequestedServerName()) + .WillOnce(testing::Return("www.google.com")); EXPECT_CALL(mock_data, GetRequestHeaders()) .WillOnce(Invoke([]() -> std::map { std::map map; @@ -341,6 +349,8 @@ TEST(AttributesBuilderTest, TestCheckAttributesWithAuthNResult) { EXPECT_CALL(mock_data, IsMutualTLS()).WillOnce(Invoke([]() -> bool { return true; })); + EXPECT_CALL(mock_data, GetRequestedServerName()) + .WillOnce(testing::Return("www.google.com")); EXPECT_CALL(mock_data, GetRequestHeaders()) .WillOnce(Invoke([]() -> std::map { std::map map; diff --git a/src/istio/control/http/mock_check_data.h b/src/istio/control/http/mock_check_data.h index 9fc44f20d71..43066567b84 100644 --- a/src/istio/control/http/mock_check_data.h +++ b/src/istio/control/http/mock_check_data.h @@ -44,6 +44,7 @@ class MockCheckData : public CheckData { MOCK_CONST_METHOD1(GetAuthenticationResult, bool(istio::authn::Result *result)); MOCK_CONST_METHOD0(IsMutualTLS, bool()); + MOCK_CONST_METHOD0(GetRequestedServerName, std::string()); }; // The mock object for HeaderUpdate interface. diff --git a/src/istio/control/tcp/attributes_builder.cc b/src/istio/control/tcp/attributes_builder.cc index 64fa59ed473..329702283cf 100644 --- a/src/istio/control/tcp/attributes_builder.cc +++ b/src/istio/control/tcp/attributes_builder.cc @@ -51,6 +51,12 @@ void AttributesBuilder::ExtractCheckAttributes(CheckData* check_data) { builder.AddBool(utils::AttributeName::kConnectionMtls, check_data->IsMutualTLS()); + std::string requested_server_name = check_data->GetRequestedServerName(); + if (!requested_server_name.empty()) { + builder.AddString(utils::AttributeName::kConnectionRequestedServerName, + requested_server_name); + } + builder.AddTimestamp(utils::AttributeName::kContextTime, std::chrono::system_clock::now()); builder.AddString(utils::AttributeName::kContextProtocol, "tcp"); diff --git a/src/istio/control/tcp/attributes_builder_test.cc b/src/istio/control/tcp/attributes_builder_test.cc index a9d14c9b3b1..d93c923f31f 100644 --- a/src/istio/control/tcp/attributes_builder_test.cc +++ b/src/istio/control/tcp/attributes_builder_test.cc @@ -67,6 +67,12 @@ attributes { bool_value: true } } +attributes { + key: "connection.requested_server_name" + value { + string_value: "www.google.com" + } +} attributes { key: "source.principal" value { @@ -305,6 +311,8 @@ TEST(AttributesBuilderTest, TestCheckAttributes) { return true; })); EXPECT_CALL(mock_data, GetConnectionId()).WillOnce(Return("1234-5")); + EXPECT_CALL(mock_data, GetRequestedServerName()) + .WillOnce(Return("www.google.com")); RequestContext request; AttributesBuilder builder(&request); diff --git a/src/istio/control/tcp/mock_check_data.h b/src/istio/control/tcp/mock_check_data.h index 170e766b500..4c10d3ee309 100644 --- a/src/istio/control/tcp/mock_check_data.h +++ b/src/istio/control/tcp/mock_check_data.h @@ -29,6 +29,7 @@ class MockCheckData : public CheckData { MOCK_CONST_METHOD2(GetSourceIpPort, bool(std::string* ip, int* port)); MOCK_CONST_METHOD1(GetSourceUser, bool(std::string* user)); MOCK_CONST_METHOD0(IsMutualTLS, bool()); + MOCK_CONST_METHOD0(GetRequestedServerName, std::string()); MOCK_CONST_METHOD0(GetConnectionId, std::string()); }; diff --git a/src/istio/utils/attribute_names.cc b/src/istio/utils/attribute_names.cc index 5b50d411c44..759cd49b985 100644 --- a/src/istio/utils/attribute_names.cc +++ b/src/istio/utils/attribute_names.cc @@ -58,6 +58,9 @@ const char AttributeName::kConnectionSendTotalBytes[] = "connection.sent.bytes_total"; const char AttributeName::kConnectionDuration[] = "connection.duration"; const char AttributeName::kConnectionMtls[] = "connection.mtls"; +const char AttributeName::kConnectionRequestedServerName[] = + "connection.requested_server_name"; + // Downstream TCP connection id. const char AttributeName::kConnectionId[] = "connection.id"; const char AttributeName::kConnectionEvent[] = "connection.event";