Opened 5 years ago

Last modified 17 months ago

#711 new enhancement

Support X-Forwarded-Proto or similar when operating as a backend behind a SSL terminator

Reported by: neovortex@… Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.7.x
Keywords: Cc:
uname -a:
nginx -V: nginx version: nginx/1.6.2

Description

Currently there is no way to override $scheme and $https variables when operating as a backend server behind a SSL terminator.

Most issues can be worked around by hardcoding https or referring to a x-forwarded-proto variable in rewrites/etc instead of $scheme, but this does not work for nginx initiated redirects (such as when adding a trailing slash) and also complicated configuration (possibly many lines need changing just to move ssl to a terminating device).

There are two ways I can see this being resolved, one by allowing inclusion of the scheme in the server_name option (or as a separate server_scheme option or similar) which is the route Apache takes (see http://httpd.apache.org/docs/2.2/mod/core.html#servername for more info)

The other option would be handling it similar to how the realip module handles setting the client address, but this lacks the option to hardcode it to always be https if no suitable upstream header is available.

Change History (2)

comment:1 follow-up: Changed 5 years ago by www.google.com/accounts/o8/id?id=AItOawkhuuJTueP4AEX24KYzvbf1rPbkAtWq0mg

I ran into a similar issue, but additionally needed to set the scheme via a per-request variable.

This workaround worked for me:

error_page 301 =301 $client_scheme://$host$uri/$is_args$args;

I also took a pass at implementing a new directive client_scheme_in_redirect:
https://github.com/kibra/nginx/pull/1

I'm not familiar with the contribution guidelines, so it might be a while before a new directive is the right option.

-Kyle

comment:2 in reply to: ↑ 1 Changed 17 months ago by roelvanduijnhoven@…

This ticket got mentioned in #1549.

I want to drop something that @ru mentioned in this ticket as well. It may help.

While in HTTP/2 the scheme is required, in HTTP/1 it is generally not present (https://tools.ietf.org/html/rfc7230#section-5.3.1) so your patch won't work for HTTP/1.

The original request scheme can be obtained either from the X-Forwarded-Proto header, or derived from the PROXY protocol v2 PP2_TYPE_SSL TLV, but nginx currently lacks support of the latter.

We've also discussed about adding support for XFP and PP2_TYPE_SSL to the realip module with the effect that the $scheme and $https variables will match the original request.

Replying to www.google.com/accounts/o8/id?id=AItOawkhuuJTueP4AEX24KYzvbf1rPbkAtWq0mg:

I ran into a similar issue, but additionally needed to set the scheme via a per-request variable.

This workaround worked for me:

error_page 301 =301 $client_scheme://$host$uri/$is_args$args;

I also took a pass at implementing a new directive client_scheme_in_redirect:
https://github.com/kibra/nginx/pull/1

I'm not familiar with the contribution guidelines, so it might be a while before a new directive is the right option.

-Kyle

Note: See TracTickets for help on using tickets.