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/posts/allow-non-root-processes-to-bind-to-privileged-ports.md
BBaoVanC 3eb95b7f16
All checks were successful
continuous-integration/drone/push Build is passing
Remove systemd tag
2021-04-16 20:55:15 -05:00

2.4 KiB

+++ title = "Allow Non Root Processes to Bind to Privileged Ports" date = "2021-03-28T20:03:16-05:00" author = "bbaovanc" tags = ["guide", "linux"] keywords = ["linux", "privileged", "ports", "tutorial", "guide", "gitea", "systemd"]

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

showFullContent = false toc = true +++

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.