forked from sysown/proxysql
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP: Support HAProxy PROXY protocol V1 on MySQL frontends
This adds basic support for the HAProxy PROXY protocol V1 on MySQL frontend client connections. This allows the true client IP to be seen in the output of `SHOW FULL PROCESSLIST` in ProxySQL's admin frontend when the ProxySQL servers sit behind a load balancer such as HAProxy or AWS classic ELBs with the PROXY protocol feature enabled. I believe this should resolve sysown#2497 (Support for proxy_protocol for proxysql behind aws load balancer). The patch adds a Proxy_Protocol class which handles: - parsing of PROXY protocol headers (only the V1 header supported for now) - matching client IPs against a list of configured network CIDRs A new option, `proxy_protocol_frontend_nets` (list of network CIDRs), is introduced to allow the PROXY protocol feature to be selectively turned on for specific subnets where e.g. load balancers are running. This is similar to how the PROXY protocol is implemented in MariaDB. This variable can be set either in the config file or via the ProxySQL Admin interface. Configuration file example: mysql_variables= { ... proxy_protocol_frontend_nets="10.42.0.0/28 127.10.0.0/16" ... } ProxySQL Admin interface example: UPDATE global_variables SET variable_value="192.168.42.0/24" WHERE variable_name="mysql-proxy_protocol_frontend_nets"; LOAD MYSQL VARIABLES TO RUNTIME; The network CIDRs are stored as a thread-local variable in the MySQL_Thread class. It's only updated by MySQL_Thread::refresh_variables(). A new MySQL Data Stream state (DSS), `STATE_PROXY_PROTOCOL`, is introduced to handle the initial parsing of the PROXY protocol header. Once this has completed, the state is reset back to `STATE_SERVER_HANDSHAKE`. The patch hooks into the MySQL_Thread's main loop where `accept()` is called to handle incoming connections. Next, the actual parsing of the PROXY protocol header is invoked from the `MySQL_Data_Stream::read_pkts()` method, which is also called from MySQL_Thread's main loop (where incoming data is handled). I've only tested this with a HAProxy configuration block like: listen proxysql-with-proxy bind *:6030 option tcp-check mode tcp timeout server 6h timeout client 6h balance roundrobin server proxysql-backend-1 127.0.0.1:6033 check send-proxy listen proxysql-without-proxy bind *:6031 option tcp-check mode tcp timeout server 6h timeout client 6h balance roundrobin server proxysql-backend-2 192.168.1.123:6033 check NOTE: I took the liberty to reindent a block of code in MySQL_Thread.cpp so please review with whitespace changes hidden.
- Loading branch information
1 parent
ca733a7
commit cffb9f6
Showing
11 changed files
with
424 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#ifndef __CLASS_PROXY_PROTOCOL_H | ||
#define __CLASS_PROXY_PROTOCOL_H | ||
|
||
#include <vector> | ||
#include <sys/types.h> | ||
#include <netinet/in.h> | ||
#include <sys/socket.h> | ||
|
||
|
||
class Proxy_Protocol { | ||
private: | ||
static bool add_subnet(const char *cidr, std::vector<proxy_protocol_subnet_t> &subnets); | ||
|
||
public: | ||
Proxy_Protocol() {} | ||
~Proxy_Protocol() {} | ||
static bool parse_subnets(const char *list, std::vector<proxy_protocol_subnet_t> &subnets); | ||
static bool match_subnet(struct sockaddr *addr, socklen_t addrlen, std::vector<proxy_protocol_subnet_t> &subnets); | ||
static bool parse_header(unsigned char *, size_t n, struct sockaddr_storage *out); | ||
}; | ||
|
||
#endif /* __CLASS_PROXY_PROTOCOL_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.