Skip to content

Instantly share code, notes, and snippets.

@guifromrio
Last active January 10, 2024 22:47
Show Gist options
  • Save guifromrio/6389682 to your computer and use it in GitHub Desktop.
Save guifromrio/6389682 to your computer and use it in GitHub Desktop.
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

@neeraj87
Copy link

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
Copy link

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

@cookie-ag
Copy link

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
Copy link

iczero 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
Copy link

DennisLoska commented Feb 13, 2018

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

@dachinat
Copy link

dachinat commented Jun 2, 2018

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

@davalapar
Copy link

davalapar commented Feb 25, 2019

  • nvm
  • pm2

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

@coolaj86
Copy link

coolaj86 commented Jul 1, 2020

I added this to webinstall.dev as cap-net-bind

Install

curl https://webinstall.dev/vps-utils | bash

Use

cap-net-bind node

Guts

#!/bin/bash

{
    set -e
    set -u

    my_bin="$1"
    if [ -z "$(which $my_bin)"]; then
        echo "'$my_bin' not found"
        exit 1
    fi
    my_sudo=""
    if [ -n "$(command -v sudo)" ]; then
        my_sudo=sudo
    fi
    $my_sudo setcap 'cap_net_bind_service=+ep' $(readlink -f $(which $my_bin))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment