Friday, January 13, 2012

Run Node on port 80 with non-root user privileges

I had been toying around wtih Node.js these few days.  With background of PHP programming, I had experience on setting up a proper LAMP server (Linux + Apache + MySQL + PHP) from scratch, I quickly noticed that running Node on port 80 with superuser privilege (binding to port below port number 1024 requires superuser aka root ) triggers my security concerns.

Although Node is widely discussed among early technology adpoters but I still wasn't able find sufficient information to run Node on production environment.  In general, Node users doesn't speak about binding port 80 while dropping the superuser privileges.

After a quick look into the Node documentation, I found the process object which packed with two methods called process.setgid() and process.setuid(). These 2 methods are crucial to prevent the process from accessing files that was not intended for it in case anything goes wrong.


Bellow are the sample code with a bare bone express setup to drop the superuser privileges
...
var process_user = 'evert';
var process_group = 'evert';
...

app.listen(80, function(){
  try {
    console.log('Giving up root privileges...');
    process.setgid(process_group);
    process.setuid(process_user);
    console.log('New uid: ' + process.getuid());
  }
  catch (err) {
    console.log('Failed to drop root privileges: ' + err);
  }
});

...
Without doubts, the most ideal case is to drop the superuser privileges as soon as possible, before everything else being initialized. However that would means diving into the Express.js code to initialize the socket.