Node.js: ECONNREFUSED on Port 80
Asked Answered
W

5

7

I've written a web-server using Node.js. When I tried to test my server with the tester I've written for it, I succeed only if the port I'm using for the server is not 80. I've checked on netstat, and no other application is using port 80. The error I'm getting on the console is:

Error: connect ECONNREFUSED
  at errnoException (net.js:640:11)
  at Object.afterConnect [as oncomplete] (net.js:631:18)

What can be done in this case?

Whetstone answered 9/1, 2012 at 17:53 Comment(4)
What is the port number the server worked for? Maybe you don't have permission to bind to port 80.Dhaulagiri
I've tried 8080 and it works like a charm.Whetstone
If you're using Ubuntu for example (or another Unix system) you can try sudo node sample.js. That does the trick normally.Hydrothorax
I'm having a similar problem, but higher port assignments don't work, nor does 'sudo'Beginner
K
3

You might not have permission to bind to ports below 1024 (including 80) as a normal user (e.g. non-root), try a higher numbered port (above 1024, e.g. 8080).

[Edit]

Depending on your target system, and assuming you are its administrator, then you can probably work around the problem like so:

  1. Execute your program using "sudo", such as: sudo node ./myprogram.js.

  2. Or, login as the "root" user on your system and run the program as normal.

However, don't get in the habit of doing either of these on a regular basis (until you understand why), they can potentially introduce security holes which may be exploitable by malicious, motivated individuals.

Kahl answered 9/1, 2012 at 17:57 Comment(6)
I have to set the port to 80 (it's an assignment I have to submit, so It has to work also on port 80). How can I get this permission?Whetstone
Permission may be granted by a system administrator. Note that your program will work the same on any port number, as long as the user running the program has permission to bind to that port.Kahl
It is my own computer. How can I do that?Whetstone
@limlim: it depends on your system, but try sudo node ./myprogram.js and enter your password when prompted. Alternatively, log in as the root user and run your program (but don't get in the habit of doing that, it's very bad!).Kahl
I added an answer with a code example how to drop the root privileges after the server has been startet to prevent a security hole by answering web requests as rootWardieu
You can also listen on 8080 and have iptables forward incoming 80 to 8080 like so: sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 && sudo iptables-savePlacentation
P
18

You should not make a habit of running node as a privileged user. Here is a method I'm using on 6 different machines:

Use iptables to forward incoming traffic on port 80 to 8080 like so:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

Then be sure to save that

sudo iptables-save

Youd also want to add that to rc.local so those are set at reboot or instance launch (in the case of EC2 or other cloud)

Then you can safely start node listening on 8080 as any user.

Placentation answered 9/2, 2012 at 19:11 Comment(4)
Do you not also need to make outbound traffic to port 8080 forward to port 80?Zagreb
@Zagreb You do not. That is automatic.Placentation
Huge +1 on this solution. I had considered using an apache virtualhost to do the same thing, but this did the trick!Brinson
@Placentation it is not working for me without making outbound traffic. Ubuntu 12.10. It only works after i give this command also. iptables -t nat -A OUTPUT -d localhost -p tcp --dport 80 -j REDIRECT --to-ports 8080Hornblende
W
10

This is basically an addition to the answer from maerics, but since I want to add a code example I write another answer with additional information how to prevent security problems.

Usually web servers are started as root, because this is needed to bind on ports below 1024, but then they change the user they run under to an not privileged user.

You can do this with node.js using process.setuid("username").

The following example starts the server and then drop the root permissions to the user "www-data" after it bound itself to port 80 when started as root:

function StartServer() {
  console.log("Starting server...");
  // Initalizations such as reading the config file, etc.
  server = http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
  });
  try {
    server.listen(80, "0.0.0.0", function(){
      process.setuid("www-data");
    });
  }
  catch(err) {
    console.error("Error: [%s] Call: [%s]", err.message, err.syscall);
    process.exit(1);
  }
}
Wardieu answered 11/1, 2012 at 14:28 Comment(4)
+1 also, just FYI you can add language syntax highlighting hints (link) to your code snippets to make them prettier!Kahl
thanks, guess it did not work by itself without the javascript tag in the question :)Wardieu
yeah, the auto-detect seems to have the most trouble with ECMAScript derivatives for some reason.Kahl
The .setuid is exactly what is needed, especially when trying to start this from Upstart or similar where everyone else is saying "do -u www-data".Concepcion
K
3

You might not have permission to bind to ports below 1024 (including 80) as a normal user (e.g. non-root), try a higher numbered port (above 1024, e.g. 8080).

[Edit]

Depending on your target system, and assuming you are its administrator, then you can probably work around the problem like so:

  1. Execute your program using "sudo", such as: sudo node ./myprogram.js.

  2. Or, login as the "root" user on your system and run the program as normal.

However, don't get in the habit of doing either of these on a regular basis (until you understand why), they can potentially introduce security holes which may be exploitable by malicious, motivated individuals.

Kahl answered 9/1, 2012 at 17:57 Comment(6)
I have to set the port to 80 (it's an assignment I have to submit, so It has to work also on port 80). How can I get this permission?Whetstone
Permission may be granted by a system administrator. Note that your program will work the same on any port number, as long as the user running the program has permission to bind to that port.Kahl
It is my own computer. How can I do that?Whetstone
@limlim: it depends on your system, but try sudo node ./myprogram.js and enter your password when prompted. Alternatively, log in as the root user and run your program (but don't get in the habit of doing that, it's very bad!).Kahl
I added an answer with a code example how to drop the root privileges after the server has been startet to prevent a security hole by answering web requests as rootWardieu
You can also listen on 8080 and have iptables forward incoming 80 to 8080 like so: sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 && sudo iptables-savePlacentation
S
0

An alternate option that I haven't seen in the above list is also to permit your process to bind to a privileged port (<1024) by executing the following command on the node executable. (Adapt the path)

setcap 'cap_net_bind_service=+ep' /opt/meteor/.meteor/tools/latest/bin/node

The annoyance is that you must reissue this command every time you update or change the node executable.

Regards,

Summertree answered 5/5, 2014 at 12:3 Comment(0)
S
0

I use Nginx server (port 80) in front of Node.js (any port >1024). It works great.

Standfast answered 25/7, 2014 at 8:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.