Passenger User Switching utilizing various mod_auth's in Apache

35 views
Skip to first unread message

Jeremy Nicklas

unread,
Mar 20, 2015, 11:10:53 AM3/20/15
to phusion-...@googlegroups.com
It is described in the documentation that Passenger starts a Rack app using either the provided PassengerUser in the apache config or as the owner of the `config.ru` file. Unfortunately the PassengerUser is defined when Apache initially starts up and cannot be altered dynamically upon requests.

Would it be possible to pass the environment variable $REMOTE_USER (or a variation of it since we use mod_auth_openid which sets REMOTE_USER=https://openid.server.com/openid/username) to Passenger for User Switching?

Currently this doesn't seem possible looking at the code. Although, I can certainly modify the method `cmd_passenger_user` in `ext/apache2/ConfigurationSetters.cpp` to read in the environment variable and parse it, but I'd rather not alter the code if at all possible.

Any ideas of workarounds would be greatly appreciated. Thanks so much ahead of time.

-Jeremy Nicklas

Hongli Lai

unread,
Mar 20, 2015, 11:19:48 AM3/20/15
to phusion-passenger
No, that is not possible. Switching user requires starting an app
process from scratch, but that is far too expensive to do for every
request.
> --
> You received this message because you are subscribed to the Google Groups
> "Phusion Passenger Discussions" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to phusion-passen...@googlegroups.com.
> To post to this group, send email to phusion-...@googlegroups.com.
> Visit this group at http://groups.google.com/group/phusion-passenger.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/phusion-passenger/17d69513-dc20-4355-8153-57de6a6744eb%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Phusion | Web Application deployment, scaling, and monitoring solutions

Web: http://www.phusion.nl/
E-mail: in...@phusion.nl
Chamber of commerce no: 08173483 (The Netherlands)

Jeremy Nicklas

unread,
Mar 20, 2015, 1:40:21 PM3/20/15
to phusion-...@googlegroups.com, hon...@phusion.nl
In our current setup we launch a new Apache server for each user. This has the overwhelming benefit of having a Passenger App launch processes on our system as an OS-user while maintaining security through system level file permissions. Users won't be able to access files or executables they weren't already given permission to at the system-level from within the Passenger App.

Unless I am misunderstanding  how the spawning process goes this should be less expensive than launching an entire Apache server per user.

So if UserA requests a Passenger App the HelperAgent would spawn a process under UserA's account. Then if UserB made a request to that same app then it would spawn a process under UserB's account. No matter how many requests UserA made to the app, it wouldn't spawn a new process and continue to use the process launched under UserA's account? Is that understanding correct? Or would it literally spawn a new process for UserA for every single request he made to the app?

Thanks again for the help so far.

Hongli Lai

unread,
Mar 30, 2015, 5:45:16 AM3/30/15
to Jeremy Nicklas, phusion-passenger
On Fri, Mar 20, 2015 at 6:40 PM, Jeremy Nicklas <jnick...@gmail.com> wrote:
> In our current setup we launch a new Apache server for each user. This has
> the overwhelming benefit of having a Passenger App launch processes on our
> system as an OS-user while maintaining security through system level file
> permissions. Users won't be able to access files or executables they weren't
> already given permission to at the system-level from within the Passenger
> App.
>
> Unless I am misunderstanding how the spawning process goes this should be
> less expensive than launching an entire Apache server per user.

Spawning an application process is actually more expensive than
launching an Apache instance. Compared to most Ruby/Python/Node.js
apps, Apache is tiny and starts up very quickly, maybe in half a
second, and uses a few MB of memory. In contrast, a Rails app can take
5 seconds or longer to start, and can use 200+ MB of memory.


> So if UserA requests a Passenger App the HelperAgent would spawn a process
> under UserA's account. Then if UserB made a request to that same app then it
> would spawn a process under UserB's account. No matter how many requests
> UserA made to the app, it wouldn't spawn a new process and continue to use
> the process launched under UserA's account? Is that understanding correct?

That depends on your configuration. If you set PassengerMaxInstances
to 1, then yes. If not, then Passenger may decide to spawn more UserA
app processes depending on the amount of traffic.

> Or would it literally spawn a new process for UserA for every single request
> he made to the app?

No, it doesn't, because spawning a process is so expensive.

Now that I look back at your question, maybe you're not talking about
the *system* environment variables, but the *Rack/request/CGI*
environment variables. Those are two different things. REMOTE_USER is
already set in the Rack/request/CGI environment variables.

Jeremy Nicklas

unread,
Mar 30, 2015, 1:21:00 PM3/30/15
to phusion-...@googlegroups.com, jnick...@gmail.com, hon...@phusion.nl


On Monday, March 30, 2015 at 5:45:16 AM UTC-4, Hongli Lai wrote:
On Fri, Mar 20, 2015 at 6:40 PM, Jeremy Nicklas <jnick...@gmail.com> wrote:
> In our current setup we launch a new Apache server for each user. This has
> the overwhelming benefit of having a Passenger App launch processes on our
> system as an OS-user while maintaining security through system level file
> permissions. Users won't be able to access files or executables they weren't
> already given permission to at the system-level from within the Passenger
> App.
>
> Unless I am misunderstanding  how the spawning process goes this should be
> less expensive than launching an entire Apache server per user.

Spawning an application process is actually more expensive than
launching an Apache instance. Compared to most Ruby/Python/Node.js
apps, Apache is tiny and starts up very quickly, maybe in half a
second, and uses a few MB of memory. In contrast, a Rails app can take
5 seconds or longer to start, and can use 200+ MB of memory.

Unfortunately, in our organization the reason an Apache server is started for each unique user is so that they can run a Passenger app in their user space. That means we not only start the Apache process, but we also start up a Passenger App process. After a certain period of inactivity we do clean this up by shutting down the Apache instance and any remaining Passenger processes owned by that user.


> So if UserA requests a Passenger App the HelperAgent would spawn a process
> under UserA's account. Then if UserB made a request to that same app then it
> would spawn a process under UserB's account. No matter how many requests
> UserA made to the app, it wouldn't spawn a new process and continue to use
> the process launched under UserA's account? Is that understanding correct?

That depends on your configuration. If you set PassengerMaxInstances
to 1, then yes. If not, then Passenger may decide to spawn more UserA
app processes depending on the amount of traffic.

 
Thanks for the clarification. I know this is not a feature implemented in Passenger, but if someone did modify


to also include REMOTE_USER. I am curious whether if UserA making a request to the app, that Passenger will only pass those requests to the process running under UserA's account and not the process running under UserB's account. The same for UserB making a request, only the process running under UserB receives that request.

This probably wouldn't work because Passenger currently doesn't distinguish between the same app running as two different users.
 
> Or would it literally spawn a new process for UserA for every single request
> he made to the app?

No, it doesn't, because spawning a process is so expensive.

Now that I look back at your question, maybe you're not talking about
the *system* environment variables, but the *Rack/request/CGI*
environment variables. Those are two different things. REMOTE_USER is
already set in the Rack/request/CGI environment variables.


I apologize for the confusion. I meant to say the CGI environment variable REMOTE_USER in our case set by mod_auth_openid.
Reply all
Reply to author
Forward
0 new messages