Skip to content

Commit f37c3ae

Browse files
committed
WL#15524 Patch #4 MGM TLS Configuration
In the NDB configuration, add boolen options RequireTls and RequireCertificate to the [MGM] section. Both options default to false. Add a new test testMgmd -n MgmdWithoutCertificate In NdbStdOpt, add the --ndb-mgm-tls command-line option. The allowed values are "relaxed" and "strict". The default is "relaxed". This option will be used for utility programs, allowing the user to specify the TLS-related behavior of MGM clients. Change-Id: Id32bb8805ca19a8cf8b52f45c54a7be4d912c5e4
1 parent 959e3f6 commit f37c3ae

File tree

7 files changed

+102
-5
lines changed

7 files changed

+102
-5
lines changed

storage/ndb/include/mgmapi/mgmapi_config_parameters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@
297297
#define CFG_MAX_LOGLEVEL 262
298298

299299
#define CFG_MGM_PORT 300
300+
#define CFG_MGM_REQUIRE_TLS 301
300301

301302
#define CFG_DB_MAX_BUFFERED_EPOCH_BYTES 350
302303

storage/ndb/include/util/ndb_opts.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "my_alloc.h" // MEM_ROOT
3131
#include "my_sys.h" // loglevel needed by my_getopt.h
3232
#include "my_getopt.h"
33+
#include "typelib.h"
3334
#include "util/BaseString.hpp"
3435
#include "util/require.h"
3536

@@ -48,6 +49,7 @@ OPT_EXTERN(int, opt_connect_retry_delay,NONE);
4849
OPT_EXTERN(int, opt_connect_retries,NONE);
4950
OPT_EXTERN(const char *,opt_charsets_dir,=0);
5051
OPT_EXTERN(const char *,opt_tls_search_path,=NDB_TLS_SEARCH_PATH);
52+
OPT_EXTERN(unsigned long long,opt_mgm_tls,=0);
5153

5254
#ifndef NDEBUG
5355
OPT_EXTERN(const char *,opt_debug,= 0);
@@ -76,6 +78,9 @@ enum ndb_std_options {
7678

7779
namespace NdbStdOpt {
7880

81+
static const char * tls_names[] = { "relaxed", "strict", nullptr };
82+
static TYPELIB mgm_tls_typelib = { 2 , "TLS requirement", tls_names, nullptr };
83+
7984
static constexpr struct my_option usage =
8085
{ "usage", '?', "Display this help and exit.",
8186
nullptr, nullptr, nullptr, GET_NO_ARG, NO_ARG,
@@ -148,6 +153,13 @@ static constexpr struct my_option tls_search_path =
148153
&opt_tls_search_path, nullptr, nullptr, GET_STR, REQUIRED_ARG,
149154
0, 0, 0, nullptr, 0, nullptr};
150155

156+
static constexpr struct my_option mgm_tls =
157+
{ "ndb-mgm-tls", NDB_OPT_NOSHORT,
158+
"MGM client TLS requirement level",
159+
&opt_mgm_tls, nullptr, &mgm_tls_typelib, GET_ENUM, REQUIRED_ARG,
160+
0 /* default=CLIENT_TLS_RELAXED */, 0 /*min*/, 1 /*max*/,
161+
nullptr, 0, nullptr};
162+
151163
#ifndef NDEBUG
152164
static constexpr struct my_option debug =
153165
{ "debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,7 +1919,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
19191919
CFG_DB_REQUIRE_TLS,
19201920
"RequireTls",
19211921
DB_TOKEN,
1922-
"Require TLS authenticated secure connections",
1922+
"Require TLS-authenticated secure connections",
19231923
ConfigInfo::CI_USED,
19241924
0,
19251925
ConfigInfo::CI_BOOL,
@@ -3359,6 +3359,32 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
33593359
STR_VALUE(MAX_INT_RNIL)
33603360
},
33613361

3362+
{
3363+
CFG_NODE_REQUIRE_CERT,
3364+
"RequireCertificate",
3365+
MGM_TOKEN,
3366+
"Require valid TLS key and certificate at startup time",
3367+
ConfigInfo::CI_USED,
3368+
false,
3369+
ConfigInfo::CI_BOOL,
3370+
"false",
3371+
"false",
3372+
"true"
3373+
},
3374+
3375+
{
3376+
CFG_MGM_REQUIRE_TLS,
3377+
"RequireTls",
3378+
MGM_TOKEN,
3379+
"Require TLS-authenticated secure connections",
3380+
ConfigInfo::CI_USED,
3381+
0,
3382+
ConfigInfo::CI_BOOL,
3383+
"false",
3384+
"false",
3385+
"true"
3386+
},
3387+
33623388
/****************************************************************************
33633389
* TCP
33643390
***************************************************************************/
@@ -3520,7 +3546,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
35203546
CFG_TCP_REQUIRE_TLS,
35213547
"RequireLinkTls",
35223548
"TCP",
3523-
"Use TLS authenticated secure connections for TCP transporter links",
3549+
"Use TLS-authenticated secure connections for TCP transporter links",
35243550
ConfigInfo::CI_INTERNAL,
35253551
0,
35263552
ConfigInfo::CI_BOOL,

storage/ndb/src/mgmsrv/MgmtSrvr.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "util/require.h"
2626
#include <ndb_global.h>
2727
#include <cstring>
28+
#include "openssl/ssl.h"
2829

2930
#include "MgmtSrvr.hpp"
3031
#include "ndb_mgmd_error.h"
@@ -59,6 +60,7 @@
5960
#include <NdbSleep.h>
6061
#include <portlib/NdbDir.hpp>
6162
#include "portlib/ndb_sockaddr.h"
63+
#include "portlib/ndb_openssl_version.h"
6264
#include <EventLogger.hpp>
6365
#include <logger/FileLogHandler.hpp>
6466
#include <logger/ConsoleLogHandler.hpp>
@@ -96,6 +98,9 @@ int g_errorInsert = 0;
9698
}\
9799
}
98100

101+
static constexpr bool openssl_version_ok =
102+
(OPENSSL_VERSION_NUMBER >= NDB_TLS_MINIMUM_OPENSSL);
103+
99104
void *
100105
MgmtSrvr::logLevelThread_C(void* m)
101106
{
@@ -482,6 +487,18 @@ MgmtSrvr::start_mgm_service(const Config* config)
482487
g_eventLogger->error("PortNumber not defined for node %d", _ownNodeId);
483488
DBUG_RETURN(false);
484489
}
490+
491+
// Find the TLS requirement level
492+
Uint32 requireCert = 0;
493+
Uint32 requireTls = 0;
494+
495+
if(openssl_version_ok)
496+
{
497+
require(iter.get(CFG_MGM_REQUIRE_TLS, &requireTls) == 0);
498+
require(iter.get(CFG_NODE_REQUIRE_CERT, &requireCert) == 0);
499+
}
500+
m_require_tls = requireTls;
501+
m_require_cert = requireCert;
485502
}
486503

487504
unsigned short port= m_port;
@@ -572,7 +589,7 @@ MgmtSrvr::start()
572589
{
573590
DBUG_ENTER("MgmtSrvr::start");
574591

575-
/* Configure TLS */
592+
/* Configure TlsKeyManager */
576593
require(m_tls_search_path);
577594
theFacade->mgm_configure_tls(m_tls_search_path);
578595

@@ -590,6 +607,19 @@ MgmtSrvr::start()
590607
DBUG_RETURN(false);
591608
}
592609

610+
/* Check for required TLS certificate */
611+
ssl_ctx_st * ctx = theFacade->get_registry()->getTlsKeyManager()->ctx();
612+
if(require_cert() && ! ctx)
613+
{
614+
g_eventLogger->error(
615+
"Shutting down. This node does not have a valid TLS certificate.");
616+
DBUG_RETURN(false);
617+
}
618+
619+
g_eventLogger->info(require_tls() ?
620+
"This server will require all MGM clients to use TLS" :
621+
"Not requiring TLS");
622+
593623
/* Use local MGM port for TransporterRegistry */
594624
if(!connect_to_self())
595625
{

storage/ndb/src/mgmsrv/MgmtSrvr.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,9 @@ class MgmtSrvr : private ConfigSubscriber, public trp_client {
458458

459459
const char * m_tls_search_path { nullptr };
460460

461+
bool m_require_tls { false };
462+
bool m_require_cert { false };
463+
461464
bool m_need_restart;
462465

463466
ndb_sockaddr m_connect_address[MAX_NODES];
@@ -530,6 +533,9 @@ class MgmtSrvr : private ConfigSubscriber, public trp_client {
530533

531534
void show_variables(NdbOut& out = ndbout);
532535

536+
bool require_tls() const { return m_require_tls; }
537+
bool require_cert() const { return m_require_tls || m_require_cert; }
538+
533539
private:
534540
class NodeIdReservations {
535541
struct Reservation {

storage/ndb/test/include/ConfigFactory.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ struct ConfigFactory
108108
return config;
109109
}
110110

111-
static bool
111+
template <typename T> static bool
112112
put(Properties& config, const char* section, Uint32 section_no,
113-
const char* key, Uint32 value)
113+
const char* key, T value)
114114
{
115115
Properties* p;
116116
// Get a copy of the section to modify

storage/ndb/test/ndbapi/testMgmd.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,6 +1935,22 @@ runTestSshKeySigning(NDBT_Context* ctx, NDBT_Step* step)
19351935
return NDBT_OK;
19361936
}
19371937

1938+
int
1939+
runTestMgmdWithoutCert(NDBT_Context* ctx, NDBT_Step* step)
1940+
{
1941+
NDBT_Workingdir wd("test_mgmd"); // temporary working directory
1942+
BaseString cfg_path = path(wd.path(), "config.ini", nullptr);
1943+
1944+
Properties config = ConfigFactory::create();
1945+
ConfigFactory::put(config, "ndb_mgmd", 1, "RequireCertificate", "true");
1946+
CHECK(ConfigFactory::write_config_ini(config, cfg_path.c_str()));
1947+
1948+
Mgmd mgmd(1);
1949+
CHECK(mgmd.start_from_config_ini(wd.path())); // Start management node
1950+
CHECK(! mgmd.connect(config)); // Cannot connect
1951+
return NDBT_OK;
1952+
}
1953+
19381954
int
19391955
runTestNdbdWithoutCert(NDBT_Context* ctx, NDBT_Step* step)
19401956
{
@@ -2197,6 +2213,12 @@ TESTCASE("SshKeySigning",
21972213
INITIALIZER(runTestSshKeySigning);
21982214
}
21992215

2216+
TESTCASE("MgmdWithoutCertificate",
2217+
"Test MGM server startup with TLS required but no certificate")
2218+
{
2219+
INITIALIZER(runTestMgmdWithoutCert)
2220+
}
2221+
22002222
TESTCASE("NdbdWithoutCertificate",
22012223
"Test data node startup with TLS required but no certificate")
22022224
{

0 commit comments

Comments
 (0)