Project

General

Profile

Feature #2703

Forward authenticated user to proxied requests

Added by flynn over 1 year ago. Updated 3 months ago.

Status:
Fixed
Priority:
Normal
Assignee:
-
Category:
mod_proxy
Target version:
Start date:
2015-12-19
Due date:
% Done:

100%

Estimated time:
Missing in 1.5.x:

Description

The proxy module should forward the authenticated user (if lighttpd has detected one) in proxy requests through the REMOTE_USER http-header.

Other backends like fcgi/scgi/cgi already do that.

I did not find a way to add this header either with lua/mod_magnet or with the directive setenv.add-request-header.

So I'm supplying this simple patch (e.g. for usage with the coming buildbot version 0.9).
Apache has a similar feature, so lighttpd should have it too.

A notice in the wiki, that the REMOTE_USER http-header can only be trusted in secure environments, should be added.

Associated revisions

Revision 371e1bf7 (diff)
Added by gstrauss 3 months ago

[mod_extforward] support Forwarded HTTP Extension (#2703)

enable with, e.g.:
extforward.headers = ( "Forwarded" )
or
extforward.headers = ( "Forwarded", "X-Forwarded-For" )
or
extforward.headers = ( "Forwarded", "X-Forwarded-For", "Forwarded-For" )

The default remains:
extforward.headers = ( "X-Forwarded-For", "Forwarded-For" )

Support for "Forwarded" is not enabled by default since intermediate
proxies might not be aware of Forwarded, and might therefore pass
spoofed Forwarded header received from client.

extforward.params = ( # overwrite "Host" with Forwarded value
#"host" => 1
# set REMOTE_USER with Forwarded value
#"remote_user" => 1
)
Note: be cautious configuring trusted proxies if enabling these options
since Forwarded header may be spoofed and passed along indescriminantly
by proxies which do not handle Forwarded.

To remove "Forwarded" from incoming requests, do not enable these
options and instead use mod_setenv to clear the request header:
setenv.set-request-header = ( "Forwarded" => "" )

Other proxy-related headers which admin might evaluate to keep or clear:
setenv.set-request-header = ( "X-Forwarded-For" => "",
"X-Forwarded-By" => "",
"X-Forwarded-Server" => "",
"X-Origin-IP" => "",
"Via" => "",
#...
)

x-ref:
"Forwarded HTTP Extension"
https://tools.ietf.org/html/rfc7239
"Forward authenticated user to proxied requests"
https://redmine.lighttpd.net/issues/2703

Revision b2e2d42c (diff)
Added by gstrauss 3 months ago

[mod_proxy] support Forwarded HTTP Extension (fixes #2703)

To enable "Forwarded", must enable which params to include.
The recommended set is "for" and "proto" unless other params
are required and proper security precautions have been taken.
proxy.forwarded = ( "for" => 1,
"proto" => 1,
#"host" => 1,
#"by" => 1,
#"remote_user" => 1,
)

See https://tools.ietf.org/html/rfc7239 for info about "Forwarded"

x-ref:
"Forwarded HTTP Extension"
https://tools.ietf.org/html/rfc7239
"Forward authenticated user to proxied requests"
https://redmine.lighttpd.net/issues/2703

History

#1 Updated by stbuehler over 1 year ago

  • Target version changed from 1.4.39 to 1.4.x

The CGI environment includes the http headers in the HTTP_* namespace; outside this namespace the CGI variables have usually well-known semantics.

Adding a CGI environment variable into HTTP headers on the other hand isn't that obvious: as the headers send by a client are not confined to a "well-known" set, any name you choose could potentially conflict with a header sent by the client, so there is always a potential information loss if you overwrite the values.
Also you really need to make sure to always overwrite the value (i.e. delete first, then set if appropriate), otherwise the client could simply send it's own REMOTE_USER header and not authenticate otherwise.

I'm not convinced hard coding this logic for a single CGI variable is the correct way.

Maybe mod_magnet could offer a more flexible solution by making the request headers modifiable in lua; maybe mod_proxy could take a list of mappings of CGI vars -> HTTP header names (in this case we probably should first refactor CGI variable semantics into a common implementation for mod_*cgi, which would be a good idea anyway).

(Edit: btw, your patch is in "reverse" mode - it removes lines instead of adding them)

#2 Updated by gstrauss over 1 year ago

I'd suggest extending the Forwarded HTTP Extension https://tools.ietf.org/html/rfc7239 with a (non-standard) extension parameter 'auth_user="$REMOTE_USER"', with $REMOTE_USER properly url-encoded, and including it only if a new config param proxy.forwarded-auth-user = "enabled". Since lighttpd mod_proxy is a reverse proxy, it might choose to always include the Forwarded header, or that might be a config param, too. If Forwarded header is not always included, then mod_proxy should probably at least check for and strip auth_user param off the final list entry in Forwarded.

Recipients of the Forwarded header would have to trust the immediate upstream server as well as the intermediate network (if the connection is not encrypted), and would need to take care to properly parse and look at the final list entry in Forwarded header to look for auth_user. (There might be multiple list entries if there were multiple proxies adding to Forwarded). Properly parsing Forwarded headers includes handling header line wrapping as well as concatenation of multiple instances of Forwarded: header. Proper handling is also necessary in mod_proxy.

#3 Updated by gstrauss about 1 year ago

  • Category set to mod_proxy

#4 Updated by gstrauss 3 months ago

  • Status changed from New to Patch Pending
  • Target version changed from 1.4.x to 1.4.46

Large patch set pushed to lighttpd.net git personal/gstrauss/master branch. See DevelGit to obtain the code. Feedback appreciated.

This feature is experimental and subject to incompatible behavior changes.

Should param name be "auth_user" or "remote_user"? I used "remote_user" for now.
Should param "auth_type" be handled so that mod_auth can pass both AUTH_TYPE and REMOTE_USER?

#5 Updated by gstrauss 3 months ago

  • Status changed from Patch Pending to Fixed
  • % Done changed from 0 to 100

Also available in: Atom