Merge branch '2.1' into 2.2

This commit is contained in:
Markus Mäkelä
2017-11-21 16:49:21 +02:00
18 changed files with 345 additions and 262 deletions

View File

@ -49,6 +49,7 @@ For more details, please refer to:
* MaxScale now supports IPv6 * MaxScale now supports IPv6
For more details, please refer to: 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.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.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) * [MariaDB MaxScale 2.1.8 Release Notes](Release-Notes/MaxScale-2.1.8-Release-Notes.md)

View File

@ -15,9 +15,8 @@ plugin modules that tailor the behavior of the program.
* [Global Settings](#global-settings) * [Global Settings](#global-settings)
* [Service](#service) * [Service](#service)
* [Server](#server) * [Server](#server)
* [Server and SSL](#server-and-ssl)
* [Listener](#listener) * [Listener](#listener)
* [Listener and SSL](#listener-and-ssl) * [TLS/SSL Encryption](#tlsssl-encryption)
* [Router Modules](#routing-modules) * [Router Modules](#routing-modules)
* [Diagnostic Modules](#diagnostic-modules) * [Diagnostic Modules](#diagnostic-modules)
* [Monitor Modules](#monitor-modules) * [Monitor Modules](#monitor-modules)
@ -198,13 +197,14 @@ auth_write_timeout=10
#### `query_retries` #### `query_retries`
The number of times an interrupted query will be retried. This feature was added The number of times an interrupted internal query will be retried. This feature
in MaxScale 2.1.10 and is disabled by default. was added in MaxScale 2.1.10 and is disabled by default.
An interrupted query is any query that is interrupted by a network An interrupted query is any query that is interrupted by a network
error. Connection timeouts are included in network errors and thus is it 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 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` #### `query_retry_timeout`
@ -1183,100 +1183,6 @@ Option string given to the authenticator module. The value of this parameter
should be a comma-separated list of key-value pairs. See authenticator specific should be a comma-separated list of key-value pairs. See authenticator specific
documentation for more details. documentation for more details.
### 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_verification_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
value is specified, the default is 9.
```
# Example
ssl_cert_verification_depth=5
```
**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 ### Listener
The listener defines a port and protocol pair that is used to listen for The listener defines a port and protocol pair that is used to listen for
@ -1390,73 +1296,98 @@ 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 to create HTTP connections to MariaDB MaxScale for use by web browsers or
RESTful API clients. RESTful API clients.
### Listener and SSL ### TLS/SSL encryption
This section describes configuration parameters for listeners that control the This section describes configuration parameters for both servers and listeners
SSL/TLS encryption method and the various certificate files involved in it. To that control the TLS/SSL encryption method and the various certificate files
enable SSL from client to MaxScale, you must configure the `ssl` parameter to involved in it.
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 To enable TLS/SSL for a listener or a server, you must set the `ssl` parameter
with SSL. Attempts to connect to the listener with a non-SSL client will fail. to `required` and provide the three files for `ssl_cert`, `ssl_key` and
Note that the same service can have an SSL listener and a non-SSL listener if `ssl_ca_cert`.
you wish, although they must be on different ports.
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` #### `ssl`
This enables SSL connections to the listener, when set to `required`. If that is This enables SSL connections when set to `required`. If enabled, the three
done, the three certificate files mentioned below must also be supplied. Client certificate files mentioned below must also be supplied. MaxScale connections
connections to this listener will then be encrypted with SSL. Non-SSL to will then be encrypted with TLS/SSL.
connections will get an error when they try to connect to the listener.
#### `ssl_key` #### `ssl_key`
A string giving a file path that identifies an existing readable file. The file 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 must be the SSL client private key MaxScale should use. This is a required
key that is used as the server side private key during a client-server SSL parameter for SSL enabled configurations.
handshake. This is a required parameter for SSL enabled listeners.
#### `ssl_cert` #### `ssl_cert`
A string giving a file path that identifies an existing readable file. The file 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 must be the SSL client certificate MaxScale should use with the server. This is
certificate that is used as the server side certificate during a client-server a required parameter for SSL enabled configurations. The certificate must match
SSL handshake. This is a required parameter for SSL enabled listeners. The the key defined in `ssl_key`.
certificate must be compatible with the key defined above.
#### `ssl_ca_cert` #### `ssl_ca_cert`
A string giving a file path that identifies an existing readable file. The file 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 must be the Certificate Authority (CA) certificate for the CA that signed the
the server certificate referred to in the previous parameter. It will be used to certificate referred to in the previous parameter. It will be used to verify
verify that the server certificate is valid. This is a required parameter for that the certificate is valid. This is a required parameter for SSL enabled
SSL enabled listeners. configurations.
#### `ssl_version` #### `ssl_version`
This parameter controls the level of encryption used. Accepted values are: This parameter controls the level of encryption used. Accepted values are:
* TLSv10 * TLSv10
* TLSv11 * TLSv11
* TLSv12 * TLSv12
* MAX * MAX
If possible, use TLSv12 for best security. Recent Linux systems will include a The default is to use the highest level of encryption available. For OpenSSL 1.0
version of OpenSSL that supports TLS version 1.2. Only if you are using and newer this is TLSv1.2. Older versions use TLSv1.0 as the default transport
MaxScale on a system that does not have OpenSSL with support for this should layer encryption.
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` **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. 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 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. value is specified, the default is 9.
#### `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:**
``` ```
# Example [server1]
ssl_cert_verification_depth=5 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:** **Example SSL enabled listener configuration:**
``` ```
@ -1464,21 +1395,16 @@ ssl_cert_verification_depth=5
type=listener type=listener
service=RW Split Router service=RW Split Router
protocol=MySQLClient protocol=MySQLClient
address=10.131.218.83
port=3306 port=3306
authenticator=MySQL
ssl=required ssl=required
ssl_cert=/usr/local/mariadb/maxscale/ssl/crt.maxscale.pem ssl_cert=/usr/local/mariadb/maxscale/ssl/crt.maxscale.pem
ssl_key=/usr/local/mariadb/maxscale/ssl/key.csr.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_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 This example configuration requires all connections to be encrypted with
also specifies that TLSv1.2 should be used as the encryption method. The paths SSL. The paths to the certificate files and the Certificate Authority file are
to the server certificate files and the Certificate Authority file are also also provided.
provided.
## Routing Modules ## Routing Modules

View File

@ -0,0 +1,54 @@
# MariaDB MaxScale 2.1.11 Release Notes -- 2017-11-21
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-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
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).

View File

@ -221,6 +221,25 @@ and a short usage description of the client program.
# Avro Schema Generator # 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 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 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 database and reading the table definitions. You can find the file in MaxScale's

View File

@ -7,6 +7,7 @@ For more information about MariaDB MaxScale 2.1, please refer to the
[ChangeLog](../Changelog.md). [ChangeLog](../Changelog.md).
For a complete list of changes in MaxScale 2.1, refer to the 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.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.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). * [MaxScale 2.1.8 Release Notes](../Release-Notes/MaxScale-2.1.8-Release-Notes.md).

View File

@ -5,7 +5,7 @@
set(MAXSCALE_VERSION_MAJOR "2" CACHE STRING "Major version") set(MAXSCALE_VERSION_MAJOR "2" CACHE STRING "Major version")
set(MAXSCALE_VERSION_MINOR "1" CACHE STRING "Minor 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 # This should only be incremented if a package is rebuilt
set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number") set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number")

View File

@ -155,6 +155,7 @@ extern const char CN_SSL[];
extern const char CN_SSL_CA_CERT[]; extern const char CN_SSL_CA_CERT[];
extern const char CN_SSL_CERT[]; extern const char CN_SSL_CERT[];
extern const char CN_SSL_CERT_VERIFY_DEPTH[]; extern const char CN_SSL_CERT_VERIFY_DEPTH[];
extern const char CN_SSL_VERIFY_PEER_CERTIFICATE[];
extern const char CN_SSL_KEY[]; extern const char CN_SSL_KEY[];
extern const char CN_SSL_VERSION[]; extern const char CN_SSL_VERSION[];
extern const char CN_STRIP_DB_ESC[]; extern const char CN_STRIP_DB_ESC[];

View File

@ -374,6 +374,11 @@ static inline uint32_t MYSQL_GET_PAYLOAD_LEN(const uint8_t* header)
return gw_mysql_get_byte3(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_ERRCODE(payload) (gw_mysql_get_byte2(&payload[5]))
#define MYSQL_GET_STMTOK_NPARAM(payload) (gw_mysql_get_byte2(&payload[9])) #define MYSQL_GET_STMTOK_NPARAM(payload) (gw_mysql_get_byte2(&payload[9]))
#define MYSQL_GET_STMTOK_NATTR(payload) (gw_mysql_get_byte2(&payload[11])) #define MYSQL_GET_STMTOK_NATTR(payload) (gw_mysql_get_byte2(&payload[11]))

View File

@ -66,6 +66,7 @@ typedef struct ssl_listener
char *ssl_key; /*< SSL private key */ char *ssl_key; /*< SSL private key */
char *ssl_ca_cert; /*< SSL CA certificate */ char *ssl_ca_cert; /*< SSL CA certificate */
bool ssl_init_done; /*< If SSL has already been initialized for this service */ 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 struct ssl_listener
*next; /*< Next SSL configuration, currently used to store obsolete configurations */ *next; /*< Next SSL configuration, currently used to store obsolete configurations */
} SSL_LISTENER; } SSL_LISTENER;
@ -90,4 +91,7 @@ ssl_method_type_t string_to_ssl_method_type(const char* str);
*/ */
int ssl_authenticate_check_status(struct dcb *dcb); int ssl_authenticate_check_status(struct dcb *dcb);
// TODO: Move this to an internal ssl.h header
void write_ssl_config(int fd, SSL_LISTENER* ssl);
MXS_END_DECLS MXS_END_DECLS

View File

@ -512,6 +512,10 @@ add_test_executable(mxs1468.cpp mxs1468 mxs1468 LABELS REPL_BACKEND)
# https://jira.mariadb.org/browse/MXS-1493 # https://jira.mariadb.org/browse/MXS-1493
add_test_executable(verify_master_failure.cpp verify_master_failure verify_master_failure LABELS REPL_BACKEND) add_test_executable(verify_master_failure.cpp verify_master_failure verify_master_failure 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 # 'namedserverfilter' test
add_test_executable(namedserverfilter.cpp namedserverfilter namedserverfilter LABELS namedserverfilter LIGHT REPL_BACKEND) add_test_executable(namedserverfilter.cpp namedserverfilter namedserverfilter LABELS namedserverfilter LIGHT REPL_BACKEND)

View File

@ -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

View File

@ -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;
}

View File

@ -134,6 +134,7 @@ const char CN_SSL[] = "ssl";
const char CN_SSL_CA_CERT[] = "ssl_ca_cert"; const char CN_SSL_CA_CERT[] = "ssl_ca_cert";
const char CN_SSL_CERT[] = "ssl_cert"; const char CN_SSL_CERT[] = "ssl_cert";
const char CN_SSL_CERT_VERIFY_DEPTH[] = "ssl_cert_verify_depth"; const char CN_SSL_CERT_VERIFY_DEPTH[] = "ssl_cert_verify_depth";
const char CN_SSL_VERIFY_PEER_CERTIFICATE[] = "ssl_verify_peer_certificate";
const char CN_SSL_KEY[] = "ssl_key"; const char CN_SSL_KEY[] = "ssl_key";
const char CN_SSL_VERSION[] = "ssl_version"; const char CN_SSL_VERSION[] = "ssl_version";
const char CN_STRIP_DB_ESC[] = "strip_db_esc"; const char CN_STRIP_DB_ESC[] = "strip_db_esc";
@ -231,6 +232,7 @@ const char *config_listener_params[] =
CN_SSL_KEY, CN_SSL_KEY,
CN_SSL_VERSION, CN_SSL_VERSION,
CN_SSL_CERT_VERIFY_DEPTH, CN_SSL_CERT_VERIFY_DEPTH,
CN_SSL_VERIFY_PEER_CERTIFICATE,
NULL NULL
}; };
@ -279,6 +281,7 @@ const char *server_params[] =
CN_SSL_KEY, CN_SSL_KEY,
CN_SSL_VERSION, CN_SSL_VERSION,
CN_SSL_CERT_VERIFY_DEPTH, CN_SSL_CERT_VERIFY_DEPTH,
CN_SSL_VERIFY_PEER_CERTIFICATE,
CN_PROXY_PROTOCOL, CN_PROXY_PROTOCOL,
NULL NULL
}; };
@ -1688,6 +1691,8 @@ SSL_LISTENER* make_ssl_structure (CONFIG_CONTEXT *obj, bool require_cert, int *e
ssl_version = config_get_value(obj->parameters, CN_SSL_VERSION); ssl_version = config_get_value(obj->parameters, CN_SSL_VERSION);
ssl_cert_verify_depth = config_get_value(obj->parameters, CN_SSL_CERT_VERIFY_DEPTH); ssl_cert_verify_depth = config_get_value(obj->parameters, CN_SSL_CERT_VERIFY_DEPTH);
new_ssl->ssl_init_done = false; 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) if (ssl_version)
{ {
@ -1710,12 +1715,20 @@ SSL_LISTENER* make_ssl_structure (CONFIG_CONTEXT *obj, bool require_cert, int *e
local_errors++; local_errors++;
} }
} }
else
if (ssl_verify_peer_certificate)
{ {
/** int rv = config_truth_value(ssl_verify_peer_certificate);
* Default of 9 as per Linux man page if (rv == -1)
*/ {
new_ssl->ssl_cert_verify_depth = 9; 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); listener_set_certificates(new_ssl, ssl_cert, ssl_key, ssl_ca_cert);
@ -3493,6 +3506,7 @@ bool config_is_ssl_parameter(const char *key)
CN_SSL_KEY, CN_SSL_KEY,
CN_SSL_VERSION, CN_SSL_VERSION,
CN_SSL_CERT_VERIFY_DEPTH, CN_SSL_CERT_VERIFY_DEPTH,
CN_SSL_VERIFY_PEER_CERTIFICATE,
NULL NULL
}; };

View File

@ -366,7 +366,7 @@ listener_init_SSL(SSL_LISTENER *ssl_listener)
} }
/* Set to require peer (client) certificate verification */ /* 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); SSL_CTX_set_verify(ssl_listener->ctx, SSL_VERIFY_PEER, NULL);
} }
@ -458,57 +458,7 @@ static bool create_listener_config(const SERV_LISTENER *listener, const char *fi
if (listener->ssl) if (listener->ssl)
{ {
dprintf(file, "ssl=required\n"); write_ssl_config(file, listener->ssl);
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);
}
} }
close(file); close(file);

View File

@ -578,6 +578,7 @@ dprintServer(DCB *dcb, const SERVER *server)
dcb_printf(dcb, "\tSSL method type: %s\n", dcb_printf(dcb, "\tSSL method type: %s\n",
ssl_method_type_to_string(l->ssl_method_type)); 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 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", dcb_printf(dcb, "\tSSL certificate: %s\n",
l->ssl_cert ? l->ssl_cert : "null"); l->ssl_cert ? l->ssl_cert : "null");
dcb_printf(dcb, "\tSSL key: %s\n", dcb_printf(dcb, "\tSSL key: %s\n",
@ -1203,57 +1204,7 @@ static bool create_server_config(const SERVER *server, const char *filename)
if (server->server_ssl) if (server->server_ssl)
{ {
dprintf(file, "%s=required\n", CN_SSL); write_ssl_config(file, server->server_ssl);
if (server->server_ssl->ssl_cert)
{
dprintf(file, "%s=%s\n", CN_SSL_CERT, server->server_ssl->ssl_cert);
}
if (server->server_ssl->ssl_key)
{
dprintf(file, "%s=%s\n", CN_SSL_KEY, server->server_ssl->ssl_key);
}
if (server->server_ssl->ssl_ca_cert)
{
dprintf(file, "%s=%s\n", CN_SSL_CA_CERT, server->server_ssl->ssl_ca_cert);
}
if (server->server_ssl->ssl_cert_verify_depth)
{
dprintf(file, "%s=%d\n", CN_SSL_CERT_VERIFY_DEPTH, 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, "%s=%s\n", CN_SSL_VERSION, version);
}
} }
close(file); close(file);

View File

@ -243,6 +243,39 @@ ssl_method_type_t string_to_ssl_method_type(const char* str)
return SERVICE_SSL_UNKNOWN; return SERVICE_SSL_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 = ssl_method_type_to_string(ssl->ssl_method_type);
dprintf(fd, "ssl_version=%s\n", version);
}
}
int ssl_authenticate_check_status(DCB* dcb) int ssl_authenticate_check_status(DCB* dcb)
{ {
int rval = MXS_AUTH_FAILED; int rval = MXS_AUTH_FAILED;
@ -273,4 +306,4 @@ int ssl_authenticate_check_status(DCB* dcb)
rval = MXS_AUTH_SSL_COMPLETE; rval = MXS_AUTH_SSL_COMPLETE;
} }
return rval; return rval;
} }

View File

@ -490,20 +490,23 @@ int gw_read_client_event(DCB* dcb)
* *
*/ */
case MXS_AUTH_STATE_MESSAGE_READ: case MXS_AUTH_STATE_MESSAGE_READ:
/* After this call read_buffer will point to freed data */ if (nbytes_read < 3 ||
dcb_readq_set(dcb, read_buffer); (0 == max_bytes && nbytes_read < MYSQL_GET_PACKET_LEN(read_buffer)) ||
if (nbytes_read < 3 || (0 == max_bytes && nbytes_read < (0 != max_bytes && nbytes_read < max_bytes))
(int)(MYSQL_GET_PAYLOAD_LEN((uint8_t *) GWBUF_DATA(read_buffer)) + 4)) ||
(0 != max_bytes && nbytes_read < max_bytes) ||
(read_buffer = modutil_get_next_MySQL_packet(&dcb->readq)) == NULL)
{ {
return 0; dcb_readq_append(dcb, read_buffer);
} }
else
{
if (nbytes_read > MYSQL_GET_PACKET_LEN(read_buffer))
{
// We read more data than was needed
dcb_readq_append(dcb, read_buffer);
read_buffer = modutil_get_next_MySQL_packet(&dcb->readq);
}
ss_dassert(read_buffer); return_code = gw_read_do_authentication(dcb, read_buffer, nbytes_read);
nbytes_read = gwbuf_length(read_buffer); }
return_code = gw_read_do_authentication(dcb, read_buffer, nbytes_read);
break; break;
/** /**
@ -1399,7 +1402,7 @@ static int gw_client_close(DCB *dcb)
/** /**
* Handle a hangup event on the client side descriptor. * 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. * backend descriptors and perform the session cleanup.
* *
* @param dcb The DCB of the connection * @param dcb The DCB of the connection
@ -1421,6 +1424,7 @@ static int gw_client_hangup_event(DCB *dcb)
goto retblock; goto retblock;
} }
modutil_send_mysql_err_packet(dcb, 0, 0, 1927, "08S01", "Connection killed by MaxScale");
dcb_close(dcb); dcb_close(dcb);
retblock: retblock:

View File

@ -831,6 +831,7 @@ createInstance(SERVICE *service, char **options)
ssl_cfg->ssl_init_done = false; ssl_cfg->ssl_init_done = false;
ssl_cfg->ssl_method_type = SERVICE_SSL_TLS_MAX; ssl_cfg->ssl_method_type = SERVICE_SSL_TLS_MAX;
ssl_cfg->ssl_cert_verify_depth = 9; ssl_cfg->ssl_cert_verify_depth = 9;
ssl_cfg->ssl_verify_peer_certificate = true;
/** Set SSL pointer in in server struct */ /** Set SSL pointer in in server struct */
server->server_ssl = ssl_cfg; server->server_ssl = ssl_cfg;