Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds option to switch to a different user/group before starting a managed process #329

Merged
merged 2 commits into from
May 5, 2014

Conversation

achingbrain
Copy link
Contributor

This is an attempt to address part of #268 - if you run pm2 as root, everything it starts also runs as root.

It adds two options to the command line --run-as-user and --run-as-group.

If you are running pm2 as root, and you start a process like this:

# pm2 --run-as-user foo start test.js

..then pm2 will fork the current process (as root), set up the child's logs and pid file (as root, in /root/.pm2), then switch to user foo to require and run test.js. Because the logs were opened before the privilege drop the process can still write to them even though the new user doesn't have the permissions to do so.

If you then do ps aux | grep pm2 you'll see something like:

root            31568   0.0  0.0  2432784    476 s009  R+    7:30PM   0:00.00 grep pm2
foo             31564   0.0  0.1  3057912  23156   ??  S     7:30PM   0:00.10 pm2: test 
root            31561   0.0  0.1  3053776  19968   ??  Ss    7:30PM   0:00.12 pm2: Satan Daemonizer 

..which shows that pm2 is still running as root whereas the managed process test.js is running as foo.

@achingbrain
Copy link
Contributor Author

Erm, the pm2 test suite appears to be non-deterministic.

@pedrofranceschi
Copy link

+1

@kmctown
Copy link

kmctown commented May 4, 2014

+1 Spent the past few hours realizing pm2 start -u doesn't do this and ended up here.

@soyuka
Copy link
Collaborator

soyuka commented May 4, 2014

+1 (should be merged soon ;))

@Rush
Copy link

Rush commented May 5, 2014

If started from user foo will it allow user bar to use pm2 completely separately?

@achingbrain achingbrain deleted the run-process-as-different-user branch May 10, 2014 08:18
@tjwebb
Copy link

tjwebb commented May 19, 2014

I'm using --run-as-user foo and all my processes are still run as root.

@benw-needsmet
Copy link

Same thing here, I am using both --run-as-user foo etc. and I am still getting permisison errors because of this.

@benw-needsmet
Copy link

Hi, the problem I'm having is I am setting it either command line to add ie --run-as-user www-data or in the json configuration script as "run_as_user": "www-data" and either way it is not setting the permission of the process, thus when I run my script or connect to the server it creates files and what not with Root and not www-data therefore my other server scripts cannot read/write the file that are created in root, and therefore it gives a 'permission' error. And the way I have to do it is manually run the server doing something like sudo -u www-data node server.js --secure --host=domain.com ...

Any help would be nice or a fix for the problem would be nice as well.

Thanks

@benw-needsmet
Copy link

I'd appreciate for some help on this please? I am about temped to go to another process manager since it has been over 28 days from a response on the issue I'm having.

@tjwebb
Copy link

tjwebb commented Jul 1, 2014

I ended up switching to forever (https://www.npmjs.org/package/forever) because for my case, the --run-as-user feature was absolutely critical, but the pm2 maintainers didn't really seem to care. And I generally found that the extra features of pm2 aren't worth it, since most of them don't actually work.

In my forever config file, I just prepend the commands with sudo -u <user> and everything works great.

@Rush
Copy link

Rush commented Jul 1, 2014

I would too advise using forever. pm2 is really insecure at its roots.

@soyuka
Copy link
Collaborator

soyuka commented Jul 1, 2014

I'm running pm2 without root without troubles.

su - someone
pm2 start xxx.js
ps -u someone | grep pm2

@tjwebb
Copy link

tjwebb commented Jul 1, 2014

  1. Then the .pm2 files are in that user's home directly. How can the sysadmin see all the processes when pm2 scatters those files everywhere? This is a benefit of the mythical --run-as-user feature, among other things.
  2. What's the point of --run-as-user, then, if you're telling us to use su -? How would you automate this if it requires creating a new shell via su -?
  3. How does this work with the upstart script? Would it know to start that process as that user every time?
  4. How would I codify this in the .json files that pm2 uses to start processes? That's where I want to store this info, not in my fingers, which would have to re type this every time I want to start a new process as a different user.

Of course it's possible to contrive a simple one-off scenario where it works. But it doesn't work in general. If I'm going to start a process using su -, then what do I need pm2 for, anyway? The point here is that the --run-as-user feature, and many other features that pm2 claims to have, simply do not work. One feature that works is better than 100 that don't.

@achingbrain
Copy link
Contributor Author

As contributed this PR doesn't solve the fuller problem and should probably be reverted.

I've kind of stopped using pm2 because of a lot of the issues cited here.

@soyuka
Copy link
Collaborator

soyuka commented Jul 1, 2014

pm2 is not ment to be multi-user - meaning that:

  • there are no security checks, everyone can start/stop/restart processes
  • different users starting processes on the same pm2 instance will not work properly (will never work?)
  • dump does not save the "user" parameter
  • there are no user mention in a JSON config file

You could try to run one instance of pm2 per user.

--run-as-user only starts a process with a specific user but it does not do security checks when restarted or such. It is not my PR, not my call to get this feature merged and I haven't worked on "multi-user" stuff on pm2. "multi-user" is not our priority.

I think you're trying to build some kind of SAAS service, and pm2 won't be the best tool there. To me, on one virtual server, it's working fine to handle processes errors, logs, upstart etc. (with a www user). I have nothing to complain about.

many other features that pm2 claims to have, simply do not work.

Such as?

@tjwebb
Copy link

tjwebb commented Jul 1, 2014

pm2 is not ment to be multi-user

So am I misunderstanding the README?

Let's say you want the startup script to be executed under another user.
Just use the -u <username> option !

different users starting processes on the same pm2 instance will not work properly (will never work?)

$ pm2 --run-as-user foo start app.js  # Start app.js as user foo instead of root (pm2 must be running as root)

Does "Start app.js as user foo instead of root" mean something different to you? If it's known not to work, why the hell is it being advertised as a feature?

there are no user mention in a JSON config file

  "deploy" : {
    "production" : {
      "user" : "node",

Sadly, you are actually more accurate than the README, since none of those features work at all. They are either totally broken or nonexistent. Either way, I've wasted enough of my time with this project.

@soyuka
Copy link
Collaborator

soyuka commented Jul 1, 2014

Yeah you're criticizing a lot but you are not very productive.

I think that those features are coming from Pull Requests and they should be tested and fixed, maybe with time they will. As I said before, multi-user is not my priority and there is a lot to do to handle users properly (security checks for instance). Also, as you might know, those features are not easy to test because they'd require additionnal system users, a unix machine etc.

 "deploy" : {
    "production" : {
      "user" : "node",

Seems to be the deployment feature, maybe that's for the pm2 future.

@Unitech
Copy link
Owner

Unitech commented Jul 1, 2014

  • PM2 is not for multi user at it's root
  • @tjwebb you're always complaining about a project that doesn't receive any fund, instead fork it and fix it
  • @tjwebb you're trying to build a PaaS system on PM2, PM2 is not meant to help you in this. PM2 is dedicated to Node worker machine that only need to manage two users, root and XUSER, not a fleet of users. Try to use Docker or whatever instead

pm2 aren't worth it, since most of them don't actually work.

There are more than 300 tests

(multi-user stuff) pm2 maintainers didn't really seem to care.

Right.

the extra features of pm2 aren't worth it,

Well I think you also don't need forever, just use that:

#!/bin/bash

while true; do
    node app.js
done

À bon entendeur,

@tjwebb
Copy link

tjwebb commented Jul 1, 2014

All I need is a way to manage a bunch of processes that each run as a different user. This is not PaaS, this is basic. If pm2 does not do this, as you're saying here, then the README should not say that it does. Since this is one of your more popular topics in the tracker, I'm apparently not the only one who was deceived by the documentation. https://github.com/Unitech/pm2/search?q=as+user&type=Issues.

So this is the logical corner you've backed yourself into: either the README is wrong/confusing and I and a bunch of people are using pm2 expecting features it doesn't have, or it's correct, and pm2 is riddled with bugs that you are ignoring in order to build new deployment and monitoring features.

@Unitech
Copy link
Owner

Unitech commented Jul 1, 2014

Ok I will revert this PR, if we get funding we will look at remixing the root of PM2 to handle multi users.

@benw-needsmet
Copy link

The main issue I had was. The environment that I am running the server is in a www-data user environment that is shared between apache2 and nodejs. When setting up the configuration script for the server I did the following:

[
{
"name": "NodeJS Server",
"script": "server.js",
"args": "['--secure', '--host=mydomain.org']",
"cwd": ".",
"run_as_user": "www-data",
"run_as_group": "www-data",
"exec_mode": "fork_mode"
}
]

Now this does work, the only thing is it won't run as user or run as the group as I need it to be. This is what I was expecting when I read the README, and therefore because from what I am seeing above that those features are NOT working as they are suppose to. Therefore it shouldn't be included as a feature to begin with. When I am looking for something for a solution, I expect professional software and this looked to be very good promising. Now I am disappointed that I have to look at another product in resolving my solution.

@Unitech
Copy link
Owner

Unitech commented Jul 2, 2014

When I am looking for something for a solution, I expect professional software

Give us some help so

https://github.com/Unitech/pm2/blob/master/lib/ProcessContainer.js#L174

@soyuka
Copy link
Collaborator

soyuka commented Jul 2, 2014

I'm personally running my own blog with pm2, an apache proxy on a www user with no trouble at all.
In my case, pm2 is started by the www user and pm2 startup -u www worked as expected (except #543 fixed in #548).
The matter with those kind of calls is that it's hard to unit test on every operating systems.


You'd notice that I do not need --run-as-user when pm2 is started by the user that has the right permission:

soyuka@vps:~$ ps -u www
  PID TTY          TIME CMD
 1633 ?        00:00:20 pm2: Satan Daem
 1639 ?        00:02:08 pm2: ghost

But, as another user, I can start/stop/restart the ghost process, and that should be fixed.

Assuming we are in a real multi-user environment, we might want to:

  • run processes per users - one pm2 app that handle everything
  • have one pm2 instance per user

To me the second solution would be better, and it should not be hard to make it work.
Running one pm2 instance for all users leads to a lot more developments to handle all cases.

@Unitech
Copy link
Owner

Unitech commented Sep 19, 2014

The new PM2 rc (0.11.0-beta1) integrates UNIX socket instead of TCP connection, so now you can pop PM2 daemon for each user :

$ npm install pm2@rc -g

@aspnetde
Copy link

aspnetde commented Jan 8, 2015

Just a thought: I found PM2 absolutely useful and well designed, it seemed to be the solution I was looking for. I really appreciate the work that is done here, but not implementing and ignoring such a fundamentally important feature as privilege separation is unfortunately a show-stopper.

You're right: if using only one Node application/website per server, the current setup is sufficient. But as soon as I have at least two sites running side by side, I don't want to run them with the same account, risking to affect each other in case of any vulnerability. I am not a bad developer, but who can say their code is 100% secure? I am not that guy ;-).

So I need to separate all of the "instances". I hope you'll find the time and motivation to implement that feature in the future.

@Unitech
Copy link
Owner

Unitech commented Jan 8, 2015

Yes it's done!

With UNIX socket feature you can now run totally separated instances of PM2.

You can either overidde the PM2_HOME variable to create another instance of PM2 for the same user:

$ PM2_HOME='/home/myuser/.pm2' pm2 start app1.js --name="app-one"
$ PM2_HOME='/home/myuser/.pm2' pm2 list 

$ PM2_HOME='/home/myuser/.pm3' pm2 start app2.js --name="app-two"
$ PM2_HOME='/home/myuser/.pm3' pm2 list

Or under different users:

user-1$ pm2 start app1.js

user-2$ pm2 start app2.js

In this case the user-1 will not be able to list the process of the pm2 started under user-2 and vice versa

@aspnetde
Copy link

aspnetde commented Jan 9, 2015

Hi @Unitech,

Thanks for the quick reply. I don't see how the first approach could help, as the two apps still would run under the same user account.

I already did try your second suggestion, too. My problem has been, that the configuration got lost after a reboot. But when executing

pm2 startup ...

for that particular user again, it seems to work. Great. Not yet the best solution I could think of, but it works. Thanks!

aspnetde added a commit to aspnetde/nodejs-webserver-guide that referenced this pull request Jan 11, 2015
@dandv
Copy link
Contributor

dandv commented May 10, 2015

Does this work as of May 2015? See also #992 (comment)

I'm trying to start Ghost as user ghost but to create a startup script after pm2 dump, I need to run pm2 as root. When I run it from a root login, it doesn't see any pm2 processes.

@adamscybot
Copy link

The main problem with this solution for me (at least with latest ver) is that when running as root, pm2 list is empty. IMO, root should be able to see all processes of all users.

@soyuka
Copy link
Collaborator

soyuka commented Jul 17, 2015

@adamscybot For this to work we'd need to connect to every RPC available on the server. I think it's possible but it would add a lot of complexity (see Interactor).

@adamscybot
Copy link

I think this is the last step to making PM2 work good in a multi-user setup. It could also be used to solve the problems mentioned above with pm2 startup etc as when these commands are run as root, they would take into account all processes. Is this something that is likely to happen?

Don't like a lot of the self entitled bickering in this thread -- but there is a point to be made about multi-user (even at a basic level) being more usable.

@aaronroberson
Copy link

First off, I love PM2, you guys are killing it!

The comment from @adamscybot is spot on regarding the need to have root behave as an overlord of all the processes.

Currently if I run any utility commands (pm2 list, monit, etc.) as the root user it spawns a new process which makes a small footprint in memory.

I would love to see it PM2 updated so that the root user can list, monit and perform other utility operations with access to all processes for all users and without spawning a new process of it's own.

@slavafomin
Copy link

slavafomin commented Jul 14, 2016

Hello!

Thank you for this great module!

I've setup PM2 to automatically start with the system under the pm2 user, however, I want to start each application under it's own unix user, otherwise it would be a high security risk. I've already created all the users and configured ACL entries on the filesystem properly. Is it possible to do this with PM2?

All my apps are declared in the single apps.json file, e.g.:

{
    "apps": [
        {
            "name": "foo",
            "cwd": "/var/apps/foo/current",
            "script": "app.js",
            "env": {
                "NODE_ENV": "production",
                "PORT": 8001
            }
        }
    ]
}

I'm running it as pm2 start /var/apps/apps.json && pm2 save.

And I would prefer to control all the apps from the single pm2 user if possible. Any suggestions will be highly appreciated. Thank you!

@mxmaxime
Copy link

Hello, I've the same problem as @slavafomin. Any news ? It has been a long time...

Thank you for your understanding and pm2 !

@icharge
Copy link

icharge commented Oct 30, 2018

Any update? I'm looking for PM2 startup with user. This still startup as root.

@knoxcard
Copy link

knoxcard commented Mar 23, 2019

Best solution for me, added these two lines to the top of my app.js file...

process.setgid('www-data')
process.setuid('www-data')

then

pm2 start app.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.