Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for proxy_protocol for proxysql behind aws load balancer #2497

Closed
pipozzz opened this issue Jan 24, 2020 · 11 comments
Closed

Support for proxy_protocol for proxysql behind aws load balancer #2497

pipozzz opened this issue Jan 24, 2020 · 11 comments

Comments

@pipozzz
Copy link

pipozzz commented Jan 24, 2020

Hello,

is it possible to implement proxy_protocol on proxysql to see real remote IP of client ?

We would like to use new feature from v2.0.9 called firewall whitelist, but our proxysql servers are running behind TCP load balancer and we still see only load balancer's IP obviously.

Thank you.

@renecannao
Copy link
Contributor

If my understanding is correct, this is NOT a duplicate of #1971 or #2241 .

Because ProxySQL is behind a TCP load balancer, to me this request makes sense!

@nvtkaszpir
Copy link

nvtkaszpir commented Feb 24, 2020

Unfortunately it looks like a duplicate:

So I guess the FR are asking to implement support for proxy protocol and extracting source IP from incoming PROXY header, so that it could be used for whitelisting.

It is doable, for example it can be used with nginx to whitelist request which come in to AWS ELB on nginx level and not on AWS ELB net/security rules.

@pipozzz
Copy link
Author

pipozzz commented Feb 28, 2020

No, I need to use source IP in proxysql firewall whitelisting feature and have more granular option to whitelist certain mysql user from certain IP/subnet to run queries and this proxysql is behind ELB.

@pipozzz
Copy link
Author

pipozzz commented Mar 25, 2020

Any update?

1 similar comment
@pipozzz
Copy link
Author

pipozzz commented Apr 16, 2020

Any update?

@pipozzz pipozzz closed this as completed Apr 29, 2020
@renecannao
Copy link
Contributor

Reopening, because we may work on it sometime in the future

@renecannao renecannao reopened this Apr 29, 2020
noahwilliamsson added a commit to noahwilliamsson/proxysql that referenced this issue Jul 20, 2020
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.
noahwilliamsson added a commit to noahwilliamsson/proxysql that referenced this issue Jul 20, 2020
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.
noahwilliamsson added a commit to noahwilliamsson/proxysql that referenced this issue Jul 20, 2020
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.
noahwilliamsson added a commit to noahwilliamsson/proxysql that referenced this issue Feb 28, 2021
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
@thunkWaltz
Copy link

Hi, Looks like there are some conflicts in the merge, so fix is still not available. Is there any plan to take this fix?

@TomaszKorwel
Copy link

We have the same use case -> our proxysql is behind load balancer and we'd like to be able to handle query rules based on actual client IP, right now all connections are 'seen' as originating from load balancer.

@dankow
Copy link

dankow commented Jul 2, 2024

We also have a need for this feature, as we are planning to put our ProxySQL servers behind a TCP load balancer.

@charles-001
Copy link

+1 this would be great to have

@jesmarcannao
Copy link
Contributor

Closing: this been implemented in #4600 and released with ProxySQL v2.7.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants