支持通过拦截策略指定ssl最大和最小版本号。

This commit is contained in:
zhengchao
2019-05-24 14:20:44 +08:00
parent 6b197e3347
commit f66658117a
2 changed files with 34 additions and 32 deletions

View File

@@ -207,6 +207,8 @@ struct ssl_stream
int ssl_min_version, ssl_max_version, negotiated_version; int ssl_min_version, ssl_max_version, negotiated_version;
const unsigned char* alpn_selected; //reference to SSL_ALPN_HTTP_2/SSL_ALPN_HTTP_1_1 const unsigned char* alpn_selected; //reference to SSL_ALPN_HTTP_2/SSL_ALPN_HTTP_1_1
struct ssl_stream* peer; struct ssl_stream* peer;
socklen_t addrlen;
struct sockaddr_storage addr;
struct __ssl_stream_debug _do_not_use; struct __ssl_stream_debug _do_not_use;
}; };
@@ -451,8 +453,8 @@ void ssl_stat_init(struct ssl_mgr * mgr)
return; return;
} }
static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt, int negotiated_version, const unsigned char* selected_alpn); static void downstream_ossl_init(struct ssl_stream* s_stream);
static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stream, evutil_socket_t fd); static void upstream_ossl_init(struct ssl_stream* s_stream);
static void sslctx_set_opts(SSL_CTX * sslctx, struct ssl_mgr * mgr); static void sslctx_set_opts(SSL_CTX * sslctx, struct ssl_mgr * mgr);
@@ -474,17 +476,18 @@ struct ssl_stream * ssl_stream_new(struct ssl_mgr * mgr, evutil_socket_t fd, enu
s_stream->dir = dir; s_stream->dir = dir;
s_stream->mgr = mgr; s_stream->mgr = mgr;
s_stream->_do_not_use.fd = fd; s_stream->_do_not_use.fd = fd;
assert(ret == 0);
s_stream->ssl_max_version=mgr->ssl_max_version; s_stream->ssl_max_version=mgr->ssl_max_version;
s_stream->ssl_min_version=mgr->ssl_min_version; s_stream->ssl_min_version=mgr->ssl_min_version;
s_stream->peer=peer; s_stream->peer=peer;
ret = getpeername(fd, (struct sockaddr *) (&s_stream->addr), &(s_stream->addrlen));
switch (dir) switch (dir)
{ {
case CONN_DIR_DOWNSTREAM: case CONN_DIR_DOWNSTREAM:
assert(peer!=NULL); assert(peer!=NULL);
ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_DOWN_NEW])); ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_DOWN_NEW]));
s_stream->down_parts.keyring = kyr; s_stream->down_parts.keyring = kyr;
s_stream->ssl = downstream_ssl_create(mgr, kyr, peer->negotiated_version, peer->alpn_selected); s_stream->peer=peer;
break; break;
case CONN_DIR_UPSTREAM: case CONN_DIR_UPSTREAM:
ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_UP_NEW])); ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_UP_NEW]));
@@ -492,17 +495,18 @@ struct ssl_stream * ssl_stream_new(struct ssl_mgr * mgr, evutil_socket_t fd, enu
s_stream->up_parts.client_hello = client_hello; s_stream->up_parts.client_hello = client_hello;
s_stream->ssl_min_version=client_hello->min_version.ossl_format; s_stream->ssl_min_version=client_hello->min_version.ossl_format;
s_stream->ssl_max_version=client_hello->max_version.ossl_format; s_stream->ssl_max_version=client_hello->max_version.ossl_format;
s_stream->ssl = upstream_ssl_create(mgr, s_stream, fd);
break; break;
default: assert(0); default: assert(0);
} }
return s_stream; return s_stream;
} }
static void ssl_stream_free(struct ssl_stream * s_stream) static void ssl_stream_free(struct ssl_stream * s_stream)
{ {
if(s_stream->ssl)
{
SSL_free(s_stream->ssl); SSL_free(s_stream->ssl);
s_stream->ssl = NULL; s_stream->ssl = NULL;
}
switch (s_stream->dir) switch (s_stream->dir)
{ {
case CONN_DIR_DOWNSTREAM: case CONN_DIR_DOWNSTREAM:
@@ -836,11 +840,12 @@ int ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
* Create new SSL context for outgoing connections to the original destination. * Create new SSL context for outgoing connections to the original destination.
* If hostname sni is provided, use it for Server Name Indication. * If hostname sni is provided, use it for Server Name Indication.
*/ */
static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stream, evutil_socket_t fd) static void upstream_ossl_init(struct ssl_stream* s_stream)
{ {
SSL_CTX * sslctx = NULL; SSL_CTX * sslctx = NULL;
SSL * ssl = NULL; SSL * ssl = NULL;
SSL_SESSION * sess = NULL; SSL_SESSION * sess = NULL;
struct ssl_mgr * mgr = s_stream->mgr;
struct ssl_chello * chello=s_stream->up_parts.client_hello; struct ssl_chello * chello=s_stream->up_parts.client_hello;
sslctx = SSL_CTX_new(mgr->sslmethod()); sslctx = SSL_CTX_new(mgr->sslmethod());
sslctx_set_opts(sslctx, mgr); sslctx_set_opts(sslctx, mgr);
@@ -865,7 +870,7 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stre
SSL_CTX_set_max_proto_version(sslctx, s_stream->ssl_max_version) == 0) SSL_CTX_set_max_proto_version(sslctx, s_stream->ssl_max_version) == 0)
{ {
SSL_CTX_free(sslctx); SSL_CTX_free(sslctx);
return NULL; return;
} }
SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, NULL); SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, NULL);
@@ -874,7 +879,7 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stre
SSL_CTX_free(sslctx); /* SSL_new() increments refcount */ SSL_CTX_free(sslctx); /* SSL_new() increments refcount */
if (!ssl) if (!ssl)
{ {
return NULL; return;
} }
SSL_set_ex_data(ssl, SSL_EX_DATA_IDX_SSLSTREAM, s_stream); SSL_set_ex_data(ssl, SSL_EX_DATA_IDX_SSLSTREAM, s_stream);
@@ -890,16 +895,13 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stre
/* lower memory footprint for idle connections */ /* lower memory footprint for idle connections */
SSL_set_mode(ssl, SSL_get_mode(ssl) | SSL_MODE_RELEASE_BUFFERS); SSL_set_mode(ssl, SSL_get_mode(ssl) | SSL_MODE_RELEASE_BUFFERS);
struct sockaddr_storage addr;
socklen_t addrlen = sizeof(struct sockaddr_storage);
if(!mgr->no_sesscache) if(!mgr->no_sesscache)
{ {
ret = getpeername(fd, (struct sockaddr *) (&addr), &addrlen);
if(ret == 0) if(ret == 0)
{ {
/* session resuming based on remote endpoint address and port */ /* session resuming based on remote endpoint address and port */
sess = up_session_get(mgr->up_sess_cache, (struct sockaddr *) &addr, addrlen, chello->sni, sess = up_session_get(mgr->up_sess_cache,
(struct sockaddr *) &(s_stream->addr), s_stream->addrlen, chello->sni,
s_stream->ssl_min_version, s_stream->ssl_max_version); s_stream->ssl_min_version, s_stream->ssl_max_version);
if (sess) if (sess)
{ {
@@ -908,9 +910,8 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stre
} }
} }
} }
s_stream->ssl=ssl;
return ;
return ssl;
} }
void ssl_connect_server_ctx_free(struct ssl_connect_server_ctx * ctx) void ssl_connect_server_ctx_free(struct ssl_connect_server_ctx * ctx)
@@ -1260,6 +1261,7 @@ static void peek_chello_on_succ(future_result_t * result, void * user)
} }
else else
{ {
upstream_ossl_init(s_stream);
ctx->bev = bufferevent_openssl_socket_new(evbase, ctx->fd_upstream, ctx->bev = bufferevent_openssl_socket_new(evbase, ctx->fd_upstream,
ctx->s_stream->ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE ); ctx->s_stream->ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE );
@@ -1456,17 +1458,11 @@ static void sslctx_set_opts(SSL_CTX * sslctx, struct ssl_mgr * mgr)
{ {
SSL_CTX_set_options(sslctx, SSL_OP_ALL); SSL_CTX_set_options(sslctx, SSL_OP_ALL);
#ifdef SSL_OP_TLS_ROLLBACK_BUG
SSL_CTX_set_options(sslctx, SSL_OP_TLS_ROLLBACK_BUG); SSL_CTX_set_options(sslctx, SSL_OP_TLS_ROLLBACK_BUG);
#endif /* SSL_OP_TLS_ROLLBACK_BUG */
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
SSL_CTX_set_options(sslctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION); SSL_CTX_set_options(sslctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
#endif /* SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION */
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
#endif /* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */
if (mgr->no_ssl2) if (mgr->no_ssl2)
{ {
@@ -1526,10 +1522,14 @@ static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
* Create and set up a new SSL_CTX instance for terminating SSL. * Create and set up a new SSL_CTX instance for terminating SSL.
* Set up all the necessary callbacks, the keyring, the keyring chain and key. * Set up all the necessary callbacks, the keyring, the keyring chain and key.
*/ */
static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt, int negotiated_version, const unsigned char* selected_alpn) void downstream_ossl_init(struct ssl_stream *s_stream)
{ {
struct ssl_mgr * mgr=s_stream->mgr;
SSL_CTX * sslctx = SSL_CTX_new(mgr->sslmethod()); SSL_CTX * sslctx = SSL_CTX_new(mgr->sslmethod());
if (!sslctx) return NULL; if (!sslctx) return;
struct keyring * crt=s_stream->down_parts.keyring;
int negotiated_version=s_stream->peer->negotiated_version;
const unsigned char* selected_alpn=s_stream->peer->alpn_selected;
SSL * ssl = NULL; SSL * ssl = NULL;
UNUSED int ret = 0; UNUSED int ret = 0;
@@ -1543,7 +1543,7 @@ static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt, i
SSL_CTX_set_max_proto_version(sslctx, negotiated_version) == 0) SSL_CTX_set_max_proto_version(sslctx, negotiated_version) == 0)
{ {
SSL_CTX_free(sslctx); SSL_CTX_free(sslctx);
return NULL; return;
} }
} }
else if(mgr->ssl_min_version) else if(mgr->ssl_min_version)
@@ -1552,7 +1552,7 @@ static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt, i
SSL_CTX_set_max_proto_version(sslctx, mgr->ssl_max_version) == 0) SSL_CTX_set_max_proto_version(sslctx, mgr->ssl_max_version) == 0)
{ {
SSL_CTX_free(sslctx); SSL_CTX_free(sslctx);
return NULL; return;
} }
} }
@@ -1615,7 +1615,8 @@ static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt, i
/* lower memory footprint for idle connections */ /* lower memory footprint for idle connections */
SSL_set_mode(ssl, SSL_get_mode(ssl) | SSL_MODE_RELEASE_BUFFERS); SSL_set_mode(ssl, SSL_get_mode(ssl) | SSL_MODE_RELEASE_BUFFERS);
} }
return ssl; s_stream->ssl=ssl;
return;
} }
void ssl_connect_client_ctx_free(struct ssl_connect_client_ctx * ctx) void ssl_connect_client_ctx_free(struct ssl_connect_client_ctx * ctx)
@@ -1751,6 +1752,7 @@ void ask_keyring_on_succ(void * result, void * user)
clock_gettime(CLOCK_MONOTONIC, &(ctx->start)); clock_gettime(CLOCK_MONOTONIC, &(ctx->start));
ctx->downstream = ssl_stream_new(mgr, ctx->fd_downstream, CONN_DIR_DOWNSTREAM, NULL, ctx->downstream = ssl_stream_new(mgr, ctx->fd_downstream, CONN_DIR_DOWNSTREAM, NULL,
kyr, ctx->origin_ssl); kyr, ctx->origin_ssl);
downstream_ossl_init(ctx->downstream);
ctx->bev_down = bufferevent_openssl_socket_new(evbase, ctx->fd_downstream, ctx->downstream->ssl, ctx->bev_down = bufferevent_openssl_socket_new(evbase, ctx->fd_downstream, ctx->downstream->ssl,
BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE); BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE);
bufferevent_openssl_set_allow_dirty_shutdown(ctx->bev_down, 1); bufferevent_openssl_set_allow_dirty_shutdown(ctx->bev_down, 1);

View File

@@ -185,8 +185,8 @@ enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_p
int pinning_staus=0, is_ev=0, is_ct=0, is_mauth=0, has_error=0; int pinning_staus=0, is_ev=0, is_ct=0, is_mauth=0, has_error=0;
if(!param->mirror_client_version) if(!param->mirror_client_version)
{ {
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, SSL3_VERSION); ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, param->ssl_min_version);
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, TLS1_3_VERSION); ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MAX_VERSION, param->ssl_max_version);
} }
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_COMMON_NAME, param->no_verify_cn); ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_COMMON_NAME, param->no_verify_cn);
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_ISSUER, param->no_verify_issuer); ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_ISSUER, param->no_verify_issuer);