haproxy-ingress icon indicating copy to clipboard operation
haproxy-ingress copied to clipboard

Custom Error Pages

Open hileef opened this issue 4 years ago • 4 comments

Hello

First of all, thanks for this project, it's proved very helpful for us ! For our use case, we would like to customize the error pages returned by HAProxy.

It seems that HAProxy supports setting custom error pages for certain status codes with the errorfile directive. Furthermore, it seems that there are lua scripts which return static html pages. I was able to successfully customize the http pages returned for status code 404 by mounting over a modified version of /usr/local/etc/haproxy/lua/services.lua .

However, I do not know what to modify to customize status code 401 . Mounting over a modified version of /etc/haproxy/template/haproxy.tmpl seems to be taken into account since the logs show messages like :

status code 401 not handled by 'errorfile', error customization will be ignored.

But I do not know if it is possible to handle it maybe on the lua side. Could you help me out ?

Also in the modified /etc/haproxy/template/haproxy.tmpl I have added lines like errorfile 503 /etc/haproxy/errors-custom/503.http but they seem to not be taken into account 😞

truncated contents of /etc/haproxy/template/haproxy.tmpl :

  # # # # # # # # # # # # # # # # # # #
# #
#     Error pages
#
backend _error404
    mode http
    http-request use-service lua.send-404

errorfile 400 /etc/haproxy/errors-custom/400.http
errorfile 401 /etc/haproxy/errors-custom/401.http
errorfile 403 /etc/haproxy/errors-custom/403.http
errorfile 404 /etc/haproxy/errors-custom/404.http
errorfile 408 /etc/haproxy/errors-custom/408.http
errorfile 413 /etc/haproxy/errors-custom/413.http
errorfile 421 /etc/haproxy/errors-custom/421.http
errorfile 495 /etc/haproxy/errors-custom/495.http
errorfile 496 /etc/haproxy/errors-custom/496.http
errorfile 500 /etc/haproxy/errors-custom/500.http
errorfile 502 /etc/haproxy/errors-custom/502.http
errorfile 503 /etc/haproxy/errors-custom/503.http
errorfile 504 /etc/haproxy/errors-custom/504.http

I've also verified in the container that the contents of /etc/haproxy/errors-custom/503.http match what I expect, but unfortunately it does not match what is returned by haproxy 😞

Could you point me to what I am doing wrong ?

Finally, I don't know if this is something that would be on the roadmap or not, but I would be very interested in a feature where I am not mounting over files like /usr/local/etc/haproxy/lua/services.lua and /etc/haproxy/template/haproxy.tmpl , which seems to be a lot more "dangerous" to do than only mounting error files over a specific path and it working out of the box.

Let me know your thoughts on if this would be possible ; Thanks !

hileef avatar May 17 '20 23:05 hileef

Hi, I think you can use a config-defaults which declares all the errorfile keywords, but you can only use with some error codes as you've said. I'd also suggest you against reusing this unused 503.http, this should be removed in the v0.8 refactor. Instead mount all the files in the controller container. I'd also suggest against overriding the template as much as you can - it'd be probably a pain to merge your changes on every single release.

Note also that haproxy let you override pages of status that itself generates. The lua script is used when haproxy-ingress need to generate eg a 413 when content-length is greater than the maximum specified. So what's your use case? Do you have a custom acl and need a custom response? Do you want to override a response from the backend?

jcmoraisjr avatar May 18 '20 18:05 jcmoraisjr

So what's your use case?

Our use case is the following :

We expect that there are errors that will be encountered and as such, returned back to the user in his browser, e.g. :

  • 404 when the user is attempting to reach an endpoint not opened up yet
  • 503 when maintenance is ongoing in the cluster
  • 401 when the user did not provide the correct basic auth credentials (especially when they have been rotated and the end user has not updated them on his side)
  • 496 when the user is to present a TLS certificate and has not set it up correctly in his browser
  • etc.

I would like to be able to customize the error pages returned, such that we can have more "nicer-looking" and "user-friendly" pages being returned in these cases (for example, pointing back to our documentation, status pages, with the company logo, etc)

Do you have a custom acl and need a custom response? Do you want to override a response from the backend?

If I understand correctly, we do not. All access control that we use is through the ingress annotations that this ingress controller evaluates. Which is very convenient btw, thanks for this 🙏

I'd also suggest against overriding the template as much as you can - it'd be probably a pain to merge your changes on every single release.

I wholeheartedly agree with you here, I think this comes from a misunderstanding of the documentation on my part.

If I understand you correctly using the config-defaults to include only the errorfile directives will allow me to point to custom error http files without having to modify the general template, which I very much prefer 👍

The lua script is used when haproxy-ingress need to generate eg a 413 when content-length is greater than the maximum specified. [...] the errorfile keywords, but you can only use with some error codes as you've said.

So my understanding is that for some error cases like 401, 404, 495 and 496, it is not possible to override them with the errorfile dirrective. But I am unclear as to what role the lua script fills in here ...

Upon re-reading the documentation, I think I can use the default-backend and auth-tls-error-page as workarounds in order to serve custom error pages for the 404, 495 and 496 errors, but I don't know how to do the same for 401.

If I can clarify : the backend is not the one returning the 401, it is this ingress controller because we have used the annotations auth-secret and auth-type, which is the behaviour we expect. We simply want to make the 401 pretty 😉

I thought customizing the lua script would allow me to modify the page returned for 401, but it appears not. Would you have a suggestion of how to do that ?

In the mean time I will go ahead and test out using the config-defaults for the errors supported by the errorfile directlve and come back here to let you know if I am successful.

hileef avatar May 21 '20 14:05 hileef

I thought customizing the lua script would allow me to modify the page returned for 401, but it appears not. Would you have a suggestion of how to do that ?

I see. It seems the 401 http status code is an haproxy generated page that cannot be customized. I can change the http-request auth to a Lua script, so the Lua script could be customized.

I've just posted a question to the haproxy dev list[1], lets see if we're missing something and make the adjusts accordingly.

[1] https://www.mail-archive.com/[email protected]/msg37410.html

I think I can use the default-backend and auth-tls-error-page as workarounds

The auth-tls-error-page could be considered a work around depending on what you're expecting, since it does a redirect. If you don't want a redirect you should overwrite the Lua script. Regarding default-backend - either command-line or ingress spec - this is the way to go, you don't need to overwrite scripts to change it.

jcmoraisjr avatar May 22 '20 00:05 jcmoraisjr

Hi, as you can see our question created such functionality in haproxy 2.2, thanks for starting the issue. In the mean time I'll update the template to use a Lua service instead, this will allow to customize responses.

jcmoraisjr avatar May 27 '20 20:05 jcmoraisjr

Hi!

I work on a megacorporation that you might be aware of that wants to show a custom page for 403 errors for a specific ingress - not globally.

Is this still a work in progress?

marcelo-devsres avatar Aug 21 '23 18:08 marcelo-devsres

Ingress resources are merged together to create a single configuration, so it's not doable a 403 error page per ingress. You can however create a 403 page per ... domain, just create an ingress for that domain and configure path / pointing to a service that should serve the 403 content.

Maybe you have a more specific doubt or problem, in that case feel free to reach out on slack.

jcmoraisjr avatar Aug 23 '23 00:08 jcmoraisjr

Btw closing, we've that implemented since v0.13. @hileef please let us know if you have any problem with the functionality or if for any reason it doesn't fit your needs.

jcmoraisjr avatar Aug 23 '23 00:08 jcmoraisjr

@marcelo-devsres nevermind, that applies to 404, not 403. This is in fact not supported, but you can however use a custom config adding an errorfile directive. It's indeed not a trivial configuration.

jcmoraisjr avatar Aug 23 '23 00:08 jcmoraisjr

Thanks for the heads up @jcmoraisjr , I've since moved companies but glad to hear that this is now supported 🙏 good call on closing this one 👍

hileef avatar Aug 23 '23 10:08 hileef