nghttpx: Disable TLS renegotiation
This commit is contained in:
parent
8f3d4fdeec
commit
4ed4efc241
|
@ -48,6 +48,10 @@ namespace {
|
||||||
void upstream_readcb(bufferevent *bev, void *arg)
|
void upstream_readcb(bufferevent *bev, void *arg)
|
||||||
{
|
{
|
||||||
auto handler = reinterpret_cast<ClientHandler*>(arg);
|
auto handler = reinterpret_cast<ClientHandler*>(arg);
|
||||||
|
if(handler->get_tls_renegotiation()) {
|
||||||
|
delete handler;
|
||||||
|
return;
|
||||||
|
}
|
||||||
int rv = handler->on_read();
|
int rv = handler->on_read();
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
delete handler;
|
delete handler;
|
||||||
|
@ -106,8 +110,9 @@ void upstream_eventcb(bufferevent *bev, short events, void *arg)
|
||||||
delete handler;
|
delete handler;
|
||||||
} else {
|
} else {
|
||||||
if(events & BEV_EVENT_CONNECTED) {
|
if(events & BEV_EVENT_CONNECTED) {
|
||||||
|
handler->set_tls_handshake(true);
|
||||||
if(LOG_ENABLED(INFO)) {
|
if(LOG_ENABLED(INFO)) {
|
||||||
CLOG(INFO, handler) << "SSL/TLS handleshake completed";
|
CLOG(INFO, handler) << "SSL/TLS handshake completed";
|
||||||
}
|
}
|
||||||
if(handler->validate_next_proto() != 0) {
|
if(handler->validate_next_proto() != 0) {
|
||||||
delete handler;
|
delete handler;
|
||||||
|
@ -226,7 +231,9 @@ ClientHandler::ClientHandler(bufferevent *bev, int fd, SSL *ssl,
|
||||||
ssl_(ssl),
|
ssl_(ssl),
|
||||||
left_connhd_len_(NGHTTP2_CLIENT_CONNECTION_HEADER_LEN),
|
left_connhd_len_(NGHTTP2_CLIENT_CONNECTION_HEADER_LEN),
|
||||||
fd_(fd),
|
fd_(fd),
|
||||||
should_close_after_write_(false)
|
should_close_after_write_(false),
|
||||||
|
tls_handshake_(false),
|
||||||
|
tls_renegotiation_(false)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
rv = bufferevent_set_rate_limit(bev_, get_config()->rate_limit_cfg);
|
rv = bufferevent_set_rate_limit(bev_, get_config()->rate_limit_cfg);
|
||||||
|
@ -238,6 +245,7 @@ ClientHandler::ClientHandler(bufferevent *bev, int fd, SSL *ssl,
|
||||||
set_upstream_timeouts(&get_config()->upstream_read_timeout,
|
set_upstream_timeouts(&get_config()->upstream_read_timeout,
|
||||||
&get_config()->upstream_write_timeout);
|
&get_config()->upstream_write_timeout);
|
||||||
if(ssl_) {
|
if(ssl_) {
|
||||||
|
SSL_set_app_data(ssl_, reinterpret_cast<char*>(this));
|
||||||
set_bev_cb(nullptr, upstream_writecb, upstream_eventcb);
|
set_bev_cb(nullptr, upstream_writecb, upstream_eventcb);
|
||||||
} else {
|
} else {
|
||||||
// For non-TLS version, first create HttpsUpstream. It may be
|
// For non-TLS version, first create HttpsUpstream. It may be
|
||||||
|
@ -254,6 +262,7 @@ ClientHandler::~ClientHandler()
|
||||||
CLOG(INFO, this) << "Deleting";
|
CLOG(INFO, this) << "Deleting";
|
||||||
}
|
}
|
||||||
if(ssl_) {
|
if(ssl_) {
|
||||||
|
SSL_set_app_data(ssl_, nullptr);
|
||||||
SSL_set_shutdown(ssl_, SSL_RECEIVED_SHUTDOWN);
|
SSL_set_shutdown(ssl_, SSL_RECEIVED_SHUTDOWN);
|
||||||
SSL_shutdown(ssl_);
|
SSL_shutdown(ssl_);
|
||||||
}
|
}
|
||||||
|
@ -498,4 +507,24 @@ std::string ClientHandler::get_upstream_scheme() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientHandler::set_tls_handshake(bool f)
|
||||||
|
{
|
||||||
|
tls_handshake_ = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientHandler::get_tls_handshake() const
|
||||||
|
{
|
||||||
|
return tls_handshake_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientHandler::set_tls_renegotiation(bool f)
|
||||||
|
{
|
||||||
|
tls_renegotiation_ = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientHandler::get_tls_renegotiation() const
|
||||||
|
{
|
||||||
|
return tls_renegotiation_;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -77,6 +77,10 @@ public:
|
||||||
bool get_http2_upgrade_allowed() const;
|
bool get_http2_upgrade_allowed() const;
|
||||||
// Returns upstream scheme, either "http" or "https"
|
// Returns upstream scheme, either "http" or "https"
|
||||||
std::string get_upstream_scheme() const;
|
std::string get_upstream_scheme() const;
|
||||||
|
void set_tls_handshake(bool f);
|
||||||
|
bool get_tls_handshake() const;
|
||||||
|
void set_tls_renegotiation(bool f);
|
||||||
|
bool get_tls_renegotiation() const;
|
||||||
private:
|
private:
|
||||||
std::set<DownstreamConnection*> dconn_pool_;
|
std::set<DownstreamConnection*> dconn_pool_;
|
||||||
std::unique_ptr<Upstream> upstream_;
|
std::unique_ptr<Upstream> upstream_;
|
||||||
|
@ -90,6 +94,8 @@ private:
|
||||||
size_t left_connhd_len_;
|
size_t left_connhd_len_;
|
||||||
int fd_;
|
int fd_;
|
||||||
bool should_close_after_write_;
|
bool should_close_after_write_;
|
||||||
|
bool tls_handshake_;
|
||||||
|
bool tls_renegotiation_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -132,6 +132,25 @@ int servername_callback(SSL *ssl, int *al, void *arg)
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void info_callback(const SSL *ssl, int where, int ret)
|
||||||
|
{
|
||||||
|
// To mitigate possible DOS attack using lots of renegotiations, we
|
||||||
|
// disable renegotiation. Since OpenSSL does not provide an easy way
|
||||||
|
// to disable it, we check that renegotiation is started in this
|
||||||
|
// callback.
|
||||||
|
if(where & SSL_CB_HANDSHAKE_START) {
|
||||||
|
auto handler = static_cast<ClientHandler*>(SSL_get_app_data(ssl));
|
||||||
|
if(handler && handler->get_tls_handshake()) {
|
||||||
|
handler->set_tls_renegotiation(true);
|
||||||
|
if(LOG_ENABLED(INFO)) {
|
||||||
|
CLOG(INFO, handler) << "TLS renegotiation started";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
namespace {
|
namespace {
|
||||||
int alpn_select_proto_cb(SSL* ssl,
|
int alpn_select_proto_cb(SSL* ssl,
|
||||||
|
@ -301,6 +320,7 @@ SSL_CTX* create_ssl_context(const char *private_key_file,
|
||||||
verify_callback);
|
verify_callback);
|
||||||
}
|
}
|
||||||
SSL_CTX_set_tlsext_servername_callback(ssl_ctx, servername_callback);
|
SSL_CTX_set_tlsext_servername_callback(ssl_ctx, servername_callback);
|
||||||
|
SSL_CTX_set_info_callback(ssl_ctx, info_callback);
|
||||||
|
|
||||||
// NPN advertisement
|
// NPN advertisement
|
||||||
auto proto_list_len = set_npn_prefs(proto_list, get_config()->npn_list,
|
auto proto_list_len = set_npn_prefs(proto_list, get_config()->npn_list,
|
||||||
|
|
Loading…
Reference in New Issue