You are not logged in.

#1 2023-02-13 03:47:47

monitor
Member
Registered: 2023-02-13
Posts: 3

[Solved] Unable to add CAP_NET_BIND_SERVICE capability to service

I am attempting to allow gitea to bind on port 80 so that it can request generate ssl keys through ACME. (the gitea web service is user configurable and binds on port 3000, ACME must use port 80 or 443).

Using setcap to allow gitea to bind to restricted ports (cap_net_bind_service) works fine when run as a user. It can bind to port 80 when I run it as the gitea user. However, setcap does not work for systemd units. From what I understand, the correct method of doing this is in a systemd unit is through AmbientCapabilities.

So I have added the following to /usr/lib/systemd/system/gitea.service

# Set port permissions capability
SecureBits=keep-caps
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_ADMIN

(CAP_NET_ADMIN was added after CAP_NET_BIND_SERVICE alone didn't work. I am aware that this is not ideal)

After running

 systemctl daemon-reload 

and restarting the service, it still failed with the message

 Failed to start the Let's Encrypt handler on port 80: listen tcp 0.0.0.0:80: bind: permission denied  

What am I missing? The documentation for systemd and capabilities lead me to believe that this should give gitea the permission to access these ports, but I just cannot get it to work.

edit: url formatting

Last edited by monitor (2023-02-13 04:26:09)

Offline

#2 2023-02-13 03:48:33

monitor
Member
Registered: 2023-02-13
Posts: 3

Re: [Solved] Unable to add CAP_NET_BIND_SERVICE capability to service

Here is the entire unit file, in case there is some conflict that I am not seeing

[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
After=mysqld.service
After=postgresql.service
After=memcached.service
After=redis.service

[Service]
User=gitea
Group=gitea
Type=simple
WorkingDirectory=~
RuntimeDirectory=gitea
LogsDirectory=gitea
StateDirectory=gitea
Environment=USER=gitea HOME=/var/lib/gitea GITEA_WORK_DIR=/var/lib/gitea
ExecStart=/usr/bin/gitea web -c /etc/gitea/app.ini
Restart=always
RestartSec=10s
ReadWritePaths=/etc/gitea/app.ini

# Set port permissions capability
SecureBits=keep-caps
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_ADMIN

LockPersonality=true
#Required by commit search
#MemoryDenyWriteExecute=true
NoNewPrivileges=True
#SecureBits=noroot-locked
PrivateDevices=true
PrivateTmp=true
PrivateUsers=true
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProtectSystem=strict
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM

[Install]
WantedBy=multi-user.target

Offline

#3 2023-02-13 04:08:13

loqs
Member
Registered: 2014-03-06
Posts: 17,308

Re: [Solved] Unable to add CAP_NET_BIND_SERVICE capability to service

See the PrivateUsers entry in the systemd.exec man page you linked.

Offline

#4 2023-02-13 04:19:38

monitor
Member
Registered: 2023-02-13
Posts: 3

Re: [Solved] Unable to add CAP_NET_BIND_SERVICE capability to service

Specifically this means that the process will have zero process capabilities on the host's user namespace, but full capabilities within the service's user namespace. Settings such as CapabilityBoundingSet= will affect only the latter, and there's no way to acquire additional capabilities in the host's user namespace.

Oh, so setting PrivateUsers=true essentially means it ignores the capabilities I attempted to give it? That's frustrating, but it does seem to explain the problem I am having. Thank you for pointing me in the right direction.

Offline

Board footer

Powered by FluxBB