Discussion:
Setting response headers conditionally
Ivan Kurnosov
2018-10-14 20:39:56 UTC
Permalink
I have the following config, it's under the `frontend` section for tls
connection and haproxy terminates https connections:

acl domain-acl-host hdr(host) -i domain.tld
rspadd X-Foo:\ bar if domain-acl-host
rspadd X-Baz:\ baz
http-response set-header X-Bar bar if domain-acl-host
use_backend backend_name if domain-acl-host

The `use_backend` directive works conditionally as expected (there are
multiple different domain names served, and they are chosen correctly)

But headers are not added/set to the response conditionally.

I expect 3 extra headers to be added there: `X-Foo`, `X-Baz`, and `X-Bar`,
but only `X-Baz` is added:

< HTTP/1.1 302 Found
< Server: nginx
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Cache-Control: max-age=0, must-revalidate, private
< Date: Sun, 14 Oct 2018 20:25:59 GMT
< Location: https://domain.tld/somewhere/else
< X-Baz: baz

I'm sure I'm missing something trivial, but reading documentation or google
did not help.

PS: it's `haproxy 1.8.8`

PPS: I originally asked it at https://serverfault.com/q/935492/45086 as well
--
With best regards, Ivan Kurnosov
Cyril Bonté
2018-10-14 22:26:19 UTC
Permalink
Hi,
Post by Ivan Kurnosov
I have the following config, it's under the `frontend` section for tls
    acl domain-acl-host hdr(host) -i domain.tld
    rspadd X-Foo:\ bar if domain-acl-host
    rspadd X-Baz:\ baz
    http-response set-header X-Bar bar if domain-acl-host
    use_backend backend_name if domain-acl-host
The `use_backend` directive works conditionally as expected (there are
multiple different domain names served, and they are chosen correctly)
But headers are not added/set to the response conditionally.
I expect 3 extra headers to be added there: `X-Foo`, `X-Baz`, and
    < HTTP/1.1 302 Found
    < Server: nginx
    < Content-Type: text/html; charset=UTF-8
    < Transfer-Encoding: chunked
    < Cache-Control: max-age=0, must-revalidate, private
    < Date: Sun, 14 Oct 2018 20:25:59 GMT
    < Location: https://domain.tld/somewhere/else
    < X-Baz: baz
I'm sure I'm missing something trivial, but reading documentation or
google did not help.
Well, did you have a look at the warnings emitted by haproxy on startup
saying your acl will never match for "rspadd X-Foo" and "http-response
set-header" ? You can't manipulate response headers based on request
headers acl (they're not in the memory buffer anymore).

You can capture the request header in a variable and modify your acl to
use this variable instead.

Example:
http-request set-var(txn.host) hdr(host)
acl domain-acl-host var(txn.host) -i domain.tld

See the documentation for details:
-
http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4.2-http-request
- http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#var
Post by Ivan Kurnosov
PS: it's `haproxy 1.8.8`
PPS: I originally asked it at https://serverfault.com/q/935492/45086 as well
--
With best regards, Ivan Kurnosov
--
Cyril Bonté
Ivan Kurnosov
2018-10-14 22:34:01 UTC
Permalink
Yep, that's what I ended up doing following the advice from serverfault.
Now it looks logical and I must admit I did not check the log for warnings
(I'm running it with systemd but I expected any warnings still to be shown
when I emit `systemctl reload`, I was wrong)

Thank you!
Post by Cyril Bonté
Hi,
Post by Ivan Kurnosov
I have the following config, it's under the `frontend` section for tls
acl domain-acl-host hdr(host) -i domain.tld
rspadd X-Foo:\ bar if domain-acl-host
rspadd X-Baz:\ baz
http-response set-header X-Bar bar if domain-acl-host
use_backend backend_name if domain-acl-host
The `use_backend` directive works conditionally as expected (there are
multiple different domain names served, and they are chosen correctly)
But headers are not added/set to the response conditionally.
I expect 3 extra headers to be added there: `X-Foo`, `X-Baz`, and
< HTTP/1.1 302 Found
< Server: nginx
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Cache-Control: max-age=0, must-revalidate, private
< Date: Sun, 14 Oct 2018 20:25:59 GMT
< Location: https://domain.tld/somewhere/else
< X-Baz: baz
I'm sure I'm missing something trivial, but reading documentation or
google did not help.
Well, did you have a look at the warnings emitted by haproxy on startup
saying your acl will never match for "rspadd X-Foo" and "http-response
set-header" ? You can't manipulate response headers based on request
headers acl (they're not in the memory buffer anymore).
You can capture the request header in a variable and modify your acl to
use this variable instead.
http-request set-var(txn.host) hdr(host)
acl domain-acl-host var(txn.host) -i domain.tld
-
http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4.2-http-request
- http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#var
Post by Ivan Kurnosov
PS: it's `haproxy 1.8.8`
PPS: I originally asked it at https://serverfault.com/q/935492/45086 as
well
Post by Ivan Kurnosov
--
With best regards, Ivan Kurnosov
--
Cyril Bonté
--
With best regards, Ivan Kurnosov
Loading...