1

I am using haproxy 1.7.8.

I have a config that blocks requests with some specific abusers domains in HTTP Referer header.

Important parts of my haproxy config looks like this:

 frontend https_l1_xxxxx

    (...)

    acl is_abuser_by_referer capture.req.hdr(7) -m reg -i ^https?:\/\/(.+\.)?(someabuser.com|someabuser2.com|someabuser3.com)(\?.*|\/.*)?$
    acl return_html_path path_beg /urlICareAbout
    use_backend abuser if is_abuser_by_referer return_html_path

 backend abuser

    # override standard 200 status code
    http-response set-status 418 reason "I'm a teapot"
    server nginx_abusers localhost:8091

...with nginx actually listening on 8091 and serving some HTML.

This works, I have tested it by setting this HTTP header in my browser/curl and making a request to my haproxy - I am getting 418.


The problem is that what my haproxy logs looks like this:

Feb 5 13:11:45 aaa-www05 haproxy_l1_xxxxx[38749]: 111.222.111.222:2605 [05/Feb/2018:13:11:44.849] DFDA00BD:0A2D_0A19800C:01BB_--_7BFDAD https_l1_xxxxx ~ abuser/nginx_abusers 280/0/1/0/282 200 6044 - - ---- 145/145/0/0/0 0/0 {e60b039c46a1e104a94558ce0e480654||07.mydomain.com|||Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB7.5; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET4.0C; .NET||http://someabuser.com/player.swf} {||} 467 "GET /urlICareAbout/?preview=true HTTP/1.1"

...with status code 200 logged, instead of 418.


Why does that happen?


UPDATE: Note that I expect haproxy to log the actually returned status code, because its HTTP log format docs state:

- "status_code" is the HTTP status code returned to the client. This status is generally set by the server, but it might also be set by haproxy when the server cannot be reached or when its response is blocked by haproxy.

  • 1
    Likely a bug in haproxy. Either a documentation bug (most likely), or a code bug. The docs do state "status_code" is the HTTP status code returned to the client., but I suspect it should say "status code returned by the server". Try pinging the haproxy mailing list. – Patrick Feb 6 '18 at 1:04
  • 1
    Patrick, this is not the issue, all works as intended. The log ALWAYS represents data received from the backed. It makes absolutely no sense to override the HTTP status code with the rules in the frontend - for instance it may create confusions when doing some debugging. – Maciej Asembler Feb 6 '18 at 9:58
  • @MaciejAsembler That is why I said "documentation bug". The observed behavior is not what is documented. Your statement is also incorrect, the log can sometimes be a response code generated by haproxy. See docs. – Patrick Feb 6 '18 at 17:04
1

It works as expected. Your backend returns 200 OK, and this is the status which gets logged. It makes no sense to override these since sysadmins want the ACTUAL backend response data in logs for debugging.

"status_code" is the HTTP status code returned to the client

The status is 418 on client side, and this works correct as Greg has written.

  • I would not say that it "works as expected" and would call this is a documentation bug, as @Patrick said. "status_code" is the HTTP status code returned to the client too me means that 418 should be logged. – Greg Dubicki Feb 6 '18 at 11:11
  • 2
    This statement is true, client gets 418. It never said its logged on haproxy side on every occasion. - "status_code" is the HTTP status code returned to the client. This status is generally set by the server, but it might also be set by haproxy when the server cannot be reached or when its response is blocked by haproxy. – Maciej Asembler Feb 6 '18 at 11:33
  • @MaciejAsembler No, the statement is false. If the statement were true, and client got 418, then the log should contain 418. It does not. The log contains 200. – Patrick Feb 6 '18 at 17:05
1

(@Maciej Asembler answered correctly, but in a way that may not be completely clear, so let me try to rephrase it for future reference.)

It works as expected as my backend server returns 200.

Why?

If you would read only this line of the docs:

"status_code" is the HTTP status code returned to the client.

..then this would be an obvious documentation bug. BUT then this follows.

This status is generally set by the server, but it might also be set by haproxy when the server cannot be reached or when its response is blocked by haproxy.

As neither of cases in this part of the sentence: "it might also be set by haproxy when the server cannot be reached or when its response is blocked by haproxy" takes place here, the first part of the sentence does: "This status is generally set by the server".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.