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.
This commit is contained in:
Tatsuhiro Tsujikawa 2017-05-18 21:11:10 +09:00
parent 14edd12304
commit 0d4f0f0db5
7 changed files with 50 additions and 1 deletions

View File

@ -166,6 +166,7 @@ OPTIONS = [
"single-process",
"no-add-x-forwarded-proto",
"no-strip-incoming-x-forwarded-proto",
"ocsp-startup",
]
LOGVARS = [

View File

@ -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=<HOST>,<PORT>[;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,

View File

@ -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";

View File

@ -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,

View File

@ -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

View File

@ -174,6 +174,8 @@ public:
void
worker_replace_downstream(std::shared_ptr<DownstreamConfig> downstreamconf);
void set_enable_acceptor_on_ocsp_completion(bool f);
private:
// Stores all SSL_CTX objects.
std::vector<SSL_CTX *> 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

View File

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