Tracking source IP when using proxy protocol


#1

Goal: Limit connections opened per IP (real client IP) when using proxy protocol

I want to limit the number of opened connections per IP when using the proxy protocol.

According to some sources it is done like so:

stick-table type ip size 100k expire 30s store conn_cur
tcp-request connection track-sc0 src
tcp-request connection reject if { src_conn_cur gt 10 }

Problem here is using “tcp-request connection” doesn’t store the “real client IP” (remember I’m using proxy protocol).

Per the documentation:

“The PROXY protocol dictates the layer
3/4 addresses of the incoming connection to be used everywhere an address is
used, with the only exception of “tcp-request connection” rules which will
only see the real connection address.”

If I use “tcp-request content” instead that works but according to the documentation “tcp connection” is more efficient.

My question is that if there are any work around to use the real client ip when using the more efficient “tcp-request connection” ?


#2

First of all it doesn’t make a lot of sense to block IP’s on a intermediate proxy. I would strongly suggest to block bad source IPs at the edge proxy that actually sees the client. Otherwise you will just block your own proxy, and you may self-DDoS yourself with this, as the edge proxy may retry or failover to another backend. This is especially true for “tcp-request *”.

Also see this guy’s problem:

Oh wait, that’s actually you. Here we go, we found the root cause for that issue as well :wink:

So, move your IP/abuse protection to the edge proxy. If you cannot do this, then use an layer 7 rejection, with “http-request deny”.


#3

@lukastribus

Well you ignored my actual question, which was using proxy protocol if there was a work around in using “tcp-request connection” using the real client ip?

First of all it doesn’t make a lot of sense to block IP’s on a intermediate proxy.

Your making an assumption that I’m not doing that which is not true. TCP connections are handled at the edge. I’m handling http requests with intermediate HAProxy but wanted to see if it was possible to use “tcp-request connection” with the real client ip instead of having to use “http-request deny”.

HAProxy high connection resets using proxy protocol
Oh wait, that’s actually you. Here we go, we found the root cause for that issue as well :wink:

That’s actually a separate issue not sure what it has to do with this.


#4

Ok, I think I found the reason why proxy protocol requires the http request/content. Per the proxy protocol spec https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt it states the real ip is sent above the http request such as:

PROXY TCP4 192.168.0.1 192.168.0.11 56324 443\r\n
GET / HTTP/1.1\r\n
Host: 192.168.0.11\r\n
\r\n

tcp-request connection must not have access to that level so therefore it uses the connection IP instead of the IP from proxy protocol (educated guess on my part).

I suppose this would just be a limitation of proxy protocol the way it is designed.


#5

I ignored your question because I believe it would be a mistake to use either “tcp content” or “tcp connection” reject, for the reason mentioned.

I’m not sure I understand … you are trying to block requests based on the IP address information from the PROXY protocol. Is that not true? What’s my assumption that is untrue here?

I assumed you are blocking requests/connections in nginx in a similar matter that you are trying todo it on the intermediate haproxy instance here, which would lead to exactly to the problems explained in this thread.


#6

I’m just intrigued really… What is the edge proxy setup? It sends proxy protocol so could you instead maybe use Tproxy to make that one truly source IP transparent? Various proxies support it like HAproxy and Pound for example.

I’ve used Stunnel in front of HAProxy with proxy protocol and then used Tproxy with HAproxy so that my real server sees the real client IP. While not the same it got me thinking…


#7

@lukastribus

First of all it doesn’t make a lot of sense to block IP’s on a intermediate proxy

This statement is not true. Because one can open a single TCP connection (handled at the edge) and do multiple http requests.

I assumed you are blocking requests/connections in nginx in a similar matter that you are trying todo it on the intermediate haproxy instance here, which would lead to exactly to the problems explained in this thread.

That assumption is wrong.


#8

@AaronWest Interesting setup using Tproxy. I’m working with a similar setup but without Tproxy, I might give that a try one day thanks for sharing.