Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introducing mysql_servers_ssl_params #4458

Merged
merged 8 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions include/MySQL_HostGroups_Manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ using json = nlohmann::json;

#define MYHGM_MYSQL_HOSTGROUP_ATTRIBUTES "CREATE TABLE mysql_hostgroup_attributes (hostgroup_id INT NOT NULL PRIMARY KEY , max_num_online_servers INT CHECK (max_num_online_servers>=0 AND max_num_online_servers <= 1000000) NOT NULL DEFAULT 1000000 , autocommit INT CHECK (autocommit IN (-1, 0, 1)) NOT NULL DEFAULT -1 , free_connections_pct INT CHECK (free_connections_pct >= 0 AND free_connections_pct <= 100) NOT NULL DEFAULT 10 , init_connect VARCHAR NOT NULL DEFAULT '' , multiplex INT CHECK (multiplex IN (0, 1)) NOT NULL DEFAULT 1 , connection_warming INT CHECK (connection_warming IN (0, 1)) NOT NULL DEFAULT 0 , throttle_connections_per_sec INT CHECK (throttle_connections_per_sec >= 1 AND throttle_connections_per_sec <= 1000000) NOT NULL DEFAULT 1000000 , ignore_session_variables VARCHAR CHECK (JSON_VALID(ignore_session_variables) OR ignore_session_variables = '') NOT NULL DEFAULT '' , hostgroup_settings VARCHAR CHECK (JSON_VALID(hostgroup_settings) OR hostgroup_settings = '') NOT NULL DEFAULT '' , servers_defaults VARCHAR CHECK (JSON_VALID(servers_defaults) OR servers_defaults = '') NOT NULL DEFAULT '' , comment VARCHAR NOT NULL DEFAULT '')"


#define MYHGM_MYSQL_SERVERS_SSL_PARAMS "CREATE TABLE mysql_servers_ssl_params (hostname VARCHAR NOT NULL , port INT CHECK (port >= 0 AND port <= 65535) NOT NULL DEFAULT 3306 , username VARCHAR NOT NULL DEFAULT '' , ssl_ca VARCHAR NOT NULL DEFAULT '' , ssl_cert VARCHAR NOT NULL DEFAULT '' , ssl_key VARCHAR NOT NULL DEFAULT '' , ssl_capath VARCHAR NOT NULL DEFAULT '' , ssl_crl VARCHAR NOT NULL DEFAULT '' , ssl_crlpath VARCHAR NOT NULL DEFAULT '' , ssl_cipher VARCHAR NOT NULL DEFAULT '' , tls_version VARCHAR NOT NULL DEFAULT '' , comment VARCHAR NOT NULL DEFAULT '' , PRIMARY KEY (hostname, port, username) )"

/*
* @brief Generates the 'runtime_mysql_servers' resultset exposed to other ProxySQL cluster members.
* @details Makes 'SHUNNED' and 'SHUNNED_REPLICATION_LAG' statuses equivalent to 'ONLINE'. 'SHUNNED' states
Expand Down Expand Up @@ -376,6 +379,68 @@ class AWS_Aurora_Info {
~AWS_Aurora_Info();
};

class MySQLServers_SslParams {
public:
string hostname;
int port;
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;
string comment;
string MapKey;
MySQLServers_SslParams(string _h, int _p, string _u,
string ca, string cert, string key, string capath,
string crl, string crlpath, string cipher, string tls,
string c) {
hostname = _h;
port = _p;
username = _u;
ssl_ca = ca;
ssl_cert = cert;
ssl_key = key;
ssl_capath = capath;
ssl_crl = crl;
ssl_crlpath = crlpath;
ssl_cipher = cipher;
tls_version = tls;
comment = c;
MapKey = "";
}
MySQLServers_SslParams(char * _h, int _p, char * _u,
char * ca, char * cert, char * key, char * capath,
char * crl, char * crlpath, char * cipher, char * tls,
char * c) {
hostname = string(_h);
port = _p;
username = string(_u);
ssl_ca = string(ca);
ssl_cert = string(cert);
ssl_key = string(key);
ssl_capath = string(capath);
ssl_crl = string(crl);
ssl_crlpath = string(crlpath);
ssl_cipher = string(cipher);
tls_version = string(tls);
comment = string(c);
MapKey = "";
}
MySQLServers_SslParams(string _h, int _p, string _u) {
MySQLServers_SslParams(_h, _p, _u, "", "", "", "", "", "", "", "", "");
}
string getMapKey(const char *del) {
if (MapKey == "") {
MapKey = hostname + string(del) + to_string(port) + string(del) + username;
}
return MapKey;
}
};

struct p_hg_counter {
enum metric {
servers_table_version = 0,
Expand Down Expand Up @@ -527,6 +592,7 @@ class MySQL_HostGroups_Manager {
MYSQL_GALERA_HOSTGROUPS,
MYSQL_AWS_AURORA_HOSTGROUPS,
MYSQL_HOSTGROUP_ATTRIBUTES,
MYSQL_SERVERS_SSL_PARAMS,
MYSQL_SERVERS,

__HGM_TABLES_SIZE
Expand Down Expand Up @@ -636,6 +702,9 @@ class MySQL_HostGroups_Manager {
PtrArray *MyHostGroups;
std::unordered_map<unsigned int, MyHGC *>MyHostGroups_map;

std::mutex Servers_SSL_Params_map_mutex;
std::unordered_map<std::string, MySQLServers_SslParams> Servers_SSL_Params_map;

MyHGC * MyHGC_find(unsigned int);
MyHGC * MyHGC_create(unsigned int);

Expand Down Expand Up @@ -710,6 +779,9 @@ class MySQL_HostGroups_Manager {
void generate_mysql_hostgroup_attributes_table();
SQLite3_result *incoming_hostgroup_attributes;

void generate_mysql_servers_ssl_params_table();
SQLite3_result *incoming_mysql_servers_ssl_params;

SQLite3_result* incoming_mysql_servers_v2;

std::thread *HGCU_thread;
Expand Down Expand Up @@ -1115,6 +1187,8 @@ class MySQL_HostGroups_Manager {
void unshun_server_all_hostgroups(const char * address, uint16_t port, time_t t, int max_wait_sec, unsigned int *skip_hid);
MySrvC* find_server_in_hg(unsigned int _hid, const std::string& addr, int port);

MySQLServers_SslParams * get_Server_SSL_Params(char *hostname, int port, char *username);

private:
void update_hostgroup_manager_mappings();
uint64_t get_mysql_servers_checksum(SQLite3_result* runtime_mysql_servers = nullptr);
Expand Down
5 changes: 5 additions & 0 deletions include/ProxySQL_Cluster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_mysql_hostgroup_attributes'. See top comment for details. */
#define CLUSTER_QUERY_MYSQL_HOSTGROUP_ATTRIBUTES "PROXY_SELECT hostgroup_id, max_num_online_servers, autocommit, free_connections_pct, init_connect, multiplex, connection_warming, throttle_connections_per_sec, ignore_session_variables, hostgroup_settings, servers_defaults, comment FROM runtime_mysql_hostgroup_attributes ORDER BY hostgroup_id"

/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_mysql_servers_ssl_params'. See top comment for details. */
#define CLUSTER_QUERY_MYSQL_SERVERS_SSL_PARAMS "PROXY_SELECT hostname, port, username, ssl_ca, ssl_cert, ssl_key, ssl_capath, ssl_crl, ssl_crlpath, ssl_cipher, tls_version, comment FROM runtime_mysql_servers_ssl_params ORDER BY hostname, port, username"

/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_mysql_aws_aurora_hostgroups'. See top comment for details. */
#define CLUSTER_QUERY_MYSQL_AWS_AURORA "PROXY_SELECT writer_hostgroup, reader_hostgroup, active, aurora_port, domain_name, max_lag_ms, check_interval_ms, check_timeout_ms, writer_is_also_reader, new_reader_weight, add_lag_ms, min_lag_ms, lag_num_checks, comment FROM runtime_mysql_aws_aurora_hostgroups ORDER BY writer_hostgroup"

Expand Down Expand Up @@ -310,6 +313,8 @@ struct p_cluster_counter {
pulled_mysql_servers_aws_aurora_hostgroups_failure,
pulled_mysql_servers_hostgroup_attributes_success,
pulled_mysql_servers_hostgroup_attributes_failure,
pulled_mysql_servers_ssl_params_success,
pulled_mysql_servers_ssl_params_failure,
pulled_mysql_servers_runtime_checks_success,
pulled_mysql_servers_runtime_checks_failure,

Expand Down
5 changes: 5 additions & 0 deletions include/mysql_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ using json = nlohmann::json;
#define STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT 0x00000800
#define STATUS_MYSQL_CONNECTION_HAS_WARNINGS 0x00001000

class MySQLServers_SslParams;

class Variable {
public:
char *value = (char*)"";
Expand Down Expand Up @@ -151,6 +153,9 @@ class MySQL_Connection {
bool unknown_transaction_status;
void compute_unknown_transaction_status();
char gtid_uuid[128];

MySQLServers_SslParams * ssl_params = NULL;

MySQL_Connection();
~MySQL_Connection();
bool set_autocommit(bool);
Expand Down
3 changes: 2 additions & 1 deletion include/proxysql_admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,10 @@ struct incoming_servers_t {
SQLite3_result* incoming_galera_hostgroups = NULL;
SQLite3_result* incoming_aurora_hostgroups = NULL;
SQLite3_result* incoming_hostgroup_attributes = NULL;
SQLite3_result* incoming_mysql_servers_ssl_params = NULL;

incoming_servers_t();
incoming_servers_t(SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*);
incoming_servers_t(SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*);
};

// Separate structs for runtime mysql server and mysql server v2 to avoid human error
Expand Down
88 changes: 88 additions & 0 deletions lib/MySQL_HostGroups_Manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1352,6 +1352,7 @@ MySQL_HostGroups_Manager::MySQL_HostGroups_Manager() {
mydb->execute(MYHGM_MYSQL_GALERA_HOSTGROUPS);
mydb->execute(MYHGM_MYSQL_AWS_AURORA_HOSTGROUPS);
mydb->execute(MYHGM_MYSQL_HOSTGROUP_ATTRIBUTES);
mydb->execute(MYHGM_MYSQL_SERVERS_SSL_PARAMS);
mydb->execute("CREATE INDEX IF NOT EXISTS idx_mysql_servers_hostname_port ON mysql_servers (hostname,port)");
MyHostGroups=new PtrArray();
runtime_mysql_servers=NULL;
Expand All @@ -1360,6 +1361,7 @@ MySQL_HostGroups_Manager::MySQL_HostGroups_Manager() {
incoming_galera_hostgroups=NULL;
incoming_aws_aurora_hostgroups = NULL;
incoming_hostgroup_attributes = NULL;
incoming_mysql_servers_ssl_params = NULL;
incoming_mysql_servers_v2 = NULL;
pthread_rwlock_init(&gtid_rwlock, NULL);
gtid_missing_nodes = false;
Expand Down Expand Up @@ -1630,6 +1632,7 @@ void MySQL_HostGroups_Manager::commit_update_checksums_from_tables(SpookyHash& m
CUCFT1(myhash,init,"mysql_galera_hostgroups","writer_hostgroup", table_resultset_checksum[HGM_TABLES::MYSQL_GALERA_HOSTGROUPS]);
CUCFT1(myhash,init,"mysql_aws_aurora_hostgroups","writer_hostgroup", table_resultset_checksum[HGM_TABLES::MYSQL_AWS_AURORA_HOSTGROUPS]);
CUCFT1(myhash,init,"mysql_hostgroup_attributes","hostgroup_id", table_resultset_checksum[HGM_TABLES::MYSQL_HOSTGROUP_ATTRIBUTES]);
CUCFT1(myhash,init,"mysql_servers_ssl_params","hostname,port,username", table_resultset_checksum[HGM_TABLES::MYSQL_SERVERS_SSL_PARAMS]);
}

/**
Expand Down Expand Up @@ -2145,6 +2148,13 @@ bool MySQL_HostGroups_Manager::commit(
generate_mysql_hostgroup_attributes_table();
}

// SSL params
if (incoming_mysql_servers_ssl_params) {
proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 4, "DELETE FROM mysql_servers_ssl_params\n");
mydb->execute("DELETE FROM mysql_servers_ssl_params");
generate_mysql_servers_ssl_params_table();
}

uint64_t new_hash = commit_update_checksum_from_mysql_servers_v2(peer_mysql_servers_v2.resultset);

{
Expand Down Expand Up @@ -2777,6 +2787,8 @@ SQLite3_result * MySQL_HostGroups_Manager::dump_table_mysql(const string& name)
query=(char *)"SELECT writer_hostgroup, reader_hostgroup, check_type, comment FROM mysql_replication_hostgroups";
} else if (name == "mysql_hostgroup_attributes") {
query=(char *)"SELECT hostgroup_id, max_num_online_servers, autocommit, free_connections_pct, init_connect, multiplex, connection_warming, throttle_connections_per_sec, ignore_session_variables, hostgroup_settings, servers_defaults, comment FROM mysql_hostgroup_attributes ORDER BY hostgroup_id";
} else if (name == "mysql_servers_ssl_params") {
query=(char *)"SELECT hostname, port, username, ssl_ca, ssl_cert, ssl_key, ssl_capath, ssl_crl, ssl_crlpath, ssl_cipher, tls_version, comment FROM mysql_servers_ssl_params ORDER BY hostname, port, username";
} else if (name == "mysql_servers") {
query = (char *)MYHGM_GEN_ADMIN_RUNTIME_SERVERS;
} else if (name == "cluster_mysql_servers") {
Expand Down Expand Up @@ -4056,6 +4068,8 @@ void MySQL_HostGroups_Manager::save_incoming_mysql_table(SQLite3_result *s, cons
inc = &incoming_replication_hostgroups;
} else if (name == "mysql_hostgroup_attributes") {
inc = &incoming_hostgroup_attributes;
} else if (name == "mysql_servers_ssl_params") {
inc = &incoming_mysql_servers_ssl_params;
} else {
assert(0);
}
Expand Down Expand Up @@ -4093,6 +4107,8 @@ SQLite3_result* MySQL_HostGroups_Manager::get_current_mysql_table(const string&
return this->incoming_replication_hostgroups;
} else if (name == "mysql_hostgroup_attributes") {
return this->incoming_hostgroup_attributes;
} else if (name == "mysql_servers_ssl_params") {
return this->incoming_mysql_servers_ssl_params;
} else if (name == "cluster_mysql_servers") {
return this->runtime_mysql_servers;
} else if (name == "mysql_servers_v2") {
Expand Down Expand Up @@ -7319,6 +7335,60 @@ void MySQL_HostGroups_Manager::generate_mysql_hostgroup_attributes_table() {
incoming_hostgroup_attributes=NULL;
}

void MySQL_HostGroups_Manager::generate_mysql_servers_ssl_params_table() {
if (incoming_mysql_servers_ssl_params==NULL) {
return;
}
int rc;
sqlite3_stmt *statement=NULL;

const char * query = (const char *)"INSERT 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 "
"(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)";

rc = mydb->prepare_v2(query, &statement);
ASSERT_SQLITE_OK(rc, mydb);
proxy_info("New mysql_servers_ssl_params table\n");
std::lock_guard<std::mutex> lock(Servers_SSL_Params_map_mutex);
Servers_SSL_Params_map.clear();

for (std::vector<SQLite3_row *>::iterator it = incoming_mysql_servers_ssl_params->rows.begin() ; it != incoming_mysql_servers_ssl_params->rows.end(); ++it) {
SQLite3_row *r=*it;
proxy_info("Loading MySQL Server SSL Params for (%s,%s,%s)\n",
r->fields[0], r->fields[1], r->fields[2]
);

rc=(*proxy_sqlite3_bind_text)(statement, 1, r->fields[0] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // hostname
rc=(*proxy_sqlite3_bind_int64)(statement, 2, atoi(r->fields[1])); ASSERT_SQLITE_OK(rc, mydb); // port
rc=(*proxy_sqlite3_bind_text)(statement, 3, r->fields[2] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // username
rc=(*proxy_sqlite3_bind_text)(statement, 4, r->fields[3] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_ca
rc=(*proxy_sqlite3_bind_text)(statement, 5, r->fields[4] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_cert
rc=(*proxy_sqlite3_bind_text)(statement, 6, r->fields[5] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_key
rc=(*proxy_sqlite3_bind_text)(statement, 7, r->fields[6] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_capath
rc=(*proxy_sqlite3_bind_text)(statement, 8, r->fields[7] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_crl
rc=(*proxy_sqlite3_bind_text)(statement, 9, r->fields[8] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_crlpath
rc=(*proxy_sqlite3_bind_text)(statement, 10, r->fields[9] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_cipher
rc=(*proxy_sqlite3_bind_text)(statement, 11, r->fields[10] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // tls_version
rc=(*proxy_sqlite3_bind_text)(statement, 12, r->fields[11] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // comment

SAFE_SQLITE3_STEP2(statement);
rc=(*proxy_sqlite3_clear_bindings)(statement); ASSERT_SQLITE_OK(rc, mydb);
rc=(*proxy_sqlite3_reset)(statement); ASSERT_SQLITE_OK(rc, mydb);

MySQLServers_SslParams MSSP(
r->fields[0], atoi(r->fields[1]), r->fields[2],
r->fields[3], r->fields[4], r->fields[5],
r->fields[6], r->fields[7], r->fields[8],
r->fields[9], r->fields[10], r->fields[11]
);
string MapKey = MSSP.getMapKey(rand_del);
Servers_SSL_Params_map.emplace(MapKey, MSSP);
}
delete incoming_mysql_servers_ssl_params;
incoming_mysql_servers_ssl_params=NULL;
}

void MySQL_HostGroups_Manager::generate_mysql_aws_aurora_hostgroups_table() {
if (incoming_aws_aurora_hostgroups==NULL) {
return;
Expand Down Expand Up @@ -8164,3 +8234,21 @@ void MySQL_HostGroups_Manager::HostGroup_Server_Mapping::remove_HGM(MySrvC* srv)
srv->status = MYSQL_SERVER_STATUS_OFFLINE_HARD;
srv->ConnectionsFree->drop_all_connections();
}

MySQLServers_SslParams * MySQL_HostGroups_Manager::get_Server_SSL_Params(char *hostname, int port, char *username) {
string MapKey = string(hostname) + string(rand_del) + to_string(port) + string(rand_del) + string(username);
std::lock_guard<std::mutex> lock(Servers_SSL_Params_map_mutex);
auto it = Servers_SSL_Params_map.find(MapKey);
if (it != Servers_SSL_Params_map.end()) {
MySQLServers_SslParams * MSSP = new MySQLServers_SslParams(it->second);
return MSSP;
} else {
MapKey = string(hostname) + string(rand_del) + to_string(port) + string(rand_del) + ""; // search for empty username
it = Servers_SSL_Params_map.find(MapKey);
if (it != Servers_SSL_Params_map.end()) {
MySQLServers_SslParams * MSSP = new MySQLServers_SslParams(it->second);
return MSSP;
}
}
return NULL;
}
Loading
Loading