Http-response set-header with condition, not working

Hello forum,

I need to set a http-response header under certain conditions.
My idea was to use this configuration in the frontend section:

acl path_set path_beg /some/path
http-response del-header Pragma if path_set
http-response set-header Cache-Control no-cache if path_set
http-response set-header Expires -1 if path_set

However, if I run a check on the config, haproxy tells me:

acl ‘path_set’ will never match because it only involves keywords that are incompatible with ‘frontend http-response header rule’

And indeed, the rule does not work. If I remove the condition (if…) the headers are set but of course for all paths.
Can someone help me understand, why this happens and how I prevent/fix this, so the condition works?

Thanks alot,
Hans

edit: I use haproxy version 1.6.13 on this server. Could it be a version problem?

You cannot match this directly, because the data is not there anymore (when the request is send to the server we don’t keep a copy of it).

I suggest you save the path to a txn variable in the frontend and than use that in the backend:

frontend ...
 http-request set-var(txn.path) path
backend ...
 acl path_set var(txn.path) -m beg /some/path
 http-response del-header Pragma if path_set
 http-response set-header Cache-Control no-cache if path_set
 http-response set-header Expires -1 if path_set

See the documentation for details:

1 Like

Thank you very much for this hint.
I try to understand what you mean by “the data is not there anymore”…

Can I also use this in the frontend section or is there a reason for using it in backend?

Yeah, you should be able to move everything to the frontend also, just make sure you use with the txn variable. I separated the two, so it is more clear that it’s happening at a different point in time.

What it means is that when you use the http-response directive, it will have to wait for the response to actually arrive. This obviously means that it would be after the request has been send to the server (otherwise we would not have an answer), and because haproxy does not keep a copy of the request around for further analysis, you cannot match something in your request (like the path), when the request was already send to the server.

Saving the path into a txn variable (which is a variable valid for the entire transaction) and matching that one instead solves the issue.

Thank you very much for the explanation!
Understood :slight_smile:

I am getting the same error in HAProxy, while using it via the OpnSense firewall.

acl ‘********************************’ will never match because it only involves keywords that are incompatible with ‘frontend http-response header rule’

My case is a bit more weird though, since I try to delete a header :

haproxy

Your previous explanation of the issue does not apply here, I think.
Here, we don’t need any data from the request in order to process the response.

Any idea how I can solve this?
I don’t see OpnSense supporting something related to txn variables and I don’t see how a variable would help in my case.
There is an option for :

Specify a HAProxy rule/ACL that is currently not supported by the GUI.

haproxy1

…but I am not sure what I can do with it.
I guess I could have pasted the:

http-request set-var(txn.path) path

…if I was fixing the original poster’s case, hoping that it works, but in my case I see no benefit in doing that.

Please share the actual haproxy configuration. I cannot help you with the opnsense abstraction.

Sure, once I find where the configuration is stored.
For sure, it doesn’t seem to be inside /etc/ or /etc/haproxy/. :frowning:

OK, here is the file:

The password is data123
I did some find and replace in there for the KKKKKK names. Hopefully it won’t matter.

And the config path was this, for anyone interested:

/usr/local/etc/haproxy.conf

Also, the HAProxy version shown in the UI is:
os-haproxy (installed) 2.22
From my understanding this is the true HAProxy version, not an OpnSense-internal version number.

Hm…
Looking at the config file, I guess the problem is that the header deletion uses ACLs that require the HOST value.
Correct?
So, it is almost the same as in the original question.
Removing the conditions from the UI fixes it, but that probably means that the rule will be executed either always or never.
I will try to do the txn trick to see what happens.

1 Like

For the record, I ended up using this simpler rule that doesn’t require the host (if the traffic is HTTP(S), remove the SERVER header):
image
Not sure if there are any slight performance implications from switching from one to the other, but I guess this new rule improves on security as well, by removing this header from all HTTP traffic, not just from some host names.