Re: SV: Incompatible with 'frontend http-request header rule'

2022-03-04 Thread Christopher Faulet

Le 3/4/22 à 00:42, Henning Svane a écrit :

Hi Christopher

I tried your rule and it did not compile, but I am trying to understand it.
/haproxy02.cfg:20] : error detected while parsing an 'http-request tarpit' 
condition : no such ACL : 'http-response'
I placed the rule in the frontend, but was thinking if it should be in the 
backend, as it is here server is called and hereby produce the return code.

I understand the idea in your rule, but at the same time, I do not understand 
the order of execution.
It looks like it has to be executed from the right with the " if { capture.req.uri 
-m beg /login } { status 401 }" first.
But then what?

If I understand correctly
1) You save the request url in a table with capture.req.uri.
2) Then server try to execute the url
3) Based on the server return the http-response (this part I have not fully 
understand yet)
4) If the response is 401 then " http-request tarpit deny_status 429"

I will try to work a little more with you suggestion and see if I can get to 
work.

Regards
Henning


haproxy02.cfg:20] : error detected while parsing an 'http-request tarpit' 
condition : no such ACL : 'http-response'.



Your email client seems to have mangled my reply. Or there is a formatting issue 
on my side. Anyway, it is not one rule with everything on one line, but 2 rules. 
An http-request one to deny the request on its own line and an http-response one 
to track login failures, on another line.


Both can be specified in the frontend, the backend or split. It depends on your 
other rules, if any. With your config snippet, it doesn't matter.



--
Christopher Faulet



SV: Incompatible with 'frontend http-request header rule'

2022-03-03 Thread Henning Svane
Hi Christopher

I tried your rule and it did not compile, but I am trying to understand it.
/haproxy02.cfg:20] : error detected while parsing an 'http-request tarpit' 
condition : no such ACL : 'http-response'
I placed the rule in the frontend, but was thinking if it should be in the 
backend, as it is here server is called and hereby produce the return code.

I understand the idea in your rule, but at the same time, I do not understand 
the order of execution.
It looks like it has to be executed from the right with the " if { 
capture.req.uri -m beg /login } { status 401 }" first.
But then what?

If I understand correctly 
1) You save the request url in a table with capture.req.uri.
2) Then server try to execute the url
3) Based on the server return the http-response (this part I have not fully 
understand yet)
4) If the response is 401 then " http-request tarpit deny_status 429"

I will try to work a little more with you suggestion and see if I can get to 
work.

Regards
Henning


haproxy02.cfg:20] : error detected while parsing an 'http-request tarpit' 
condition : no such ACL : 'http-response'.

-Oprindelig meddelelse-
Fra: Christopher Faulet  
Sendt: 2. marts 2022 09:06
Til: haproxy@formilux.org
Emne: Re: Incompatible with 'frontend http-request header rule'

Le 3/1/22 à 22:00, Henning Svane a écrit :
> http-request track-sc0 src table table_login_limiter if { url_beg 
> /login } { status 401 }
> 
> http-request tarpit deny_status 429 if { sc_http_req_rate(0) gt 10 } { 
> url_beg /login }
> 

Hi,

You cannot match on the response status in a request rule. At this stage, the 
response is not received yet. So, you should rely on an http-response rule 
instead. But, at this stage, url_beg is no longer available because the request 
was already sent. You must use capture.req.uri instead.

In addition, because the tracking will be performed during the response 
evaluation, you must use table_http_req_rate() converter to look up in your 
stick-table. (Note that in your tarpit rule, you must explicitly specify the 
table name)

You can try the following rules :

http-request tarpit deny_status 429 if { 
src,table_http_req_rate(table_login_limiter) gt 10 } { url_beg /login } 
http-response track-sc0 src table table_login_limiter if { capture.req.uri -m 
beg /login } { status 401 }

You can also match on the url in an http-request rule to set a variable and use 
it in the http-response rule.

Regards,
--
Christopher Faulet



Re: Incompatible with 'frontend http-request header rule'

2022-03-02 Thread Christopher Faulet

Le 3/1/22 à 22:00, Henning Svane a écrit :
http-request track-sc0 src table table_login_limiter if { url_beg /login } { 
status 401 }


http-request tarpit deny_status 429 if { sc_http_req_rate(0) gt 10 } { url_beg 
/login }




Hi,

You cannot match on the response status in a request rule. At this stage, the
response is not received yet. So, you should rely on an http-response rule
instead. But, at this stage, url_beg is no longer available because the request
was already sent. You must use capture.req.uri instead.

In addition, because the tracking will be performed during the response
evaluation, you must use table_http_req_rate() converter to look up in your
stick-table. (Note that in your tarpit rule, you must explicitly specify the
table name)

You can try the following rules :

http-request tarpit deny_status 429 if { 
src,table_http_req_rate(table_login_limiter) gt 10 } { url_beg /login }
http-response track-sc0 src table table_login_limiter if { capture.req.uri -m 
beg /login } { status 401 }

You can also match on the url in an http-request rule to set a variable and use
it in the http-response rule.

Regards,
--
Christopher Faulet



Incompatible with 'frontend http-request header rule'

2022-03-01 Thread Henning Svane
Hi

I am trying to make a configuration that counts missed login attempts and block 
after 10 attempts in 60 sec.
The following example are accepted, but with a warning.
It looks like the configuration will not work as keyword 'status' is 
incompatible with 'frontend http-request header rule'
I have also tried to find an explanation around the keyword 'status' but cannot 
find anything.
Have also tried to remove status keyword, but that return an error instead.
So what is the trick to get this to work?

defaults
retries 3 # Try to connect up to 3 times in case of failure
timeout connect 5s # 5 seconds max to connect or to stay in queue
timeout http-keep-alive 1s # 1 second max for the client to post next 
request
timeout http-request 15s # 15 seconds max for the client to send a 
request
timeout queue 30s # 30 seconds max queued on load balancer
timeout client 30s
timeout server 10s

log global
mode http
option httplog
option dontlognull
option http-server-close
maxconn 100

frontend http-in
bind :80
http-request track-sc0 src table table_login_limiter if { url_beg /login } { 
status 401 }
http-request tarpit deny_status 429 if { sc_http_req_rate(0) gt 10 } { url_beg 
/login }
default_backend be_default_server

backend table_login_limiter
stick-table type ip size 1m expire 60s store http_req_rate(60s)

backend be_default_server
balance leastconn
server server_1 127.0.0.1:80

haproxy -f /home/user/haproxy02.cfg -c
[NOTICE]   (1338291) : haproxy version is 2.5.3-1ppa1~focal
[NOTICE]   (1338291) : path to executable is /usr/sbin/haproxy
[WARNING]  (1338291) : config : parsing [/home/user/haproxy02.cfg:19] : 
anonymous acl will never match because it uses keyword 'status' which is 
incompatible with 'frontend http-request header rule'
[WARNING]  (1338291) : config : log format ignored for frontend 'http-in' since 
it has no log address.
Warnings were found.
Configuration file is valid

Regards
Henning