Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For one systemd service, grant CAP_NET_BIND_SERVICE in its unit rather than running the application as root. If the policy should apply across a network namespace, Linux also provides the net.ipv4.ip_unprivileged_port_start sysctl. Choose based on the scope you need: a capability targets a process context; the sysctl changes the namespace’s privileged-port boundary.

Option 1: Grant the service CAP_NET_BIND_SERVICE

Linux permits binding to privileged ports when a process has root privileges or the CAP_NET_BIND_SERVICE capability. Granting that specific capability lets a service run as a non-root user while receiving permission to bind to ports such as 80 or 443. Capabilities divide traditionally broad root privileges into named permissions; they are governed by process capability sets and execution rules. See the Linux capabilities(7) manual.

For a systemd-managed service, add the capability to the service unit’s applicable configuration:

[Service]
User=example
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE

Replace example with the account that should run the service. AmbientCapabilities= passes the selected capability to a service running as a non-privileged user. CapabilityBoundingSet= restricts the capabilities available to the executed process; listing only the required capability can help keep the set constrained. These directives and their supported context depend on the installed systemd version and unit policy. Check the local systemd.exec manual and the service’s existing configuration before applying them. The systemd project documents both directives in its systemd.exec manual.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

After changing a unit, use the system’s normal systemd configuration-reload and service-restart procedure, then verify that the service starts and can bind the intended port. A systemd unit is not a universal recipe: other service managers and container runtimes have different controls.

Option 2: Change the unprivileged-port threshold

The kernel setting net.ipv4.ip_unprivileged_port_start defines the first port treated as unprivileged in a network namespace. The Linux kernel documentation specifies a default of 1024; ports below that boundary are privileged by default. Setting the threshold to 0 disables the privileged-port distinction in that namespace, so processes there do not need the capability solely to bind those ports.

This is a broader policy change than granting a capability to one service: it changes the threshold for the network namespace, not just the permissions of a particular process. The configured value must not overlap the namespace’s ip_local_port_range. Consult the kernel’s IP sysctl documentation and your distribution’s guidance before changing it.

Because the setting is per network namespace, a host-level change does not by itself establish what a container’s network namespace allows. The effective result depends on how that namespace is created and configured, as well as any restrictions imposed by the container environment.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Which approach should you use?

Approach Scope Best fit Important constraint
CAP_NET_BIND_SERVICE Process or service execution context A particular non-root service needs to bind a privileged port It expands that process’s privileges; constrain its capability set and check service-manager or container policy.
net.ipv4.ip_unprivileged_port_start Network namespace The namespace’s port-boundary policy should change for processes in it The value must not overlap ip_local_port_range; confirm the target namespace and persistence mechanism.

In many deployments, another design is to have the application listen on a higher port and configure a separate front end to receive traffic on the desired low port. That is an architectural alternative, not a change to Linux’s privileged-port rules, and its suitability depends on the deployment.

Check the environment before changing permissions

  • Identify the network namespace. Determine whether the process runs on the host or in a container; the sysctl boundary is namespace-specific.
  • Identify the service manager and versions. Confirm that the installed manager supports the capability directives and that the unit’s policy permits them.
  • Check container restrictions. A container’s capability bounding set or runtime policy may prevent a capability grant from taking effect.
  • Grant only what is needed. Prefer a narrowly scoped service capability when only one process needs the permission; avoid running the whole application as root merely to open a low port.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

For systemd-nspawn containers

For a program started through systemd-nspawn, the AmbientCapability= setting can pass selected capabilities to the started program, subject to its capability bounding set. This is separate from the service-unit directive above; check the installed nspawn manual and the container’s effective policy. The systemd project describes the setting in its systemd.nspawn manual.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.