nghttpx: Add encryption support for TLS ticket key retrieval
This commit is contained in:
parent
3297a303bf
commit
3a41e4dd1a
|
@ -117,7 +117,10 @@ OPTIONS = [
|
|||
"backend-http1-tls",
|
||||
"backend-tls-session-cache-per-worker",
|
||||
"tls-session-cache-memcached-cert-file",
|
||||
"tls-session-cache-memcached-private-key-file"
|
||||
"tls-session-cache-memcached-private-key-file",
|
||||
"tls-ticket-key-memcached-tls",
|
||||
"tls-ticket-key-memcached-cert-file",
|
||||
"tls-ticket-key-memcached-private-key-file"
|
||||
]
|
||||
|
||||
LOGVARS = [
|
||||
|
|
48
src/shrpx.cc
48
src/shrpx.cc
|
@ -1520,16 +1520,16 @@ SSL/TLS:
|
|||
ticket key sharing between nghttpx instances is not
|
||||
required.
|
||||
--tls-ticket-key-memcached=<HOST>,<PORT>
|
||||
Specify address of memcached server to store session
|
||||
cache. This enables shared TLS ticket key between
|
||||
multiple nghttpx instances. nghttpx does not set TLS
|
||||
ticket key to memcached. The external ticket key
|
||||
generator is required. nghttpx just gets TLS ticket
|
||||
keys from memcached, and use them, possibly replacing
|
||||
current set of keys. It is up to extern TLS ticket key
|
||||
generator to rotate keys frequently. See "TLS SESSION
|
||||
TICKET RESUMPTION" section in manual page to know the
|
||||
data format in memcached entry.
|
||||
Specify address of memcached server to get TLS ticket
|
||||
keys for session resumption. This enables shared TLS
|
||||
ticket key between multiple nghttpx instances. nghttpx
|
||||
does not set TLS ticket key to memcached. The external
|
||||
ticket key generator is required. nghttpx just gets TLS
|
||||
ticket keys from memcached, and use them, possibly
|
||||
replacing current set of keys. It is up to extern TLS
|
||||
ticket key generator to rotate keys frequently. See
|
||||
"TLS SESSION TICKET RESUMPTION" section in manual page
|
||||
to know the data format in memcached entry.
|
||||
--tls-ticket-key-memcached-interval=<DURATION>
|
||||
Set interval to get TLS ticket keys from memcached.
|
||||
Default: )"
|
||||
|
@ -1550,6 +1550,15 @@ SSL/TLS:
|
|||
Specify cipher to encrypt TLS session ticket. Specify
|
||||
either aes-128-cbc or aes-256-cbc. By default,
|
||||
aes-128-cbc is used.
|
||||
--tls-ticket-key-memcached-tls
|
||||
Enable SSL/TLS on memcached connections to get TLS
|
||||
ticket keys.
|
||||
--tls-ticket-key-memcached-cert-file=<PATH>
|
||||
Path to client certificate for memcached connections to
|
||||
get TLS ticket keys.
|
||||
--tls-ticket-key-memcached-private-key-file=<PATH>
|
||||
Path to client private key for memcached connections to
|
||||
get TLS ticket keys.
|
||||
--fetch-ocsp-response-file=<PATH>
|
||||
Path to fetch-ocsp-response script file. It should be
|
||||
absolute path.
|
||||
|
@ -2414,6 +2423,11 @@ int main(int argc, char **argv) {
|
|||
&flag, 109},
|
||||
{SHRPX_OPT_TLS_SESSION_CACHE_MEMCACHED_PRIVATE_KEY_FILE,
|
||||
required_argument, &flag, 110},
|
||||
{SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_TLS, no_argument, &flag, 111},
|
||||
{SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_CERT_FILE, required_argument, &flag,
|
||||
112},
|
||||
{SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_PRIVATE_KEY_FILE, required_argument,
|
||||
&flag, 113},
|
||||
{nullptr, 0, nullptr, 0}};
|
||||
|
||||
int option_index = 0;
|
||||
|
@ -2886,6 +2900,20 @@ int main(int argc, char **argv) {
|
|||
cmdcfgs.emplace_back(
|
||||
SHRPX_OPT_TLS_SESSION_CACHE_MEMCACHED_PRIVATE_KEY_FILE, optarg);
|
||||
break;
|
||||
case 111:
|
||||
// --tls-ticket-key-memcached-tls
|
||||
cmdcfgs.emplace_back(SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_TLS, "yes");
|
||||
break;
|
||||
case 112:
|
||||
// --tls-ticket-key-memcached-cert-file
|
||||
cmdcfgs.emplace_back(SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_CERT_FILE,
|
||||
optarg);
|
||||
break;
|
||||
case 113:
|
||||
// --tls-ticket-key-memcached-private-key-file
|
||||
cmdcfgs.emplace_back(
|
||||
SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_PRIVATE_KEY_FILE, optarg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -764,9 +764,12 @@ enum {
|
|||
SHRPX_OPTID_TLS_TICKET_KEY_CIPHER,
|
||||
SHRPX_OPTID_TLS_TICKET_KEY_FILE,
|
||||
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED,
|
||||
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_CERT_FILE,
|
||||
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_INTERVAL,
|
||||
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL,
|
||||
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_RETRY,
|
||||
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_PRIVATE_KEY_FILE,
|
||||
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_TLS,
|
||||
SHRPX_OPTID_USER,
|
||||
SHRPX_OPTID_VERIFY_CLIENT,
|
||||
SHRPX_OPTID_VERIFY_CLIENT_CACERT,
|
||||
|
@ -1328,6 +1331,9 @@ int option_lookup_token(const char *name, size_t namelen) {
|
|||
if (util::strieq_l("http2-max-concurrent-stream", name, 27)) {
|
||||
return SHRPX_OPTID_HTTP2_MAX_CONCURRENT_STREAMS;
|
||||
}
|
||||
if (util::strieq_l("tls-ticket-key-memcached-tl", name, 27)) {
|
||||
return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_TLS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -1363,6 +1369,11 @@ int option_lookup_token(const char *name, size_t namelen) {
|
|||
break;
|
||||
case 34:
|
||||
switch (name[33]) {
|
||||
case 'e':
|
||||
if (util::strieq_l("tls-ticket-key-memcached-cert-fil", name, 33)) {
|
||||
return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_CERT_FILE;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
if (util::strieq_l("frontend-http2-dump-request-heade", name, 33)) {
|
||||
return SHRPX_OPTID_FRONTEND_HTTP2_DUMP_REQUEST_HEADER;
|
||||
|
@ -1429,6 +1440,16 @@ int option_lookup_token(const char *name, size_t namelen) {
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 41:
|
||||
switch (name[40]) {
|
||||
case 'e':
|
||||
if (util::strieq_l("tls-ticket-key-memcached-private-key-fil", name,
|
||||
40)) {
|
||||
return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_PRIVATE_KEY_FILE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 44:
|
||||
switch (name[43]) {
|
||||
case 'e':
|
||||
|
@ -2267,6 +2288,18 @@ int parse_config(const char *opt, const char *optarg,
|
|||
case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_PRIVATE_KEY_FILE:
|
||||
mod_config()->tls.session_cache.memcached.private_key_file = optarg;
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_TLS:
|
||||
mod_config()->tls.ticket.memcached.tls = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_CERT_FILE:
|
||||
mod_config()->tls.ticket.memcached.cert_file = optarg;
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_PRIVATE_KEY_FILE:
|
||||
mod_config()->tls.ticket.memcached.private_key_file = optarg;
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_CONF:
|
||||
LOG(WARN) << "conf: ignored";
|
||||
|
|
|
@ -215,6 +215,12 @@ constexpr char SHRPX_OPT_TLS_SESSION_CACHE_MEMCACHED_CERT_FILE[] =
|
|||
"tls-session-cache-memcached-cert-file";
|
||||
constexpr char SHRPX_OPT_TLS_SESSION_CACHE_MEMCACHED_PRIVATE_KEY_FILE[] =
|
||||
"tls-session-cache-memcached-private-key-file";
|
||||
constexpr char SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_TLS[] =
|
||||
"tls-ticket-key-memcached-tls";
|
||||
constexpr char SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_CERT_FILE[] =
|
||||
"tls-ticket-key-memcached-cert-file";
|
||||
constexpr char SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_PRIVATE_KEY_FILE[] =
|
||||
"tls-ticket-key-memcached-private-key-file";
|
||||
|
||||
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
||||
|
||||
|
@ -341,6 +347,9 @@ struct TLSConfig {
|
|||
Address addr;
|
||||
uint16_t port;
|
||||
std::unique_ptr<char[]> host;
|
||||
// Client private key and certificate for authentication
|
||||
ImmutableString private_key_file;
|
||||
ImmutableString cert_file;
|
||||
ev_tstamp interval;
|
||||
// Maximum number of retries when getting TLS ticket key from
|
||||
// mamcached, due to network error.
|
||||
|
@ -348,6 +357,7 @@ struct TLSConfig {
|
|||
// Maximum number of consecutive error from memcached, when this
|
||||
// limit reached, TLS ticket is disabled.
|
||||
size_t max_fail;
|
||||
bool tls;
|
||||
} memcached;
|
||||
std::vector<std::string> files;
|
||||
const EVP_CIPHER *cipher;
|
||||
|
|
|
@ -759,6 +759,23 @@ void ConnectionHandler::schedule_next_tls_ticket_key_memcached_get(
|
|||
ev_timer_start(loop_, w);
|
||||
}
|
||||
|
||||
SSL_CTX *ConnectionHandler::create_tls_ticket_key_memcached_ssl_ctx() {
|
||||
auto &tlsconf = get_config()->tls;
|
||||
auto &memcachedconf = get_config()->tls.ticket.memcached;
|
||||
|
||||
auto ssl_ctx = ssl::create_ssl_client_context(
|
||||
#ifdef HAVE_NEVERBLEED
|
||||
nb_.get(),
|
||||
#endif // HAVE_NEVERBLEED
|
||||
StringRef::from_maybe_nullptr(tlsconf.cacert.get()),
|
||||
StringRef(memcachedconf.cert_file),
|
||||
StringRef(memcachedconf.private_key_file), StringRef(), nullptr);
|
||||
|
||||
all_ssl_ctx_.push_back(ssl_ctx);
|
||||
|
||||
return ssl_ctx;
|
||||
}
|
||||
|
||||
#ifdef HAVE_NEVERBLEED
|
||||
void ConnectionHandler::set_neverbleed(std::unique_ptr<neverbleed_t> nb) {
|
||||
nb_ = std::move(nb);
|
||||
|
|
|
@ -129,6 +129,7 @@ public:
|
|||
on_tls_ticket_key_get_success(const std::shared_ptr<TicketKeys> &ticket_keys,
|
||||
ev_timer *w);
|
||||
void schedule_next_tls_ticket_key_memcached_get(ev_timer *w);
|
||||
SSL_CTX *create_tls_ticket_key_memcached_ssl_ctx();
|
||||
|
||||
#ifdef HAVE_NEVERBLEED
|
||||
void set_neverbleed(std::unique_ptr<neverbleed_t> nb);
|
||||
|
|
|
@ -420,14 +420,24 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
|
|||
|
||||
#endif // HAVE_NEVERBLEED
|
||||
|
||||
MemchunkPool mcpool;
|
||||
|
||||
ev_timer renew_ticket_key_timer;
|
||||
if (!upstreamconf.no_tls) {
|
||||
auto &ticketconf = get_config()->tls.ticket;
|
||||
auto &memcachedconf = ticketconf.memcached;
|
||||
|
||||
if (ticketconf.memcached.host) {
|
||||
SSL_CTX *ssl_ctx = nullptr;
|
||||
|
||||
if (memcachedconf.tls) {
|
||||
ssl_ctx = conn_handler.create_tls_ticket_key_memcached_ssl_ctx();
|
||||
}
|
||||
|
||||
conn_handler.set_tls_ticket_key_memcached_dispatcher(
|
||||
make_unique<MemcachedDispatcher>(&ticketconf.memcached.addr, loop,
|
||||
nullptr, "", nullptr));
|
||||
make_unique<MemcachedDispatcher>(
|
||||
&ticketconf.memcached.addr, loop, ssl_ctx,
|
||||
StringRef(memcachedconf.host.get()), &mcpool));
|
||||
|
||||
ev_timer_init(&renew_ticket_key_timer, memcached_get_ticket_key_cb, 0.,
|
||||
0.);
|
||||
|
|
Loading…
Reference in New Issue