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(); }