ssl stream隐藏peek_sni和cert store的处理流程。

This commit is contained in:
zhengchao
2018-08-24 19:22:43 +08:00
parent 6d7940ff00
commit b000487322
2 changed files with 95 additions and 92 deletions

View File

@@ -2,35 +2,22 @@
#include <event2/event.h> #include <event2/event.h>
#include <tfe_future.h> #include <tfe_future.h>
#include <cert.h> #include <cert.h>
#include <field_stat2.h>
struct ssl_stream; struct ssl_stream;
struct ssl_mgr; struct ssl_mgr;
struct ssl_mgr* init_ssl_manager(const char* ini_profile, const char* section, void* logger); struct ssl_mgr* ssl_manager_init(const char* ini_profile, const char* section, struct event_base *evbase, void* logger, screen_stat_handle_t* fs);
void destroy_ssl_manager(struct ssl_mgr* mgr); void ssl_manager_destroy(struct ssl_mgr* mgr);
struct ssl_chello
{
//client hello
int version;
char* sni;
char* cipher_suites;
};
struct ssl_chello* ssl_peek_result_release_chello(future_result_t* result);
void ssl_chello_free(struct ssl_chello* client_hello);
void ssl_async_peek_client_hello(struct future* future, evutil_socket_t fd, struct event_base *evbase);
struct ssl_stream* ssl_upstream_create_result_release_stream(future_result_t* result); struct ssl_stream* ssl_upstream_create_result_release_stream(future_result_t* result);
struct bufferevent* ssl_upstream_create_result_release_bev(future_result_t* result); struct bufferevent* ssl_upstream_create_result_release_bev(future_result_t* result);
void ssl_async_upstream_create(struct future* future, struct ssl_mgr* mgr, const struct ssl_chello* chello, evutil_socket_t fd, struct event_base *evbase); void ssl_async_upstream_create(struct future* f, struct ssl_mgr* mgr, evutil_socket_t fd_upstream, evutil_socket_t fd_downstream, struct event_base *evbase);
struct ssl_stream* ssl_downstream_create_result_release_stream(future_result_t* result);
struct bufferevent* ssl_downstream_create_result_release_bev(future_result_t* result);
void ssl_async_downstream_create(struct future* f, struct ssl_mgr* mgr, struct ssl_stream* upstream, evutil_socket_t fd_downstream, struct event_base *evbase);
struct ssl_stream * ssl_downstream_create(struct ssl_mgr* mgr, struct ssl_chello* hello, struct cert* crt);
void ssl_stream_free_and_close_fd(struct ssl_stream* stream, struct event_base *evbase, evutil_socket_t fd); void ssl_stream_free_and_close_fd(struct ssl_stream* stream, struct event_base *evbase, evutil_socket_t fd);

View File

@@ -27,23 +27,27 @@
#include <tfe_future.h> #include <tfe_future.h>
#include <stream.h> #include <stream.h>
#include <cert.h> #include <cert.h>
#include <ssl_sess_cache.h>
#include <ssl.h> #include <ssl.h>
#include <MESA_htable.h> #include <MESA_htable.h>
#define SSL_EX_DATA_IDX_SSLMGR 0 #define SSL_EX_DATA_IDX_SSLMGR 0
#define MAX_NET_RETRIES 50
struct ssl_mgr struct ssl_mgr
{ {
uint8_t sslcomp; int sslcomp;
uint8_t no_ssl2; int no_ssl2;
uint8_t no_ssl3; int no_ssl3;
uint8_t no_tls10; int no_tls10;
uint8_t no_tls11; int no_tls11;
uint8_t no_tls12; int no_tls12;
CONST_SSL_METHOD *(*sslmethod)(void); CONST_SSL_METHOD *(*sslmethod)(void); //Parameter of SSL_CTX_new
int sslversion; int sslversion;
char ssl_session_context[8]; char ssl_session_context[8];
MESA_htable_handle down_sess_cache; int cache_slot_num;
MESA_htable_handle up_sess_cache; int sess_expire_seconds;
char* default_ciphers; struct sess_cache* down_sess_cache;
struct sess_cache* up_sess_cache;
char* default_ciphers[TFE_SYMBOL_MAX];
DH * dh; DH * dh;
char * ecdhcurve; char * ecdhcurve;
char * crlurl; char * crlurl;
@@ -57,13 +61,19 @@ struct ssl_stream
struct ssl_mgr* ref_mgr; struct ssl_mgr* ref_mgr;
char* sni; char* sni;
}; };
struct ssl_chello
{
//client hello
int version;
char* sni;
char* cipher_suites;
};
struct peek_client_hello_ctx struct peek_client_hello_ctx
{ {
unsigned char sni_peek_retries; /* max 64 SNI parse retries */ unsigned char sni_peek_retries; /* max 64 SNI parse retries */
struct event* ev; struct event* ev;
struct event_base* evbase; struct event_base* evbase;
}; };
struct ssl_connect_origin_ctx struct ssl_connect_origin_ctx
{ {
@@ -81,64 +91,76 @@ struct ssl_shutdown_ctx {
struct event *ev; struct event *ev;
unsigned int retries; unsigned int retries;
}; };
static int parse_ssl_version(const char * version_str)
struct ssl_mgr* init_ssl_manager(const char* ini_profile, const char* section, void* logger)
{ {
struct ssl_mgr* mgr=ALLOC(struct ssl_mgr, 1); int sslversion=-1;
mgr->logger=logger; assert(OPENSSL_VERSION_NUMBER >= 0x10100000L);
memcpy(mgr->ssl_session_context,"mesa-tfe",sizeof(mgr->ssl_session_context)); /*
return mgr; * Support for SSLv2 and the corresponding SSLv2_method(),
* SSLv2_server_method() and SSLv2_client_method() functions were
* removed in OpenSSL 1.1.0.
*/
if (!strcmp(version_str, "ssl3"))
{
sslversion = SSL3_VERSION;
} }
void destroy_ssl_manager(struct ssl_mgr* mgr) else if (!strcmp(version_str, "tls10") || !strcmp(version_str, "tls1"))
{
sslversion = TLS1_VERSION;
}
else if (!strcmp(version_str, "tls11"))
{
sslversion = TLS1_1_VERSION;
}
else if (!strcmp(version_str, "tls12"))
{
sslversion = TLS1_2_VERSION;
}
else
{
sslversion =-1;
}
return sslversion;
}
void ssl_manager_destroy(struct ssl_mgr* mgr)
{ {
free(mgr); free(mgr);
} }
SSL_SESSION* up_session_get(MESA_htable_handle* cache, struct sockaddr * addr, socklen_t addr_len, const char* sni)
{
struct ssl_mgr* ssl_manager_init(const char* ini_profile, const char* section, void* logger)
{
struct ssl_mgr* mgr=ALLOC(struct ssl_mgr, 1);
int ret=0,value=0;
char version_str[TFE_SYMBOL_MAX];
mgr->logger=logger;
MESA_load_profile_string_def(ini_profile, section, "ssl_version", version_str, sizeof(version_str),"tls12");
mgr->sslversion=parse_ssl_version(version_str);
if(mgr->sslversion<0)
{
TFE_LOG_ERROR(logger, "Unsupported SSL/TLS protocol %s",version_str);
goto error_out;
} }
void up_session_set(MESA_htable_handle* cache, struct sockaddr * addr, socklen_t addr_len, const char* sni, SSL_SESSION * value) //tfe2a uses SSLv23_method, it was been deprecated and replaced with the TLS_method() in openssl 1.1.0.
{ mgr->sslmethod=TLS_method;
MESA_load_profile_int_def(ini_profile, section, "ssl_compression", &(mgr->sslcomp), 1);
MESA_load_profile_int_def(ini_profile, section, "no_ssl2", &(mgr->no_ssl2), 1);
MESA_load_profile_int_def(ini_profile, section, "no_ssl3", &(mgr->no_ssl3), 1);
MESA_load_profile_int_def(ini_profile, section, "no_tls10", &(mgr->no_tls10), 1);
MESA_load_profile_int_def(ini_profile, section, "no_tls11", &(mgr->no_tls11), 0);
MESA_load_profile_int_def(ini_profile, section, "no_tls12", &(mgr->no_tls12), 0);
MESA_load_profile_int_def(ini_profile, section, "session_cache_slot_num", &(mgr->cache_slot_num), 4*1024*1024);
MESA_load_profile_int_def(ini_profile, section, "session_cache_slot_num", &(mgr->sess_expire_seconds), 30*60);
} mgr->up_sess_cache=ssl_sess_cache_create(mgr->cache_slot_num, mgr->sess_expire_seconds,CONN_DIR_UPSTREAM);
SSL_SESSION* down_session_get(MESA_htable_handle* cache, unsigned char * id, int idlen) mgr->down_sess_cache=ssl_sess_cache_create(mgr->cache_slot_num, mgr->sess_expire_seconds,CONN_DIR_DOWNSTREAM);
{
dynbuf_t *valbuf = (dynbuf_t *)val;
MESA_htable_search_cb(const MESA_htable_handle table, const uchar * key, uint size, hash_cb_fun_t * cb, void * arg, long * cb_ret);
SSL_SESSION *sess;
const unsigned char *p;
p = (const unsigned char *)valbuf->buf; memcpy(mgr->ssl_session_context,"mesa-tfe",sizeof(mgr->ssl_session_context));
sess = d2i_SSL_SESSION(NULL, &p, valbuf->sz); /* increments p */ return mgr;
if (!sess) error_out:
return NULL; ssl_manager_destroy(mgr);
if (!ssl_session_is_valid(sess)) {
SSL_SESSION_free(sess);
return NULL; return NULL;
} }
if (copy)
return sess;
SSL_SESSION_free(sess);
return ((void*)-1);
}
void down_session_set(MESA_htable_handle* cache, SSL_SESSION* sess)
{
unsigned int len=0;
const unsigned char* id = SSL_SESSION_get_id(sess, &len);
unsigned char *p=NULL;
size_t asn1sz=0;
asn1sz = i2d_SSL_SESSION(sess, NULL);
p=ALLOC(char, asn1sz);
i2d_SSL_SESSION(sess, &p); /* updates p */
int ret=MESA_htable_add(cache, id, len, p);
return;
}
void down_session_del(MESA_htable_handle* cache, SSL_SESSION* sess)
{
}
void peek_client_hello_ctx_free(void* ctx) void peek_client_hello_ctx_free(void* ctx)
{ {
@@ -223,7 +245,7 @@ static void peek_client_hello_cb(evutil_socket_t fd, short what, void * arg)
reason="see no client hello"; reason="see no client hello";
goto failed; goto failed;
} }
if(ctx->sni_peek_retries++ > MAX_NET_RETRIES) if(ctx->sni_peek_retries++ > MAX_NET_RETRIES)
{ {
TFE_LOG_ERROR("Peek failed due to too many retries\n"); TFE_LOG_ERROR("Peek failed due to too many retries\n");
@@ -324,11 +346,6 @@ static SSL* upstream_ssl_create(struct ssl_mgr* mgr, const struct ssl_chello* ch
return ssl; return ssl;
} }
void ssl_stream_shutdown(struct bufferevent *bev,struct ssl_stream* ssl)
{
//TODO:
void ssl_connect_origin_ctx_free(struct ssl_connect_origin_ctx* ctx) void ssl_connect_origin_ctx_free(struct ssl_connect_origin_ctx* ctx)
{ {
@@ -395,7 +412,7 @@ static void ssl_connect_origin_eventcb(struct bufferevent * bev, short events, v
ssl_connect_origin_ctx_free(ctx); ssl_connect_origin_ctx_free(ctx);
return return
} }
void ssl_async_upstream_create(struct future* f, struct ssl_mgr* mgr, const struct ssl_chello* chello, evutil_socket_t fd, struct event_base *evbase) void ssl_async_upstream_create(struct future* f, struct ssl_mgr* mgr, const struct ssl_chello* chello, evutil_socket_t fd, struct event_base *evbase)
{ {
struct promise* p=future_to_promise(future); struct promise* p=future_to_promise(future);
@@ -453,6 +470,7 @@ static void
static void static void
ossl_sessremove_cb(UNUSED SSL_CTX * sslctx, SSL_SESSION * sess) ossl_sessremove_cb(UNUSED SSL_CTX * sslctx, SSL_SESSION * sess)
{ {
struct ssl_mgr* mgr=(struct ssl_mgr*) SSL_get_ex_data(ssl, SSL_EX_DATA_IDX_SSLMGR, mgr);
assert(mgr!=NULL); assert(mgr!=NULL);
if (sess) if (sess)
{ {
@@ -566,11 +584,8 @@ static SSL_CTX * down_sslctx_create(struct ssl_mgr* mgr, struct cert* crt)
SSL_CTX_sess_set_remove_cb(sslctx, ossl_sessremove_cb); SSL_CTX_sess_set_remove_cb(sslctx, ossl_sessremove_cb);
SSL_CTX_sess_set_get_cb(sslctx, ossl_sessget_cb); SSL_CTX_sess_set_get_cb(sslctx, ossl_sessget_cb);
SSL_CTX_set_session_cache_mode(sslctx, SSL_SESS_CACHE_SERVER | SSL_CTX_set_session_cache_mode(sslctx, SSL_SESS_CACHE_SERVER |
SSL_SESS_CACHE_NO_INTERNAL);
SSL_SESS_CACHE_NO_INTERNAL); SSL_SESS_CACHE_NO_INTERNAL);
SSL_CTX_set_session_id_context(sslctx, (void *)(mgr->ssl_session_context), SSL_CTX_set_session_id_context(sslctx, (void *)(mgr->ssl_session_context),
sizeof(mgr->ssl_session_context));
#endif /* USE_SSL_SESSION_ID_CONTEXT */
sizeof(mgr->ssl_session_context)); sizeof(mgr->ssl_session_context));
#ifndef OPENSSL_NO_DH #ifndef OPENSSL_NO_DH
if (mgr->dh) if (mgr->dh)
@@ -611,8 +626,9 @@ static SSL_CTX * down_sslctx_create(struct ssl_mgr* mgr, struct cert* crt)
/* /*
* Create new SSL context for the incoming connection, based on the a designate cert * Create new SSL context for the incoming connection, based on the a designate cert
* Returns NULL when openssl error. * Returns NULL when openssl error.
*/ */
void ssl_async_downstream_create(struct future* f, struct ssl_mgr* mgr, struct ssl_chello* hello, evutil_socket_t fd, struct event_base *evbase) void ssl_async_downstream_create(struct future* f, struct ssl_mgr* mgr, struct ssl_chello* hello, evutil_socket_t fd, struct event_base *evbase)
{
struct cert* crt; struct cert* crt;
struct ssl_stream* p=NULL; struct ssl_stream* p=NULL;
if(crt==NULL) if(crt==NULL)
@@ -735,7 +751,7 @@ pxy_ssl_shutdown_cb(evutil_socket_t fd, UNUSED short what, void *arg)
} }
goto complete; goto complete;
retry: retry:
if (ctx->retries++ >= MAX_NET_RETRIES) { if (ctx->retries++ >= MAX_NET_RETRIES) {
TFE_LOG_ERROR(logger,"Failed to shutdown SSL connection cleanly: " TFE_LOG_ERROR(logger,"Failed to shutdown SSL connection cleanly: "
"Max retries reached. Closing fd.\n"); "Max retries reached. Closing fd.\n");