MXS-1220: Add HTTPS support
The REST API now supports encryption. The user needs to configure certificates for the REST API before encryption is used.
This commit is contained in:
@ -172,35 +172,6 @@ write or modify the data in the backend server. The default is 2 seconds.
|
|||||||
auth_write_timeout=10
|
auth_write_timeout=10
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `admin_host`
|
|
||||||
|
|
||||||
The network interface where the HTTP admin interface listens on. The default
|
|
||||||
value is the IPv6 address `::` which listens on all available network
|
|
||||||
interfaces.
|
|
||||||
|
|
||||||
#### `admin_port`
|
|
||||||
|
|
||||||
The port where the HTTP admin interface listens on. The default value is port
|
|
||||||
8080.
|
|
||||||
|
|
||||||
#### `admin_auth`
|
|
||||||
|
|
||||||
Enable HTTP admin interface authentication using HTTP Basic Access
|
|
||||||
authentication. This is not a secure method of authentication but it does add a
|
|
||||||
small layer of security. This option id disabled by default.
|
|
||||||
|
|
||||||
#### `admin_user`
|
|
||||||
|
|
||||||
The HTTP admin interface username. This is the username which is used when
|
|
||||||
_admin_auth_ is enabled. The default user for the HTTP admin interface is
|
|
||||||
`admin`.
|
|
||||||
|
|
||||||
#### `admin_password`
|
|
||||||
|
|
||||||
The HTTP admin interface password. This is the which which is used when
|
|
||||||
_admin_auth_ is enabled. The default password for the HTTP admin interface is
|
|
||||||
`mariadb`.
|
|
||||||
|
|
||||||
#### `ms_timestamp`
|
#### `ms_timestamp`
|
||||||
|
|
||||||
Enable or disable the high precision timestamps in logfiles. Enabling this adds
|
Enable or disable the high precision timestamps in logfiles. Enabling this adds
|
||||||
@ -548,6 +519,60 @@ This will log all statements that cannot be parsed completely. This may be
|
|||||||
useful if you suspect that MariaDB MaxScale routes statements to the wrong
|
useful if you suspect that MariaDB MaxScale routes statements to the wrong
|
||||||
server (e.g. to a slave instead of to a master).
|
server (e.g. to a slave instead of to a master).
|
||||||
|
|
||||||
|
### REST API Configuration
|
||||||
|
|
||||||
|
The MaxScale REST API is an HTTP interface that provides JSON format data
|
||||||
|
intended to be consumed by monitoring appllications and visualization tools.
|
||||||
|
|
||||||
|
The following options must be defined under the `[maxscale]` section in the
|
||||||
|
configuration file.
|
||||||
|
|
||||||
|
#### `admin_host`
|
||||||
|
|
||||||
|
The network interface where the HTTP admin interface listens on. The default
|
||||||
|
value is the IPv6 address `::` which listens on all available network
|
||||||
|
interfaces.
|
||||||
|
|
||||||
|
#### `admin_port`
|
||||||
|
|
||||||
|
The port where the HTTP admin interface listens on. The default value is port
|
||||||
|
8080.
|
||||||
|
|
||||||
|
#### `admin_auth`
|
||||||
|
|
||||||
|
Enable HTTP admin interface authentication using HTTP Basic Access
|
||||||
|
authentication. This is not a secure method of authentication but it does add a
|
||||||
|
small layer of security. This option id disabled by default.
|
||||||
|
|
||||||
|
#### `admin_user`
|
||||||
|
|
||||||
|
The HTTP admin interface username. This is the username which is used when
|
||||||
|
_admin_auth_ is enabled. The default user for the HTTP admin interface is
|
||||||
|
`admin`.
|
||||||
|
|
||||||
|
#### `admin_password`
|
||||||
|
|
||||||
|
The HTTP admin interface password. This is the which which is used when
|
||||||
|
_admin_auth_ is enabled. The default password for the HTTP admin interface is
|
||||||
|
`mariadb`.
|
||||||
|
|
||||||
|
#### `admin_ssl_key`
|
||||||
|
|
||||||
|
The path to the TLS private key in PEM format for the admin interface.
|
||||||
|
|
||||||
|
If the `admin_ssl_key`, `admin_ssl_cert` and `admin_ssl_ca_cert` options are all
|
||||||
|
defined, the admin interface will use encrypted HTTPS instead of plain HTTP.
|
||||||
|
|
||||||
|
#### `admin_ssl_cert`
|
||||||
|
|
||||||
|
The path to the TLS public certificate in PEM format. See `admin_ssl_key`
|
||||||
|
documentation for more details.
|
||||||
|
|
||||||
|
#### `admin_ssl_ca_cert`
|
||||||
|
|
||||||
|
The path to the TLS CA certificate in PEM format. See `admin_ssl_key`
|
||||||
|
documentation for more details.
|
||||||
|
|
||||||
### Service
|
### Service
|
||||||
|
|
||||||
A service represents the database service that MariaDB MaxScale offers to the
|
A service represents the database service that MariaDB MaxScale offers to the
|
||||||
|
@ -48,6 +48,9 @@ extern const char CN_ADMIN_HOST[];
|
|||||||
extern const char CN_ADMIN_PASSWORD[];
|
extern const char CN_ADMIN_PASSWORD[];
|
||||||
extern const char CN_ADMIN_PORT[];
|
extern const char CN_ADMIN_PORT[];
|
||||||
extern const char CN_ADMIN_USER[];
|
extern const char CN_ADMIN_USER[];
|
||||||
|
extern const char CN_ADMIN_SSL_KEY[];
|
||||||
|
extern const char CN_ADMIN_SSL_CERT[];
|
||||||
|
extern const char CN_ADMIN_SSL_CA_CERT[];
|
||||||
extern const char CN_AUTHENTICATOR[];
|
extern const char CN_AUTHENTICATOR[];
|
||||||
extern const char CN_AUTHENTICATOR_OPTIONS[];
|
extern const char CN_AUTHENTICATOR_OPTIONS[];
|
||||||
extern const char CN_AUTH_ALL_SERVERS[];
|
extern const char CN_AUTH_ALL_SERVERS[];
|
||||||
@ -162,6 +165,9 @@ typedef struct
|
|||||||
char admin_host[MAX_ADMIN_HOST_LEN]; /**< Admin interface host */
|
char admin_host[MAX_ADMIN_HOST_LEN]; /**< Admin interface host */
|
||||||
uint16_t admin_port; /**< Admin interface port */
|
uint16_t admin_port; /**< Admin interface port */
|
||||||
bool admin_auth; /**< Admin interface authentication */
|
bool admin_auth; /**< Admin interface authentication */
|
||||||
|
char admin_ssl_key[PATH_MAX]; /**< Admin SSL key */
|
||||||
|
char admin_ssl_cert[PATH_MAX]; /**< Admin SSL cert */
|
||||||
|
char admin_ssl_ca_cert[PATH_MAX]; /**< Admin SSL CA cert */
|
||||||
} MXS_CONFIG;
|
} MXS_CONFIG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
#include <fstream>
|
||||||
#include <microhttpd.h>
|
#include <microhttpd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
@ -29,14 +31,23 @@
|
|||||||
#include <maxscale/utils.h>
|
#include <maxscale/utils.h>
|
||||||
#include <maxscale/config.h>
|
#include <maxscale/config.h>
|
||||||
#include <maxscale/hk_heartbeat.h>
|
#include <maxscale/hk_heartbeat.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "maxscale/resource.hh"
|
#include "maxscale/resource.hh"
|
||||||
#include "maxscale/http.hh"
|
#include "maxscale/http.hh"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
using std::ifstream;
|
||||||
|
|
||||||
static struct MHD_Daemon* http_daemon = NULL;
|
static struct MHD_Daemon* http_daemon = NULL;
|
||||||
|
|
||||||
|
/** In-memory certificates in PEM format */
|
||||||
|
static char* admin_ssl_key = NULL;
|
||||||
|
static char* admin_ssl_cert = NULL;
|
||||||
|
static char* admin_ssl_ca_cert = NULL;
|
||||||
|
|
||||||
|
static bool using_ssl = false;
|
||||||
|
|
||||||
int kv_iter(void *cls,
|
int kv_iter(void *cls,
|
||||||
enum MHD_ValueKind kind,
|
enum MHD_ValueKind kind,
|
||||||
const char *key,
|
const char *key,
|
||||||
@ -221,6 +232,58 @@ static bool host_to_sockaddr(const char* host, uint16_t port, struct sockaddr_st
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char* load_cert(const char* file)
|
||||||
|
{
|
||||||
|
char* rval = NULL;
|
||||||
|
ifstream infile(file);
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat(file, &st) == 0 &&
|
||||||
|
(rval = new (std::nothrow) char[st.st_size + 1]))
|
||||||
|
{
|
||||||
|
infile.read(rval, st.st_size);
|
||||||
|
rval[st.st_size] = '\0';
|
||||||
|
|
||||||
|
if (!infile.good())
|
||||||
|
{
|
||||||
|
MXS_ERROR("Failed to load certificate file: %s", file);
|
||||||
|
delete rval;
|
||||||
|
rval = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool load_ssl_certificates()
|
||||||
|
{
|
||||||
|
bool rval = false;
|
||||||
|
const char* key = config_get_global_options()->admin_ssl_key;
|
||||||
|
const char* cert = config_get_global_options()->admin_ssl_cert;
|
||||||
|
const char* ca = config_get_global_options()->admin_ssl_ca_cert;
|
||||||
|
|
||||||
|
if (*key && *cert && *ca)
|
||||||
|
{
|
||||||
|
if ((admin_ssl_key = load_cert(key)) &&
|
||||||
|
(admin_ssl_cert = load_cert(cert)) &&
|
||||||
|
(admin_ssl_ca_cert = load_cert(ca)))
|
||||||
|
{
|
||||||
|
rval = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete admin_ssl_key;
|
||||||
|
delete admin_ssl_cert;
|
||||||
|
delete admin_ssl_ca_cert;
|
||||||
|
admin_ssl_key = NULL;
|
||||||
|
admin_ssl_cert = NULL;
|
||||||
|
admin_ssl_ca_cert = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
bool mxs_admin_init()
|
bool mxs_admin_init()
|
||||||
{
|
{
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
@ -236,10 +299,20 @@ bool mxs_admin_init()
|
|||||||
options |= MHD_USE_DUAL_STACK;
|
options |= MHD_USE_DUAL_STACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (load_ssl_certificates())
|
||||||
|
{
|
||||||
|
using_ssl = true;
|
||||||
|
options |= MHD_USE_SSL;
|
||||||
|
}
|
||||||
|
|
||||||
// The port argument is ignored and the port in the struct sockaddr is used instead
|
// The port argument is ignored and the port in the struct sockaddr is used instead
|
||||||
http_daemon = MHD_start_daemon(options, 0, NULL, NULL, handle_client, NULL,
|
http_daemon = MHD_start_daemon(options, 0, NULL, NULL, handle_client, NULL,
|
||||||
MHD_OPTION_NOTIFY_COMPLETED, close_client, NULL,
|
MHD_OPTION_NOTIFY_COMPLETED, close_client, NULL,
|
||||||
MHD_OPTION_SOCK_ADDR, &addr,
|
MHD_OPTION_SOCK_ADDR, &addr,
|
||||||
|
!using_ssl ? MHD_OPTION_END :
|
||||||
|
MHD_OPTION_HTTPS_MEM_KEY, admin_ssl_key,
|
||||||
|
MHD_OPTION_HTTPS_MEM_CERT, admin_ssl_cert,
|
||||||
|
MHD_OPTION_HTTPS_MEM_TRUST, admin_ssl_cert,
|
||||||
MHD_OPTION_END);
|
MHD_OPTION_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,3 +323,8 @@ void mxs_admin_shutdown()
|
|||||||
{
|
{
|
||||||
MHD_stop_daemon(http_daemon);
|
MHD_stop_daemon(http_daemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mxs_admin_https_enabled()
|
||||||
|
{
|
||||||
|
return using_ssl;
|
||||||
|
}
|
||||||
|
@ -57,6 +57,9 @@ const char CN_ADMIN_HOST[] = "admin_host";
|
|||||||
const char CN_ADMIN_PASSWORD[] = "admin_password";
|
const char CN_ADMIN_PASSWORD[] = "admin_password";
|
||||||
const char CN_ADMIN_PORT[] = "admin_port";
|
const char CN_ADMIN_PORT[] = "admin_port";
|
||||||
const char CN_ADMIN_USER[] = "admin_user";
|
const char CN_ADMIN_USER[] = "admin_user";
|
||||||
|
const char CN_ADMIN_SSL_KEY[] = "admin_ssl_key";
|
||||||
|
const char CN_ADMIN_SSL_CERT[] = "admin_ssl_cert";
|
||||||
|
const char CN_ADMIN_SSL_CA_CERT[] = "admin_ssl_ca_cert";
|
||||||
const char CN_AUTHENTICATOR[] = "authenticator";
|
const char CN_AUTHENTICATOR[] = "authenticator";
|
||||||
const char CN_AUTHENTICATOR_OPTIONS[] = "authenticator_options";
|
const char CN_AUTHENTICATOR_OPTIONS[] = "authenticator_options";
|
||||||
const char CN_AUTH_ALL_SERVERS[] = "auth_all_servers";
|
const char CN_AUTH_ALL_SERVERS[] = "auth_all_servers";
|
||||||
@ -1525,6 +1528,18 @@ handle_global_item(const char *name, const char *value)
|
|||||||
{
|
{
|
||||||
strcpy(gateway.admin_host, value);
|
strcpy(gateway.admin_host, value);
|
||||||
}
|
}
|
||||||
|
else if (strcmp(name, CN_ADMIN_SSL_KEY) == 0)
|
||||||
|
{
|
||||||
|
strcpy(gateway.admin_ssl_key, value);
|
||||||
|
}
|
||||||
|
else if (strcmp(name, CN_ADMIN_SSL_CERT) == 0)
|
||||||
|
{
|
||||||
|
strcpy(gateway.admin_ssl_cert, value);
|
||||||
|
}
|
||||||
|
else if (strcmp(name, CN_ADMIN_SSL_CA_CERT) == 0)
|
||||||
|
{
|
||||||
|
strcpy(gateway.admin_ssl_ca_cert, value);
|
||||||
|
}
|
||||||
else if (strcmp(name, CN_ADMIN_AUTH) == 0)
|
else if (strcmp(name, CN_ADMIN_AUTH) == 0)
|
||||||
{
|
{
|
||||||
gateway.admin_auth = config_truth_value(value);
|
gateway.admin_auth = config_truth_value(value);
|
||||||
@ -1754,6 +1769,9 @@ global_defaults()
|
|||||||
strcpy(gateway.admin_host, DEFAULT_ADMIN_HOST);
|
strcpy(gateway.admin_host, DEFAULT_ADMIN_HOST);
|
||||||
strcpy(gateway.admin_user, INET_DEFAULT_USERNAME);
|
strcpy(gateway.admin_user, INET_DEFAULT_USERNAME);
|
||||||
strcpy(gateway.admin_password, INET_DEFAULT_PASSWORD);
|
strcpy(gateway.admin_password, INET_DEFAULT_PASSWORD);
|
||||||
|
gateway.admin_ssl_key[0] = '\0';
|
||||||
|
gateway.admin_ssl_cert[0] = '\0';
|
||||||
|
gateway.admin_ssl_ca_cert[0] = '\0';
|
||||||
|
|
||||||
if (version_string != NULL)
|
if (version_string != NULL)
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "maxscale/httprequest.hh"
|
#include "maxscale/httprequest.hh"
|
||||||
|
#include "maxscale/admin.hh"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -98,8 +99,8 @@ HttpRequest::HttpRequest(struct MHD_Connection *connection, string url, string m
|
|||||||
m_connection(connection)
|
m_connection(connection)
|
||||||
{
|
{
|
||||||
process_uri(url, m_resource_parts);
|
process_uri(url, m_resource_parts);
|
||||||
// TODO: Add https support
|
|
||||||
m_hostname = HttpRequest::HTTP_PREFIX;
|
m_hostname = mxs_admin_https_enabled() ? HttpRequest::HTTPS_PREFIX : HttpRequest::HTTP_PREFIX;
|
||||||
m_hostname += get_header(HTTP_HOST_HEADER);
|
m_hostname += get_header(HTTP_HOST_HEADER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,3 +68,10 @@ bool mxs_admin_init();
|
|||||||
* @brief Shutdown the administrative interface
|
* @brief Shutdown the administrative interface
|
||||||
*/
|
*/
|
||||||
void mxs_admin_shutdown();
|
void mxs_admin_shutdown();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if admin interface uses HTTPS protocol
|
||||||
|
*
|
||||||
|
* @return True if HTTPS is enabled
|
||||||
|
*/
|
||||||
|
bool mxs_admin_https_enabled();
|
||||||
|
Reference in New Issue
Block a user