Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Allow Node.js to bind to privileged ports without root access on Ubuntu

How to: Allow Node to bind to port 80 without sudo

TL;DR

Only do this if you understand the consequences: all node programs will be able to bind on ports < 1024

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

Important: your node location may vary. Use which node to find it, or use it directly in the command:

sudo setcap 'cap_net_bind_service=+ep' `which node`

Explanation

In UNIX-like systems, non-root users are unable to bind to ports lower than 1024.

This is a nuisance when proxying adresses on port 80. Tipically, you end up sudoing all apps that must bind to such ports.

However, since kernel 2.6.24, you can use the setcap command to set specific capabilities to a program.

To enable all node programs to bind on any port lower than 1024, issue the following command:

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

Voilà! You can now bind to port 80 without sudoing.

If your node binary isn't on this path, find it with whereis node and substitute /usr/local/bin/node for wherever it is.

Important Caveat

setcap functions per-program. Therefore, if you update your node version you will probably need to run this command again.


source: http://stackoverflow.com/a/414258

@rodrigomuniz

This comment has been minimized.

Copy link

commented Aug 30, 2013

Mac users: OS X doesn't recognize setcap. I'm searching for an alternative but still no success.

@klzns

This comment has been minimized.

Copy link

commented Aug 30, 2013

I'm using Ubuntu 13.04 and this worked for me:

sudo setcap 'cap_net_bind_service=+ep' /usr/bin/nodejs
@uchoa

This comment has been minimized.

Copy link

commented Aug 31, 2013

@rodrigomuniz: this solution allows you to forward traffic from port 80 to port 8080, for example, on Mac OS X. Now you can bind to the upper port as if you were bound to the forwarded lower port. This is temporary and you would need to redo the mapping after each reboot. Maybe you might add step 2 to .bash_profile.

Step 1: View current firewall rules.
sudo ipfw show

Step 2: Add port forwarding rule (80 to 8080)
sudo ipfw add 100 fwd 127.0.0.1,8080 tcp from any to any 80 in

If you want to remove your firewall rules run:
sudo ipfw flush

[source]

@dotnetCarpenter

This comment has been minimized.

Copy link

commented Dec 10, 2014

Unfortunately ipfw is removed in OSX Yosemite. pfctl (pf) might be able to do the same but I still haven't found out how.

@afonso-praca

This comment has been minimized.

Copy link

commented Nov 26, 2015

It works like a charm. Thanks @firstdoit

@skerit

This comment has been minimized.

Copy link

commented Dec 1, 2015

which node will probably return a symlink, which setcap refuses to use. You can resolve it using readlink:

sudo setcap 'cap_net_bind_service=+ep' $(readlink -f $(which node))
@TotzkePaul

This comment has been minimized.

Copy link

commented Mar 26, 2016

Any explanation as to why which node needs to be in barticks? I tried it with regular single quotes and it didn't work.

@jhixson

This comment has been minimized.

Copy link

commented Apr 11, 2016

@TotzkePaul: The backticks evaluate the expression as a command. So which node will return the path of your system's node location without you manually having to find it and type it.

@Tyler-Murphy

This comment has been minimized.

Copy link

commented May 26, 2016

OSX users can use authbind: https://github.com/Castaglia/MacOSX-authbind

@adryanf

This comment has been minimized.

Copy link

commented Feb 27, 2017

@firstdoit works for systemd controlled node js processes. Thanks!

@laggingreflex

This comment has been minimized.

Copy link

commented Apr 7, 2017

On Windows Ubuntu Bash (Win10 CU) I'm getting this error:

Failed to set capabilities on file `/usr/bin/node' (Invalid argument)
The value of the capability argument is not permitted for a file. Or the file is not a regular (non-symlink) file
@neeraj87

This comment has been minimized.

Copy link

commented Apr 19, 2017

It did not work for me. I did
sudo setcap cap_net_bind_service=+ep /usr/bin/nodejs

(for mac).

When I do netstat -tlpn it still shows apache2 on port 80 and nodejs on 8000. What am I doing wrong?

@softrare

This comment has been minimized.

Copy link

commented Jul 1, 2017

sudo setcap 'cap_net_bind_service=+ep' /usr/bin/nodejs

confirmed for Ubuntu 14.04 LTS

Thank you, sir! Very helpful.

@serganus

This comment has been minimized.

Copy link

commented Jul 18, 2017

Failed to set capabilities on file `/usr/local/bin/node' (Invalid argument)
The value of the capability argument is not permitted for a file. Or the file is not a regular (non-symlink) file

I get this error, any suggestions?

https://github.com/serpkk

@iczero

This comment has been minimized.

Copy link

commented Aug 16, 2017

@serganus
You need to run setcap on the actual executable file, not the symlink. Try
sudo setcap 'cap_net_bind_service=+ep' $(readlink -f $(which node))

@DennisLoska

This comment has been minimized.

Copy link

commented Feb 13, 2018

how can I undo:
sudo setcap 'cap_net_bind_service=+ep' which node

@dachinat

This comment has been minimized.

Copy link

commented Jun 2, 2018

I think it's setcap -r /path/to/program

@davalapar

This comment has been minimized.

Copy link

commented Feb 25, 2019

  • nvm
  • pm2

sudo setcap 'cap_net_bind_service=+ep' $(which node)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.