Gitea Knowledge â Admin Handbuch
Channel: #gitea
Persona: Deepbit đ§
Version: Gitea 1.25.4 auf Debian 12 (Bookworm)
DB: SQLite (/var/lib/gitea/data/gitea.db)
Config:/etc/gitea/app.ini
User:gitea(system)
Binary:/usr/local/bin/gitea
1. Architektur im Crumbforest
Internet â nginx (443) â Gitea (3000, localhost) â SQLite
â â
TLS + Proxy Repos + Users
Bot-Filter Webhooks
Gitea lauscht nur auf localhost:3000. nginx macht TLS und Reverse Proxy.
Kein direkter Zugang von auĂen auf Port 3000.
2. Service Management
# Status
systemctl status gitea
# Neustart (nach Config-Ănderung)
systemctl restart gitea
# Logs
journalctl -u gitea -f
journalctl -u gitea -n 50 --no-pager
# Gitea Version
gitea --version
3. Konfiguration: app.ini
Pfad: /etc/gitea/app.ini
Kritische Sicherheits-Settings
[service]
DISABLE_REGISTRATION = true # Keine öffentliche Registrierung
REQUIRE_SIGNIN_VIEW = true # Repos nur fĂŒr eingeloggte User sichtbar
ENABLE_CAPTCHA = true # Captcha bei Registrierung (falls offen)
DEFAULT_ALLOW_CREATE_ORGANIZATION = false
SHOW_REGISTRATION_BUTTON = false # Kein "Registrieren" Button
ENABLE_NOTIFY_MAIL = false # Kein Mail-Versand
[openid]
ENABLE_OPENID_SIGNIN = false # Kein OpenID
ENABLE_OPENID_SIGNUP = false
[other]
SHOW_FOOTER_VERSION = false # Versionsnummer verstecken
Nach jeder Ănderung
systemctl restart gitea
Config validieren
# PrĂŒfe ob Setting gesetzt ist
grep -A5 '\[service\]' /etc/gitea/app.ini
4. User Management
User anlegen (nur Admin)
sudo -u gitea gitea admin user create \
--username neueruser \
--password "sicheres_passwort" \
--email user@crumbforest.org \
--admin false \
-c /etc/gitea/app.ini
User auflisten
sudo -u gitea gitea admin user list -c /etc/gitea/app.ini
User löschen
# Ohne Repos
sudo -u gitea gitea admin user delete --username USERNAME -c /etc/gitea/app.ini
# Mit Repos (purge = alles löschen)
sudo -u gitea gitea admin user delete --username USERNAME --purge -c /etc/gitea/app.ini
Wichtig: Ohne --purge schlÀgt das Löschen fehl wenn der User Repos besitzt.
User zum Admin machen
sudo -u gitea gitea admin user change-password \
--username USERNAME --must-change-password false -c /etc/gitea/app.ini
# Oder direkt in der DB
sqlite3 /var/lib/gitea/data/gitea.db "UPDATE user SET is_admin=1 WHERE lower_name='username'"
Bulk-Delete (mit Rate-Limit Schutz)
cat spam_users.txt | while read user; do
sudo -u gitea gitea admin user delete --username "$user" --purge -c /etc/gitea/app.ini
sleep 2 # Rate-Limit umgehen
done
5. Repository Management
Repos auflisten
sqlite3 /var/lib/gitea/data/gitea.db "
SELECT r.id, u.lower_name AS owner, r.name, r.is_private
FROM repository r
JOIN user u ON r.owner_id = u.id
ORDER BY u.lower_name, r.name
"
Repo-Statistiken
sqlite3 /var/lib/gitea/data/gitea.db "
SELECT u.lower_name AS owner, COUNT(*) AS repos, SUM(r.num_stars) AS stars
FROM repository r
JOIN user u ON r.owner_id = u.id
GROUP BY u.lower_name
ORDER BY repos DESC
"
Verwaiste Repos finden
sqlite3 /var/lib/gitea/data/gitea.db "
SELECT r.name, r.owner_id
FROM repository r
LEFT JOIN user u ON r.owner_id = u.id
WHERE u.id IS NULL
"
6. Datenbank
SQLite Basics
# Shell öffnen
sqlite3 /var/lib/gitea/data/gitea.db
# Tabellen anzeigen
.tables
# Schema einer Tabelle
.schema user
# Beenden
.quit
Wichtige Queries
# Alle User mit Details
sqlite3 /var/lib/gitea/data/gitea.db "
SELECT id, lower_name, email, is_admin, num_repos,
datetime(created_unix, 'unixepoch') AS created,
datetime(last_login_unix, 'unixepoch') AS last_login
FROM user WHERE type=0
ORDER BY created_unix DESC
"
# User pro Tag (Bulk-Registrierungen erkennen)
sqlite3 /var/lib/gitea/data/gitea.db "
SELECT date(created_unix, 'unixepoch') AS d, COUNT(*) AS c
FROM user WHERE type=0
GROUP BY d ORDER BY d DESC LIMIT 30
"
# User ohne Repos (Spam-Kandidaten)
sqlite3 /var/lib/gitea/data/gitea.db "
SELECT lower_name, email, datetime(created_unix, 'unixepoch') AS created
FROM user
WHERE type=0 AND is_admin=0 AND num_repos=0
ORDER BY created_unix DESC
"
# Repos pro User
sqlite3 /var/lib/gitea/data/gitea.db "
SELECT u.lower_name, COUNT(r.id) AS repos
FROM user u
LEFT JOIN repository r ON u.id = r.owner_id
WHERE u.type=0
GROUP BY u.lower_name
ORDER BY repos DESC
"
Backup
# SQLite Backup (atomic)
sqlite3 /var/lib/gitea/data/gitea.db ".backup /root/gitea_backup_$(date +%Y%m%d).db"
# Oder mit borgmatic (empfohlen)
# Gitea-Daten sind in den borgmatic Pfaden enthalten:
# /var/lib/gitea/data/
# /etc/gitea/
# /opt/gitea/ (repos)
7. Nginx Reverse Proxy
Typische Config
server {
listen 443 ssl http2;
server_name git.crumbforest.org;
ssl_certificate /etc/letsencrypt/live/git.crumbforest.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.crumbforest.org/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Git ĂŒber HTTP: groĂe Uploads erlauben
client_max_body_size 100M;
}
}
Registrierungs-Versuche im Log finden
grep "user/sign_up\|user/register" /var/log/nginx/access.log | \
awk '{print $1}' | sort | uniq -c | sort -rn | head -20
8. Spam-Erkennung & Forensik
Schnell-Check
# Gibt es verdÀchtige User?
sqlite3 /var/lib/gitea/data/gitea.db "
SELECT lower_name, email, website
FROM user WHERE type=0
AND (email LIKE '%@topcompanygroup.com'
OR website LIKE '%:3000%'
OR website LIKE '%:30000%'
OR website LIKE '%rentry.co%')
"
Automatisiert
# gitea_ninja.sh installiert unter /root/
gitea_ninja.sh --analyze # Read-only Analyse
gitea_ninja.sh --harden # Config prĂŒfen
gitea_ninja.sh --report # Markdown fĂŒr Vektor
Typische Spam-Merkmale
| Signal | Bewertung |
|---|---|
| 0 Repos, 0 Commits | â ïž VerdĂ€chtig (wenn nicht frisch registriert) |
| Gleiche Email-Domain bei >5 Usern | â Spam |
| Profil-Website auf Port 3000/30000 | â Spam (externe Gitea-Instanzen) |
| >3 Registrierungen am gleichen Tag | â ïž Bulk-Registrierung |
| Kein Login nach Registrierung | â ïž Bot |
9. Gitea Update
# 1. Backup
sqlite3 /var/lib/gitea/data/gitea.db ".backup /root/gitea_pre_update.db"
cp /etc/gitea/app.ini /etc/gitea/app.ini.bak
# 2. Download neue Version
wget -O /tmp/gitea https://dl.gitea.com/gitea/VERSION/gitea-VERSION-linux-amd64
chmod +x /tmp/gitea
# 3. Service stoppen
systemctl stop gitea
# 4. Binary ersetzen
cp /usr/local/bin/gitea /usr/local/bin/gitea.old
mv /tmp/gitea /usr/local/bin/gitea
# 5. Starten
systemctl start gitea
# 6. PrĂŒfen
gitea --version
systemctl status gitea
# 7. Nach Update: Sicherheits-Settings prĂŒfen!
gitea_ninja.sh --harden
10. Webhooks fĂŒr den Wald
Repo-Push â Vector Collector triggern
# In Gitea: Repository â Settings â Webhooks â Add Webhook
# URL: http://127.0.0.1:5001/api/webhook/gitea
# Content-Type: application/json
# Events: Push
Webhook-Log prĂŒfen
sqlite3 /var/lib/gitea/data/gitea.db "
SELECT id, repo_id, url, last_status,
datetime(updated_unix, 'unixepoch') AS updated
FROM webhook
ORDER BY updated_unix DESC
"
11. Troubleshooting
Gitea startet nicht
# Logs prĂŒfen
journalctl -u gitea -n 50 --no-pager
# HĂ€ufige Ursachen:
# 1. Port 3000 belegt
ss -tlnp | grep 3000
# 2. Berechtigungen
ls -la /var/lib/gitea/data/gitea.db
# Muss gitea:gitea gehören
# 3. Config-Fehler
gitea doctor check -c /etc/gitea/app.ini
Git Clone schlÀgt fehl
# 503 vom Proxy? â Gitea ĂŒberlastet oder Rate-Limit
# Lösung: sleep zwischen Clones
for repo in repo1 repo2 repo3; do
git clone https://git.crumbforest.org/branko/$repo.git
sleep 1 # Gitea atmen lassen
done
"Repository does not exist"
# PrĂŒfe ob Repo-Daten noch auf Disk liegen
ls /opt/gitea/data/gitea-repositories/branko/
# PrĂŒfe DB
sqlite3 /var/lib/gitea/data/gitea.db "
SELECT name, is_empty FROM repository WHERE lower_name='reponame'
"
12. Wichtige Pfade
| Pfad | Inhalt |
|---|---|
/etc/gitea/app.ini |
Hauptkonfiguration |
/var/lib/gitea/data/gitea.db |
SQLite Datenbank |
/var/lib/gitea/data/ |
Gitea Daten (Avatare, Attachments, LFS) |
/opt/gitea/data/gitea-repositories/ |
Git Bare Repos (oder /var/lib/gitea/repositories/) |
/usr/local/bin/gitea |
Binary |
/var/log/nginx/access.log |
Nginx Zugriffs-Log |
/root/gitea_ninja.sh |
Spam-Forensik Tool |
/root/gitea-forensics/ |
Forensik Reports |
13. Crumbforest-spezifisch
Vector Collector braucht Clone-Zugriff
# vector-collector-nullfeld.sh klont alle Repos
# Bei REQUIRE_SIGNIN_VIEW=true braucht der Collector Auth:
git clone https://USER:TOKEN@git.crumbforest.org/branko/REPO.git
# Token erstellen: Gitea â User Settings â Applications â Generate Token
# Oder: .netrc Datei
echo "machine git.crumbforest.org login branko password TOKEN" >> ~/.netrc
chmod 600 ~/.netrc
Neues Repo â Vektor Pipeline
1. Repo in Gitea erstellen
2. Content pushen
3. REPO_MAP in forest_seed.py erweitern
4. forest_seed --repo NeuesRepo
5. â Chunks im Vektor, Persona kann antworten
Erstellt: 30.03.2026 â Aus echtem Angriff gelernt.
Gitea 1.25.4 · Debian 12 · Der Wald schĂŒtzt sich selbst. đ„·đČ