You are not logged in.
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
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
See the PrivateUsers entry in the systemd.exec man page you linked.
Offline
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