diff --git a/include/mysql_connection.h b/include/mysql_connection.h index ae7dbeffe6..350a8940ca 100644 --- a/include/mysql_connection.h +++ b/include/mysql_connection.h @@ -253,5 +253,6 @@ class MySQL_Connection { bool requires_CHANGE_USER(const MySQL_Connection *client_conn); unsigned int number_of_matching_session_variables(const MySQL_Connection *client_conn, unsigned int& not_matching); unsigned long get_mysql_thread_id() { return mysql ? mysql->thread_id : 0; } + static void set_ssl_params(MYSQL *mysql, MySQLServers_SslParams *ssl_params); }; #endif /* __CLASS_MYSQL_CONNECTION_H */ diff --git a/lib/MySQL_Monitor.cpp b/lib/MySQL_Monitor.cpp index 747c8e2488..c58e0ccd55 100644 --- a/lib/MySQL_Monitor.cpp +++ b/lib/MySQL_Monitor.cpp @@ -1525,15 +1525,10 @@ bool MySQL_Monitor_State_Data::set_wait_timeout() { bool MySQL_Monitor_State_Data::create_new_connection() { mysql=mysql_init(NULL); assert(mysql); - if (use_ssl) { - mysql_ssl_set(mysql, - mysql_thread___ssl_p2s_key, - mysql_thread___ssl_p2s_cert, - mysql_thread___ssl_p2s_ca, - mysql_thread___ssl_p2s_capath, - 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); + MySQLServers_SslParams * ssl_params = NULL; + if (use_ssl && port) { + ssl_params = MyHGM->get_Server_SSL_Params(hostname, port, mysql_thread___monitor_username); + MySQL_Connection::set_ssl_params(mysql,ssl_params); mysql_options(mysql, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); } unsigned int timeout=mysql_thread___monitor_connect_timeout/1000; @@ -1551,6 +1546,13 @@ bool MySQL_Monitor_State_Data::create_new_connection() { mysql_error_msg=strdup(mysql_error(mysql)); int myerrno=mysql_errno(mysql); MyHGM->p_update_mysql_error_counter(p_mysql_error_type::proxysql, hostgroup_id, hostname, port, myerrno); + if (ssl_params != NULL && myerrno == 2026) { + proxy_error("Failed to connect to server %s:%d . SSL Params: %s , %s , %s , %s , %s , %s , %s , %s\n", + ( port ? hostname : "localhost" ) , port , + ssl_params->ssl_ca.c_str() , ssl_params->ssl_cert.c_str() , ssl_params->ssl_key.c_str() , ssl_params->ssl_capath.c_str() , + ssl_params->ssl_crl.c_str() , ssl_params->ssl_crlpath.c_str() , ssl_params->ssl_cipher.c_str() , ssl_params->tls_version.c_str() + ); + } if (myerrno < 2000) { mysql_close(mysql); } else { diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 91e2207c4e..432abdc8a6 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -222,25 +222,24 @@ void* kill_query_thread(void *arg) { std::unique_ptr mysql_thr(new MySQL_Thread()); mysql_thr->curtime=monotonic_time(); mysql_thr->refresh_variables(); + + MySQLServers_SslParams * ssl_params = NULL; + MYSQL *mysql=mysql_init(NULL); + if (!mysql) { + goto __exit_kill_query_thread; + } + mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, "program_name", "proxysql_killer"); mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, "_server_host", ka->hostname); + if (ka->use_ssl && ka->port) { - mysql_ssl_set(mysql, - mysql_thread___ssl_p2s_key, - mysql_thread___ssl_p2s_cert, - mysql_thread___ssl_p2s_ca, - mysql_thread___ssl_p2s_capath, - 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); + ssl_params = MyHGM->get_Server_SSL_Params(ka->hostname, ka->port, ka->username); + MySQL_Connection::set_ssl_params(mysql,ssl_params); mysql_options(mysql, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); } - if (!mysql) { - goto __exit_kill_query_thread; - } MYSQL *ret; if (ka->port) { switch (ka->kill_type) { @@ -274,7 +273,16 @@ void* kill_query_thread(void *arg) { ret=mysql_real_connect(mysql,"localhost",ka->username,ka->password,NULL,0,ka->hostname,0); } if (!ret) { - proxy_error("Failed to connect to server %s:%d to run KILL %s %lu: Error: %s\n" , ka->hostname, ka->port, ( ka->kill_type==KILL_QUERY ? "QUERY" : "CONNECTION" ) , ka->id, mysql_error(mysql)); + int myerr = mysql_errno(mysql); + if (ssl_params != NULL && myerr == 2026) { + proxy_error("Failed to connect to server %s:%d to run KILL %s %lu. SSL Params: %s , %s , %s , %s , %s , %s , %s , %s\n", + ka->hostname, ka->port, ( ka->kill_type==KILL_QUERY ? "QUERY" : "CONNECTION" ) , ka->id, + ssl_params->ssl_ca.c_str() , ssl_params->ssl_cert.c_str() , ssl_params->ssl_key.c_str() , ssl_params->ssl_capath.c_str() , + ssl_params->ssl_crl.c_str() , ssl_params->ssl_crlpath.c_str() , ssl_params->ssl_cipher.c_str() , ssl_params->tls_version.c_str() + ); + } else { + proxy_error("Failed to connect to server %s:%d to run KILL %s %lu: Error: %s\n" , ka->hostname, ka->port, ( ka->kill_type==KILL_QUERY ? "QUERY" : "CONNECTION" ) , ka->id, mysql_error(mysql)); + } MyHGM->p_update_mysql_error_counter(p_mysql_error_type::mysql, ka->hid, ka->hostname, ka->port, mysql_errno(mysql)); goto __exit_kill_query_thread; } @@ -299,6 +307,10 @@ void* kill_query_thread(void *arg) { if (mysql) mysql_close(mysql); delete ka; + if (ssl_params != NULL) { + delete ssl_params; + ssl_params = NULL; + } return NULL; } diff --git a/lib/ProxySQL_Config.cpp b/lib/ProxySQL_Config.cpp index 79dee6c1ea..dc7360471a 100644 --- a/lib/ProxySQL_Config.cpp +++ b/lib/ProxySQL_Config.cpp @@ -1087,6 +1087,59 @@ int ProxySQL_Config::Read_MySQL_Servers_from_configfile() { rows++; } } + if (root.exists("mysql_servers_ssl_params")==true) { // mysql_servers_ssl_params + const Setting &mysql_servers_ssl_params = root["mysql_servers_ssl_params"]; + int count = mysql_servers_ssl_params.getLength(); + char *q=(char *)"INSERT OR REPLACE INTO mysql_servers_ssl_params (hostname, port, username, ssl_ca, ssl_cert, ssl_key, ssl_capath, ssl_crl, ssl_crlpath, ssl_cipher, tls_version, comment) VALUES ('%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')"; + for (i=0; i< count; i++) { + const Setting &line = mysql_servers_ssl_params[i]; + string hostname = ""; + int port = 3306; + string username = ""; + string ssl_ca = ""; + string ssl_cert = ""; + string ssl_key = ""; + string ssl_capath = ""; + string ssl_crl = ""; + string ssl_crlpath = ""; + string ssl_cipher = ""; + string tls_version = ""; + std::string comment=""; + if (line.lookupValue("hostname", hostname)==false) { + proxy_error("Admin: detected a mysql_servers_ssl_params in config file without a mandatory hostname\n"); + continue; + } + line.lookupValue("port", port); + line.lookupValue("username", username); + line.lookupValue("ssl_ca", ssl_ca); + line.lookupValue("ssl_cert", ssl_cert); + line.lookupValue("ssl_key", ssl_key); + line.lookupValue("ssl_capath", ssl_capath); + line.lookupValue("ssl_crl", ssl_crl); + line.lookupValue("ssl_crlpath", ssl_crlpath); + line.lookupValue("ssl_cipher", ssl_cipher); + line.lookupValue("tls_version", tls_version); + line.lookupValue("comment", comment); + char *o1=strdup(comment.c_str()); + char *o=escape_string_single_quotes(o1, false); + char *query=(char *)malloc( + strlen(q) + + hostname.length() + username.length() + + ssl_ca.length() + ssl_cert.length() + ssl_key.length() + ssl_capath.length() + + ssl_crl.length() + ssl_crlpath.length() + ssl_cipher.length() + tls_version.length() + + strlen(o) + 32); + sprintf(query, q, + hostname.c_str() , port , username.c_str() , + ssl_ca.c_str() , ssl_cert.c_str() , ssl_key.c_str() , ssl_capath.c_str() , + ssl_crl.c_str() , ssl_crlpath.c_str() , ssl_cipher.c_str() , tls_version.c_str() , + o); + admindb->execute(query); + if (o!=o1) free(o); + free(o1); + free(query); + rows++; + } + } if (root.exists("mysql_group_replication_hostgroups")==true) { const Setting &mysql_group_replication_hostgroups = root["mysql_group_replication_hostgroups"]; int count = mysql_group_replication_hostgroups.getLength(); diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index e3430b02a7..37e8b58b2e 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -750,26 +750,7 @@ void MySQL_Connection::connect_start() { ssl_params = NULL; } ssl_params = MyHGM->get_Server_SSL_Params(parent->address, parent->port, userinfo->username); - if (ssl_params == NULL) { - mysql_ssl_set(mysql, - mysql_thread___ssl_p2s_key, - mysql_thread___ssl_p2s_cert, - mysql_thread___ssl_p2s_ca, - mysql_thread___ssl_p2s_capath, - 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); - } else { - mysql_ssl_set(mysql, - ssl_params->ssl_key.c_str(), - ssl_params->ssl_cert.c_str(), - ssl_params->ssl_ca.c_str(), - ssl_params->ssl_capath.c_str(), - ssl_params->ssl_cipher.c_str() - ); - mysql_options(mysql, MYSQL_OPT_SSL_CRL, ssl_params->ssl_crl.c_str()); - mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, ssl_params->ssl_crlpath.c_str()); - } + MySQL_Connection::set_ssl_params(mysql, ssl_params); mysql_options(mysql, MARIADB_OPT_SSL_KEYLOG_CALLBACK, (void*)proxysql_keylog_write_line_callback); } unsigned int timeout= 1; @@ -2976,3 +2957,28 @@ bool MySQL_Connection::get_gtid(char *buff, uint64_t *trx_id) { } return ret; } + +void MySQL_Connection::set_ssl_params(MYSQL *mysql, MySQLServers_SslParams *ssl_params) { + if (ssl_params == NULL) { + mysql_ssl_set(mysql, + mysql_thread___ssl_p2s_key, + mysql_thread___ssl_p2s_cert, + mysql_thread___ssl_p2s_ca, + mysql_thread___ssl_p2s_capath, + 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); + } else { + mysql_ssl_set(mysql, + ( ssl_params->ssl_key.length() > 0 ? ssl_params->ssl_key.c_str() : NULL ) , + ( ssl_params->ssl_cert.length() > 0 ? ssl_params->ssl_cert.c_str() : NULL ) , + ( ssl_params->ssl_ca.length() > 0 ? ssl_params->ssl_ca.c_str() : NULL ) , + ( ssl_params->ssl_capath.length() > 0 ? ssl_params->ssl_capath.c_str() : NULL ) , + ( ssl_params->ssl_cipher.length() > 0 ? ssl_params->ssl_cipher.c_str() : NULL ) + ); + mysql_options(mysql, MYSQL_OPT_SSL_CRL, + ( ssl_params->ssl_crl.length() > 0 ? ssl_params->ssl_crl.c_str() : NULL ) ); + mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, + ( ssl_params->ssl_crlpath.length() > 0 ? ssl_params->ssl_crlpath.c_str() : NULL ) ); + } +}