We are running envoy as host proxy to enforce mTLS.
We find that Envoy could be hammer by TLS handshake.
We enabled max_session_keys in UpstreamTlsContext and see signicant CPU utilization drop in experiment.
However, in production the max_session_keys is not very pratical,
because
the session key pool is shared by all the endpoint in the cluster and there is no hint to select the available session.
For example, if the cluster has two endpoints, 10.0.0.1:80 and 10.0.0.2:80.
When 10.0.0.1:80 is selected by the load balancer, ssl socket may pick the saved session that are created with 10.0.0.2:80.
See #4791
In the worse secanrio, if the two endpoints are selected in turn, the session reuse rate is 0.
In realworld, the session reuse rate drop to 1/N where N is the endpoints in the cluster.
My proposal is to add hint when selecting the ssl session.
A typical hint is the upstream endpoint address.
The hint can be stored in the transport socket options which is already attached to the SSL_SESSION,
and
replace the per ClientContext
std::deque<bssl::UniquePtr<SSL_SESSION>> session_keys_
by
std::unordered_map<SessionHint, std::deque<bssl::UniquePtr<SSL_SESSION>>> session_key_map_
- when a
SSL_SESSION is created with SSL
find the hint of the SSL and cache the session in the session_key_map_
- when a SSL is created via
ClientContextImpl::newSsl(const Network::TransportSocketOptionsConstSharedPtr&)
use the transport socket option to find hint, set session to the SSL if there is available a SSL_SESSION
The alternative method is spread the session among TLS servers, but this method not only expand the compromise size,
it also introduce shared storage as a depedencies. The extra dependency does not work when Envoy is close to the lowest layer.
We are running envoy as host proxy to enforce mTLS.
We find that Envoy could be hammer by TLS handshake.
We enabled max_session_keys in UpstreamTlsContext and see signicant CPU utilization drop in experiment.
However, in production the max_session_keys is not very pratical,
because
the session key pool is shared by all the endpoint in the cluster and there is no hint to select the available session.
For example, if the cluster has two endpoints, 10.0.0.1:80 and 10.0.0.2:80.
When 10.0.0.1:80 is selected by the load balancer, ssl socket may pick the saved session that are created with 10.0.0.2:80.
See #4791
In the worse secanrio, if the two endpoints are selected in turn, the session reuse rate is 0.
In realworld, the session reuse rate drop to 1/N where N is the endpoints in the cluster.
My proposal is to add hint when selecting the ssl session.
A typical hint is the upstream endpoint address.
The hint can be stored in the transport socket options which is already attached to the
SSL_SESSION,and
replace the per ClientContext
std::deque<bssl::UniquePtr<SSL_SESSION>> session_keys_by
std::unordered_map<SessionHint, std::deque<bssl::UniquePtr<SSL_SESSION>>> session_key_map_SSL_SESSIONis created withSSLfind the hint of the
SSLand cache the session in thesession_key_map_ClientContextImpl::newSsl(const Network::TransportSocketOptionsConstSharedPtr&)use the transport socket option to find hint, set session to the
SSLif there is available aSSL_SESSIONThe alternative method is spread the session among TLS servers, but this method not only expand the compromise size,
it also introduce shared storage as a depedencies. The extra dependency does not work when Envoy is close to the lowest layer.