nghttpx: Add --tls-proto-list option to enable SSL/TLS protocol selectively
This commit is contained in:
parent
3e21bed4f9
commit
7ce3065f32
24
src/shrpx.cc
24
src/shrpx.cc
|
@ -329,6 +329,10 @@ const char *DEFAULT_NPN_LIST = NGHTTP2_PROTO_VERSION_ID ","
|
|||
"http/1.1";
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
const char *DEFAULT_TLS_PROTO_LIST = "TLSv1.2,TLSv1.1,TLSv1.0";
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
void fill_default_config()
|
||||
{
|
||||
|
@ -622,6 +626,17 @@ void print_help(std::ostream& out)
|
|||
<< " Path to file that contains client\n"
|
||||
<< " certificate used in backend client\n"
|
||||
<< " authentication.\n"
|
||||
<< " --tls-proto-list=<LIST>\n"
|
||||
<< " Comma delimited list of SSL/TLS protocol to\n"
|
||||
<< " be enabled.\n"
|
||||
<< " The following protocols are available:\n"
|
||||
<< " TLSv1.2, TLSv1.1, TLSv1.0, SSLv3\n"
|
||||
<< " The name matching is done in case-insensitive\n"
|
||||
<< " manner.\n"
|
||||
<< " The parameter must be delimited by a single\n"
|
||||
<< " comma only and any white spaces are treated\n"
|
||||
<< " as a part of protocol string.\n"
|
||||
<< " Default: " << DEFAULT_TLS_PROTO_LIST << "\n"
|
||||
<< "\n"
|
||||
<< " HTTP/2.0 and SPDY:\n"
|
||||
<< " -c, --http2-max-concurrent-streams=<NUM>\n"
|
||||
|
@ -798,6 +813,7 @@ int main(int argc, char **argv)
|
|||
{"http2-no-cookie-crumbling", no_argument, &flag, 45},
|
||||
{"frontend-http2-connection-window-bits", required_argument, &flag, 46},
|
||||
{"backend-http2-connection-window-bits", required_argument, &flag, 47},
|
||||
{"tls-proto-list", required_argument, &flag, 48},
|
||||
{nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
|
@ -1049,6 +1065,10 @@ int main(int argc, char **argv)
|
|||
(SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_BITS,
|
||||
optarg));
|
||||
break;
|
||||
case 48:
|
||||
// --tls-proto-list
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_TLS_PROTO_LIST, optarg));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1091,6 +1111,10 @@ int main(int argc, char **argv)
|
|||
mod_config()->npn_list = parse_config_str_list(&mod_config()->npn_list_len,
|
||||
DEFAULT_NPN_LIST);
|
||||
}
|
||||
if(!get_config()->tls_proto_list) {
|
||||
mod_config()->tls_proto_list = parse_config_str_list
|
||||
(&mod_config()->tls_proto_list_len, DEFAULT_TLS_PROTO_LIST);
|
||||
}
|
||||
|
||||
if(!get_config()->subcerts.empty()) {
|
||||
mod_config()->cert_tree = ssl::cert_lookup_tree_new();
|
||||
|
|
|
@ -105,6 +105,7 @@ const char SHRPX_OPT_READ_BURST[] = "read-burst";
|
|||
const char SHRPX_OPT_WRITE_RATE[] = "write-rate";
|
||||
const char SHRPX_OPT_WRITE_BURST[] = "write-burst";
|
||||
const char SHRPX_OPT_NPN_LIST[] = "npn-list";
|
||||
const char SHRPX_OPT_TLS_PROTO_LIST[] = "tls-proto-list";
|
||||
const char SHRPX_OPT_VERIFY_CLIENT[] = "verify-client";
|
||||
const char SHRPX_OPT_VERIFY_CLIENT_CACERT[] = "verify-client-cacert";
|
||||
const char SHRPX_OPT_CLIENT_PRIVATE_KEY_FILE[] = "client-private-key-file";
|
||||
|
@ -453,6 +454,10 @@ int parse_config(const char *opt, const char *optarg)
|
|||
delete [] mod_config()->npn_list;
|
||||
mod_config()->npn_list = parse_config_str_list(&mod_config()->npn_list_len,
|
||||
optarg);
|
||||
} else if(util::strieq(opt, SHRPX_OPT_TLS_PROTO_LIST)) {
|
||||
delete [] mod_config()->tls_proto_list;
|
||||
mod_config()->tls_proto_list = parse_config_str_list
|
||||
(&mod_config()->tls_proto_list_len, optarg);
|
||||
} else if(util::strieq(opt, SHRPX_OPT_VERIFY_CLIENT)) {
|
||||
mod_config()->verify_client = util::strieq(optarg, "yes");
|
||||
} else if(util::strieq(opt, SHRPX_OPT_VERIFY_CLIENT_CACERT)) {
|
||||
|
|
|
@ -94,6 +94,7 @@ extern const char SHRPX_OPT_READ_BURST[];
|
|||
extern const char SHRPX_OPT_WRITE_RATE[];
|
||||
extern const char SHRPX_OPT_WRITE_BURST[];
|
||||
extern const char SHRPX_OPT_NPN_LIST[];
|
||||
extern const char SHRPX_OPT_TLS_PROTO_LIST[];
|
||||
extern const char SHRPX_OPT_VERIFY_CLIENT[];
|
||||
extern const char SHRPX_OPT_VERIFY_CLIENT_CACERT[];
|
||||
extern const char SHRPX_OPT_CLIENT_PRIVATE_KEY_FILE[];
|
||||
|
@ -151,6 +152,9 @@ struct Config {
|
|||
// preference. The each element of this list is a NULL-terminated
|
||||
// string.
|
||||
char **npn_list;
|
||||
// list of supported SSL/TLS protocol strings. The each element of
|
||||
// this list is a NULL-terminated string.
|
||||
char **tls_proto_list;
|
||||
// Path to file containing CA certificate solely used for client
|
||||
// certificate validation
|
||||
char *verify_client_cacert;
|
||||
|
@ -173,6 +177,8 @@ struct Config {
|
|||
size_t write_burst;
|
||||
// The number of elements in npn_list
|
||||
size_t npn_list_len;
|
||||
// The number of elements in tls_proto_list
|
||||
size_t tls_proto_list_len;
|
||||
// downstream protocol; this will be determined by given options.
|
||||
shrpx_proto downstream_proto;
|
||||
int syslog_facility;
|
||||
|
|
|
@ -149,6 +149,29 @@ int alpn_select_proto_cb(SSL* ssl,
|
|||
} // namespace
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
namespace {
|
||||
const char *names[] = { "TLSv1.2", "TLSv1.1", "TLSv1.0", "SSLv3" };
|
||||
const size_t namelen = sizeof(names)/sizeof(names[0]);
|
||||
const long int masks[] = { SSL_OP_NO_TLSv1_2, SSL_OP_NO_TLSv1_1,
|
||||
SSL_OP_NO_TLSv1, SSL_OP_NO_SSLv3 };
|
||||
long int create_tls_proto_mask(char **tls_proto_list, size_t len)
|
||||
{
|
||||
long int res = 0;
|
||||
for(size_t i = 0; i < namelen; ++i) {
|
||||
size_t j;
|
||||
for(j = 0; j < len; ++j) {
|
||||
if(strcasecmp(names[i], tls_proto_list[j]) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(j == len) {
|
||||
res |= masks[i];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
SSL_CTX* create_ssl_context(const char *private_key_file,
|
||||
const char *cert_file)
|
||||
{
|
||||
|
@ -158,11 +181,14 @@ SSL_CTX* create_ssl_context(const char *private_key_file,
|
|||
LOG(FATAL) << ERR_error_string(ERR_get_error(), nullptr);
|
||||
DIE();
|
||||
}
|
||||
|
||||
SSL_CTX_set_options(ssl_ctx,
|
||||
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION |
|
||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
|
||||
SSL_OP_SINGLE_ECDH_USE | SSL_OP_SINGLE_DH_USE |
|
||||
SSL_OP_NO_TICKET);
|
||||
SSL_OP_NO_TICKET |
|
||||
create_tls_proto_mask(get_config()->tls_proto_list,
|
||||
get_config()->tls_proto_list_len));
|
||||
|
||||
const unsigned char sid_ctx[] = "shrpx";
|
||||
SSL_CTX_set_session_id_context(ssl_ctx, sid_ctx, sizeof(sid_ctx)-1);
|
||||
|
@ -295,7 +321,9 @@ SSL_CTX* create_ssl_client_context()
|
|||
}
|
||||
SSL_CTX_set_options(ssl_ctx,
|
||||
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION |
|
||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
|
||||
create_tls_proto_mask(get_config()->tls_proto_list,
|
||||
get_config()->tls_proto_list_len));
|
||||
|
||||
if(get_config()->ciphers) {
|
||||
if(SSL_CTX_set_cipher_list(ssl_ctx, get_config()->ciphers) == 0) {
|
||||
|
|
Loading…
Reference in New Issue