Is Zope4/5 be able to manage x-forwarded-proto header?

I tried to configure plone.recipe.zope2instance for waitress with options described here:

but I can't achieve that trusted-proxy works in buildout (I tried this solution). I think that for this reason the request doesn't execute parse_proxy_headers function in:

So, I'm doing something wrong? There is some point that I didn't take into account?

Thank you,

Alberto Duran via Plone Community wrote at 2022-12-23 09:06 +0000:

I tried to configure plone.recipe.zope2instance for waitress with options described here:
https://github.com/plone/plone.recipe.zope2instance#advanced-options

but I can't achieve that trusted-proxy works in buildout (I tried this solution). I think that for this reason the request doesn't execute parse_proxy_headers function in:

waitress/proxy_headers.py at main · Pylons/waitress · GitHub

trusted-proxy works with zc.buildout.
You put it into the zope-conf-additional definition.

Note that trusted-proxy is a ZPublisher and not a waitress option.
It lets ZPublisher honor the X_FORWARDED_FOR option for
trusted proxies (when it determines a request's
effective IP address). It has no effect on waitress.

According to

https://docs.pylonsproject.org/projects/waitress/en/stable/reverse-proxy.html

Waitress should support the X-Forwarded-For headers, which is the default wsgi runner for the Plone backend since Plone 5.2

Please also consider the role of buildout here: it is not buildout that does or does not support trusted-proxy.

A buildout recipe generates the configurations for Zope/Waitress in somepath / zope.conf and wsgi.ini. It’s waitress that needs to peel off the request headers set by trusted proxies (there can be multiple) and set the correct client ip.

There are also generic wsgi middlewares that can do this, maybe useful for other wsgi servers thar don’t support this.

Also check that your nginx/Apache config correctly forwards/leaves the x-forwarded-for headers intact.

A nice debugging trick to see all incoming headers is to create a small Python script in the ZMI in the root of your site that echo’s all headers.

Hi Fred, thanks for the info.

I understand what you say but the situation is the following:
Our customer uses AWS and alb balancer and doesn't want to use nginx. He adds some headers:
"X_FORWARDED_FOR": ip,
"X_FORWARDED_PROTO":"https"

and wants that Zope/Plone answers using https. As you said before, Plone backend uses Waitress as the default wsgi since Plone 5.2. However, I don't know how configurate Waitress to work with Plone and understand these headers.

Any information will helps me.

Thanks a lot for your time.

Alberto Duran via Plone Community wrote at 2022-12-23 13:28 +0000:

I understand what you say but the situation is the following:
Our customer uses AWS and alb balancer and doesn't want to use nginx. He adds some headers:
"X_FORWARDED_FOR": ip,
"X_FORWARDED_PROTO":"https"

and wants that Zope/Plone answers using https. As you said before, Plone backend uses Waitress as the default wsgi since Plone 5.2. However, I don't know how configurate Waitress to work with Plone and understand these headers.

Any information will helps me.

ZPublisher understands the trusted-proxy configuration option
(code in ZPublisher.HTTPRequest.HTTPRequest.__init__)
and uses it to determine the effective client IP address.
This is a ZPubliser (not waitress) option and must be put into zope.conf
(not zope.ini).

Why should Plone answer differently then it has been requested,
e.g. why should it answer with https for a http request?

Zope uses virtual host support to control the protocol
reference in the URLs it generates.
You find documentation via <URL to your Zope>/virtual_hosting/manage_main.

I am under the impression that this is not how the headers should be spelled here: the all-uppercase-underscore-separated syntax appears to be internal to how Waitress handles environment variables based on headers, and is not the name of the headers, which should be X-Forwarded-For (with hyphens, not underscores), and X-Forwarded-Proto.

I would highly recommend that you consider printing, logging, or actively debugging actual headers coming from any requests from reverse proxies you intend to configure behind, to verify that the headers you are expecting are the ones set.

Thanks a lot Dieter. I've been seen Zope/HTTPRequest.py at master · zopefoundation/Zope · GitHub, and in that point is when the application decides to use one protocol or another. If I have an external rewriter, I'll add some headers such as 'HTTPS', 'SERVER_PORT_SECURE' or 'REQUEST_SCHEME' to specify 'https' but in this case I can't do it. There is another option 'wsgi.url_scheme', but I don't know how to set it up. Is it also needed a Web Server?

Zope uses virtual host support to control the protocol
reference in the URLs it generates.
You find documentation via <URL to your Zope>/virtual_hosting/manage_main .

It helps me to understand how it works. But it doesn't work for me because I don't have a Web Server.

Thanks Sean. I've extracted this headers at some point of code during last week when I was debugging. I don't remember if it is from the environ variable in ZPublisher or from waitress egg.
I'll revise it again but I think that this headers are correct.

Alberto Duran via Plone Community wrote at 2022-12-28 10:12 +0000:

...
If I have an external rewriter, I'll add some headers such as 'HTTPS', 'SERVER_PORT_SECURE' or 'REQUEST_SCHEME' to specify 'https' but in this case I can't do it. There is another option 'wsgi.url_scheme', but I don't know how to set it up. Is it also needed a Web Server?

Zope is not a full blown WSGI application.
For legacy reasons, Zope still partially uses its own options.
This is the case for trusted-proxy and virtual hosting.
Therefore, it will not help when you set wsgi.url_scheme.

Zope uses virtual host support to control the protocol
reference in the URLs it generates.
You find documentation via <URL to your Zope>/virtual_hosting/manage_main .

It helps me to understand how it works. But it doesn't work for me because I don't have a Web Server.

You have at least 2 web servers:

  1. the one which adds the X-Forwarded-For header
  2. waitress.

Typically, the first web server would be configured to rewrite
the incoming URL to include the virtual hosting parts.

Zope's virtual hosting supports in addition a static
mapping. I have never used it (because the type of web server
I use has not problems with the URL rewriting). Therefore,
you must look around yourself to find out how it works.