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:
parent
4ed4773d91
commit
bf44cd0d14
@ -172,35 +172,6 @@ write or modify the data in the backend server. The default is 2 seconds.
|
||||
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`
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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_PORT[];
|
||||
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_OPTIONS[];
|
||||
extern const char CN_AUTH_ALL_SERVERS[];
|
||||
@ -162,6 +165,9 @@ typedef struct
|
||||
char admin_host[MAX_ADMIN_HOST_LEN]; /**< Admin interface host */
|
||||
uint16_t admin_port; /**< Admin interface port */
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,9 @@
|
||||
|
||||
#include <climits>
|
||||
#include <new>
|
||||
#include <fstream>
|
||||
#include <microhttpd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
@ -29,14 +31,23 @@
|
||||
#include <maxscale/utils.h>
|
||||
#include <maxscale/config.h>
|
||||
#include <maxscale/hk_heartbeat.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "maxscale/resource.hh"
|
||||
#include "maxscale/http.hh"
|
||||
|
||||
using std::string;
|
||||
using std::ifstream;
|
||||
|
||||
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,
|
||||
enum MHD_ValueKind kind,
|
||||
const char *key,
|
||||
@ -221,6 +232,58 @@ static bool host_to_sockaddr(const char* host, uint16_t port, struct sockaddr_st
|
||||
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()
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
@ -236,10 +299,20 @@ bool mxs_admin_init()
|
||||
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
|
||||
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_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);
|
||||
}
|
||||
|
||||
@ -250,3 +323,8 @@ void mxs_admin_shutdown()
|
||||
{
|
||||
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_PORT[] = "admin_port";
|
||||
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_OPTIONS[] = "authenticator_options";
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
gateway.admin_auth = config_truth_value(value);
|
||||
@ -1754,6 +1769,9 @@ global_defaults()
|
||||
strcpy(gateway.admin_host, DEFAULT_ADMIN_HOST);
|
||||
strcpy(gateway.admin_user, INET_DEFAULT_USERNAME);
|
||||
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)
|
||||
{
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "maxscale/httprequest.hh"
|
||||
#include "maxscale/admin.hh"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
@ -98,8 +99,8 @@ HttpRequest::HttpRequest(struct MHD_Connection *connection, string url, string m
|
||||
m_connection(connection)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -68,3 +68,10 @@ bool mxs_admin_init();
|
||||
* @brief Shutdown the administrative interface
|
||||
*/
|
||||
void mxs_admin_shutdown();
|
||||
|
||||
/**
|
||||
* @brief Check if admin interface uses HTTPS protocol
|
||||
*
|
||||
* @return True if HTTPS is enabled
|
||||
*/
|
||||
bool mxs_admin_https_enabled();
|
||||
|
Loading…
x
Reference in New Issue
Block a user