跳转到内容
Try Gitea Cloud ☁️ for 30 days → Accelerate your Development & Deploys!
这是下一个版本的文档,仍在开发中。查看最新发布版本

Running Gitea with SELinux

当前中文文档翻译不是最新版,访问英文版本查看最新内容,或帮助我们翻译

Distributions such as Fedora, RHEL, CentOS Stream, Rocky Linux and AlmaLinux ship SELinux in enforcing mode. Packages from a distribution repository come with a policy that fits them, but an installation from binary or from source puts the binary and the data in paths the policy knows nothing about, so the labels have to be set by hand. The same applies to any other distribution where SELinux is enabled.

Do not turn SELinux off to work around the problems below. setenforce 0 is useful to confirm that a failure really comes from SELinux, but switch it back on with setenforce 1 afterwards.

Gitea should not run as root, and an unprivileged process may not bind to a port below 1024. Granting the capability to the binary with setcap 'cap_net_bind_service=+ep' /usr/local/bin/gitea is often suggested, but it is the least robust option:

  • file capabilities are stored in an extended attribute of the binary, so they are lost every time the binary is replaced, which happens on every upgrade.
  • the SELinux policy has to allow the capability for the label of the binary, and a binary in a path such as /opt usually does not carry a label that allows it.

Let systemd grant the capability to the process instead. It works with SELinux in enforcing mode and survives upgrades, the sample unit file has the two lines commented out:

/etc/systemd/system/gitea.service
[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE

Reload and restart the service afterwards:

Terminal window
sudo systemctl daemon-reload
sudo systemctl restart gitea

If the capability still does not reach the process, add PrivateUsers=false to the unit: the sandboxing runs the service in a user namespace where the capability does not apply to the host.

Two alternatives avoid the privileged port altogether, and are what most installations end up doing:

  • put a reverse proxy in front of Gitea and let it own ports 80 and 443.
  • redirect the port in the firewall, for example with firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=3000.

Labelling the binary and the data directory

Section titled “Labelling the binary and the data directory”

If Gitea starts but cannot read its own files, or fails in ways that are not explained by the file permissions, the labels are usually wrong. The tools come from the policycoreutils-python-utils package.

Label the binary as an executable and the data directory as application state:

Terminal window
sudo semanage fcontext -a -t bin_t '/usr/local/bin/gitea'
sudo restorecon -v /usr/local/bin/gitea
sudo semanage fcontext -a -t var_lib_t '/var/lib/gitea(/.*)?'
sudo restorecon -Rv /var/lib/gitea

semanage fcontext records the rule, restorecon applies it to the files that are already there. Use the two together rather than chcon, whose labels are reverted by the next relabel of the file system.

Adjust the paths if the installation does not follow installation from binary; the configuration in /etc/gitea is read with the label distributions give to /etc, so it normally needs nothing.

SELinux denials are written to the audit log, not to the Gitea log, so a failure often looks like a permission problem without any further explanation:

Terminal window
sudo ausearch -m AVC -c gitea --start recent

If a denial shows up that the rules above do not cover, turn it into a local policy module. Read what it allows before installing it, audit2allow writes down whatever was denied, including the things that were denied for a good reason:

Terminal window
sudo ausearch -c gitea --raw | audit2allow -M gitea-local
cat gitea-local.te
sudo semodule -i gitea-local.pp

If the denials point at a path Gitea should not be using at all, fix the path instead of allowing the access.