From 0d4f0f0db5e96ec565f8aef1f342c88eedc12d8f Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 18 May 2017 21:11:10 +0900 Subject: [PATCH] nghttpx: Run OCSP at startup With --ocsp-startup option, nghttpx starts accepting connections after initial attempts to get OCSP responses finish. It does not matter some of the attempts fail. This feature is useful if OCSP responses must be available before accepting connections. --- gennghttpxfun.py | 1 + src/shrpx.cc | 12 ++++++++++++ src/shrpx_config.cc | 9 +++++++++ src/shrpx_config.h | 3 +++ src/shrpx_connection_handler.cc | 16 +++++++++++++++- src/shrpx_connection_handler.h | 5 +++++ src/shrpx_worker_process.cc | 5 +++++ 7 files changed, 50 insertions(+), 1 deletion(-) diff --git a/gennghttpxfun.py b/gennghttpxfun.py index 4c80550f..f46fac78 100755 --- a/gennghttpxfun.py +++ b/gennghttpxfun.py @@ -166,6 +166,7 @@ OPTIONS = [ "single-process", "no-add-x-forwarded-proto", "no-strip-incoming-x-forwarded-proto", + "ocsp-startup", ] LOGVARS = [ diff --git a/src/shrpx.cc b/src/shrpx.cc index 2de63a52..760db27b 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -2234,6 +2234,12 @@ SSL/TLS: Set interval to update OCSP response cache. Default: )" << util::duration_str(config->tls.ocsp.update_interval) << R"( + --ocsp-startup + Start accepting connections after initial attempts to + get OCSP responses finish. It does not matter some of + the attempts fail. This feature is useful if OCSP + responses must be available before accepting + connections. --no-ocsp Disable OCSP stapling. --tls-session-cache-memcached=,[;tls] Specify address of memcached server to store session @@ -3183,6 +3189,7 @@ int main(int argc, char **argv) { {SHRPX_OPT_BACKEND_HTTP_PROXY_URI.c_str(), required_argument, &flag, 26}, {SHRPX_OPT_BACKEND_NO_TLS.c_str(), no_argument, &flag, 27}, + {SHRPX_OPT_OCSP_STARTUP.c_str(), no_argument, &flag, 28}, {SHRPX_OPT_FRONTEND_NO_TLS.c_str(), no_argument, &flag, 29}, {SHRPX_OPT_BACKEND_TLS_SNI_FIELD.c_str(), required_argument, &flag, 31}, {SHRPX_OPT_DH_PARAM_FILE.c_str(), required_argument, &flag, 33}, @@ -3533,6 +3540,11 @@ int main(int argc, char **argv) { cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_NO_TLS, StringRef::from_lit("yes")); break; + case 28: + // --ocsp-startup + cmdcfgs.emplace_back(SHRPX_OPT_OCSP_STARTUP, + StringRef::from_lit("yes")); + break; case 29: // --frontend-no-tls cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_NO_TLS, diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index c33f8c51..cb6d6f21 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -1591,6 +1591,11 @@ int option_lookup_token(const char *name, size_t namelen) { return SHRPX_OPTID_HTTP2_BRIDGE; } break; + case 'p': + if (util::strieq_l("ocsp-startu", name, 11)) { + return SHRPX_OPTID_OCSP_STARTUP; + } + break; case 'y': if (util::strieq_l("client-prox", name, 11)) { return SHRPX_OPTID_CLIENT_PROXY; @@ -3420,6 +3425,10 @@ int parse_config(Config *config, int optid, const StringRef &opt, case SHRPX_OPTID_NO_STRIP_INCOMING_X_FORWARDED_PROTO: config->http.xfp.strip_incoming = !util::strieq_l("yes", optarg); + return 0; + case SHRPX_OPTID_OCSP_STARTUP: + config->tls.ocsp.startup = util::strieq_l("yes", optarg); + return 0; case SHRPX_OPTID_CONF: LOG(WARN) << "conf: ignored"; diff --git a/src/shrpx_config.h b/src/shrpx_config.h index 9db9c1fe..820f90fa 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -341,6 +341,7 @@ constexpr auto SHRPX_OPT_NO_ADD_X_FORWARDED_PROTO = StringRef::from_lit("no-add-x-forwarded-proto"); constexpr auto SHRPX_OPT_NO_STRIP_INCOMING_X_FORWARDED_PROTO = StringRef::from_lit("no-strip-incoming-x-forwarded-proto"); +constexpr auto SHRPX_OPT_OCSP_STARTUP = StringRef::from_lit("ocsp-startup"); constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8; @@ -561,6 +562,7 @@ struct TLSConfig { ev_tstamp update_interval; StringRef fetch_ocsp_response_file; bool disabled; + bool startup; } ocsp; // Client verification configurations @@ -1045,6 +1047,7 @@ enum { SHRPX_OPTID_NO_STRIP_INCOMING_X_FORWARDED_PROTO, SHRPX_OPTID_NO_VIA, SHRPX_OPTID_NPN_LIST, + SHRPX_OPTID_OCSP_STARTUP, SHRPX_OPTID_OCSP_UPDATE_INTERVAL, SHRPX_OPTID_PADDING, SHRPX_OPTID_PID_FILE, diff --git a/src/shrpx_connection_handler.cc b/src/shrpx_connection_handler.cc index b3b56991..ae55701c 100644 --- a/src/shrpx_connection_handler.cc +++ b/src/shrpx_connection_handler.cc @@ -118,7 +118,8 @@ ConnectionHandler::ConnectionHandler(struct ev_loop *loop, std::mt19937 &gen) tls_ticket_key_memcached_get_retry_count_(0), tls_ticket_key_memcached_fail_count_(0), worker_round_robin_cnt_(get_config()->api.enabled ? 1 : 0), - graceful_shutdown_(false) { + graceful_shutdown_(false), + enable_acceptor_on_ocsp_completion_(false) { ev_timer_init(&disable_acceptor_timer_, acceptor_disable_cb, 0., 0.); disable_acceptor_timer_.data = this; @@ -504,6 +505,9 @@ bool ConnectionHandler::get_graceful_shutdown() const { } void ConnectionHandler::cancel_ocsp_update() { + enable_acceptor_on_ocsp_completion_ = false; + ev_timer_stop(loop_, &ocsp_timer_); + if (ocsp_.proc.pid == 0) { return; } @@ -656,6 +660,12 @@ void ConnectionHandler::proceed_next_cert_ocsp() { // We have updated all ocsp response, and schedule next update. ev_timer_set(&ocsp_timer_, get_config()->tls.ocsp.update_interval, 0.); ev_timer_start(loop_, &ocsp_timer_); + + if (enable_acceptor_on_ocsp_completion_) { + enable_acceptor_on_ocsp_completion_ = false; + enable_acceptor(); + } + return; } @@ -855,4 +865,8 @@ ConnectionHandler::get_indexed_ssl_ctx(size_t idx) const { return indexed_ssl_ctx_[idx]; } +void ConnectionHandler::set_enable_acceptor_on_ocsp_completion(bool f) { + enable_acceptor_on_ocsp_completion_ = f; +} + } // namespace shrpx diff --git a/src/shrpx_connection_handler.h b/src/shrpx_connection_handler.h index d5f86f27..56a58581 100644 --- a/src/shrpx_connection_handler.h +++ b/src/shrpx_connection_handler.h @@ -174,6 +174,8 @@ public: void worker_replace_downstream(std::shared_ptr downstreamconf); + void set_enable_acceptor_on_ocsp_completion(bool f); + private: // Stores all SSL_CTX objects. std::vector all_ssl_ctx_; @@ -220,6 +222,9 @@ private: size_t tls_ticket_key_memcached_fail_count_; unsigned int worker_round_robin_cnt_; bool graceful_shutdown_; + // true if acceptors should be enabled after the initial ocsp update + // has finished. + bool enable_acceptor_on_ocsp_completion_; }; } // namespace shrpx diff --git a/src/shrpx_worker_process.cc b/src/shrpx_worker_process.cc index 758f8f2d..558029f3 100644 --- a/src/shrpx_worker_process.cc +++ b/src/shrpx_worker_process.cc @@ -547,6 +547,11 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) { ev_io_start(loop, &ipcev); if (tls::upstream_tls_enabled(config->conn) && !config->tls.ocsp.disabled) { + if (config->tls.ocsp.startup) { + conn_handler.set_enable_acceptor_on_ocsp_completion(true); + conn_handler.disable_acceptor(); + } + conn_handler.proceed_next_cert_ocsp(); }