Nodejs: Listen on port 80 after using setuid/setgid - node.js

I just got convinced by some internet articles, that using setuid/setgid to switch to a lower privileged user might be important. Since I am developing a web app, I decided to go for www-data.
So I am using the userid NPM module to figure out the user and group ID of www-data, and then change to it. However, when I do that - and it doesn't matter where entirely - I get the following (in this example, the security handler was executed at the very, very bottom of the code):
2014-09-04T23:07:05.812Z - info: BIRD3 Security -> Changed to www-data:www-data (33:33)
events.js:72
throw er; // Unhandled 'error' event
^
Error: listen EACCES
at errnoException (net.js:904:11)
at Server._listen2 (net.js:1023:19)
at listen (net.js:1064:10)
at net.js:1146:9
at dns.js:72:18
at process._tickCallback (node.js:419:13)
at Function.Module.runMain (module.js:499:11)
at startup (node.js:119:16)
at node.js:906:3
As you can see, as soon as I change my privilege level, it drops the accessibility to port 80 too.
Is there a way how I can implement security but keep using port 80 without using something like this?

You don't need a third-party module to do that. process.setgid() and process.setuid() both accept either an ID or a groupname/username.
Also make sure you are dropping the privileges AFTER listening on port 80 and that you call process.setgid() before process.setuid().
Example:
var net = require('net');
var srv = net.createServer(function(s) {
});
srv.listen(24, function() {
console.log('listening');
});
process.setgid('www-data');
process.setuid('www-data');

Isn't the setgid() and setuid() supposed to run after connecting, within the callback response?
srv.listen(24, function() {
console.log('listening');
process.setgid('www-data');
process.setuid('www-data');
});

Related

why node js socket not working when change port to https?

Normally in app.js i use this code on port 3000 it's work good (on my-domain.com:3000).
.
http.listen(3000, function(){
console.log('start server on port :3000');
});
then i want to use on https, so i change app.js to
http.listen(443, function(){
console.log('start server on port :443');
});
When run node app.js , it's show error
events.js:160
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE :::443
at Object.exports._errnoException (util.js:1012:11)
at exports._exceptionWithHostPort (util.js:1035:20)
at Server._listen2 (net.js:1252:14)
at listen (net.js:1288:10)
at Server.listen (net.js:1384:5)
at Object.<anonymous> (/home/admin/web/my-domain.com/public_html/app.js:28:6)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
Normally i have to access to my-domain.com:3000 for user chat. So i want to know how can i access to https://www.my-domain.com for user chat ?
You have the following error message:
Error: listen EADDRINUSE :::443
[...]
This message means that the port 443 is currently in use by some process.
You can check which process is actually using the said port by executing one of the many tools for network checking (such as netstat for Windows, lsof or netstat on Linux).
Refer to the manual for those tools to achieve the correct result, based upon your operating system.

port 100 not running in node.js in localhost

I have created a http server in node.js with the following code, and trying to run it on port 100:
var http = require("http");
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end("Howdy");
}).listen(100);
console.log("server running on port 100");
With this, the server does not start and I am getting the following error message on the linux console:
events.js:72
throw er; // Unhandled 'error' event
^
Error: listen EACCES
at errnoException (net.js:901:11)
at Server._listen2 (net.js:1020:19)
at listen (net.js:1061:10)
at Server.listen (net.js:1135:5)
at Object.<anonymous> (/home/badhai/Desktop/mainn.js:6:4)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
But if I lift a sails.js app on port 100, it runs successfully on port 100. However, the above code runs successfully on port 8081. I want to know if I need to make any changes in the server creation method or elsewhere so that it can be made to run successfully on port 100?
The EACCES part of the error message is the key here - it means you don't have access to that port. Ports < 1024 are system reserved. It's better to use ports in the range 1024-65535
Most modern operating systems limit binding to reserved ports (less than 1024) to processes running as root (or equivalent).
If you absolutely must bind to port 100, googling around will give you a bunch of ways to do it:
https://gist.github.com/firstdoit/6389682
It's better to use ports > 1024. I'm using ports starting from 3000. But if you really want to start it on port 100 and you understand what you're doing then install setcap and just allow to bind ports <1024.
> sudo apt-get install setcap
> sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/node
NodeJS can be installed in other directory also, so better to check where it is and call above setcap command with your path.
> which node
/usr/local/bin/node

Everytime I run cluster.fork(), I get a Error: bind EADDRINUSE

I'm using node.js, and using the cluster module. Everytime I run cluster.fork(), I always get a
throw er; // Unhandled 'error' event
Error: bind EADDRINUSE
at exports._errnoException (util.js:746:11)
at cb (net.js:1205:33)
at rr (cluster.js:592:14)
at Worker.<anonymous> (cluster.js:563:9)
at process.<anonymous> (cluster.js:692:8)
at process.emit (events.js:129:20)
at handleMessage (child_process.js:324:10)
at Pipe.channel.onread (child_process.js:352:11)
I've been googling this, and I have no idea how this is happening because I'm not passing in any port numbers.
Thanks
EDIT: Posting code
var setupWorkers = function() {
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < 5; i++) {
cluster.fork();
}
}
and this is a function that is called in the app.js which I run by calling node app.js
I was starting a server more than once with all the threads so the port was bound already
The stack trace you provide indicates that EADDRINUSE is coming from the net module. EADDRINUSE typically means that you are trying to listen on an IP/port combination more than once. So, for example, if this is a clustered web server, perhaps all your workers are trying to bind to port 80 on the same IP address. Without more code, it's impossible to tell what's happening.
The example code you gave in the subsequent comment does not trigger EADDRINUSE for me. Instead it errors with cluster.fork is not a function because there's no check for cluster.isMaster before calling cluster.fork().

Node.js Unhandled 'error' event when using http.createServer().listen() on Ubuntu 12.04

Salam (means Hello) :)
I've developed a node.js script on my windows seven machine and it's working fine. but when I run it on my Ubuntu 12.04, the following error shows up and halts my app:
throw er; // Unhandled 'error' event
^
Error: listen EACCES
at errnoException (net.js:901:11)
at Server._listen2 (net.js:1020:19)
at listen (net.js:1061:10)
at Server.listen (net.js:1127:5)
at Object.start (/httpServer/httpServer.js:9:34)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
and the point that caused error is .listen(80) in this line:
http.createServer(onRequest).listen(80);
^
I've also tried some other port numbers (like 100, 300, 500,...) instead of 80 and the error was still the same.
On Ubuntu you can't listen on ports < 1024 without root privileges. Try running node under sudo.
sudo node app.js
You probably have apache running on port 80, so it's conflicting.
Use another port (NOT within 0-1023), or disable apache.
Cheers
You probably have something else running on port 80, so it's conflicting.
Read here to find out what is using port 80 and stop it
http://www.cyberciti.biz/faq/find-linux-what-running-on-port-80-command/
Usually it means another server like apache is enabled. so stop it.
sudo service apache2 stop
or You have npm start already running in another terminal
or skype is running. in which case go to settings and change it's port. logout n login
Go to Tools -> Options -> Advanced -> Connections and uncheck the box "use port 80 and 443 as alternative".src
or use another port
http-server -a localhost -p 8000
I suggest to install the latest node packets, maybe directly from Node.js server, maybe compiling it.
Try to set a port which is not reserved to any service, like 3700.
Could be heplful to see some other fragment of code, though.
This can also be caused if you have something else already listening on that port - you can try changing the port from the typical default 80 to something more like 10014 and see if that helps!
I was able to rectify the error by explicitely mentionining the "IP address" along with the port when listening to the server.

Sending and receiving a UDP broadcast to and from 255.255.255.255 in Node.js

I'm trying to implement a BOOTP server in Node, for which broadcasting is a necessity. Sadly the docs are a little bit confusing and I'm getting weird errors all the way. Funny enough, the errors are different on Windows 7 and Ubuntu.
Did someone actually manage to send a UDP broadcast to 255.255.255.255 or receive one under this address?
Could someone provide me a simple Node UDP broadcasting demo?
Using punt I tried to bind a connection to 255.255.255.255 on port 5000 and I get this error EADDRNOTAVAIL
I think the address it too general. See this link
Here is the code, which is just a slightly modified version of a punt example.
var punt = require('punt');
var server = punt.bind('255.255.255.255:5000');
var a = punt.connect('255.255.255.255:5000');
server.on('message', function(msg){
console.log(msg);
});
setInterval(function(){
a.send({ hello: 'world' });
}, 150);
which yields this error:
events.js:72
throw er; // Unhandled 'error' event
^
Error: bind EADDRNOTAVAIL
at errnoException (dgram.js:439:11)
at dgram.js:206:28
at dns.js:72:18
at process._tickCallback (node.js:415:13)
at Function.Module.runMain (module.js:499:11)
at startup (node.js:119:16)
at node.js:901:3

Resources