From 1287b0e595a5f99026f66df7eeaef091b8ffc774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 30 Oct 2017 12:20:18 +0200 Subject: [PATCH 01/15] Backport authentication fix from 2.2 The authentication code assumed that the initial request only had authentication related data. This is not true if the client library predicts that the authentication will succeed and it sends a query right after it sends the authentication data. --- .../protocol/MySQL/MySQLClient/mysql_client.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/server/modules/protocol/MySQL/MySQLClient/mysql_client.c b/server/modules/protocol/MySQL/MySQLClient/mysql_client.c index a25b329d0..830c88d9a 100644 --- a/server/modules/protocol/MySQL/MySQLClient/mysql_client.c +++ b/server/modules/protocol/MySQL/MySQLClient/mysql_client.c @@ -502,17 +502,12 @@ int gw_read_client_event(DCB* dcb) * */ case MXS_AUTH_STATE_MESSAGE_READ: - /* After this call read_buffer will point to freed data */ - if (nbytes_read < 3 || (0 == max_bytes && nbytes_read < - (MYSQL_GET_PAYLOAD_LEN((uint8_t *) GWBUF_DATA(read_buffer)) + 4)) || - (0 != max_bytes && nbytes_read < max_bytes)) + dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer); + + if ((read_buffer = modutil_get_next_MySQL_packet(&dcb->dcb_readqueue))) { - - dcb->dcb_readqueue = read_buffer; - - return 0; + return_code = gw_read_do_authentication(dcb, read_buffer, gwbuf_length(read_buffer)); } - return_code = gw_read_do_authentication(dcb, read_buffer, nbytes_read); break; /** From 4da28789acd8a4a9c40d1ccf38c74a9cca9f4348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 8 Nov 2017 10:00:10 +0200 Subject: [PATCH 02/15] Fix SSL regression This builds on commit 1287b0e595a5f99026f66df7eeaef091b8ffc774 and cleans up the original code. This fixes a bug introduced in the aforementioned commit and cleans up the code. --- include/maxscale/protocol/mysql.h | 5 +++++ .../protocol/MySQL/MySQLClient/mysql_client.c | 19 +++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/maxscale/protocol/mysql.h b/include/maxscale/protocol/mysql.h index b67876630..533b21415 100644 --- a/include/maxscale/protocol/mysql.h +++ b/include/maxscale/protocol/mysql.h @@ -335,6 +335,11 @@ static inline uint32_t MYSQL_GET_PAYLOAD_LEN(const uint8_t* header) return gw_mysql_get_byte3(header); } +static inline uint32_t MYSQL_GET_PACKET_LEN(const GWBUF* buffer) +{ + return MYSQL_GET_PAYLOAD_LEN(GWBUF_DATA(buffer)) + MYSQL_HEADER_LEN; +} + #define MYSQL_GET_ERRCODE(payload) (gw_mysql_get_byte2(&payload[5])) #define MYSQL_GET_STMTOK_NPARAM(payload) (gw_mysql_get_byte2(&payload[9])) #define MYSQL_GET_STMTOK_NATTR(payload) (gw_mysql_get_byte2(&payload[11])) diff --git a/server/modules/protocol/MySQL/MySQLClient/mysql_client.c b/server/modules/protocol/MySQL/MySQLClient/mysql_client.c index 830c88d9a..56f0acdc6 100644 --- a/server/modules/protocol/MySQL/MySQLClient/mysql_client.c +++ b/server/modules/protocol/MySQL/MySQLClient/mysql_client.c @@ -502,11 +502,22 @@ int gw_read_client_event(DCB* dcb) * */ case MXS_AUTH_STATE_MESSAGE_READ: - dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer); - - if ((read_buffer = modutil_get_next_MySQL_packet(&dcb->dcb_readqueue))) + if (nbytes_read < 3 || + (0 == max_bytes && nbytes_read < MYSQL_GET_PACKET_LEN(read_buffer)) || + (0 != max_bytes && nbytes_read < max_bytes)) { - return_code = gw_read_do_authentication(dcb, read_buffer, gwbuf_length(read_buffer)); + dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer); + } + else + { + if (nbytes_read > MYSQL_GET_PACKET_LEN(read_buffer)) + { + // We read more data than was needed + dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer); + read_buffer = modutil_get_next_MySQL_packet(&dcb->dcb_readqueue); + } + + return_code = gw_read_do_authentication(dcb, read_buffer, nbytes_read); } break; From 17b7cde56a329889a8724640c55960de00f76fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 8 Nov 2017 11:54:55 +0200 Subject: [PATCH 03/15] Clarify query_retries documentation The parameter documentation did not clearly specify that it affects only internal queries done by the core and monitors. --- Documentation/Getting-Started/Configuration-Guide.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index face2aa65..0ba969fcf 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -174,13 +174,14 @@ auth_write_timeout=10 #### `query_retries` -The number of times an interrupted query will be retried. This feature was added -in MaxScale 2.1.10 and is disabled by default. +The number of times an interrupted internal query will be retried. This feature +was added in MaxScale 2.1.10 and is disabled by default. An interrupted query is any query that is interrupted by a network error. Connection timeouts are included in network errors and thus is it advisable to make sure that the value of `query_retry_timeout` is set to an -adequate value. +adequate value. Internal queries are only used to retrieve authentication data +and monitor the servers. #### `query_retry_timeout` From bc36dd3e1a25cf6ace1daff42c6529b57f921036 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Fri, 10 Nov 2017 09:57:33 +0200 Subject: [PATCH 04/15] Update 2.1 version to 2.1.11 --- VERSION21.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION21.cmake b/VERSION21.cmake index 8ebe7a010..42ce2974e 100644 --- a/VERSION21.cmake +++ b/VERSION21.cmake @@ -5,7 +5,7 @@ set(MAXSCALE_VERSION_MAJOR "2" CACHE STRING "Major version") set(MAXSCALE_VERSION_MINOR "1" CACHE STRING "Minor version") -set(MAXSCALE_VERSION_PATCH "10" CACHE STRING "Patch version") +set(MAXSCALE_VERSION_PATCH "11" CACHE STRING "Patch version") # This should only be incremented if a package is rebuilt set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number") From 41f6400852db77ca2adb4ef50369ca1eb9f600d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 13 Nov 2017 10:45:13 +0200 Subject: [PATCH 05/15] MXS-1476: Add test case Test for MXS-1476 that checks that the behavior is what is expected. Currently, the test passes as behavior is what is expected. --- maxscale-system-test/CMakeLists.txt | 4 ++ .../cnf/maxscale.cnf.template.mxs1476 | 52 +++++++++++++++ maxscale-system-test/mxs1476.cpp | 63 +++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 maxscale-system-test/cnf/maxscale.cnf.template.mxs1476 create mode 100644 maxscale-system-test/mxs1476.cpp diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index 9d32e9568..6556007e7 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -506,6 +506,10 @@ add_test_executable(mxs1457_ignore_deleted.cpp mxs1457_ignore_deleted mxs1457_ig # https://jira.mariadb.org/browse/MXS-1468 add_test_executable(mxs1468.cpp mxs1468 mxs1468 LABELS REPL_BACKEND) + # MXS-1476: priority value ignored when a Galera node rejoins with a lower wsrep_local_index than current master + # https://jira.mariadb.org/browse/MXS-1476 +add_test_executable(mxs1476.cpp mxs1476 mxs1476 LABELS GALERA_BACKEND) + # 'namedserverfilter' test add_test_executable(namedserverfilter.cpp namedserverfilter namedserverfilter LABELS namedserverfilter LIGHT REPL_BACKEND) diff --git a/maxscale-system-test/cnf/maxscale.cnf.template.mxs1476 b/maxscale-system-test/cnf/maxscale.cnf.template.mxs1476 new file mode 100644 index 000000000..668a3fc83 --- /dev/null +++ b/maxscale-system-test/cnf/maxscale.cnf.template.mxs1476 @@ -0,0 +1,52 @@ +[maxscale] +threads=###threads### +retry_queries=1 + +[Galera Monitor] +type=monitor +module=galeramon +servers=server1,server2 +user=maxskysql +passwd=skysql +monitor_interval=1000 +root_node_as_master=false +use_priority=true +backend_connect_timeout=1 +backend_read_timeout=1 + +[RW Split Router] +type=service +router=readwritesplit +servers=server1,server2 +user=maxskysql +passwd=skysql + +[RW Split Listener] +type=listener +service=RW Split Router +protocol=MySQLClient +port=4006 + +[CLI] +type=service +router=cli + +[CLI Listener] +type=listener +service=CLI +protocol=maxscaled +socket=default + +[server1] +type=server +address=###galera_server_IP_1### +port=###galera_server_port_1### +protocol=MySQLBackend +priority=2 + +[server2] +type=server +address=###galera_server_IP_2### +port=###galera_server_port_2### +protocol=MySQLBackend +priority=1 diff --git a/maxscale-system-test/mxs1476.cpp b/maxscale-system-test/mxs1476.cpp new file mode 100644 index 000000000..7cca5a558 --- /dev/null +++ b/maxscale-system-test/mxs1476.cpp @@ -0,0 +1,63 @@ +/** + * MXS-1476: priority value ignored when a Galera node rejoins with a lower wsrep_local_index than current master + * + * https://jira.mariadb.org/browse/MXS-1476 + */ + +#include "testconnections.h" + +void do_test(TestConnections& test, int master, int slave) +{ + test.connect_maxscale(); + test.try_query(test.conn_rwsplit, "DROP TABLE IF EXISTS test.t1"); + test.try_query(test.conn_rwsplit, "CREATE TABLE test.t1 (id int)"); + test.try_query(test.conn_rwsplit, "INSERT INTO test.t1 VALUES (1)"); + + test.tprintf("Block a slave node and perform an insert"); + test.galera->block_node(slave); + sleep(5); + test.try_query(test.conn_rwsplit, "INSERT INTO test.t1 VALUES (1)"); + + test.tprintf("Unblock the slave node and perform another insert"); + test.galera->unblock_node(slave); + sleep(5); + test.try_query(test.conn_rwsplit, "INSERT INTO test.t1 VALUES (1)"); + test.close_maxscale_connections(); + + test.tprintf("Block the master node and perform an insert"); + test.galera->block_node(master); + sleep(5); + test.connect_maxscale(); + test.try_query(test.conn_rwsplit, "INSERT INTO test.t1 VALUES (1)"); + + test.tprintf("Unblock the master node and perform another insert (expecting failure)"); + test.galera->unblock_node(master); + sleep(5); + test.add_result(execute_query_silent(test.conn_rwsplit, "INSERT INTO test.t1 VALUES (1)") == 0, "Query should fail"); + test.close_maxscale_connections(); + + test.connect_maxscale(); + test.try_query(test.conn_rwsplit, "DROP TABLE test.t1"); +} + +int main(int argc, char** argv) +{ + TestConnections test(argc, argv); + test.galera->stop_node(2); + test.galera->stop_node(3); + + do_test(test, 1, 0); + + test.tprintf("Swap the priorities around and run the test again"); + test.ssh_maxscale(true, "sed -i 's/priority=1/priority=3/' /etc/maxscale.cnf;" + "sed -i 's/priority=2/priority=1/' /etc/maxscale.cnf;" + "sed -i 's/priority=3/priority=2/' /etc/maxscale.cnf;"); + test.restart_maxscale(); + + do_test(test, 0, 1); + + test.galera->start_node(2, ""); + test.galera->start_node(3, ""); + test.galera->fix_replication(); + return test.global_result; +} From 925fff4abcb891b5d4f7b7cf25401ade45413ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 14 Nov 2017 13:07:58 +0200 Subject: [PATCH 06/15] MXS-1518: Fix ssl_cert_verify_depth documentation Corrected the parameter name to the actual used value. --- Documentation/Getting-Started/Configuration-Guide.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index 0ba969fcf..45ae89a52 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -1036,16 +1036,16 @@ layer encryption. **Note:** It is highly recommended to leave this parameter to the default value of _MAX_. This will guarantee that the strongest available encryption is used. -#### `ssl_cert_verification_depth` +#### `ssl_cert_verify_depth` The maximum length of the certificate authority chain that will be accepted. Legal values are positive integers. Note that if the client is to submit an SSL -certificate, the `ssl_cert_verification_depth` parameter must not be 0. If no +certificate, the `ssl_cert_verify_depth` parameter must not be 0. If no value is specified, the default is 9. ``` # Example -ssl_cert_verification_depth=5 +ssl_cert_verify_depth=5 ``` **Example SSL enabled server configuration:** @@ -1239,16 +1239,16 @@ MaxScale on a system that does not have OpenSSL with support for this should earlier versions be used. It is unlikely that TLS 1.1 will be available unless TLS 1.2 is also available. MAX will use the best available version. -#### `ssl_cert_verification_depth` +#### `ssl_cert_verify_depth` The maximum length of the certificate authority chain that will be accepted. Legal values are positive integers. Note that if the client is to submit an SSL -certificate, the `ssl_cert_verification_depth` parameter must not be 0. If no +certificate, the `ssl_cert_verify_depth` parameter must not be 0. If no value is specified, the default is 9. ``` # Example -ssl_cert_verification_depth=5 +ssl_cert_verify_depth=5 ``` **Example SSL enabled listener configuration:** From 63ae436bd576c1d327ec9934ead574ed6901ebac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 14 Nov 2017 13:21:40 +0200 Subject: [PATCH 07/15] MXS-1019: Make peer certificate verification configurable The new `ssl_verify_peer_certificate` parameter controls whether the peer certificate is verified. This allows self-signed certificates to be properly used with MaxScale. --- include/maxscale/ssl.h | 2 + server/core/config.c | 23 +++++-- server/core/listener.c | 54 +--------------- server/core/server.c | 53 +--------------- server/core/ssl.c | 61 +++++++++++++++++++ server/modules/routing/binlogrouter/blr.c | 1 + .../modules/routing/binlogrouter/blr_slave.c | 1 + 7 files changed, 87 insertions(+), 108 deletions(-) diff --git a/include/maxscale/ssl.h b/include/maxscale/ssl.h index f1d761982..8f61e6db0 100644 --- a/include/maxscale/ssl.h +++ b/include/maxscale/ssl.h @@ -65,6 +65,7 @@ typedef struct ssl_listener char *ssl_key; /*< SSL private key */ char *ssl_ca_cert; /*< SSL CA certificate */ bool ssl_init_done; /*< If SSL has already been initialized for this service */ + bool ssl_verify_peer_certificate; /*< Enable peer certificate verification */ struct ssl_listener *next; /*< Next SSL configuration, currently used to store obsolete configurations */ } SSL_LISTENER; @@ -75,5 +76,6 @@ bool ssl_check_data_to_process(struct dcb *dcb); bool ssl_required_by_dcb(struct dcb *dcb); bool ssl_required_but_not_negotiated(struct dcb *dcb); const char* ssl_method_type_to_string(ssl_method_type_t method_type); +void write_ssl_config(int fd, SSL_LISTENER* ssl); MXS_END_DECLS diff --git a/server/core/config.c b/server/core/config.c index 34f4bb97d..083a0ed3c 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -154,6 +154,7 @@ static const char *listener_params[] = "ssl_key", "ssl_version", "ssl_cert_verify_depth", + "ssl_verify_peer_certificate", NULL }; @@ -199,6 +200,7 @@ static const char *server_params[] = "ssl_key", "ssl_version", "ssl_cert_verify_depth", + "ssl_verify_peer_certificate", NULL }; @@ -1466,8 +1468,11 @@ SSL_LISTENER* make_ssl_structure (CONFIG_CONTEXT *obj, bool require_cert, int *e ssl_key = config_get_value(obj->parameters, "ssl_key"); ssl_ca_cert = config_get_value(obj->parameters, "ssl_ca_cert"); ssl_version = config_get_value(obj->parameters, "ssl_version"); + char* ssl_verify_peer_certificate = config_get_value(obj->parameters, "ssl_verify_peer_certificate"); ssl_cert_verify_depth = config_get_value(obj->parameters, "ssl_cert_verify_depth"); new_ssl->ssl_init_done = false; + new_ssl->ssl_cert_verify_depth = 9; // Default of 9 as per Linux man page + new_ssl->ssl_verify_peer_certificate = true; if (ssl_version) { @@ -1490,12 +1495,20 @@ SSL_LISTENER* make_ssl_structure (CONFIG_CONTEXT *obj, bool require_cert, int *e local_errors++; } } - else + + if (ssl_verify_peer_certificate) { - /** - * Default of 9 as per Linux man page - */ - new_ssl->ssl_cert_verify_depth = 9; + int rv = config_truth_value(ssl_verify_peer_certificate); + if (rv == -1) + { + MXS_ERROR("Invalid parameter value for 'ssl_verify_peer_certificate" + " for service '%s': %s", obj->object, ssl_verify_peer_certificate); + local_errors++; + } + else + { + new_ssl->ssl_verify_peer_certificate = rv; + } } listener_set_certificates(new_ssl, ssl_cert, ssl_key, ssl_ca_cert); diff --git a/server/core/listener.c b/server/core/listener.c index 8d2adc1ad..9a067fe07 100644 --- a/server/core/listener.c +++ b/server/core/listener.c @@ -337,7 +337,7 @@ listener_init_SSL(SSL_LISTENER *ssl_listener) } /* Set to require peer (client) certificate verification */ - if (ssl_listener->ssl_cert_verify_depth) + if (ssl_listener->ssl_verify_peer_certificate) { SSL_CTX_set_verify(ssl_listener->ctx, SSL_VERIFY_PEER, NULL); } @@ -430,57 +430,7 @@ static bool create_listener_config(const SERV_LISTENER *listener, const char *fi if (listener->ssl) { - dprintf(file, "ssl=required\n"); - - if (listener->ssl->ssl_cert) - { - dprintf(file, "ssl_cert=%s\n", listener->ssl->ssl_cert); - } - - if (listener->ssl->ssl_key) - { - dprintf(file, "ssl_key=%s\n", listener->ssl->ssl_key); - } - - if (listener->ssl->ssl_ca_cert) - { - dprintf(file, "ssl_ca_cert=%s\n", listener->ssl->ssl_ca_cert); - } - if (listener->ssl->ssl_cert_verify_depth) - { - dprintf(file, "ssl_cert_verify_depth=%d\n", listener->ssl->ssl_cert_verify_depth); - } - - const char *version = NULL; - - switch (listener->ssl->ssl_method_type) - { -#ifndef OPENSSL_1_1 - case SERVICE_TLS10: - version = "TLSV10"; - break; -#endif -#ifdef OPENSSL_1_0 - case SERVICE_TLS11: - version = "TLSV11"; - break; - - case SERVICE_TLS12: - version = "TLSV12"; - break; -#endif - case SERVICE_SSL_TLS_MAX: - version = "MAX"; - break; - - default: - break; - } - - if (version) - { - dprintf(file, "ssl_version=%s\n", version); - } + write_ssl_config(file, listener->ssl); } close(file); diff --git a/server/core/server.c b/server/core/server.c index 0a5b434e2..744e0d931 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -577,6 +577,7 @@ dprintServer(DCB *dcb, const SERVER *server) dcb_printf(dcb, "\tSSL method type: %s\n", ssl_method_type_to_string(l->ssl_method_type)); dcb_printf(dcb, "\tSSL certificate verification depth: %d\n", l->ssl_cert_verify_depth); + dcb_printf(dcb, "\tSSL peer verification : %s\n", l->ssl_verify_peer_certificate ? "true" : "false"); dcb_printf(dcb, "\tSSL certificate: %s\n", l->ssl_cert ? l->ssl_cert : "null"); dcb_printf(dcb, "\tSSL key: %s\n", @@ -1167,57 +1168,7 @@ static bool create_server_config(const SERVER *server, const char *filename) if (server->server_ssl) { - dprintf(file, "ssl=required\n"); - - if (server->server_ssl->ssl_cert) - { - dprintf(file, "ssl_cert=%s\n", server->server_ssl->ssl_cert); - } - - if (server->server_ssl->ssl_key) - { - dprintf(file, "ssl_key=%s\n", server->server_ssl->ssl_key); - } - - if (server->server_ssl->ssl_ca_cert) - { - dprintf(file, "ssl_ca_cert=%s\n", server->server_ssl->ssl_ca_cert); - } - if (server->server_ssl->ssl_cert_verify_depth) - { - dprintf(file, "ssl_cert_verify_depth=%d\n", server->server_ssl->ssl_cert_verify_depth); - } - - const char *version = NULL; - - switch (server->server_ssl->ssl_method_type) - { -#ifndef OPENSSL_1_1 - case SERVICE_TLS10: - version = "TLSV10"; - break; -#endif -#ifdef OPENSSL_1_0 - case SERVICE_TLS11: - version = "TLSV11"; - break; - - case SERVICE_TLS12: - version = "TLSV12"; - break; -#endif - case SERVICE_SSL_TLS_MAX: - version = "MAX"; - break; - - default: - break; - } - - if (version) - { - dprintf(file, "ssl_version=%s\n", version); - } + write_ssl_config(file, server->server_ssl); } close(file); diff --git a/server/core/ssl.c b/server/core/ssl.c index 02c1f7385..32ee7c340 100644 --- a/server/core/ssl.c +++ b/server/core/ssl.c @@ -214,3 +214,64 @@ const char* ssl_method_type_to_string(ssl_method_type_t method_type) return "Unknown"; } } + +void write_ssl_config(int fd, SSL_LISTENER* ssl) +{ + if (ssl) + { + dprintf(fd, "ssl=required\n"); + + if (ssl->ssl_cert) + { + dprintf(fd, "ssl_cert=%s\n", ssl->ssl_cert); + } + + if (ssl->ssl_key) + { + dprintf(fd, "ssl_key=%s\n", ssl->ssl_key); + } + + if (ssl->ssl_ca_cert) + { + dprintf(fd, "ssl_ca_cert=%s\n", ssl->ssl_ca_cert); + } + if (ssl->ssl_cert_verify_depth) + { + dprintf(fd, "ssl_cert_verify_depth=%d\n", ssl->ssl_cert_verify_depth); + } + + dprintf(fd, "ssl_verify_peer_certificate=%s\n", + ssl->ssl_verify_peer_certificate ? "true" : "false"); + + const char *version = NULL; + + switch (ssl->ssl_method_type) + { +#ifndef OPENSSL_1_1 + case SERVICE_TLS10: + version = "TLSV10"; + break; +#endif +#ifdef OPENSSL_1_0 + case SERVICE_TLS11: + version = "TLSV11"; + break; + + case SERVICE_TLS12: + version = "TLSV12"; + break; +#endif + case SERVICE_SSL_TLS_MAX: + version = "MAX"; + break; + + default: + break; + } + + if (version) + { + dprintf(fd, "ssl_version=%s\n", version); + } + } +} \ No newline at end of file diff --git a/server/modules/routing/binlogrouter/blr.c b/server/modules/routing/binlogrouter/blr.c index fb17426c7..e091f188f 100644 --- a/server/modules/routing/binlogrouter/blr.c +++ b/server/modules/routing/binlogrouter/blr.c @@ -712,6 +712,7 @@ createInstance(SERVICE *service, char **options) ssl_cfg->ssl_init_done = false; ssl_cfg->ssl_method_type = SERVICE_SSL_TLS_MAX; ssl_cfg->ssl_cert_verify_depth = 9; + ssl_cfg->ssl_verify_peer_certificate = true; /** Set SSL pointer in in server struct */ server->server_ssl = ssl_cfg; diff --git a/server/modules/routing/binlogrouter/blr_slave.c b/server/modules/routing/binlogrouter/blr_slave.c index 1eb6571bc..de009b213 100644 --- a/server/modules/routing/binlogrouter/blr_slave.c +++ b/server/modules/routing/binlogrouter/blr_slave.c @@ -5766,6 +5766,7 @@ blr_set_master_ssl(ROUTER_INSTANCE *router, CHANGE_MASTER_OPTIONS config, char * server_ssl->ssl_init_done = false; server_ssl->ssl_method_type = SERVICE_SSL_TLS_MAX; server_ssl->ssl_cert_verify_depth = 9; + server_ssl->ssl_verify_peer_certificate = true; /* Set the pointer */ router->service->dbref->server->server_ssl = server_ssl; From 4280ec7ee82865d8e44891032c9822ca463227df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 14 Nov 2017 23:09:26 +0200 Subject: [PATCH 08/15] MXS-1019: Update SSL documentation Added ssl_verify_peer_certificate documentation for listeners and servers. --- .../Getting-Started/Configuration-Guide.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index 45ae89a52..2f008a328 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -1048,6 +1048,14 @@ value is specified, the default is 9. ssl_cert_verify_depth=5 ``` +#### `ssl_verify_peer_certificate` + +Peer certificate verification. This functionality is enabled by default. + +When this feature is enabled, the certificate sent by the peer is verified +against the configured Certificate Authority. If you are using self-signed +certificates, disable this feature. + **Example SSL enabled server configuration:** ``` @@ -1251,6 +1259,14 @@ value is specified, the default is 9. ssl_cert_verify_depth=5 ``` +#### `ssl_verify_peer_certificate` + +Peer certificate verification. This functionality is enabled by default. + +When this feature is enabled, the certificate sent by the peer is verified +against the configured Certificate Authority. If you are using self-signed +certificates, disable this feature. + **Example SSL enabled listener configuration:** ``` From 5d6f7e3fbd43809e8dce279d414ae17e17fb004e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 14 Nov 2017 23:10:07 +0200 Subject: [PATCH 09/15] Add 2.1.11 release notes Added 2.1.11 release notes. --- .../MaxScale-2.1.11-Release-Notes.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md diff --git a/Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md new file mode 100644 index 000000000..278c4de3f --- /dev/null +++ b/Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md @@ -0,0 +1,53 @@ +# MariaDB MaxScale 2.1.11 Release Notes + +Release 2.1.11 is a GA release. + +This document describes the changes in release 2.1.11, when compared +to release [2.1.10](MaxScale-2.1.10-Release-Notes.md). + +If you are upgrading from release 2.0, please also read the following +release notes: + +* [2.1.10](./MaxScale-2.1.10-Release-Notes.md) +* [2.1.9](./MaxScale-2.1.9-Release-Notes.md) +* [2.1.8](./MaxScale-2.1.8-Release-Notes.md) +* [2.1.7](./MaxScale-2.1.7-Release-Notes.md) +* [2.1.6](./MaxScale-2.1.6-Release-Notes.md) +* [2.1.5](./MaxScale-2.1.5-Release-Notes.md) +* [2.1.4](./MaxScale-2.1.4-Release-Notes.md) +* [2.1.3](./MaxScale-2.1.3-Release-Notes.md) +* [2.1.2](./MaxScale-2.1.2-Release-Notes.md) +* [2.1.1](./MaxScale-2.1.1-Release-Notes.md) +* [2.1.0](./MaxScale-2.1.0-Release-Notes.md) + +For any problems you encounter, please consider submitting a bug report at +[Jira](https://jira.mariadb.org). + +## Changed Features + +### Peer Certificate Verification + +The SSL peer certificate verification can now be disabled for servers and +listeners by adding `ssl_verify_peer_certificate=false` to the respective +definitions. + +## Bug fixes + +[Here is a list of bugs fixed in MaxScale 2.1.11.](https://jira.mariadb.org/issues/?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20status%20%3D%20Closed%20AND%20fixVersion%20%3D%202.1.11) + +* [MXS-1500](https://jira.mariadb.org/browse/MXS-1500) Invalid characters in real_type schema field + +## Packaging + +RPM and Debian packages are provided for the Linux distributions supported by +MariaDB Enterprise. + +Packages can be downloaded [here](https://mariadb.com/resources/downloads). + +## Source Code + +The source code of MaxScale is tagged at GitHub with a tag, which is identical +with the version of MaxScale. For instance, the tag of version X.Y.Z of MaxScale +is maxscale-X.Y.Z. + +The source code is available [here](https://github.com/mariadb-corporation/MaxScale). From fbdd6601e9481054e7e3b673c3a5aa7ec747aefa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 15 Nov 2017 10:10:08 +0200 Subject: [PATCH 10/15] Combine TLS/SSL documentation The TLS/SSL documentation is now defined in one place. The documentation states that both servers and listeners use the same parameters. --- .../Getting-Started/Configuration-Guide.md | 201 +++++------------- 1 file changed, 55 insertions(+), 146 deletions(-) diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index 2f008a328..f367176a6 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -13,9 +13,8 @@ plugin modules that tailor the behavior of the program. * [Global Settings](#global-settings) * [Service](#service) * [Server](#server) - * [Server and SSL](#server-and-ssl) * [Listener](#listener) - * [Listener and SSL](#listener-and-ssl) + * [TLS/SSL Encryption](#tlsssl-encryption) * [Router Modules](#routing-modules) * [Diagnostic Modules](#diagnostic-modules) * [Monitor Modules](#monitor-modules) @@ -977,108 +976,6 @@ closed. For more information about persistent connections, please read the [Administration Tutorial](../Tutorials/Administration-Tutorial.md). -### Server and SSL - -This section describes configuration parameters for servers that control the -SSL/TLS encryption method and the various certificate files involved in it when -applied to back end servers. To enable SSL between MaxScale and a back end -server, you must configure the `ssl` parameter in the relevant server section to -the value `required` and provide the three files for `ssl_cert`, `ssl_key` and -`ssl_ca_cert`. After this, MaxScale connections to this server will be encrypted -with SSL. Attempts to connect to the server without using SSL will cause -failures. Hence, the database server in question must have been configured to be -able to accept SSL connections. - -#### `ssl` - -This enables SSL connections to the server, when set to `required`. If that is -done, the three certificate files mentioned below must also be supplied. -MaxScale connections to this server will then be encrypted with SSL. If this is -not possible, client connection attempts that rely on the server will fail. - -#### `ssl_key` - -A string giving a file path that identifies an existing readable file. The file -must be the SSL client private key MaxScale should use with the server. This -will be the private key that is used as the client side private key during a -MaxScale-server SSL handshake. This is currently a required parameter for SSL -enabled servers. - -#### `ssl_cert` - -A string giving a file path that identifies an existing readable file. The file -must be the SSL client certificate MaxScale should use with the server. This -will be the public certificate that is used as the client side certificate -during a MaxScale-server SSL handshake. This is a required parameter for SSL -enabled servers. The certificate must be compatible with the key defined above. - -#### `ssl_ca_cert` - -A string giving a file path that identifies an existing readable file. The file -must be the SSL Certificate Authority (CA) certificate for the CA that signed -the client certificate referred to in the previous parameter. It will be used to -verify that the client certificate is valid. This is a required parameter for -SSL enabled listeners. - -#### `ssl_version` - -This parameter controls the level of encryption used. Accepted values are: - - * TLSv10 - * TLSv11 - * TLSv12 - * MAX - -The default is to use the highest level of encryption available. For OpenSSL 1.0 -and newer this is TLSv1.2. Older versions use TLSv1.0 as the default transport -layer encryption. - -**Note:** It is highly recommended to leave this parameter to the default value - of _MAX_. This will guarantee that the strongest available encryption is used. - -#### `ssl_cert_verify_depth` - -The maximum length of the certificate authority chain that will be accepted. -Legal values are positive integers. Note that if the client is to submit an SSL -certificate, the `ssl_cert_verify_depth` parameter must not be 0. If no -value is specified, the default is 9. - -``` -# Example -ssl_cert_verify_depth=5 -``` - -#### `ssl_verify_peer_certificate` - -Peer certificate verification. This functionality is enabled by default. - -When this feature is enabled, the certificate sent by the peer is verified -against the configured Certificate Authority. If you are using self-signed -certificates, disable this feature. - -**Example SSL enabled server configuration:** - -``` -[server1] -type=server -address=10.131.24.62 -port=3306 -protocol=MySQLBackend -#persistpoolmax=200 -persistmaxtime=3000 -ssl=required -ssl_version=TLSv10 -ssl_cert=/usr/local/mariadb/maxscale/ssl/crt.max-client.pem -ssl_key=/usr/local/mariadb/maxscale/ssl/key.max-client.pem -ssl_ca_cert=/usr/local/mariadb/maxscale/ssl/crt.ca.maxscale.pem - -``` - -This example configuration requires all connections to this server to be -encrypted with SSL. It also specifies that TLSv1.0 should be used as the -encryption method. The paths to the server certificate files and the Certificate -Authority file are also provided. - ### Listener The listener defines a port and protocol pair that is used to listen for @@ -1192,60 +1089,63 @@ This protocol module is currently still under development, it provides a means to create HTTP connections to MariaDB MaxScale for use by web browsers or RESTful API clients. -### Listener and SSL +### TLS/SSL encryption -This section describes configuration parameters for listeners that control the -SSL/TLS encryption method and the various certificate files involved in it. To -enable SSL from client to MaxScale, you must configure the `ssl` parameter to -the value `required` and provide the three files for `ssl_cert`, `ssl_key` and -`ssl_ca_cert`. After this, MySQL connections to this listener will be encrypted -with SSL. Attempts to connect to the listener with a non-SSL client will fail. -Note that the same service can have an SSL listener and a non-SSL listener if -you wish, although they must be on different ports. +This section describes configuration parameters for both servers and listeners +that control the TLS/SSL encryption method and the various certificate files +involved in it. + +To enable TLS/SSL for a listener or a server, you must set the `ssl` parameter +to `required` and provide the three files for `ssl_cert`, `ssl_key` and +`ssl_ca_cert`. + +After this, MaxScale connections between the server and/or the client will be +encrypted. Note that the database must be configured to use TLS/SSL connections +if backend connection encryption is used. When client-side encryption is +enabled, only encrypted connections to MaxScale can be created. #### `ssl` -This enables SSL connections to the listener, when set to `required`. If that is -done, the three certificate files mentioned below must also be supplied. Client -connections to this listener will then be encrypted with SSL. Non-SSL -connections will get an error when they try to connect to the listener. +This enables SSL connections when set to `required`. If enabled, the three +certificate files mentioned below must also be supplied. MaxScale connections +to will then be encrypted with TLS/SSL. #### `ssl_key` A string giving a file path that identifies an existing readable file. The file -must be the SSL private key the listener should use. This will be the private -key that is used as the server side private key during a client-server SSL -handshake. This is a required parameter for SSL enabled listeners. +must be the SSL client private key MaxScale should use. This is a required +parameter for SSL enabled configurations. #### `ssl_cert` A string giving a file path that identifies an existing readable file. The file -must be the SSL certificate the listener should use. This will be the public -certificate that is used as the server side certificate during a client-server -SSL handshake. This is a required parameter for SSL enabled listeners. The -certificate must be compatible with the key defined above. +must be the SSL client certificate MaxScale should use with the server. This is +a required parameter for SSL enabled configurations. The certificate must match +the key defined in `ssl_key`. #### `ssl_ca_cert` A string giving a file path that identifies an existing readable file. The file -must be the SSL Certificate Authority (CA) certificate for the CA that signed -the server certificate referred to in the previous parameter. It will be used to -verify that the server certificate is valid. This is a required parameter for -SSL enabled listeners. +must be the Certificate Authority (CA) certificate for the CA that signed the +certificate referred to in the previous parameter. It will be used to verify +that the certificate is valid. This is a required parameter for SSL enabled +configurations. #### `ssl_version` This parameter controls the level of encryption used. Accepted values are: + * TLSv10 * TLSv11 * TLSv12 * MAX -If possible, use TLSv12 for best security. Recent Linux systems will include a -version of OpenSSL that supports TLS version 1.2. Only if you are using -MaxScale on a system that does not have OpenSSL with support for this should -earlier versions be used. It is unlikely that TLS 1.1 will be available unless -TLS 1.2 is also available. MAX will use the best available version. +The default is to use the highest level of encryption available. For OpenSSL 1.0 +and newer this is TLSv1.2. Older versions use TLSv1.0 as the default transport +layer encryption. + +**Note:** It is highly recommended to leave this parameter to the default value + of _MAX_. This will guarantee that the strongest available encryption is used. #### `ssl_cert_verify_depth` @@ -1254,11 +1154,6 @@ Legal values are positive integers. Note that if the client is to submit an SSL certificate, the `ssl_cert_verify_depth` parameter must not be 0. If no value is specified, the default is 9. -``` -# Example -ssl_cert_verify_depth=5 -``` - #### `ssl_verify_peer_certificate` Peer certificate verification. This functionality is enabled by default. @@ -1267,6 +1162,25 @@ When this feature is enabled, the certificate sent by the peer is verified against the configured Certificate Authority. If you are using self-signed certificates, disable this feature. +**Example SSL enabled server configuration:** + +``` +[server1] +type=server +address=10.131.24.62 +port=3306 +protocol=MySQLBackend +ssl=required +ssl_cert=/usr/local/mariadb/maxscale/ssl/crt.max-client.pem +ssl_key=/usr/local/mariadb/maxscale/ssl/key.max-client.pem +ssl_ca_cert=/usr/local/mariadb/maxscale/ssl/crt.ca.maxscale.pem + +``` + +This example configuration requires all connections to this server to be +encrypted with SSL. The paths to the certificate files and the Certificate +Authority file are also provided. + **Example SSL enabled listener configuration:** ``` @@ -1274,21 +1188,16 @@ certificates, disable this feature. type=listener service=RW Split Router protocol=MySQLClient -address=10.131.218.83 port=3306 -authenticator=MySQL ssl=required ssl_cert=/usr/local/mariadb/maxscale/ssl/crt.maxscale.pem ssl_key=/usr/local/mariadb/maxscale/ssl/key.csr.maxscale.pem ssl_ca_cert=/usr/local/mariadb/maxscale/ssl/crt.ca.maxscale.pem -ssl_version=TLSv12 -ssl_cert_verify_depth=9 ``` -This example configuration requires all connections to be encrypted with SSL. It -also specifies that TLSv1.2 should be used as the encryption method. The paths -to the server certificate files and the Certificate Authority file are also -provided. +This example configuration requires all connections to be encrypted with +SSL. The paths to the certificate files and the Certificate Authority file are +also provided. ## Routing Modules From 060a96d7f3e55158c6c05a61f7afbe1c599e6459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 15 Nov 2017 14:43:35 +0200 Subject: [PATCH 11/15] Send error on client DCB hangup events Sending an error to the client allows the connector to show more information to the user when the DCB is closed due to a reason internal to MaxScale. The error message states that the connection was killed by MaxScale to distinct it from the error sent by the server. The error number and SQL state are still the same as both errors should be treated the same way. --- server/modules/protocol/MySQL/MySQLClient/mysql_client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/modules/protocol/MySQL/MySQLClient/mysql_client.c b/server/modules/protocol/MySQL/MySQLClient/mysql_client.c index 56f0acdc6..0a4a6747b 100644 --- a/server/modules/protocol/MySQL/MySQLClient/mysql_client.c +++ b/server/modules/protocol/MySQL/MySQLClient/mysql_client.c @@ -1424,7 +1424,7 @@ gw_client_close(DCB *dcb) /** * Handle a hangup event on the client side descriptor. * - * We simply close the DCB, this will propogate the closure to any + * We simply close the DCB, this will propagate the closure to any * backend descriptors and perform the session cleanup. * * @param dcb The DCB of the connection @@ -1446,6 +1446,7 @@ static int gw_client_hangup_event(DCB *dcb) goto retblock; } + modutil_send_mysql_err_packet(dcb, 0, 0, 1927, "70100", "Connection killed by MaxScale"); dcb_close(dcb); retblock: From 7cc4018c1584fe1ebab086235db45d73a22ac00d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 15 Nov 2017 15:00:40 +0200 Subject: [PATCH 12/15] Use SQLSTATE 08S01 for hangup errors This will tell the connectors that the connection cannot be used. --- server/modules/protocol/MySQL/MySQLClient/mysql_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/protocol/MySQL/MySQLClient/mysql_client.c b/server/modules/protocol/MySQL/MySQLClient/mysql_client.c index 0a4a6747b..a646263c1 100644 --- a/server/modules/protocol/MySQL/MySQLClient/mysql_client.c +++ b/server/modules/protocol/MySQL/MySQLClient/mysql_client.c @@ -1446,7 +1446,7 @@ static int gw_client_hangup_event(DCB *dcb) goto retblock; } - modutil_send_mysql_err_packet(dcb, 0, 0, 1927, "70100", "Connection killed by MaxScale"); + modutil_send_mysql_err_packet(dcb, 0, 0, 1927, "08S01", "Connection killed by MaxScale"); dcb_close(dcb); retblock: From 8c72b9d233718a87cb5246615f999e8605cf795f Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 20 Nov 2017 09:50:21 +0200 Subject: [PATCH 13/15] Update release docs for 2.1.11 --- Documentation/Changelog.md | 1 + Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md | 1 + Documentation/Upgrading/Upgrading-To-MaxScale-2.1.md | 1 + 3 files changed, 3 insertions(+) diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index faa61c742..a73a4c261 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -21,6 +21,7 @@ * MaxScale now supports IPv6 For more details, please refer to: +* [MariaDB MaxScale 2.1.11 Release Notes](Release-Notes/MaxScale-2.1.11-Release-Notes.md) * [MariaDB MaxScale 2.1.10 Release Notes](Release-Notes/MaxScale-2.1.10-Release-Notes.md) * [MariaDB MaxScale 2.1.9 Release Notes](Release-Notes/MaxScale-2.1.9-Release-Notes.md) * [MariaDB MaxScale 2.1.8 Release Notes](Release-Notes/MaxScale-2.1.8-Release-Notes.md) diff --git a/Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md index 278c4de3f..c818ef9a3 100644 --- a/Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md @@ -35,6 +35,7 @@ definitions. [Here is a list of bugs fixed in MaxScale 2.1.11.](https://jira.mariadb.org/issues/?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20status%20%3D%20Closed%20AND%20fixVersion%20%3D%202.1.11) +* [MXS-1518](https://jira.mariadb.org/browse/MXS-1518) Wrong parameter name for ssl_cert_verify_depth * [MXS-1500](https://jira.mariadb.org/browse/MXS-1500) Invalid characters in real_type schema field ## Packaging diff --git a/Documentation/Upgrading/Upgrading-To-MaxScale-2.1.md b/Documentation/Upgrading/Upgrading-To-MaxScale-2.1.md index e311e047e..91ae243db 100644 --- a/Documentation/Upgrading/Upgrading-To-MaxScale-2.1.md +++ b/Documentation/Upgrading/Upgrading-To-MaxScale-2.1.md @@ -7,6 +7,7 @@ For more information about MariaDB MaxScale 2.1, please refer to the [ChangeLog](../Changelog.md). For a complete list of changes in MaxScale 2.1, refer to the +* [MaxScale 2.1.11 Release Notes](../Release-Notes/MaxScale-2.1.11-Release-Notes.md) * [MaxScale 2.1.10 Release Notes](../Release-Notes/MaxScale-2.1.10-Release-Notes.md) * [MaxScale 2.1.9 Release Notes](../Release-Notes/MaxScale-2.1.9-Release-Notes.md). * [MaxScale 2.1.8 Release Notes](../Release-Notes/MaxScale-2.1.8-Release-Notes.md). From 30e154bc6f4781efec5e5f56420913ec33103860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 20 Nov 2017 12:18:29 +0200 Subject: [PATCH 14/15] Add missing python schema generator documentation The documentation for the Python 3 version of the schema generator was missing. --- Documentation/Routers/Avrorouter.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Documentation/Routers/Avrorouter.md b/Documentation/Routers/Avrorouter.md index 686bcfd4a..f9c9e0fb2 100644 --- a/Documentation/Routers/Avrorouter.md +++ b/Documentation/Routers/Avrorouter.md @@ -203,6 +203,25 @@ and a short usage description of the client program. # Avro Schema Generator +If the CREATE TABLE statements for the tables aren't present in the current +binary logs, the schema files must be generated with a schema file +generator. There are currently two methods to generate the .avsc schema files. + +## Python Schema Generator + +``` +usage: cdc_schema.py [--help] [-h HOST] [-P PORT] [-u USER] [-p PASSWORD] DATABASE +``` + +The _cdc_schema.py_ executable is installed as a part of MaxScale. This is a +Python 3 script that generates Avro schema files from an existing database. + +The script will generate the .avsc schema files into the current directory. Run +the script for all required databases copy the generated .avsc files to the +directory where the avrorouter stores the .avro files (the value of `avrodir`). + +## Go Schema Generator + The _cdc_schema.go_ example Go program is provided with MaxScale. This file can be used to create Avro schemas for the avrorouter by connecting to a database and reading the table definitions. You can find the file in MaxScale's From dd699f27398e9fe733bdea0445680496bfd4bade Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 21 Nov 2017 14:09:30 +0200 Subject: [PATCH 15/15] Update release date. --- Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md index c818ef9a3..837bfa22e 100644 --- a/Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.1.11-Release-Notes.md @@ -1,4 +1,4 @@ -# MariaDB MaxScale 2.1.11 Release Notes +# MariaDB MaxScale 2.1.11 Release Notes -- 2017-11-21 Release 2.1.11 is a GA release.