Forgejo
Forgejo is a fork of Gitea.
Installation
As of 2024-09-18, Forgejo is not provided as a Gentoo package, but is available in the GURU overlay. Alternatively, Forgejo is distributed as a single binary file.
Official binaries
Forgejo
The Forgejo project distributes binaries for AMD64 and ARM64 architectures, which can be downloaded here. The binaries are compatible with musl-based systems.
To download and verify the binary file, follow the instructions provided here.
In case GnuPG fails to retrieve the key, the key can be imported manually:
user $
wget -O - https://keys.openpgp.org/vks/v1/by-fingerprint/EB114F5E6C0DC2BCDD183550A4B61A2DC5923710 | gpg --import
The binary does not require root privileges to run and can be launched from any directory:
user $
./forgejo-*-linux-arm64
If there is a plan to install the binary into the system, follow the steps provided here.
SELinux policy
The policy provided in this section is created using
audit2allow
. Review the policy before using it.The policy was tested with Forgejo v. 8.0.3 on the default/linux/arm64/23.0/musl/hardened/selinux
profile.
module forgejo-workaround 1.0;
require {
type ntop_port_t;
type urandom_device_t;
type node_t;
type user_git_t;
type user_t;
type shell_exec_t;
class chr_file { open read };
class file { execute execute_no_trans map open read };
class tcp_socket { name_bind node_bind };
}
#============= user_git_t ==============
allow user_git_t shell_exec_t:file { execute execute_no_trans map open read };
#!!!! This avc can be allowed using one of the these booleans:
# authlogin_nsswitch_use_ldap, global_ssp
allow user_git_t urandom_device_t:chr_file { open read };
#============= user_t ==============
#!!!! This avc can be allowed using the boolean 'user_tcp_server'
allow user_t node_t:tcp_socket node_bind;
allow user_t ntop_port_t:tcp_socket name_bind;
To compile and install the policy module, follow the instructions provided here.
The policy is created based on the following AVC:
root #
cat /var/log/audit/audit.log
type=AVC msg=audit(1726646452.356:370): avc: denied { name_bind } for pid=17068 comm="forgejo-8.0.3-l" src=3000 scontext=user_u:user_r:user_t tcontext=system_u:object_r:ntop_port_t tclass=tcp_socket permissive=0 type=AVC msg=audit(1726646664.936:379): avc: denied { node_bind } for pid=17133 comm="forgejo-8.0.3-l" src=3000 scontext=user_u:user_r:user_t tcontext=system_u:object_r:node_t tclass=tcp_socket permissive=0 type=AVC msg=audit(1726640154.672:319): avc: denied { open } for pid=15303 comm="git" path="/dev/urandom" dev="devtmpfs" ino=7 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:urandom_device_t tclass=chr_file permissive=0 type=AVC msg=audit(1726639601.600:316): avc: denied { read } for pid=15206 comm="git" name="urandom" dev="devtmpfs" ino=7 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:urandom_device_t tclass=chr_file permissive=0 type=AVC msg=audit(1726640489.788:322): avc: denied { execute } for pid=15424 comm="git" name="bash" dev="dm-0" ino=78724 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:shell_exec_t tclass=file permissive=0 type=AVC msg=audit(1726640788.812:325): avc: denied { read open } for pid=15473 comm="git" path="/usr/bin/bash" dev="dm-0" ino=78724 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:shell_exec_t tclass=file permissive=0 type=AVC msg=audit(1726640898.432:328): avc: denied { execute_no_trans } for pid=15511 comm="git" path="/usr/bin/bash" dev="dm-0" ino=78724 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:shell_exec_t tclass=file permissive=0 type=AVC msg=audit(1726641153.272:331): avc: denied { map } for pid=15560 comm="sh" path="/usr/bin/bash" dev="dm-0" ino=78724 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:shell_exec_t tclass=file permissive=0
Forgejo Actions (self-hosted)
This section describes a way to run Actions on bare hardware, without virtualization or containers. This means that everything that is uploaded to the repository will run on the same system that the server is running on. This can lead to any number of consequences (data loss, hardware damage, etc.). Only persons with the ultimate level of trust should be able to push data to repositories.
Enable Actions in Forgejo:
[actions]
ENABLED = true
The runner can be downloaded from here.
Once downloaded, create and copy the token via GUI as described here.
Register the runner:
user $
./forgejo-runner-* register --no-interactive --token <OBTAINED TOKEN> --name self-hosted --instance http://[::1]:3001/
http://[::1]:3001/
is Forgejo's address.Once registered, create the minimal configuration file:
log:
level: info
runner:
timeout: 1h
labels:
- self-hosted
cache:
enabled: false
And launch the runner as a daemon:
user $
./forgejo-runner-* --config config.yml daemon
To test that everything works, push the following file to the repository:
on: [push]
jobs:
test:
runs-on: self-hosted
steps:
- run: echo Works
SELinux policy
module forgejo-runner-workaround 1.0;
require {
type sysfs_t;
type proc_t;
type shell_exec_t;
type ntop_port_t;
type user_git_t;
type user_home_t;
class file { execute execute_no_trans getattr read };
class process { getsched setpgid signal };
class filesystem getattr;
class tcp_socket name_connect;
}
#============= user_git_t ==============
allow user_git_t ntop_port_t:tcp_socket name_connect;
allow user_git_t proc_t:filesystem getattr;
allow user_git_t self:process { getsched setpgid signal };
allow user_git_t shell_exec_t:file getattr;
allow user_git_t sysfs_t:file read;
allow user_git_t user_home_t:file { execute execute_no_trans };
The policy depends on the policy provided above.
The policy is created based on the following AVC:
root #
cat /var/log/audit/audit.log
type=AVC msg=audit(1726657298.028:232): avc: denied { execute } for pid=2301 comm="git" name="pre-receive" dev="dm-0" ino=589246 scontext=user_u:user_r:user_git_t tcontext=user_u:object_r:user_home_t tclass=file permissive=0 type=AVC msg=audit(1726657298.028:234): avc: denied { execute } for pid=2301 comm="git" name="post-receive" dev="dm-0" ino=589252 scontext=user_u:user_r:user_git_t tcontext=user_u:object_r:user_home_t tclass=file permissive=0 type=AVC msg=audit(1726657748.236:239): avc: denied { execute_no_trans } for pid=2376 comm="git" path="/home/launcher/servers/servers/forgejo/data/forgejo-repositories/larshint/test.git/hooks/pre-receive" dev="dm-0" ino=589246 scontext=user_u:user_r:user_git_t tcontext=user_u:object_r:user_home_t tclass=file permissive=0 type=AVC msg=audit(1726657835.972:258): avc: denied { getattr } for pid=2432 comm="bash" path="/usr/bin/bash" dev="dm-0" ino=78724 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:shell_exec_t tclass=file permissive=0 type=AVC msg=audit(1726657835.976:259): avc: denied { getattr } for pid=2436 comm="bash" path="/usr/bin/bash" dev="dm-0" ino=78724 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:shell_exec_t tclass=file permissive=0 type=AVC msg=audit(1726657835.980:260): avc: denied { getsched } for pid=2437 comm="forgejo-8.0.3-l" scontext=user_u:user_r:user_git_t tcontext=user_u:user_r:user_git_t tclass=process permissive=0 type=AVC msg=audit(1726657835.980:261): avc: denied { read } for pid=2437 comm="forgejo-8.0.3-l" name="hpage_pmd_size" dev="sysfs" ino=1005 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:sysfs_t tclass=file permissive=0 type=AVC msg=audit(1726657836.004:262): avc: denied { signal } for pid=2437 comm="forgejo-8.0.3-l" scontext=user_u:user_r:user_git_t tcontext=user_u:user_r:user_git_t tclass=process permissive=0 type=AVC msg=audit(1726657836.104:263): avc: denied { getattr } for pid=2437 comm="forgejo-8.0.3-l" name="/" dev="proc" ino=1 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:proc_t tclass=filesystem permissive=0 type=AVC msg=audit(1726657836.108:264): avc: denied { getattr } for pid=2437 comm="forgejo-8.0.3-l" path="/usr/bin/bash" dev="dm-0" ino=78724 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:shell_exec_t tclass=file permissive=0 type=AVC msg=audit(1726657836.108:265): avc: denied { setpgid } for pid=2442 comm="forgejo-8.0.3-l" scontext=user_u:user_r:user_git_t tcontext=user_u:user_r:user_git_t tclass=process permissive=0 type=AVC msg=audit(1726657836.108:266): avc: denied { name_connect } for pid=2437 comm="forgejo-8.0.3-l" dest=3001 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:ntop_port_t tclass=tcp_socket permissive=0 type=AVC msg=audit(1726657836.108:267): avc: denied { name_connect } for pid=2437 comm="forgejo-8.0.3-l" dest=3001 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:ntop_port_t tclass=tcp_socket permissive=0 type=AVC msg=audit(1726657836.108:268): avc: denied { setpgid } for pid=2443 comm="forgejo-8.0.3-l" scontext=user_u:user_r:user_git_t tcontext=user_u:user_r:user_git_t tclass=process permissive=0 type=AVC msg=audit(1726657836.108:269): avc: denied { name_connect } for pid=2437 comm="forgejo-8.0.3-l" dest=3001 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:ntop_port_t tclass=tcp_socket permissive=0 type=AVC msg=audit(1726657836.108:270): avc: denied { name_connect } for pid=2437 comm="forgejo-8.0.3-l" dest=3001 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:ntop_port_t tclass=tcp_socket permissive=0 type=AVC msg=audit(1726657836.112:271): avc: denied { name_connect } for pid=2437 comm="forgejo-8.0.3-l" dest=3001 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:ntop_port_t tclass=tcp_socket permissive=0 type=AVC msg=audit(1726657836.112:272): avc: denied { name_connect } for pid=2437 comm="forgejo-8.0.3-l" dest=3001 scontext=user_u:user_r:user_git_t tcontext=system_u:object_r:ntop_port_t tclass=tcp_socket permissive=
See also
- Node.js as a reverse proxy for Forgejo
- Gitea — painless self-hosted git service, a fork of gogs