Coder Perfect

[closed] Best practices for running Node.js on port 80 (Ubuntu / Linode)

Problem

I’m setting up my first Node.js server on a cloud Linux node, and I’m still learning about Linux administration. (By the way, I’m not using Apache at the same time.)

Everything is installed successfully, however I am unable to listen on port 80 with node unless I use the root login. However, for security reasons, I would not execute it as root.

What is the most effective way to:

Should I redirect traffic from port 80 to a different listening port?

Thanks

Asked by Robotbugs

Solution #1

On my cloud instances, I use the following command to convert port 80 to port 3000:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000

After that, I start my Node. On port 3000, you’ll find JavaScript. Port 80 requests will be redirected to port 3000.

You need also add that line to your /etc/rc.local file, omitting the sudo. When the machine boots up, the redirect will be added. Because the commands in /etc/rc.local are run as root when the system boots, you don’t require sudo there.

To get started with Node.js, use the forever module. It will ensure that it restarts if it crashes, and console logs will be redirected to a file.

Add your Node.js start script to the /etc/rc.local file you changed for port redirection. When the system boots up, your Node.js launch script will run.

This is true not only for Linode, but also for Digital Ocean, AWS EC2, and other VPS providers. On RedHat systems, however, /etc/rc.local is /ect/rc.d/local.

Answered by Daniel

Solution #2

Allow a trusted user to use port 80.

Remember, we don’t want you to run your apps as root, but there’s a catch: your safe user doesn’t have access to the default HTTP port (80). Your goal is to be able to create a website that people may access by going to a simple URL such as http://ip:port/.

Unfortunately, unless you log in as root, you’ll have to use a URL like http://ip:port, where the port number is greater than 1024.

Many people find themselves in this situation, but the remedy is simple. There are a few possibilities, but I prefer this one. Type the commands below:

sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep `readlink -f \`which node\``

Now, when you tell a Node application that you want it to run on port 80, it will not complain.

Take a look at this resource link.

Answered by Meet Mehta

Solution #3

After binding to port 80, remove root privileges (or 443).

This ensures that port 80/443 is protected while prohibiting you from serving requests as root:

function drop_root() {
    process.setgid('nobody');
    process.setuid('nobody');
}

Here’s a complete example of how to use the above function:

var process = require('process');
var http = require('http');
var server = http.createServer(function(req, res) {
    res.write("Success!");
    res.end();
});

server.listen(80, null, null, function() {
    console.log('User ID:',process.getuid()+', Group ID:',process.getgid());
    drop_root();
    console.log('User ID:',process.getuid()+', Group ID:',process.getgid());
});

More information can be found in this complete reference.

Answered by slund

Solution #4

Daniel is correct in regards to port 80 (which was the initial question). I recently switched to https and had to replace iptables with a light nginx proxy to manage SSL certs. I discovered a helpful answer, as well as a gist from gabrielhpugliese on how to deal with it. In general, I

Hopefully, this will save someone else some time and aggravation. There’s probably a pure-node way to achieve this, but nginx was quick and effective.

Answered by Nick Benes

Post is based on https://stackoverflow.com/questions/16573668/best-practices-when-running-node-js-with-port-80-ubuntu-linode