2

So I wanted to run a Node server on port 80 but I didn't want to run the entire process on root privileges, for security I thought this would be the best.

So I thought a good solution would be to use as root:

su - (myuser) -c 'node forever script to run'

However I get EACCESS errors but running the script directly as root is fine. I hear others doing the same and working for them so could it be that I am doing something different?

Is there a better strategy to do this, to open the port on root privileges and then drop the root privileges once the application is running?

  • What operating system are you using? (I can see it is a Unix, but which one?). – ctrl-alt-delor Sep 20 '14 at 11:32
3

yes, can do this. see this blog post that explains better than I can.

https://thomashunter.name/blog/drop-root-privileges-in-node-js/

I am copying the relevant code here in case the blog becomes unavailable

app.listen(80, 'localhost', null, function() {
  // Listening
  try {
    console.log('Old User ID: ' + process.getuid() + ', Old Group ID: ' + process.getgid());
    process.setgid('users');
    process.setuid('tlhunter');
    console.log('New User ID: ' + process.getuid() + ', New Group ID: ' + process.getgid());
  } catch (err) {
    console.log('Cowardly refusing to keep the process alive as root.');
    process.exit(1);
  }
});
  • +1 for the link, although I may not use the code above, the link pointed me towards the 'authbind' tool. So will test that out later and see how it goes. – iQ. Sep 20 '14 at 11:42
2

su - <user> switches to <user> before doing anything else, so the NodeJS server is going to be started as your user and not have any clue about root running the su command, and since users aren't allowed to use privileged ports this is never going to work.

There are two ways to work around this that I can think of off the top of my head:

  1. Using a file capability that will let unprivileged users open privileged ports. Though they generally don't work on scripts in this case they should since, as far as I know, you start the server using node <filename>. (Correct me if I'm wrong tho.)

  2. Using a reverse-proxy like NGINX that sits in front of the application server, running as root. In this case users connect directly to NGINX which then proxies the connections to the application server, but more easily lets you run multiple servers/instances and lets NGINX cache resources. This tends to be the generally preferred approach when it comes to deploying application servers.

0

If using Gnu/Linux then you can use capabilities to give the application the capability to open privileged ports, and no other capabilities (root gives all capabilities).

See here for a very basic introduction https://unix.stackexchange.com/questions/101263/what-are-the-different-ways-to-set-file-permissions-etc-on-gnu-linux

[edit:] The GNU/Linux capability you are looking for is cap_net_bind_service. On Solaris, use PRIV_NET_PRIVADDR. For more detailed information, see man capabilities(7) (Linux) or man privileges(5) (Solaris).

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.