sipwise / rtpengine

The Sipwise media proxy for Kamailio
GNU General Public License v3.0
785 stars 369 forks source link

Issue in debian package systemd startup script: Failed to apply ambient capabilities (before UID change): Operation not permitted #1605

Open markboots opened 1 year ago

markboots commented 1 year ago

We're using the Debian packages at https://dfx.at/rtpengine/

Using the default systemd startup script, rtpengine-daemon fails to start:

root@ip-...:/home/admin# systemctl status rtpengine-daemon.service
● rtpengine-daemon.service - NGCP RTP/media Proxy Daemon
   Loaded: loaded (/lib/systemd/system/rtpengine-daemon.service; disabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Sun 2023-02-05 03:57:16 UTC; 4min 56s ago
  Process: 906 ExecStartPre=/usr/sbin/rtpengine-iptables-setup start (code=exited, status=0/SUCCESS)
  Process: 925 ExecStart=/usr/bin/rtpengine -f -E --no-log-timestamps --pidfile /run/rtpengine/rtpengine-daemon.pid --config-file /etc/rtpengine/rtpengine.conf (code=exited, status=218/CAPABILITIES)
  Process: 927 ExecStopPost=/usr/sbin/rtpengine-iptables-setup stop (code=exited, status=0/SUCCESS)
 Main PID: 925 (code=exited, status=218/CAPABILITIES)

Feb 05 03:57:16 ip-172-31-255-254 systemd[1]: Starting NGCP RTP/media Proxy Daemon...
Feb 05 03:57:16 ip-172-31-255-254 rtpengine-iptables-setup[906]: modprobing...
Feb 05 03:57:16 ip-172-31-255-254 rtpengine-iptables-setup[906]: adding iptables rules
Feb 05 03:57:16 ip-172-31-255-254 systemd[925]: rtpengine-daemon.service: Failed to apply ambient capabilities (before UID change): Operation not permitted
Feb 05 03:57:16 ip-172-31-255-254 systemd[925]: rtpengine-daemon.service: Failed at step CAPABILITIES spawning /usr/bin/rtpengine: Operation not permitted
Feb 05 03:57:16 ip-172-31-255-254 systemd[1]: rtpengine-daemon.service: Main process exited, code=exited, status=218/CAPABILITIES
Feb 05 03:57:16 ip-172-31-255-254 systemd[1]: rtpengine-daemon.service: Failed with result 'exit-code'.
Feb 05 03:57:16 ip-172-31-255-254 systemd[1]: Failed to start NGCP RTP/media Proxy Daemon.

We resolved this by commenting out the following Ambient Capabilities in /lib/systemd/system/rtpengine-daemon.service:

# Service process does not receive ambient capabilities
# NOTE: we need caps for running as non-root user
#--removed--: AmbientCapabilities=CAP_NET_ADMIN CAP_SYS_NICE

Contrary to the NOTE, this change succeeds at launching successfully, running as the non-root rtpengine user.

rfuchs commented 1 year ago

What kind of kernel and environment was this under?

markboots commented 1 year ago

This is on Debian Buster, kernel 4.19.0-23-cloud-amd64, using the Debian AWS AMI.

rfuchs commented 1 year ago

Could be the cloud/AWS kernel not allowing CAP_NET_ADMIN then

markboots commented 1 year ago

Is there anything in rtpengine that will fail without having CAP_NET_ADMIN? If the daemon launches are we good to go, or could there be runtime failures later?

markboots commented 1 year ago

(Note: It looks like this is only a Debian buster issue; the default systemd scripts worked fine on Debian bullseye, 5.10.0-20-cloud-amd64.)

rfuchs commented 1 year ago

CAP_NET_ADMIN is needed for managing the iptables rules if that feature is enabled (see iptables-chain option, which is unrelated to the kernel module). I don't think it's needed for anything else.

And we've been using this on both bullseye and buster with the stock kernels just fine, so this is probably something specific to that cloud kernel.

ddamw commented 1 year ago

I had the same problem as @markboots on a plain Debian Buster installation and I can confirm that commenting out AmbientCapabilities in the systemd service file works.

However, I was not pleased by the solution and experimented some more and found that I could keep AmbientCapabilities enabled if I commented out CapabilityBoundingSet=(empty here) at line 59 of the systemd file (https://github.com/sipwise/rtpengine/blob/master/debian/ngcp-rtpengine-daemon.service) or at least setting CapabilityBoundingSet to anything but an empty set, such as the example on line 65 of the same file.

So for me this works:

#CapabilityBoundingSet=
AmbientCapabilities=CAP_NET_ADMIN CAP_SYS_NICE

as well as

CapabilityBoundingSet=CAP_CHOWN CAP_DAC_OVERRIDE CAP_SETGID CAP_SETUID CAP_FOWNER CAP_NET_ADMIN CAP_SYS_NICE
AmbientCapabilities=CAP_NET_ADMIN CAP_SYS_NICE

but this doesn't:

CapabilityBoundingSet=
AmbientCapabilities=CAP_NET_ADMIN CAP_SYS_NICE