From a1fcf5d94f7cb55ef308fe5e0c4069a8f127ac86 Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Tue, 6 Jun 2023 00:13:34 +0500 Subject: [PATCH] Added SSLKeylog in ProxySQL Modules --- include/proxysql_sslkeylog.h | 3 ++- lib/MySQL_Monitor.cpp | 1 + lib/MySQL_Session.cpp | 7 ++----- lib/ProxySQL_Admin.cpp | 4 ++-- lib/ProxySQL_Cluster.cpp | 30 ++++++++++++++++++++++++------ lib/mysql_connection.cpp | 10 +--------- lib/proxysql_sslkeylog.cpp | 6 ++++++ 7 files changed, 38 insertions(+), 23 deletions(-) diff --git a/include/proxysql_sslkeylog.h b/include/proxysql_sslkeylog.h index 550598c7f1..9fa433c63a 100644 --- a/include/proxysql_sslkeylog.h +++ b/include/proxysql_sslkeylog.h @@ -5,6 +5,7 @@ void proxysql_keylog_init(); bool proxysql_keylog_open(const char* keylog_file); void proxysql_keylog_close(bool lock = true); -void proxysql_keylog_write_line_callback(const SSL *ssl, const char* line); +void proxysql_keylog_attach_callback(SSL_CTX* ssl_ctx); +void proxysql_keylog_write_line_callback(const SSL* ssl, const char* line); #endif // __PROXYSQL_SSLKEYLOG_H diff --git a/lib/MySQL_Monitor.cpp b/lib/MySQL_Monitor.cpp index b905933b34..d766620ae9 100644 --- a/lib/MySQL_Monitor.cpp +++ b/lib/MySQL_Monitor.cpp @@ -1510,6 +1510,7 @@ bool MySQL_Monitor_State_Data::create_new_connection() { mysql_thread___ssl_p2s_cipher); mysql_options(mysql, MYSQL_OPT_SSL_CRL, mysql_thread___ssl_p2s_crl); mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, mysql_thread___ssl_p2s_crlpath); + mysql_options(mysql, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); } unsigned int timeout=mysql_thread___monitor_connect_timeout/1000; if (timeout==0) timeout=1; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 3ab890c7fc..e9cd3043ae 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -224,6 +224,7 @@ void * kill_query_thread(void *arg) { mysql=mysql_init(NULL); mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, "program_name", "proxysql_killer"); mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, "_server_host", ka->hostname); + //mysql_options(mysql, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); if (!mysql) { goto __exit_kill_query_thread; } @@ -5365,11 +5366,7 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE( SSL_set_accept_state(client_myds->ssl); SSL_set_bio(client_myds->ssl, client_myds->rbio_ssl, client_myds->wbio_ssl); l_free(pkt->size,pkt->ptr); - - SSL_CTX* ssl_ctx = GloVars.get_SSL_ctx(); - if (ssl_ctx && (SSL_CTX_get_keylog_callback(ssl_ctx) == (SSL_CTX_keylog_cb_func)NULL)) { - SSL_CTX_set_keylog_callback(ssl_ctx, proxysql_keylog_write_line_callback); - } + proxysql_keylog_attach_callback(GloVars.get_SSL_ctx()); return; } diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 9d0f00a3e2..f8e286657b 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -1804,7 +1804,7 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_ } SPA->flush_error_log(); proxysql_keylog_close(); - char* ssl_keylog_file = SPA->get_variable("ssl_keylog_file"); + char* ssl_keylog_file = SPA->get_variable((char*)"ssl_keylog_file"); if (ssl_keylog_file != NULL) { if (strlen(ssl_keylog_file) > 0) { if (proxysql_keylog_open(ssl_keylog_file) == false) { @@ -8805,7 +8805,7 @@ bool ProxySQL_Admin::set_variable(char *name, char *value, bool lock) { // this if (value[0] == '/') { // absolute path sslkeylogfile = strdup(value); } else { // relative path - sslkeylogfile = (char*)malloc(strlen(GloVars.datadir) + strlen(value) + 1); + sslkeylogfile = (char*)malloc(strlen(GloVars.datadir) + strlen(value) + 2); sprintf(sslkeylogfile, "%s/%s", GloVars.datadir, value); } if (proxysql_keylog_open(sslkeylogfile) == false) { diff --git a/lib/ProxySQL_Cluster.cpp b/lib/ProxySQL_Cluster.cpp index 03ad962389..6d9d42f9f0 100644 --- a/lib/ProxySQL_Cluster.cpp +++ b/lib/ProxySQL_Cluster.cpp @@ -93,7 +93,10 @@ void * ProxySQL_Cluster_Monitor_thread(void *args) { mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout); //mysql_options(conn, MYSQL_OPT_READ_TIMEOUT, &timeout_long); //mysql_options(conn, MYSQL_OPT_WRITE_TIMEOUT, &timeout); - { unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); } + { + unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); + mysql_options(conn, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); + } //rc_conn = mysql_real_connect(conn, node->hostname, username, password, NULL, node->port, NULL, CLIENT_COMPRESS); // FIXME: add optional support for compression rc_conn = mysql_real_connect(conn, node->get_host_address(), username, password, NULL, node->port, NULL, 0); // if (rc_conn) { @@ -1037,7 +1040,10 @@ void ProxySQL_Cluster::pull_mysql_query_rules_from_peer(const string& expected_c mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout); //mysql_options(conn, MYSQL_OPT_READ_TIMEOUT, &timeout_long); //mysql_options(conn, MYSQL_OPT_WRITE_TIMEOUT, &timeout); - { unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); } + { + unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); + mysql_options(conn, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); + } proxy_info("Cluster: Fetching MySQL Query Rules from peer %s:%d started. Expected checksum: %s\n", hostname, port, expected_checksum.c_str()); rc_conn = mysql_real_connect(conn, ip_address ? ip_address : hostname, username, password, NULL, port, NULL, 0); if (rc_conn) { @@ -1308,7 +1314,10 @@ void ProxySQL_Cluster::pull_mysql_users_from_peer(const string& expected_checksu mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout); //mysql_options(conn, MYSQL_OPT_READ_TIMEOUT, &timeout_long); //mysql_options(conn, MYSQL_OPT_WRITE_TIMEOUT, &timeout); - { unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); } + { + unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); + mysql_options(conn, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); + } proxy_info("Cluster: Fetching MySQL Users from peer %s:%d started. Expected checksum: %s\n", hostname, port, expected_checksum.c_str()); rc_conn = mysql_real_connect(conn, ip_address ? ip_address : hostname, username, password, NULL, port, NULL, 0); @@ -1631,7 +1640,10 @@ void ProxySQL_Cluster::pull_mysql_servers_from_peer(const std::string& checksum, mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout); //mysql_options(conn, MYSQL_OPT_READ_TIMEOUT, &timeout_long); //mysql_options(conn, MYSQL_OPT_WRITE_TIMEOUT, &timeout); - { unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); } + { + unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); + mysql_options(conn, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); + } proxy_info("Cluster: Fetching MySQL Servers from peer %s:%d started. Expected checksum %s\n", hostname, port, peer_checksum); rc_conn = mysql_real_connect(conn, ip_address ? ip_address : hostname, username, password, NULL, port, NULL, 0); if (rc_conn) { @@ -2049,7 +2061,10 @@ void ProxySQL_Cluster::pull_global_variables_from_peer(const string& var_type, c mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout); //mysql_options(conn, MYSQL_OPT_READ_TIMEOUT, &timeout_long); //mysql_options(conn, MYSQL_OPT_WRITE_TIMEOUT, &timeout); - { unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); } + { + unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); + mysql_options(conn, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); + } proxy_info("Cluster: Fetching %s variables from peer %s:%d started\n", vars_type_str, hostname, port); rc_conn = mysql_real_connect(conn, ip_address ? ip_address : hostname, username, password, NULL, port, NULL, 0); @@ -2201,7 +2216,10 @@ void ProxySQL_Cluster::pull_proxysql_servers_from_peer(const std::string& expect mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout); //mysql_options(conn, MYSQL_OPT_READ_TIMEOUT, &timeout_long); //mysql_options(conn, MYSQL_OPT_WRITE_TIMEOUT, &timeout); - { unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); } + { + unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); + mysql_options(conn, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); + } proxy_info( "Cluster: Fetching ProxySQL Servers from peer %s:%d started. Expected checksum: %s\n", hostname, port, expected_checksum.c_str() diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 1f8bce51e3..1f15cc80e2 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -718,6 +718,7 @@ void MySQL_Connection::connect_start() { mysql_thread___ssl_p2s_cipher); mysql_options(mysql, MYSQL_OPT_SSL_CRL, mysql_thread___ssl_p2s_crl); mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, mysql_thread___ssl_p2s_crlpath); + mysql_options(mysql, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); } unsigned int timeout= 1; const char *csname = NULL; @@ -1166,15 +1167,6 @@ MDB_ASYNC_ST MySQL_Connection::handler(short event) { //vio_blocking(mysql->net.vio, FALSE, 0); //fcntl(mysql->net.vio->sd, F_SETFL, O_RDWR|O_NONBLOCK); //} - if (mysql->options.use_ssl == 1) { - SSL_CTX* ssl_ctx = NULL; - P_MARIADB_TLS* matls = (P_MARIADB_TLS*)mysql->net.pvio->ctls; - if (matls != NULL) ssl_ctx = SSL_get_SSL_CTX((SSL*)matls->ssl); - - if (ssl_ctx && (SSL_CTX_get_keylog_callback(ssl_ctx) == (SSL_CTX_keylog_cb_func)NULL)) { - SSL_CTX_set_keylog_callback(ssl_ctx, proxysql_keylog_write_line_callback); - } - } MySQL_Monitor::update_dns_cache_from_mysql_conn(mysql); break; case ASYNC_CONNECT_FAILED: diff --git a/lib/proxysql_sslkeylog.cpp b/lib/proxysql_sslkeylog.cpp index 9dca193702..5bdee53500 100644 --- a/lib/proxysql_sslkeylog.cpp +++ b/lib/proxysql_sslkeylog.cpp @@ -94,3 +94,9 @@ void proxysql_keylog_write_line_callback(const SSL *ssl, const char *line) __exit: pthread_rwlock_unlock(&keylog_file_rwlock); } + +void proxysql_keylog_attach_callback(SSL_CTX* ssl_ctx) { + if (ssl_ctx && (SSL_CTX_get_keylog_callback(ssl_ctx) == (SSL_CTX_keylog_cb_func)NULL)) { + SSL_CTX_set_keylog_callback(ssl_ctx, proxysql_keylog_write_line_callback); + } +}