From 5cfc4e7073f1a7f12d24fe1ee4d17fe451b36947 Mon Sep 17 00:00:00 2001 From: "496148326@qq.com" <496148326@qq.com> Date: Fri, 25 Aug 2023 03:40:26 +0000 Subject: [PATCH] [FEAT MERGE]SQL SSL support specify the minimum TLS version number --- deps/easy/src/io/easy_connection.c | 1 + deps/easy/src/io/easy_io_struct.h | 1 + deps/easy/src/io/easy_ssl.c | 6 ++---- deps/oblib/src/lib/ssl/ob_ssl_config.cpp | 7 +++---- deps/oblib/src/lib/ssl/ob_ssl_config.h | 2 +- deps/oblib/src/rpc/obmysql/ob_sql_nio.cpp | 13 ++++++++++-- deps/oblib/src/rpc/obmysql/ob_sql_nio.h | 1 + .../src/rpc/obmysql/ob_sql_sock_session.cpp | 5 +++++ .../src/rpc/obmysql/ob_sql_sock_session.h | 1 + src/observer/mysql/obsm_conn_callback.cpp | 20 +++++++++++++++++++ src/observer/mysql/obsm_handler.cpp | 6 ++++++ src/share/config/ob_config_helper.cpp | 11 ++++++++++ src/share/config/ob_config_helper.h | 10 ++++++++++ src/share/parameter/ob_parameter_seed.ipp | 7 ++++++- .../all_virtual_sys_parameter_stat.result | 1 + 15 files changed, 80 insertions(+), 12 deletions(-) diff --git a/deps/easy/src/io/easy_connection.c b/deps/easy/src/io/easy_connection.c index 7eb407e41..6783c55c0 100644 --- a/deps/easy/src/io/easy_connection.c +++ b/deps/easy/src/io/easy_connection.c @@ -2543,6 +2543,7 @@ static easy_connection_t *easy_connection_new() c->write = easy_socket_write; c->fd = -1; c->armed_ack_timeout = -1; + c->tls_version_option = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; easy_list_init(&c->message_list); easy_list_init(&c->server_session_list); diff --git a/deps/easy/src/io/easy_io_struct.h b/deps/easy/src/io/easy_io_struct.h index 2514b46d0..a416d5ede 100644 --- a/deps/easy/src/io/easy_io_struct.h +++ b/deps/easy/src/io/easy_io_struct.h @@ -417,6 +417,7 @@ struct easy_connection_t { int64_t keepalive_enabled; int64_t tx_keepalive_cnt; int64_t rx_keepalive_cnt; + uint64_t tls_version_option; ev_tstamp last_tx_tstamp; ev_tstamp last_rx_tstamp; uint8_t local_magic_ver; diff --git a/deps/easy/src/io/easy_ssl.c b/deps/easy/src/io/easy_ssl.c index 106c3c6cd..4554fd6e4 100644 --- a/deps/easy/src/io/easy_ssl.c +++ b/deps/easy/src/io/easy_ssl.c @@ -233,7 +233,7 @@ int easy_ssl_connection_create(easy_ssl_ctx_t *ssl, easy_connection_t *c) easy_error_log("SSL_set_ex_data() failed"); return EASY_ERROR; } - + SSL_set_options(sc->connection, c->tls_version_option); sc->session_reuse = ssl->conf.session_reuse; c->sc = sc; @@ -1614,9 +1614,7 @@ static int easy_ssl_ctx_create_for_mysql(easy_ssl_ctx_t *ssl, int is_babassl) /* server side options */ SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG); SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); -#if OPENSSL_VERSION_NUMBER >= 0x10101000L - SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_3); -#endif + /* this option allow a potential SSL 2.0 rollback (CAN-2005-2969) */ SSL_CTX_set_options(ssl->ctx, SSL_OP_MSIE_SSLV2_RSA_PADDING); diff --git a/deps/oblib/src/lib/ssl/ob_ssl_config.cpp b/deps/oblib/src/lib/ssl/ob_ssl_config.cpp index 750b67bd1..a44227052 100644 --- a/deps/oblib/src/lib/ssl/ob_ssl_config.cpp +++ b/deps/oblib/src/lib/ssl/ob_ssl_config.cpp @@ -399,9 +399,7 @@ static SSL_CTX* ob_ssl_create_ssl_ctx(const ObSSLConfig& ssl_config) /* server side options */ SSL_CTX_set_options(ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG); SSL_CTX_set_options(ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); -#if OPENSSL_VERSION_NUMBER >= 0x10101000L - SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3); -#endif + /* this option allow a potential SSL 2.0 rollback (CAN-2005-2969) */ SSL_CTX_set_options(ctx, SSL_OP_MSIE_SSLV2_RSA_PADDING); @@ -484,7 +482,7 @@ int ob_ssl_load_config(int ctx_id, const ObSSLConfig& ssl_config) return ret; } -int ob_fd_enable_ssl_for_server(int fd, int ctx_id) +int ob_fd_enable_ssl_for_server(int fd, int ctx_id, uint64_t tls_option) { int ret = OB_SUCCESS; SSL_CTX *ctx = NULL; @@ -504,6 +502,7 @@ int ob_fd_enable_ssl_for_server(int fd, int ctx_id) ret = OB_ERR_UNEXPECTED; COMMON_LOG(WARN, "SSL_set_fd failed", K(ret), K(fd), K(ctx_id)); } else { + SSL_set_options(ssl, tls_option); SSL_set_accept_state(ssl); ATOMIC_STORE(&(gs_ssl_array[fd].ssl), ssl); } diff --git a/deps/oblib/src/lib/ssl/ob_ssl_config.h b/deps/oblib/src/lib/ssl/ob_ssl_config.h index 1b689df7a..fc83a760b 100644 --- a/deps/oblib/src/lib/ssl/ob_ssl_config.h +++ b/deps/oblib/src/lib/ssl/ob_ssl_config.h @@ -33,7 +33,7 @@ enum OB_SSL_ROLE { }; int ob_ssl_load_config(int ctx_id, const ObSSLConfig& ssl_config); -int ob_fd_enable_ssl_for_server(int fd, int ctx_id); +int ob_fd_enable_ssl_for_server(int fd, int ctx_id, uint64_t tls_option); int ob_fd_enable_ssl_for_client(int fd, int ctx_id); void ob_fd_disable_ssl(int fd); SSL* ob_fd_get_ssl_st(int fd); diff --git a/deps/oblib/src/rpc/obmysql/ob_sql_nio.cpp b/deps/oblib/src/rpc/obmysql/ob_sql_nio.cpp index beb6f0ae7..e135a4536 100644 --- a/deps/oblib/src/rpc/obmysql/ob_sql_nio.cpp +++ b/deps/oblib/src/rpc/obmysql/ob_sql_nio.cpp @@ -344,7 +344,7 @@ public: ObSqlSock(ObSqlNioImpl *nio, int fd): dlink_(), all_list_link_(), write_task_link_(), nio_impl_(nio), fd_(fd), err_(0), read_buffer_(fd), need_epoll_trigger_write_(false), may_handling_(true), handler_close_flag_(false), need_shutdown_(false), last_decode_time_(0), last_write_time_(0), - sql_session_info_(NULL) { + sql_session_info_(NULL), tls_verion_option_(SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3) { memset(sess_, 0, sizeof(sess_)); } ~ObSqlSock() {} @@ -443,6 +443,7 @@ public: void shutdown() { ::shutdown(fd_, SHUT_RD); } int set_ssl_enabled(); SSL* get_ssl_st(); + void set_tls_version_option(uint64_t tls_option) { tls_verion_option_ = tls_option; } int write_handshake_packet(const char* buf, int64_t sz); public: ObDLink dlink_; @@ -463,6 +464,7 @@ private: int64_t last_decode_time_; int64_t last_write_time_; void* sql_session_info_; + uint64_t tls_verion_option_; private: const rpc::TraceId* get_trace_id() const { ObSqlSockSession* sess = (ObSqlSockSession *)sess_; @@ -476,6 +478,7 @@ private: ObSqlSockSession* sess = (ObSqlSockSession *)sess_; return sess->sql_session_id_; } + public: char sess_[3000] __attribute__((aligned(16))); }; @@ -488,7 +491,7 @@ static ObSqlSock *sess2sock(void *sess) int ObSqlSock::set_ssl_enabled() { int ret = OB_SUCCESS; - if (OB_FAIL(ob_fd_enable_ssl_for_server(fd_, OB_SSL_CTX_ID_SQL_NIO))) { + if (OB_FAIL(ob_fd_enable_ssl_for_server(fd_, OB_SSL_CTX_ID_SQL_NIO, tls_verion_option_))) { LOG_WARN("sqlnio enable ssl for server failed", K(ret), K(fd_)); } return ret; @@ -1231,5 +1234,11 @@ int ObSqlNio::write_handshake_packet(void* sess, const char* buf, int64_t sz) { return sess2sock(sess)->write_handshake_packet(buf, sz); } + +void ObSqlNio::set_tls_version_option(void* sess, uint64_t tls_option) +{ + sess2sock(sess)->set_tls_version_option(tls_option); +} + }; // end namespace obmysql }; // end namespace oceanbase diff --git a/deps/oblib/src/rpc/obmysql/ob_sql_nio.h b/deps/oblib/src/rpc/obmysql/ob_sql_nio.h index cf2855194..c9f4780cc 100644 --- a/deps/oblib/src/rpc/obmysql/ob_sql_nio.h +++ b/deps/oblib/src/rpc/obmysql/ob_sql_nio.h @@ -59,6 +59,7 @@ public: } void update_tcp_keepalive_params(int keepalive_enabled, uint32_t tcp_keepidle, uint32_t tcp_keepintvl, uint32_t tcp_keepcnt); int write_handshake_packet(void* sess, const char* buf, int64_t sz); + void set_tls_version_option(void* sess, uint64_t tls_option); private: void run(int64_t idx); private: diff --git a/deps/oblib/src/rpc/obmysql/ob_sql_sock_session.cpp b/deps/oblib/src/rpc/obmysql/ob_sql_sock_session.cpp index a71f950c4..dd8720c0a 100644 --- a/deps/oblib/src/rpc/obmysql/ob_sql_sock_session.cpp +++ b/deps/oblib/src/rpc/obmysql/ob_sql_sock_session.cpp @@ -178,5 +178,10 @@ int ObSqlSockSession::write_hanshake_packet(const char *buf, int64_t sz) return nio_->write_handshake_packet((void *)this, buf, sz); } +void ObSqlSockSession::set_tls_version_option(uint64_t tls_option) +{ + nio_->set_tls_version_option((void *)this, tls_option); +} + }; // end namespace obmysql }; // end namespace oceanbase diff --git a/deps/oblib/src/rpc/obmysql/ob_sql_sock_session.h b/deps/oblib/src/rpc/obmysql/ob_sql_sock_session.h index 0db7e0dbd..3d1dd54db 100644 --- a/deps/oblib/src/rpc/obmysql/ob_sql_sock_session.h +++ b/deps/oblib/src/rpc/obmysql/ob_sql_sock_session.h @@ -63,6 +63,7 @@ public: SSL* get_ssl_st(); bool is_inited() const { return is_inited_; } int write_hanshake_packet(const char *buf, int64_t sz); + void set_tls_version_option(uint64_t tls_option); ObSqlNio* nio_; ObISMConnectionCallback& sm_conn_cb_; rpc::ObRequest sql_req_; diff --git a/src/observer/mysql/obsm_conn_callback.cpp b/src/observer/mysql/obsm_conn_callback.cpp index d38ca5d33..7427adf43 100644 --- a/src/observer/mysql/obsm_conn_callback.cpp +++ b/src/observer/mysql/obsm_conn_callback.cpp @@ -11,6 +11,7 @@ */ #define USING_LOG_PREFIX RPC_OBMYSQL +#include #include "observer/mysql/obsm_conn_callback.h" #include "rpc/obmysql/ob_sql_sock_session.h" #include "rpc/obmysql/obsm_struct.h" @@ -29,6 +30,22 @@ using namespace observer; namespace obmysql { +uint64_t ob_calculate_tls_version_option(const ObString &tls_min_version) +{ + uint64_t tls_option = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; + if (0 == tls_min_version.case_compare("NONE")) { + } else if (0 == tls_min_version.case_compare("TLSV1")) { + //no need to set because OPENSSL support all protocol by default + } else if (0 == tls_min_version.case_compare("TLSV1.1")) { + tls_option |= SSL_OP_NO_TLSv1; + } else if (0 == tls_min_version.case_compare("TLSV1.2")) { + tls_option |= (SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1); + } else if (0 == tls_min_version.case_compare("TLSV1.3")) { + tls_option |= (SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2); + } + return tls_option; +} + static int create_scramble_string(char *scramble_buf, const int64_t buf_len, common::ObMysqlRandom &thread_rand) { int ret = OB_SUCCESS; @@ -118,6 +135,9 @@ int ObSMConnectionCallback::init(ObSqlSockSession& sess, ObSMConnection& conn) LOG_WARN("send handshake fail", K(ret), K(sess.client_addr_)); } else { sess.sql_session_id_ = conn.sessid_; + uint64_t tls_version_option = ob_calculate_tls_version_option( + GCONF.sql_protocol_min_tls_version.str()); + sess.set_tls_version_option(tls_version_option); LOG_INFO("sm conn init succ", K(conn.sessid_), K(sess.client_addr_)); } diff --git a/src/observer/mysql/obsm_handler.cpp b/src/observer/mysql/obsm_handler.cpp index 8ae8f16d6..55ae9269f 100644 --- a/src/observer/mysql/obsm_handler.cpp +++ b/src/observer/mysql/obsm_handler.cpp @@ -30,6 +30,9 @@ namespace oceanbase using namespace rpc; using namespace common; using namespace name; +namespace obmysql { +extern uint64_t ob_calculate_tls_version_option(const ObString &tls_min_version); +} namespace observer { bool enable_proto_dia() @@ -113,6 +116,9 @@ int ObSMHandler::on_connect(easy_connection_t *c) eret = EASY_ERROR; LOG_WARN_RET(tmp_ret, "send handshake packet failed", K(tmp_ret), K(eret)); } else { + uint64_t tls_version_option = obmysql::ob_calculate_tls_version_option( + GCONF.sql_protocol_min_tls_version.str()); + c->tls_version_option = tls_version_option; LOG_INFO("new mysql sessid created", K(easy_connection_str(c)), K(sessid), K(crt_id_ret)); } } diff --git a/src/share/config/ob_config_helper.cpp b/src/share/config/ob_config_helper.cpp index f1edaa7c2..a5b513558 100644 --- a/src/share/config/ob_config_helper.cpp +++ b/src/share/config/ob_config_helper.cpp @@ -857,5 +857,16 @@ bool ObConfigRuntimeFilterChecker::check(const ObConfigItem &t) const int64_t rf_type = get_runtime_filter_type(t.str(), len); return rf_type >= 0; } + +bool ObConfigSQLTlsVersionChecker::check(const ObConfigItem &t) const +{ + const ObString tmp_str(t.str()); + return 0 == tmp_str.case_compare("NONE") || + 0 == tmp_str.case_compare("TLSV1") || + 0 == tmp_str.case_compare("TLSV1.1") || + 0 == tmp_str.case_compare("TLSV1.2") || + 0 == tmp_str.case_compare("TLSV1.3"); +} + } // end of namepace common } // end of namespace oceanbase diff --git a/src/share/config/ob_config_helper.h b/src/share/config/ob_config_helper.h index d7b9ecb32..a24e0e1e5 100644 --- a/src/share/config/ob_config_helper.h +++ b/src/share/config/ob_config_helper.h @@ -614,6 +614,16 @@ private: DISALLOW_COPY_AND_ASSIGN(ObRpcServerAuthMethodChecker); }; +class ObConfigSQLTlsVersionChecker + : public ObConfigChecker +{ +public: + ObConfigSQLTlsVersionChecker() {} + virtual ~ObConfigSQLTlsVersionChecker() {} + bool check(const ObConfigItem &t) const; +private: + DISALLOW_COPY_AND_ASSIGN(ObConfigSQLTlsVersionChecker); +}; typedef __ObConfigContainer ObConfigContainer; } // namespace common diff --git a/src/share/parameter/ob_parameter_seed.ipp b/src/share/parameter/ob_parameter_seed.ipp index e5546cead..cf74259fa 100755 --- a/src/share/parameter/ob_parameter_seed.ipp +++ b/src/share/parameter/ob_parameter_seed.ipp @@ -1575,4 +1575,9 @@ ERRSIM_DEF_STR_LIST(errsim_module_types, OB_TENANT_PARAMETER, "", ERRSIM_DEF_DBL(errsim_module_error_percentage, OB_TENANT_PARAMETER, "0", "[0,100]", "the percentage of the error happened to errsim module. " "Range: [0, 100] in percentage", - ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)) + ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +DEF_STR_WITH_CHECKER(sql_protocol_min_tls_version, OB_CLUSTER_PARAMETER, "none", + common::ObConfigSQLTlsVersionChecker, + "SQL SSL control options, used to specify the minimum SSL/TLS version number. " + "values: none, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result index a57149f80..cec436918 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result @@ -196,6 +196,7 @@ server_cpu_quota_min server_permanent_offline_time sql_login_thread_count sql_net_thread_count +sql_protocol_min_tls_version sql_work_area ssl_client_authentication ssl_external_kms_info