Proxy protocol setting error detection + documentation
The setting parsing is now similar to the other server settings. The header is printed if log_info is on. Changed the setting name to simply "proxy_protocol". Updated documentation.
This commit is contained in:
@ -1073,23 +1073,36 @@ closed.
|
||||
For more information about persistent connections, please read the
|
||||
[Administration Tutorial](../Tutorials/Administration-Tutorial.md).
|
||||
|
||||
#### `use_proxy_protocol`
|
||||
#### `proxy_protocol`
|
||||
|
||||
If `use_proxy_protocol` is set to `yes`, MaxScale will send a proxy protocol
|
||||
If `proxy_protocol` is set to `on`, MaxScale will send a
|
||||
[PROXY protocol](http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)
|
||||
header when connecting client sessions to the server. The header contains the
|
||||
original client IP address and port, as seen by MaxScale. The server will then
|
||||
read the header and perform authentication as if the connection originated from
|
||||
this address instead of the MaxScale IP address. With this feature, the user
|
||||
this address instead of MaxScale's IP address. With this feature, the user
|
||||
accounts on the backend server can be simplified to only contain the actual
|
||||
client hosts and not the MaxScale host.
|
||||
|
||||
Currently, using this feature is unpractical due to the restrictiveness of the
|
||||
proxy protocol. The protocol requires that *all* connections from proxy enabled
|
||||
addresses must send a valid proxy header. MaxScale has other connections to the
|
||||
servers in addition to client sessions, e.g. monitors, and the server will
|
||||
refuse these due to the lack of the header. To bypass this restriction, the
|
||||
server monitor needs to be disabled and the service listener needs to be
|
||||
PROXY protocol will be supported by MariaDB 10.3, which this feature has been
|
||||
tested with. To use it, enable the PROXY protocol in MaxScale for every
|
||||
compatible server and configure the MariaDB servers themselves to accept the
|
||||
protocol headers from MaxScale's IP address. On the server side, the protocol
|
||||
should be enabled only for trusted IPs, as it allows the sender to spoof the
|
||||
connection origin. If a proxy header is sent to a server not expecting it, the
|
||||
connection will fail. Usually PROXY protocol should be enabled for every
|
||||
server in a cluster, as they typically have similar grants.
|
||||
|
||||
Other SQL-servers may support PROXY protocol as well, but the implementation may
|
||||
be highly restricting. Strict adherence to the protocol requires that the
|
||||
backend server does not allow mixing of un-proxied and proxied connections from
|
||||
a given IP. MaxScale requires normal connections to backends for monitoring and
|
||||
authentication data queries, which would be blocked. To bypass this restriction,
|
||||
the server monitor needs to be disabled and the service listener needs to be
|
||||
configured to disregard authentication errors (`skip_authentication=true`).
|
||||
Server states also need to be set manually in MaxAdmin. These steps are *not*
|
||||
required for MariaDB 10.3, since its implementation is more flexible and allows
|
||||
both PROXY-headered and headerless connections from a proxy-enabled IP.
|
||||
|
||||
#### `authenticator`
|
||||
|
||||
|
@ -39,7 +39,7 @@ extern const char CN_MONITORPW[];
|
||||
extern const char CN_MONITORUSER[];
|
||||
extern const char CN_PERSISTMAXTIME[];
|
||||
extern const char CN_PERSISTPOOLMAX[];
|
||||
extern const char CN_USE_PROXY_PROTOCOL[];
|
||||
extern const char CN_PROXY_PROTOCOL[];
|
||||
|
||||
/**
|
||||
* The server parameters used for weighting routing decissions
|
||||
@ -133,7 +133,7 @@ typedef struct server
|
||||
uint8_t charset; /**< Default server character set */
|
||||
bool is_active; /**< Server is active and has not been "destroyed" */
|
||||
bool created_online; /**< Whether this server was created after startup */
|
||||
bool use_proxy_protocol; /**< Send proxy-protocol header when connecting client sessions. */
|
||||
bool proxy_protocol; /**< Send proxy-protocol header to backend when connecting client sessions. */
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t server_chk_tail;
|
||||
#endif
|
||||
|
@ -269,7 +269,7 @@ const char *server_params[] =
|
||||
CN_SSL_KEY,
|
||||
CN_SSL_VERSION,
|
||||
CN_SSL_CERT_VERIFY_DEPTH,
|
||||
CN_USE_PROXY_PROTOCOL,
|
||||
CN_PROXY_PROTOCOL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -2953,7 +2953,25 @@ int create_new_server(CONFIG_CONTEXT *obj)
|
||||
}
|
||||
}
|
||||
|
||||
server->use_proxy_protocol = config_get_bool(obj->parameters, CN_USE_PROXY_PROTOCOL);
|
||||
const char* proxy_protocol = config_get_value_string(obj->parameters, CN_PROXY_PROTOCOL);
|
||||
if (*proxy_protocol)
|
||||
{
|
||||
int truth_value = config_truth_value(proxy_protocol);
|
||||
if (truth_value == 1)
|
||||
{
|
||||
server->proxy_protocol = true;
|
||||
}
|
||||
else if (truth_value == 0)
|
||||
{
|
||||
server->proxy_protocol = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Invalid value for '%s' for server %s: %s",
|
||||
CN_PROXY_PROTOCOL, server->unique_name, proxy_protocol);
|
||||
error_count++;
|
||||
}
|
||||
}
|
||||
|
||||
MXS_CONFIG_PARAMETER *params = obj->parameters;
|
||||
|
||||
|
@ -56,7 +56,7 @@ const char CN_MONITORPW[] = "monitorpw";
|
||||
const char CN_MONITORUSER[] = "monitoruser";
|
||||
const char CN_PERSISTMAXTIME[] = "persistmaxtime";
|
||||
const char CN_PERSISTPOOLMAX[] = "persistpoolmax";
|
||||
const char CN_USE_PROXY_PROTOCOL[] = "use_proxy_protocol";
|
||||
const char CN_PROXY_PROTOCOL[] = "proxy_protocol";
|
||||
|
||||
static SPINLOCK server_spin = SPINLOCK_INIT;
|
||||
static SERVER *allServers = NULL;
|
||||
@ -141,7 +141,7 @@ SERVER* server_alloc(const char *name, const char *address, unsigned short port,
|
||||
server->is_active = true;
|
||||
server->created_online = false;
|
||||
server->charset = SERVER_DEFAULT_CHARSET;
|
||||
server->use_proxy_protocol = false;
|
||||
server->proxy_protocol = false;
|
||||
|
||||
spinlock_acquire(&server_spin);
|
||||
server->next = allServers;
|
||||
@ -570,9 +570,9 @@ dprintServer(DCB *dcb, const SERVER *server)
|
||||
dcb_printf(dcb, "\tSSL CA certificate: %s\n",
|
||||
l->ssl_ca_cert ? l->ssl_ca_cert : "null");
|
||||
}
|
||||
if (server->use_proxy_protocol)
|
||||
if (server->proxy_protocol)
|
||||
{
|
||||
dcb_printf(dcb, "\tProxy protocol enabled.\n");
|
||||
dcb_printf(dcb, "\tPROXY protocol: on.\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1173,9 +1173,9 @@ static bool create_server_config(const SERVER *server, const char *filename)
|
||||
dprintf(file, "%s=%ld\n", CN_PERSISTMAXTIME, server->persistmaxtime);
|
||||
}
|
||||
|
||||
if (server->use_proxy_protocol)
|
||||
if (server->proxy_protocol)
|
||||
{
|
||||
dprintf(file, "%s=yes\n", CN_USE_PROXY_PROTOCOL);
|
||||
dprintf(file, "%s=on\n", CN_PROXY_PROTOCOL);
|
||||
}
|
||||
|
||||
for (SERVER_PARAM *p = server->parameters; p; p = p->next)
|
||||
|
@ -198,7 +198,7 @@ static int gw_create_backend_connection(DCB *backend_dcb,
|
||||
protocol->fd,
|
||||
session->client_dcb->fd);
|
||||
|
||||
if (server->use_proxy_protocol)
|
||||
if (server->proxy_protocol)
|
||||
{
|
||||
gw_send_proxy_protocol_header(backend_dcb);
|
||||
}
|
||||
@ -919,7 +919,7 @@ static int gw_write_backend_event(DCB *dcb)
|
||||
if (backend_protocol->protocol_auth_state == MXS_AUTH_STATE_PENDING_CONNECT)
|
||||
{
|
||||
backend_protocol->protocol_auth_state = MXS_AUTH_STATE_CONNECTED;
|
||||
if (dcb->server->use_proxy_protocol)
|
||||
if (dcb->server->proxy_protocol)
|
||||
{
|
||||
gw_send_proxy_protocol_header(dcb);
|
||||
}
|
||||
@ -1906,6 +1906,8 @@ static void gw_send_proxy_protocol_header(DCB *backend_dcb)
|
||||
GWBUF *headerbuf = gwbuf_alloc_and_load(strlen(proxy_header), proxy_header);
|
||||
if (headerbuf)
|
||||
{
|
||||
MXS_INFO("Sending proxy-protocol header '%s' to backend %s.", proxy_header,
|
||||
backend_dcb->server->unique_name);
|
||||
if (!dcb_write(backend_dcb, headerbuf))
|
||||
{
|
||||
gwbuf_free(headerbuf);
|
||||
|
Reference in New Issue
Block a user