This repository has been archived on 2021-05-20. You can view files and clone it, but cannot push or open issues or pull requests.
blog/content/blog/allow-non-root-processes-to...

2.3 KiB

+++ title = "Allow Non Root Processes to Bind to Privileged Ports" date = "2021-03-28" aliases = [ "posts/allow-non-root-processes-to-bind-to-privileged-ports/", ]

description = """ In Linux, processes cannot bind to privileged ports (<=1024) unless they are running as root. Here's how to allow any process to bind to privileged ports. """

tags = [ "guide", "linux", ] +++

Introduction

In Linux, processes cannot bind to privileged ports (<=1024) unless they are running as root. I learned about this when I was trying to add SSH cloning to my Gitea instance. This can be bypassed by giving CAP_NET_BIND_SERVICE capabilities to either the systemd service, or the executable itself.

Giving CAP_NET_BIND_SERVICE capabilities

Using systemd (preferred)

The best way is to tell systemd to give CAP_NET_BIND_SERVICE capabilities to the service. In fact, the Gitea systemd service has two lines1 that are commented out:

CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE

Uncommenting these two lines was all I had to do for Gitea.

Using setcap

You can add CAP_NET_BIND_SERVICE to the executable directly using setcap, allowing it to bind to any port. Run the following command2:

setcap 'cap_net_bind_service=+ep' /path/to/program

Note that this means that anyone with permission to run this program will be able to run it and bind to any privileged ports.

Other caveats2:

  1. You will need at least a 2.6.24 kernel
  2. This won't work if your file is a script. (ie, uses a #! line to launch an interpreter). In this case, as far I as understand, you'd have to apply the capability to the interpreter executable itself, which of course is a security nightmare, since any program using that interpreter will have the capability. I wasn't able to find any clean, easy way to work around this problem.
  3. Linux will disable LD_LIBRARY_PATH on any program that has elevated privileges like setcap or suid. So if your program uses its own .../lib/, you might have to look into another option like port forwarding.