Skip to content

Commit

Permalink
log: add upstream TLS info (envoyproxy#7911)
Browse files Browse the repository at this point in the history
Description: add upstream TLS info for logging purposes

Refactor SSL connection info to be a shared pointer.
Use read-only interface.
Cache computed values in the SSL info object (this allows transition to remove the underlying SSL object if necessary).

Risk Level: medium due to use of bssl::SSL to back ConnectionInfo
Testing: unit
Docs Changes: none
Release Notes: add upstream TLS info

Signed-off-by: Kuat Yessenov <[email protected]>
  • Loading branch information
kyessenov authored and lizan committed Sep 6, 2019
1 parent 5dc6f09 commit 838eb20
Show file tree
Hide file tree
Showing 57 changed files with 833 additions and 600 deletions.
4 changes: 3 additions & 1 deletion include/envoy/http/conn_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ class Callbacks {
* @param encoder supplies the request encoder to use.
* @param host supplies the description of the host that will carry the request. For logical
* connection pools the description may be different each time this is called.
* @param info supplies the stream info object associated with the upstream connection.
*/
virtual void onPoolReady(Http::StreamEncoder& encoder,
Upstream::HostDescriptionConstSharedPtr host) PURE;
Upstream::HostDescriptionConstSharedPtr host,
const StreamInfo::StreamInfo& info) PURE;
};

/**
Expand Down
2 changes: 1 addition & 1 deletion include/envoy/network/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ class Connection : public Event::DeferredDeletable, public FilterManager {
* @return the const SSL connection data if this is an SSL connection, or nullptr if it is not.
*/
// TODO(snowp): Remove this in favor of StreamInfo::downstreamSslConnection.
virtual const Ssl::ConnectionInfo* ssl() const PURE;
virtual Ssl::ConnectionInfoConstSharedPtr ssl() const PURE;

/**
* @return requested server name (e.g. SNI in TLS), if any.
Expand Down
2 changes: 1 addition & 1 deletion include/envoy/network/transport_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class TransportSocket {
/**
* @return the const SSL connection data if this is an SSL connection, or nullptr if it is not.
*/
virtual const Ssl::ConnectionInfo* ssl() const PURE;
virtual Ssl::ConnectionInfoConstSharedPtr ssl() const PURE;
};

using TransportSocketPtr = std::unique_ptr<TransportSocket>;
Expand Down
2 changes: 2 additions & 0 deletions include/envoy/ssl/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,7 @@ class ConnectionInfo {
virtual std::string tlsVersion() const PURE;
};

using ConnectionInfoConstSharedPtr = std::shared_ptr<const ConnectionInfo>;

} // namespace Ssl
} // namespace Envoy
17 changes: 15 additions & 2 deletions include/envoy/stream_info/stream_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,13 +424,26 @@ class StreamInfo {
/**
* @param connection_info sets the downstream ssl connection.
*/
virtual void setDownstreamSslConnection(const Ssl::ConnectionInfo* ssl_connection_info) PURE;
virtual void
setDownstreamSslConnection(const Ssl::ConnectionInfoConstSharedPtr& ssl_connection_info) PURE;

/**
* @return the downstream SSL connection. This will be nullptr if the downstream
* connection does not use SSL.
*/
virtual const Ssl::ConnectionInfo* downstreamSslConnection() const PURE;
virtual Ssl::ConnectionInfoConstSharedPtr downstreamSslConnection() const PURE;

/**
* @param connection_info sets the upstream ssl connection.
*/
virtual void
setUpstreamSslConnection(const Ssl::ConnectionInfoConstSharedPtr& ssl_connection_info) PURE;

/**
* @return the upstream SSL connection. This will be nullptr if the upstream
* connection does not use SSL.
*/
virtual Ssl::ConnectionInfoConstSharedPtr upstreamSslConnection() const PURE;

/**
* @return const Router::RouteEntry* Get the route entry selected for this request. Note: this
Expand Down
1 change: 1 addition & 0 deletions source/common/http/codec_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ StreamEncoder& CodecClient::newStream(StreamDecoder& response_decoder) {
void CodecClient::onEvent(Network::ConnectionEvent event) {
if (event == Network::ConnectionEvent::Connected) {
ENVOY_CONN_LOG(debug, "connected", *connection_);
connection_->streamInfo().setDownstreamSslConnection(connection_->ssl());
connected_ = true;
}

Expand Down
2 changes: 2 additions & 0 deletions source/common/http/codec_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ class CodecClient : Logger::Loggable<Logger::Id::client>,

Type type() const { return type_; }

const StreamInfo::StreamInfo& streamInfo() { return connection_->streamInfo(); }

protected:
/**
* Create a codec client and connect to a remote host/port.
Expand Down
3 changes: 2 additions & 1 deletion source/common/http/http1/conn_pool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ void ConnPoolImpl::attachRequestToClient(ActiveClient& client, StreamDecoder& re
host_->cluster().stats().upstream_rq_total_.inc();
host_->stats().rq_total_.inc();
client.stream_wrapper_ = std::make_unique<StreamWrapper>(response_decoder, client);
callbacks.onPoolReady(*client.stream_wrapper_, client.real_host_description_);
callbacks.onPoolReady(*client.stream_wrapper_, client.real_host_description_,
client.codec_client_->streamInfo());
}

void ConnPoolImpl::checkForDrained() {
Expand Down
3 changes: 2 additions & 1 deletion source/common/http/http2/conn_pool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ void ConnPoolImpl::newClientStream(Http::StreamDecoder& response_decoder,
host_->cluster().stats().upstream_rq_active_.inc();
host_->cluster().resourceManager(priority_).requests().inc();
callbacks.onPoolReady(primary_client_->client_->newStream(response_decoder),
primary_client_->real_host_description_);
primary_client_->real_host_description_,
primary_client_->client_->streamInfo());
}
}

Expand Down
2 changes: 1 addition & 1 deletion source/common/network/connection_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class ConnectionImpl : public FilterManagerConnection,
}
absl::optional<UnixDomainSocketPeerCredentials> unixSocketPeerCredentials() const override;
void setConnectionStats(const ConnectionStats& stats) override;
const Ssl::ConnectionInfo* ssl() const override { return transport_socket_->ssl(); }
Ssl::ConnectionInfoConstSharedPtr ssl() const override { return transport_socket_->ssl(); }
State state() const override;
void write(Buffer::Instance& data, bool end_stream) override;
void setBufferLimits(uint32_t limit) override;
Expand Down
2 changes: 1 addition & 1 deletion source/common/network/raw_buffer_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class RawBufferSocket : public TransportSocket, protected Logger::Loggable<Logge
void onConnected() override;
IoResult doRead(Buffer::Instance& buffer) override;
IoResult doWrite(Buffer::Instance& buffer, bool end_stream) override;
const Ssl::ConnectionInfo* ssl() const override { return nullptr; }
Ssl::ConnectionInfoConstSharedPtr ssl() const override { return nullptr; }

private:
TransportSocketCallbacks* callbacks_{};
Expand Down
6 changes: 5 additions & 1 deletion source/common/router/router.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1538,7 +1538,8 @@ void Filter::UpstreamRequest::onPoolFailure(Http::ConnectionPool::PoolFailureRea
}

void Filter::UpstreamRequest::onPoolReady(Http::StreamEncoder& request_encoder,
Upstream::HostDescriptionConstSharedPtr host) {
Upstream::HostDescriptionConstSharedPtr host,
const StreamInfo::StreamInfo& info) {
// This may be called under an existing ScopeTrackerScopeState but it will unwind correctly.
ScopeTrackerScopeState scope(&parent_.callbacks_->scope(), parent_.callbacks_->dispatcher());
ENVOY_STREAM_LOG(debug, "pool ready", *parent_.callbacks_);
Expand All @@ -1549,6 +1550,9 @@ void Filter::UpstreamRequest::onPoolReady(Http::StreamEncoder& request_encoder,
onUpstreamHostSelected(host);
request_encoder.getStream().addCallbacks(*this);

stream_info_.setUpstreamSslConnection(info.downstreamSslConnection());
parent_.callbacks_->streamInfo().setUpstreamSslConnection(info.downstreamSslConnection());

if (parent_.downstream_end_stream_) {
setupPerTryTimeout();
} else {
Expand Down
3 changes: 2 additions & 1 deletion source/common/router/router.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,8 @@ class Filter : Logger::Loggable<Logger::Id::router>,
absl::string_view transport_failure_reason,
Upstream::HostDescriptionConstSharedPtr host) override;
void onPoolReady(Http::StreamEncoder& request_encoder,
Upstream::HostDescriptionConstSharedPtr host) override;
Upstream::HostDescriptionConstSharedPtr host,
const StreamInfo::StreamInfo& info) override;

void setRequestEncoder(Http::StreamEncoder& request_encoder);
void clearRequestEncoder();
Expand Down
16 changes: 13 additions & 3 deletions source/common/stream_info/stream_info_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,23 @@ struct StreamInfoImpl : public StreamInfo {
return downstream_remote_address_;
}

void setDownstreamSslConnection(const Ssl::ConnectionInfo* connection_info) override {
void
setDownstreamSslConnection(const Ssl::ConnectionInfoConstSharedPtr& connection_info) override {
downstream_ssl_info_ = connection_info;
}

const Ssl::ConnectionInfo* downstreamSslConnection() const override {
Ssl::ConnectionInfoConstSharedPtr downstreamSslConnection() const override {
return downstream_ssl_info_;
}

void setUpstreamSslConnection(const Ssl::ConnectionInfoConstSharedPtr& connection_info) override {
upstream_ssl_info_ = connection_info;
}

Ssl::ConnectionInfoConstSharedPtr upstreamSslConnection() const override {
return upstream_ssl_info_;
}

const Router::RouteEntry* routeEntry() const override { return route_entry_; }

envoy::api::v2::core::Metadata& dynamicMetadata() override { return metadata_; };
Expand Down Expand Up @@ -243,7 +252,8 @@ struct StreamInfoImpl : public StreamInfo {
Network::Address::InstanceConstSharedPtr downstream_local_address_;
Network::Address::InstanceConstSharedPtr downstream_direct_remote_address_;
Network::Address::InstanceConstSharedPtr downstream_remote_address_;
const Ssl::ConnectionInfo* downstream_ssl_info_{};
Ssl::ConnectionInfoConstSharedPtr downstream_ssl_info_;
Ssl::ConnectionInfoConstSharedPtr upstream_ssl_info_;
std::string requested_server_name_;
UpstreamTiming upstream_timing_;
std::string upstream_transport_failure_reason_;
Expand Down
1 change: 1 addition & 0 deletions source/common/tcp/conn_pool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ void ConnPoolImpl::onConnectionEvent(ActiveConn& conn, Network::ConnectionEvent
// whether the connection is in the ready list (connected) or the pending list (failed to
// connect).
if (event == Network::ConnectionEvent::Connected) {
conn.conn_->streamInfo().setDownstreamSslConnection(conn.conn_->ssl());
conn_connect_ms_->complete();
processIdleConnection(conn, true, false);
}
Expand Down
1 change: 1 addition & 0 deletions source/common/tcp_proxy/tcp_proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ void Filter::onPoolReady(Tcp::ConnectionPool::ConnectionDataPtr&& conn_data,

getStreamInfo().onUpstreamHostSelected(host);
getStreamInfo().setUpstreamLocalAddress(connection.localAddress());
getStreamInfo().setUpstreamSslConnection(connection.streamInfo().downstreamSslConnection());

// Simulate the event that onPoolReady represents.
upstream_callbacks_->onEvent(Network::ConnectionEvent::Connected);
Expand Down
4 changes: 2 additions & 2 deletions source/common/tcp_proxy/tcp_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ class Filter : public Network::ReadFilter,
bool on_high_watermark_called_{false};
};

virtual StreamInfo::StreamInfo& getStreamInfo() { return stream_info_; }

protected:
struct DownstreamCallbacks : public Network::ConnectionCallbacks {
DownstreamCallbacks(Filter& parent) : parent_(parent) {}
Expand Down Expand Up @@ -260,8 +262,6 @@ class Filter : public Network::ReadFilter,
read_callbacks_->connection().close(Network::ConnectionCloseType::NoFlush);
}

virtual StreamInfo::StreamInfo& getStreamInfo() { return stream_info_; }

void initialize(Network::ReadFilterCallbacks& callbacks, bool set_connection_stats);
Network::FilterStatus initializeUpstreamConnection();
void onConnectTimeout();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ void Utility::extractCommonAccessLogProperties(
}
if (stream_info.downstreamSslConnection() != nullptr) {
auto* tls_properties = common_access_log.mutable_tls_properties();
const auto* downstream_ssl_connection = stream_info.downstreamSslConnection();
const Ssl::ConnectionInfoConstSharedPtr downstream_ssl_connection =
stream_info.downstreamSslConnection();

tls_properties->set_tls_sni_hostname(stream_info.requestedServerName());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void CheckRequestUtils::setAttrContextPeer(envoy::service::auth::v2::AttributeCo

// Set the principal. Preferably the URI SAN, DNS SAN or Subject in that order from the peer's
// cert.
Ssl::ConnectionInfo* ssl = const_cast<Ssl::ConnectionInfo*>(connection.ssl());
auto ssl = connection.ssl();
if (ssl != nullptr) {
if (local) {
const auto uri_sans = ssl->uriSanLocalCertificate();
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/filters/common/lua/wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class MetadataMapWrapper : public BaseLuaObject<MetadataMapWrapper> {
*/
class SslConnectionWrapper : public BaseLuaObject<SslConnectionWrapper> {
public:
SslConnectionWrapper(const Ssl::ConnectionInfo*) {}
SslConnectionWrapper(const Ssl::ConnectionInfoConstSharedPtr) {}
static ExportedFunctions exportedFunctions() { return {}; }

// TODO(dio): Add more Lua APIs around Ssl::Connection.
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/filters/common/rbac/matchers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ bool PortMatcher::matches(const Network::Connection& connection, const Envoy::Ht
bool AuthenticatedMatcher::matches(const Network::Connection& connection,
const Envoy::Http::HeaderMap&,
const StreamInfo::StreamInfo&) const {
const auto* ssl = connection.ssl();
const auto& ssl = connection.ssl();
if (!ssl) { // connection was not authenticated
return false;
} else if (!matcher_.has_value()) { // matcher allows any subject
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/transport_sockets/alts/tsi_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class TsiSocket : public Network::TransportSocket,
std::string protocol() const override;
absl::string_view failureReason() const override;
bool canFlushClose() override { return handshake_complete_; }
const Envoy::Ssl::ConnectionInfo* ssl() const override { return nullptr; }
Envoy::Ssl::ConnectionInfoConstSharedPtr ssl() const override { return nullptr; }
Network::IoResult doWrite(Buffer::Instance& buffer, bool end_stream) override;
void closeSocket(Network::ConnectionEvent event) override;
Network::IoResult doRead(Buffer::Instance& buffer) override;
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/transport_sockets/tap/tap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Network::IoResult TapSocket::doWrite(Buffer::Instance& buffer, bool end_stream)

void TapSocket::onConnected() { transport_socket_->onConnected(); }

const Ssl::ConnectionInfo* TapSocket::ssl() const { return transport_socket_->ssl(); }
Ssl::ConnectionInfoConstSharedPtr TapSocket::ssl() const { return transport_socket_->ssl(); }

TapSocketFactory::TapSocketFactory(
const envoy::config::transport_socket::tap::v2alpha::Tap& proto_config,
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/transport_sockets/tap/tap.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class TapSocket : public Network::TransportSocket {
Network::IoResult doRead(Buffer::Instance& buffer) override;
Network::IoResult doWrite(Buffer::Instance& buffer, bool end_stream) override;
void onConnected() override;
const Ssl::ConnectionInfo* ssl() const override;
Ssl::ConnectionInfoConstSharedPtr ssl() const override;

private:
SocketTapConfigSharedPtr config_;
Expand Down
Loading

0 comments on commit 838eb20

Please sign in to comment.