65

I am trying to create https server to test socket io by node js. According this page

openssl genrsa -out privatekey.pem 2048 
openssl req -new -key privatekey.pem -out certrequest.csr 
openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem

enter image description here

I created privatekey.pem and certificate.pem and this is my code:

var express = require('express');
var https = require('https');
var fs = require('fs');

var options = {
    key: fs.readFileSync('privatekey.pem'),
    cert: fs.readFileSync('certificate.pem')
  };
var app = express();

 var server = https.createServer(options, app).listen(443);

var io = require('socket.io').listen(server,()=>{
    console.log('listen to https');
});



io.on('connection', function (socket) {
    console.log(' user connected');
    socket.on('disconnect', function () {
        console.log('a user disconnected');
    });
});

but after running server i got this errors:

tazik@mx:/mnt/Projects/Projects/nodejs/socketserver
$ node app.js 
events.js:288
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES: permission denied 0.0.0.0:80
    at Server.setupListenHandle [as _listen2] (net.js:1292:21)
    at listenInCluster (net.js:1357:12)
    at Server.listen (net.js:1445:7)
    at Object.<anonymous> (/mnt/Projects/Projects/nodejs/socketserver/app.js:15:24)
    at Module._compile (internal/modules/cjs/loader.js:1158:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
    at Module.load (internal/modules/cjs/loader.js:1002:32)
    at Function.Module._load (internal/modules/cjs/loader.js:901:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
    at internal/main/run_main_module.js:18:47
Emitted 'error' event on Server instance at:
    at emitErrorNT (net.js:1336:8)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  code: 'EACCES',
  errno: 'EACCES',
  syscall: 'listen',
  address: '0.0.0.0',
  port: 80
}

I am using linux mx.

starball
  • 20,030
  • 7
  • 43
  • 238
Cyrus the Great
  • 5,145
  • 5
  • 68
  • 149
  • I think Apache is using port 80 so please make sure port is not getting conflicted (If you have apache on your system)? – Deep Kakkar Feb 24 '20 at 09:42
  • 1
    [enter image description here](https://i.stack.imgur.com/OgL6I.png) For Windows.. Here I'm Killing The port number:1024 and Works properly :) – Sanket Bendale May 17 '21 at 15:57
  • Does this answer your question? [Node.js EACCES error when listening on most ports](https://stackoverflow.com/questions/9164915/node-js-eacces-error-when-listening-on-most-ports) – Michael Freidgeim Dec 21 '21 at 22:28

9 Answers9

135

Non-privileged user (not root) can't open a listening socket on ports below 1024.

Check this

Give Safe User Permission To Use Port 80

Remember, we do NOT want to run your applications as the root user, but there is a hitch: your safe user does not have permission to use the default HTTP port (80). You goal is to be able to publish a website that visitors can use by navigating to an easy to use URL like http://ip:port/

Unfortunately, unless you sign on as root, you’ll normally have to use a URL like http://ip:port - where port number > 1024.

A lot of people get stuck here, but the solution is easy. There a few options but this is the one I like. Type the following commands:

> 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.

EDIT: Add a space in the setcap command

MattR
  • 127
  • 2
  • 11
Sohan
  • 6,252
  • 5
  • 35
  • 56
  • when i do your suggestion , i expected to print console.log('listen to https'); but nothing is happen. I think something in my code is wrong @sohan – Cyrus the Great Feb 24 '20 at 09:54
  • I am trying to understand your above code, where are you starting service with `http` port. I can see only `https` being used. Could you please clean the code? @sayreskabir – Sohan Feb 24 '20 at 10:02
  • I suggest you follow this.https://socket.io/get-started/chat/ and https://socket.io/docs/. I think you are not service your request with `html` and socket are not being created. Because when using express there are certain steps – Sohan Feb 24 '20 at 10:16
  • How are you notifying server when client joins, are you doing somethings like this, ` var socket = io.connect('http://localhost:3000'); socket.on('connect', function(data) { socket.emit('join', 'Hello World from client'); });` – Sohan Feb 24 '20 at 10:29
  • The problem is when i want to connect so server by `https:///172.16.130.3:443` i got `Connection to https:///172.16.130.3:443 timed out!` @sohan – Cyrus the Great Feb 24 '20 at 10:45
  • I get `Note must be a regular (non-symlink) file.` – Chiptus Aug 23 '20 at 10:39
  • Looks like the symlink is linking to another file. Could you try running directly on file location like `/usr/bin/nodejs` ? – Sohan Aug 25 '20 at 07:30
  • I had the same issue, In my case I change the port from 80 to 8080 and everything run just fine. Thanks for helping. – Felipe Windmoller Nov 04 '20 at 15:25
  • @Chiptus I got the same error. There is a space missing in the second command, should be `sudo setcap cap_net_bind_service=+ep \`readlink -f \\`which node\\`\`` I tried to edit the post but StackOverflow doesn't allow less than 6-character edits – MattR Dec 06 '20 at 20:09
  • @MattR thanks. Just add a line at the bottom with "edit: remove space" :) – Chiptus Dec 07 '20 at 08:12
  • 1
    @Chiptus ahh wow that's so obvious. I should've realized it. Thanks! – MattR Dec 07 '20 at 21:42
  • Not true, I tried 1023 or 1000 and they work - so where that magical number 1024 comes from, you tell me ! (I'm on a Windows OS). – joedotnot Apr 11 '21 at 18:39
  • replacing `apt-get` with `yum` did worked for me. – Santosh Jul 05 '22 at 12:11
  • @Sohan how to install `libcap2-bin` in AWS EC2 AMI instance? I always got 'No package libcap2-bin available' error when doing `sudo yum install libcap2-bin` – eggsloveoats Jan 31 '23 at 23:10
  • This is also a typical issue when running servers inside a WSL Linux distro – Greg Feb 22 '23 at 19:40
20

I believe you need root privileges to run on ports below 1024.

sudo node app.js

If you do not have a sudo account, try using other ports, 8080 and 4433 for example.

Edit: As others have pointed out, this is not recommended practice. Please understand the risks before you follow this approach. Otherwise, see Sohan's answer: https://stackoverflow.com/a/60373143/10225299.

huytc
  • 1,074
  • 7
  • 20
  • when i do your suggestion , i expected to print `console.log('listen to https');` but nothing is happend @huytc – Cyrus the Great Feb 24 '20 at 09:46
  • @sayreskabir So is there anything printed to the console whatsoever? – huytc Feb 24 '20 at 09:48
  • Nothing is printed : http://pasteall.org/pic/show.php?id=ad0ad07fbc112f4e2e89a44bc05e17e0 @huytc – Cyrus the Great Feb 24 '20 at 09:50
  • @sayreskabir Move this part `// Create an HTTP service. var io = require('socket.io').listen(server,()=>{ console.log('listen to https'); });` below `var server = ...`. Remove this line: `var io = require('socket.io').listen(server);`. – huytc Feb 24 '20 at 09:58
  • @sayreskabir `https.createServer(...).listen(...)` doesn't return a server, therefore your code is not working. Try this: https://pastebin.com/Cy130weF – huytc Feb 24 '20 at 10:15
  • 4
    This would run the node server as "root" which is a bad idea for security reasons. http://syskall.com/dont-run-node-dot-js-as-root/ – pizoelectric Oct 04 '21 at 16:06
5

It's a permission issue, you can just write sudo as a prefix

sudo npm start

It worked for me!

Mohit Rathod
  • 1,057
  • 1
  • 19
  • 33
  • 3
    This runs node as the root user. This is considered bad security. Consider an alternative like giving the node process specific permission. http://syskall.com/dont-run-node-dot-js-as-root/ – pizoelectric Oct 04 '21 at 17:32
  • ...and it will only work if the `start` command in package.json also has sudo access e.g. `sudo node app.js`. – Mike Poole Nov 26 '22 at 09:13
4

In case of windows user, some other app or service is using port 80 that's why we get this error. You can check which all apps are using this service

You can stop all services which are using port 80 by using following command in your command:

net stop http

Now try to run app which you want to run on port 80.

lejlun
  • 4,140
  • 2
  • 15
  • 31
4

@Sohan answer alternate

I had to use yum instead of apt-get

sudo yum install libcap2-bin 
sudo setcap cap_net_bind_service=+ep `readlink -f \`which node\``
Santosh
  • 3,477
  • 5
  • 37
  • 75
1

In server.listen the first argument must be port and then hostname:

server.listen(port , hostname , () => 
    console.log('server started'); 
});
pheeleeppoo
  • 1,491
  • 6
  • 25
  • 29
jayesh
  • 21
  • 2
1

That's problem can occur because your user don't have permission to use the port 80. You can sign in like root user or give the permission to NodeJS like DigitalOcean recommend:

sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep /usr/local/bin/node 

or

sudo setcap cap_net_bind_service=+ep /usr/local/node 

Reference:

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
Antonio
  • 11
  • 1
1

For me (Windows 10) this was happening even when running any of my terminals with Administrator level access. The solution for me was to stop IIS from running which was also (by default) listening on port 80. I stopped, re-ran my start command, and it started without further issue.

Can't have two webservers listening on the same port, DOH!

Jason Ayer
  • 621
  • 1
  • 10
  • 20
-2

Try this,

var server = https.createServer(options, app); // Creating a server
var io = require('socket.io').listen(server); // Mapping socket with server

server.listen(8443,() => { // setting port for existing server
    console.log('Https listening'); // Now socket and server both listens to same port
});
Deepak M
  • 849
  • 8
  • 17