Skip to content

Commit 85152cc

Browse files
committed
WL#15524 Patches #9 and #10: --ndb-mgm-tls in ndbd and ndb_mgmd
When a node starts up, it might connect to a management server to obtain the cluster configuration. The component that does this is known as ConfigRetriever. This patch adds an instance of TlsKeyManager to ConfigRetriever for use in MGM TLS by both sorts of ndbd processes: the data node and the angel process. The data node (but not the angel) also has a TlsKeyManager in the global TransporterRegistry. In the data node, these two TlsKeyManagers are initialized with the same node type and TLS search path, so they will both use the same certificate. In a data node, ConfigRetriever's MGM connection is the one that will get turned in to a transporter. In the existing MTR test tls_off_certs, the behavior changes so that the data nodes now have TLS connections to the MGM node. An NDB management server might also be a client of some other NDB management server. This patch adds support for the --ndb-mgm-tls option to ndb_mgmd, for setting its MGM TLS requirement level when it acts as a client. This patch extends the test testMgmd -n NdbdWithCertificate to run with [MGM]RequireTls set to true. Change-Id: I9ab68bef61b80a18edbf1375366c81ed874d7026
1 parent 024e2c8 commit 85152cc

File tree

16 files changed

+107
-33
lines changed

16 files changed

+107
-33
lines changed

mysql-test/suite/ndb_tls/tls_off_certs.test

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,10 @@
33

44
# Data node certs exist and are visible in ndbinfo
55

6-
# Expect 2 node certificates.
7-
# ndbinfo is aware of DB certs that belong to each data node, but it
8-
# is not aware of any API or MGM certs because no data node has a TLS
9-
# connection to an MGM or API node.
6+
# Expect 3 node certificates, for DB, DB, and MGM.
107
#
118
SELECT * FROM ndbinfo.certificates order by Node_id;
129

13-
# Expect all connections unencrypted
10+
# Expect encrypted connections to MGMD (node 3) only
1411
SELECT node_id, remote_node_id, encrypted from ndbinfo.transporters
1512
WHERE status = 'CONNECTED' ORDER BY node_id, remote_node_id;

storage/ndb/include/mgmcommon/ConfigRetriever.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <ndb_types.h>
2929
#include <mgmapi.h>
3030
#include "mgmcommon/NdbMgm.hpp"
31+
#include "util/TlsKeyManager.hpp"
3132
#include <BaseString.hpp>
3233

3334
/**
@@ -42,6 +43,9 @@ class ConfigRetriever {
4243
int timeout_ms = 30000);
4344
~ConfigRetriever();
4445

46+
/* Initialize a built-in TlsKeyManager to use for MGM TLS. */
47+
void init_mgm_tls(const char * tls_search_path, Node::Type, int req_level);
48+
4549
int do_connect(int no_retries, int retry_delay_in_seconds, int verbose);
4650
int disconnect();
4751
bool is_connected();
@@ -98,7 +102,9 @@ class ConfigRetriever {
98102
void end_session(bool end) { m_end_session= end; }
99103

100104
Uint32 get_configuration_nodeid() const;
105+
ssl_ctx_st * ssl_ctx() const { return m_tlsKeyManager.ctx(); }
101106
private:
107+
TlsKeyManager m_tlsKeyManager;
102108
BaseString errorString;
103109
enum ErrorType {
104110
CR_NO_ERROR = 0,
@@ -113,6 +119,7 @@ class ConfigRetriever {
113119
Uint32 m_version;
114120
ndb_mgm_node_type m_node_type;
115121
NdbMgmHandle m_handle;
122+
int m_tls_req_level{0};
116123
};
117124

118125
#endif

storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,16 @@ ConfigRetriever::~ConfigRetriever()
110110
DBUG_VOID_RETURN;
111111
}
112112

113+
void
114+
ConfigRetriever::init_mgm_tls(const char * tls_search_path,
115+
Node::Type node_type,
116+
int mgm_tls_req_level)
117+
{
118+
m_tlsKeyManager.init_mgm_client(tls_search_path, node_type);
119+
ndb_mgm_set_ssl_ctx(m_handle, m_tlsKeyManager.ctx());
120+
m_tls_req_level = mgm_tls_req_level;
121+
}
122+
113123
Uint32
114124
ConfigRetriever::get_configuration_nodeid() const
115125
{
@@ -138,7 +148,8 @@ int
138148
ConfigRetriever::do_connect(int no_retries,
139149
int retry_delay_in_seconds, int verbose)
140150
{
141-
if (ndb_mgm_connect(m_handle, no_retries, retry_delay_in_seconds, verbose) == 0)
151+
if (ndb_mgm_connect_tls(m_handle, no_retries, retry_delay_in_seconds,
152+
verbose, m_tls_req_level) == 0)
142153
{
143154
return 0;
144155
}
@@ -486,7 +497,7 @@ ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds,
486497
while (1)
487498
{
488499
if (ndb_mgm_is_connected(m_handle) == 1 ||
489-
ndb_mgm_connect(m_handle, 0, 0, verbose) == 0)
500+
ndb_mgm_connect_tls(m_handle, 0, 0, verbose, m_tls_req_level) == 0)
490501
{
491502
int res =
492503
ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type,
@@ -496,8 +507,9 @@ ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds,
496507
}
497508

498509
error = ndb_mgm_get_latest_error(m_handle);
499-
if (no_retries == 0 || /* No more retries */
500-
error == NDB_MGM_ALLOCID_CONFIG_MISMATCH) /* Fatal error */
510+
if (no_retries == 0 || /* No more retries */
511+
error == NDB_MGM_ALLOCID_CONFIG_MISMATCH ||
512+
error == NDB_MGM_AUTH_REQUIRES_TLS) /* Fatal errors */
501513
{
502514
break;
503515
}

storage/ndb/src/kernel/angel.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#include <portlib/ndb_daemon.h>
3737
#include <portlib/NdbSleep.h>
3838
#include <portlib/NdbDir.hpp>
39-
39+
#include "util/TlsKeyManager.hpp"
4040
#include <ConfigRetriever.hpp>
4141

4242
#include <NdbTCP.h>
@@ -212,7 +212,8 @@ static void
212212
reportShutdown(const ndb_mgm_configuration* config,
213213
NodeId nodeid, int error_exit,
214214
bool restart, bool nostart, bool initial,
215-
Uint32 error, Uint32 signum, Uint32 sphase)
215+
Uint32 error, Uint32 signum, Uint32 sphase,
216+
ssl_ctx_st * tls, int tls_req_level)
216217
{
217218
// Only allow "initial" and "nostart" to be set if "restart" is set
218219
assert(restart ||
@@ -279,8 +280,9 @@ reportShutdown(const ndb_mgm_configuration* config,
279280
continue;
280281
}
281282

283+
ndb_mgm_set_ssl_ctx(h, tls);
282284
if (ndb_mgm_set_connectstring(h, connect_str.c_str()) ||
283-
ndb_mgm_connect(h, 1, 0, 0) ||
285+
ndb_mgm_connect_tls(h, 1, 0, 0, tls_req_level) ||
284286
ndb_mgm_report_event(h, theData, length))
285287
{
286288
g_eventLogger->warning("Unable to report shutdown reason "
@@ -613,7 +615,9 @@ angel_run(const char* progname,
613615
bool no_start,
614616
bool daemon,
615617
int connnect_retries,
616-
int connect_delay)
618+
int connect_delay,
619+
const char * tls_search_path,
620+
int mgm_tls_level)
617621
{
618622
ConfigRetriever retriever(connect_str,
619623
force_nodeid,
@@ -627,6 +631,8 @@ angel_run(const char* progname,
627631
angel_exit(1);
628632
}
629633

634+
retriever.init_mgm_tls(tls_search_path, Node::Type::DB, mgm_tls_level);
635+
630636
const int verbose = 1;
631637
if (retriever.do_connect(connnect_retries, connect_delay, verbose) != 0)
632638
{
@@ -879,7 +885,8 @@ angel_run(const char* progname,
879885
case NRT_Default:
880886
g_eventLogger->info("Angel shutting down");
881887
reportShutdown(config.get(), nodeid, 0, 0, false, false,
882-
child_error, child_signal, child_sphase);
888+
child_error, child_signal, child_sphase,
889+
retriever.ssl_ctx(), mgm_tls_level);
883890
angel_exit(0);
884891
break;
885892
case NRT_NoStart_Restart:
@@ -903,7 +910,8 @@ angel_run(const char* progname,
903910
*/
904911
reportShutdown(config.get(), nodeid,
905912
error_exit, 0, false, false,
906-
child_error, child_signal, child_sphase);
913+
child_error, child_signal, child_sphase,
914+
retriever.ssl_ctx(), mgm_tls_level);
907915
angel_exit(0);
908916
}
909917
[[fallthrough]];
@@ -932,7 +940,8 @@ angel_run(const char* progname,
932940
*/
933941
reportShutdown(config.get(), nodeid,
934942
error_exit, 0, false, false,
935-
child_error, child_signal, child_sphase);
943+
child_error, child_signal, child_sphase,
944+
retriever.ssl_ctx(), mgm_tls_level);
936945
angel_exit(0);
937946
}
938947
else
@@ -957,7 +966,8 @@ angel_run(const char* progname,
957966
"not restarting again", failed_startups_counter);
958967
reportShutdown(config.get(), nodeid,
959968
error_exit, 0, false, false,
960-
child_error, child_signal, child_sphase);
969+
child_error, child_signal, child_sphase,
970+
retriever.ssl_ctx(), mgm_tls_level);
961971
angel_exit(0);
962972
}
963973
g_eventLogger->info("Angel detected startup failure, count: %u",
@@ -975,7 +985,8 @@ angel_run(const char* progname,
975985
error_exit, 1,
976986
no_start,
977987
initial,
978-
child_error, child_signal, child_sphase);
988+
child_error, child_signal, child_sphase,
989+
retriever.ssl_ctx(), mgm_tls_level);
979990
g_eventLogger->info("Child has terminated (pid %jd). "
980991
"Angel restarting child process",
981992
child_pid);

storage/ndb/src/kernel/angel.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ angel_run(const char* progname,
3939
bool no_start,
4040
bool daemon,
4141
int connnect_retries,
42-
int connect_delay);
42+
int connect_delay,
43+
const char * tls_search_path,
44+
int mgm_tls_level);
4345

4446
void
4547
angel_stop(void);

storage/ndb/src/kernel/main.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ static struct my_option my_long_options[] =
8282
NdbStdOpt::connect_retry_delay, //used
8383
NdbStdOpt::connect_retries, // used
8484
NdbStdOpt::tls_search_path,
85+
NdbStdOpt::mgm_tls,
8586
NDB_STD_OPT_DEBUG
8687
{ "core-file", NDB_OPT_NOSHORT, "Write core on errors.",\
8788
&opt_core, nullptr, nullptr, GET_BOOL, NO_ARG,
@@ -271,7 +272,7 @@ real_main(int argc, char** argv)
271272
opt_ndb_connectstring, opt_ndb_nodeid, opt_bind_address,
272273
opt_no_start, opt_initial, opt_initialstart,
273274
opt_allocated_nodeid, opt_connect_retries, opt_connect_retry_delay,
274-
opt_logbuffer_size, opt_tls_search_path);
275+
opt_logbuffer_size, opt_tls_search_path, opt_mgm_tls);
275276
}
276277

277278
/**
@@ -290,7 +291,9 @@ real_main(int argc, char** argv)
290291
opt_no_start,
291292
opt_daemon,
292293
opt_connect_retries,
293-
opt_connect_retry_delay);
294+
opt_connect_retry_delay,
295+
opt_tls_search_path,
296+
opt_mgm_tls);
294297

295298
return 1; // Never reached
296299
}

storage/ndb/src/kernel/ndbd.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444

4545
#include <TransporterRegistry.hpp>
4646

47-
#include <ConfigRetriever.hpp>
4847
#include <LogLevel.hpp>
4948

5049
#if defined NDB_SOLARIS
@@ -1034,7 +1033,7 @@ ndbd_run(bool foreground, int report_fd,
10341033
const char* connect_str, int force_nodeid, const char* bind_address,
10351034
bool no_start, bool initial, bool initialstart,
10361035
unsigned allocated_nodeid, int connect_retries, int connect_delay,
1037-
size_t logbuffer_size, const char * tls_search_path)
1036+
size_t logbuffer_size, const char * tls_search_path, int mgm_tls_req)
10381037
{
10391038
log_memusage("ndbd_run");
10401039
LogBuffer* logBuf = new LogBuffer(logbuffer_size);
@@ -1151,9 +1150,9 @@ ndbd_run(bool foreground, int report_fd,
11511150
already assigned the nodeid, either by the operator or by the angel
11521151
process.
11531152
*/
1154-
theConfig->fetch_configuration(connect_str, force_nodeid, bind_address,
1155-
allocated_nodeid, connect_retries,
1156-
connect_delay);
1153+
theConfig->fetch_configuration(connect_str, force_nodeid,
1154+
bind_address, allocated_nodeid, connect_retries, connect_delay,
1155+
tls_search_path, opt_mgm_tls);
11571156

11581157
/**
11591158
Set the NDB DataDir, this is where we will locate log files and data
@@ -1369,8 +1368,7 @@ ndbd_run(bool foreground, int report_fd,
13691368
ndbd_exit(-1);
13701369
}
13711370
// Re-use the mgm handle as a transporter
1372-
if(!globalTransporterRegistry.connect_client(
1373-
theConfig->get_config_retriever()->get_mgmHandlePtr()))
1371+
if(!globalTransporterRegistry.connect_client(theConfig->get_mgm_handle_ptr()))
13741372
ERROR_SET(fatal, NDBD_EXIT_CONNECTION_SETUP_FAILED,
13751373
"Failed to convert mgm connection to a transporter",
13761374
__FILE__);

storage/ndb/src/kernel/ndbd.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ ndbd_run(bool foreground, int report_fd,
3333
const char* connect_str, int force_nodeid, const char* bind_address,
3434
bool no_start, bool initial, bool initialstart,
3535
unsigned allocated_nodeid, int connect_retries, int connect_delay,
36-
size_t logbuffer_size, const char * tls_search_path);
36+
size_t logbuffer_size, const char * tls_search_path, int mgm_tls_req);
3737

3838
enum NdbShutdownType {
3939
NST_Normal,

storage/ndb/src/kernel/vm/Configuration.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ Configuration::fetch_configuration(const char* _connect_string,
132132
int force_nodeid,
133133
const char* _bind_address,
134134
NodeId allocated_nodeid,
135-
int connect_retries, int connect_delay)
135+
int connect_retries, int connect_delay,
136+
const char * tls_search_path, int mgm_tls)
136137
{
137138
/**
138139
* Fetch configuration from management server
@@ -159,6 +160,8 @@ Configuration::fetch_configuration(const char* _connect_string,
159160
m_config_retriever->getErrorString());
160161
}
161162

163+
m_config_retriever->init_mgm_tls(tls_search_path, Node::Type::DB, mgm_tls);
164+
162165
if(m_config_retriever->do_connect(connect_retries, connect_delay, 1) == -1){
163166
const char * s = m_config_retriever->getErrorString();
164167
if(s == 0)
@@ -1656,5 +1659,11 @@ Configuration::initThreadArray()
16561659
NdbMutex_Unlock(threadIdMutex);
16571660
}
16581661

1662+
NdbMgmHandle *
1663+
Configuration::get_mgm_handle_ptr()
1664+
{
1665+
return m_config_retriever->get_mgmHandlePtr();
1666+
}
1667+
16591668
template class Vector<struct ThreadInfo>;
16601669

storage/ndb/src/kernel/vm/Configuration.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ class Configuration {
7575
void fetch_configuration(const char* _connect_string, int force_nodeid,
7676
const char* _bind_adress,
7777
NodeId allocated_nodeid,
78-
int connect_retries, int connect_delay);
78+
int connect_retries, int connect_delay,
79+
const char * tls_search_path, int mgm_tls_level);
80+
7981
void setupConfiguration();
8082
void closeConfiguration(bool end_session= true);
8183

@@ -149,6 +151,7 @@ class Configuration {
149151
const ndb_mgm_configuration_iterator * getOwnConfigIterator() const;
150152

151153
ConfigRetriever* get_config_retriever() { return m_config_retriever; }
154+
NdbMgmHandle * get_mgm_handle_ptr();
152155

153156
class LogLevel * m_logLevel;
154157
ndb_mgm_configuration_iterator * getClusterConfigIterator() const;

storage/ndb/src/mgmsrv/ConfigManager.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2230,6 +2230,9 @@ ConfigManager::fetch_config(void)
22302230
{
22312231
DBUG_ENTER("ConfigManager::fetch_config");
22322232

2233+
m_config_retriever.init_mgm_tls(m_opts.tls_search_path,
2234+
Node::Type::MGMD, m_opts.mgm_tls);
2235+
22332236
while(true)
22342237
{
22352238
/* Loop until config loaded from other mgmd(s) */

storage/ndb/src/mgmsrv/MgmtSrvr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ MgmtSrvr::MgmtSrvr(const MgmtOpts& opts) :
255255
_ownReference(0),
256256
m_config_manager(NULL),
257257
m_tls_search_path(opts.tls_search_path),
258+
m_client_tls_req(opts.mgm_tls),
258259
m_need_restart(false),
259260
theFacade(NULL),
260261
_isStopThread(false),

storage/ndb/src/mgmsrv/MgmtSrvr.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class MgmtSrvr : private ConfigSubscriber, public trp_client {
116116
int initial;
117117
NodeBitmask nowait_nodes;
118118
const char* tls_search_path;
119+
int mgm_tls;
119120

120121
MgmtOpts() : configdir(MYSQLCLUSTERDIR),
121122
tls_search_path(NDB_TLS_SEARCH_PATH) {}
@@ -458,7 +459,8 @@ class MgmtSrvr : private ConfigSubscriber, public trp_client {
458459

459460
const char * m_tls_search_path { nullptr };
460461

461-
bool m_require_tls { false };
462+
int m_client_tls_req; // TLS requirement level as MGM client ...
463+
bool m_require_tls { false }; // ... and as MGM server.
462464
bool m_require_cert { false };
463465

464466
bool m_need_restart;

storage/ndb/src/mgmsrv/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ static struct my_option my_long_options[] =
118118
NdbStdOpt::mgmd_host,
119119
NdbStdOpt::connectstring,
120120
NdbStdOpt::tls_search_path,
121+
NdbStdOpt::mgm_tls,
121122
NDB_STD_OPT_DEBUG
122123
{ "config-file", 'f', "Specify cluster configuration file",
123124
&opts.config_filename, nullptr, nullptr, GET_STR, REQUIRED_ARG,
@@ -464,6 +465,7 @@ static int mgmd_main(int argc, char** argv)
464465
}
465466

466467
opts.tls_search_path = opt_tls_search_path;
468+
opts.mgm_tls = opt_mgm_tls;
467469

468470
/* Setup use of event logger */
469471
g_eventLogger->setCategory(opt_logname);

0 commit comments

Comments
 (0)