commit f5c763be7bea98d3a77560c8046b6f8b950167dc Author: zomas Date: Tue Sep 1 16:54:15 2026 +0200 Gitea theme: capital theta (circle+H) logo + homepage senza badge - Logo/favicon ridisegnati come theta maiuscola: cerchio (anello) con 'H' centrata, clearance verificata (non tocca l'anello); ring ispessito per la favicon; centratura ottica verificata. - Rimosso il badge 'Self-hosted Git' dal hero della homepage (era esteticamente di troppo) - CSS e markup. - Aggiornati generate_theta.py, README, home.tmpl; caricati sul VPS in staging (md5 locali == remoti); tarball ricostruito. - Salvataggio iniziale dell'intero admin pack in git. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..01a36aa --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Segreti — MAI commitare +vps_ssh.env +risultati.txt \ No newline at end of file diff --git a/STATO_SESSIONE_2026-09-01.md b/STATO_SESSIONE_2026-09-01.md new file mode 100644 index 0000000..30237b3 --- /dev/null +++ b/STATO_SESSIONE_2026-09-01.md @@ -0,0 +1,92 @@ +# STATO SESSIONE — Gitea + Cloudflare (1 set 2026) + +File di memorizzazione del lavoro fatto, per riprendere dopo un cambio di +ambito. Aggiornato: 2026-09-01. + +--- + +## 1. Obiettivo della sessione + +Deploy di **Gitea** sul VPS OVH (145.239.94.49, Debian 12) come `https://git.zomas.net` +per tracciare il progetto Tacticus e aprirlo (in futuro) a contributi esterni. +Backup automatico incluso. Tutto completato e verificato. + +--- + +## 2. Stato finale (TUTTO FUNZIONANTE) + +| Componente | Stato | +|---|---| +| Gitea 1.27.3 | attivo (systemd, `/etc/gitea/app.ini`), DB sqlite `/var/lib/gitea/data/gitea.db` | +| Web | `https://git.zomas.net` → Apache → `127.0.0.1:3000` (200 esterno) | +| SSH git | server **built-in** Gitea su `0.0.0.0:2222` (host key ed25519/rsa/ecdsa) | +| SSH cliente | questo PC → `gitea@git.zomas.net:2222` (IP origine 145.239.94.49, chiave `~/.ssh/id_ed25519`) | +| Repo | `zomas/tacticus` **privato**, `main`, con README + `bot/.env.example` | +| Mailer | `smtp+starttls` → smtp.gmail.com:587, App Password, test email **ok** | +| 2FA | attiva (richiesta globale) + `TWO_FACTOR_AUTH=enforced` | +| Backup | `/var/backups/gitea/gitea-dump-*.zip` (gitea dump, cron giornaliero 02:30, retention 14gg) | +| Cloudflare | proxy arancio su git/zomas.net/zomas.org, SSL Full (strict), Universal SSL, CAA a posto | + +### Warning Gitea: TUTTI RISOLTI +- `https://(null)/` → colpa di `RequestHeader set Host %{HTTP_HOST}e` in Apache + (Host vuoto). Rimosso, basta `ProxyPreserveHost On`. +- Deprecazioni `[mailer].MAILER_TYPE/HOST/IS_TLS_ENABLED/SKIP_VERIFY` → + opzioni moderne (`PROTOCOL=smtp+starttls`, `SMTP_ADDR`, `SMTP_PORT`). + Log: "NESSUNA deprecazione residua". + +--- + +## 3. Errori incontrati e soluzioni (utile se si ripete) + +1. **`(null)` nel warning** → `RequestHeader set Host %{HTTP_HOST}e` sovrascrive Host + con vuoto (variabile senza valore). Fix: riga rimossa. +2. **Server SSH non partiva** → Gitea default `START_SSH_SERVER=false` (usa OpenSSH + esterno). Config: `START_SSH_SERVER=true` + `SSH_LISTEN_HOST=0.0.0.0`. + Con built-in, l'utente SSH è il **RUN_USER di Gitea = `gitea`** (NON `git`, + NON zomas): remote = `gitea@git.zomas.net:zomas/tacticus.git`. +3. **`git@` "Permission denied"** → normale: il client SSH deve usare `gitea@`. + Config in `~/.ssh/config`: `Host git.zomas.net → HostName 145.239.94.49, + Port 2222, User gitea`. +4. **Cloudflare non passa TCP 2222** → il record proxied serve solo 80/443; + per SSH si punta all'IP origine via `HostName 145.239.94.49`. +5. **SSH rifiuto public key "invalid \r"** → il `.pub` finiva con CRLF; STRIPPARE `\r` + prima di POST all'API `POST /api/v1/user/keys`. +6. **Backup "permission denied"** → `gitea dump` gira come utente `gitea`, che non + può scrivere in `/var/backups/gitea` (root). Fix: dump in `/tmp`, poi `mv` da root. +7. **Sole IPv6 da questo PC** → `git.zomas.net` risolve solo IPv6 (anycast CF); + per curl ok, per ssh serve IP IPv4 esplicito. + +--- + +## 4. Credenziali / segreti (NON committare) + +- `/home/zomas/vps-admin/vps_ssh.env` — `VPS_*`, `TOKEN_CLOUDFLARE`, `GITEA_TOKEN` +- `bot/.env` — chiavi API Tacticus + token bot Telegram (niente nel repo) +- Il repo `tacticus.git` NON contiene segreti (verificato: `.env`, `vps_ssh.env`, + `risultati.txt`, script setup esclusi da `.gitignore`). + +--- + +## 5. Comandi utili + +```bash +# SSH git (da questo PC) +git -C /home/zomas/tacticus remote -v # gitea@git.zomas.net:zomas/tacticus.git +git -C /home/zomas/tacticus push # aggiorna il remote + +# Backup manuale (da root sul VPS) +/usr/local/sbin/backup_gitea.sh +ls -lh /var/backups/gitea/ # retention 14 giorni + +# Stato servizi +systemctl status gitea apache2 cron # VPS +ss -tlnp | grep -E ':(2222|3000)\b' +``` + +--- + +## 6. PROSSIMI PASSI (cambio di ambito dell'utente) + +- (Opzionale) Download automatico dei backup VPS sul PC locale (ora solo sul VPS). +- (Opzionale) Girare il repo `tacticus` da privato a pubblico + aprire contributi. +- (Opzionale) `daily.py --fresh` (proposta rimasta aperta dal 31 ago, mai richiesta). \ No newline at end of file diff --git a/backup_gitea.sh b/backup_gitea.sh new file mode 100644 index 0000000..3dfd115 --- /dev/null +++ b/backup_gitea.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Backup automatico Gitea via `gitea dump` (db sqlite + repos + config in un unico zip). +# Retention: 14 giorni (modificare KEEP_DAYS). +set -euo pipefail + +BACKUP_DIR=/var/backups/gitea +KEEP_DAYS=14 +STAMP=$(date +%Y%m%d-%H%M%S) +TMP_ARC="/tmp/gitea-dump-$STAMP.zip" +ARC="$BACKUP_DIR/gitea-dump-$STAMP.zip" + +mkdir -p "$BACKUP_DIR" + +# Esegue il dump come utente 'gitea' (stesso user del servizio). +# Il file va in /tmp (scrivibile da gitea), poi lo spostiamo come root. +su -s /bin/bash gitea -c \ + "/usr/local/bin/gitea dump --config /etc/gitea/app.ini --file '$TMP_ARC' --type zip" \ + >/tmp/gitea-dump.log 2>&1 + +if [ ! -s "$TMP_ARC" ]; then + echo "ERRORE: dump non creato" >>/tmp/gitea-dump.log + exit 1 +fi + +mv "$TMP_ARC" "$ARC" + +# Pulisce i dump piu' vecchi di KEEP_DAYS +find "$BACKUP_DIR" -name 'gitea-dump-*.zip' -mtime +"$KEEP_DAYS" -delete + +echo "OK: $ARC ($(du -h "$ARC" | cut -f1))" \ No newline at end of file diff --git a/comandi_backup_root.txt b/comandi_backup_root.txt new file mode 100644 index 0000000..f713a78 --- /dev/null +++ b/comandi_backup_root.txt @@ -0,0 +1,2 @@ +# Verifica integrita' del dump (lo script e' gia' in /tmp) +su -s /bin/bash gitea -c "python3 /tmp/check_dump.py" 2>/dev/null || su -s /bin/bash gitea -c "python3 /tmp/check_dump.py" \ No newline at end of file diff --git a/fix_gitea_builtin_ssh.sh b/fix_gitea_builtin_ssh.sh new file mode 100644 index 0000000..bff5f4d --- /dev/null +++ b/fix_gitea_builtin_ssh.sh @@ -0,0 +1,26 @@ +# FIX: attiva il server SSH BUILT-IN di Gitea (default: esterno -> le chiavi finivano in authorized_keys senza nessun sshd su 2222) +# Dal cheat sheet: START_SSH_SERVER=false di default => Gitea delega a OpenSSH esterno. + +# 1) Backup +cp /etc/gitea/app.ini /etc/gitea/app.ini.bak.$(date +%Y%m%d%H%M%S) + +# 2) Imposta START_SSH_SERVER = true nella sezione [server] +sed -i 's/^DISABLE_SSH = false/DISABLE_SSH = false\nSTART_SSH_SERVER = true/' /etc/gitea/app.ini + +# controllo: se non ci fosse la riga DISABLE_SSH esatta, aggiunge comunque +grep -q '^START_SSH_SERVER = true' /etc/gitea/app.ini || sed -i '/^\[server\]/a START_SSH_SERVER = true' /etc/gitea/app.ini + +# 3) Mostra la sezione [server] +sed -n '/^\[server\]/,/^\[/p' /etc/gitea/app.ini + +# 4) Riavvio +systemctl restart gitea +sleep 6 + +# 5) Verifica: 2222 deve essere in ascolto E devono essere generate le host key +echo "--- listener ---" +ss -tlnp | grep -E ':(2222|3000)\b' +echo "--- host key ---" +ls -la /var/lib/gitea/data/ssh/ 2>/dev/null || echo "ATTENZIONE: nessuna host key creata" +echo "--- log avvio ssh ---" +journalctl -u gitea --since "-1 min" --no-pager | grep -iE 'ssh|listen' | tail -8 \ No newline at end of file diff --git a/fix_gitea_ssh_listen.sh b/fix_gitea_ssh_listen.sh new file mode 100644 index 0000000..b0dee20 --- /dev/null +++ b/fix_gitea_ssh_listen.sh @@ -0,0 +1,18 @@ +# Fix SSH di Gitea: forza il listener built-in su tutte le interfacce +# (di default Gitea deriva SSH_LISTEN_HOST da SSH_DOMAIN = IP Cloudflare -> bind fallisce) + +# 1) Backup +cp /etc/gitea/app.ini /etc/gitea/app.ini.bak.$(date +%Y%m%d%H%M%S) + +# 2) Aggiunge SSH_LISTEN_HOST = 0.0.0.0 dopo SSH_PORT nella sezione [server] +sed -i 's/^SSH_PORT = 2222/SSH_PORT = 2222\nSSH_LISTEN_HOST = 0.0.0.0/' /etc/gitea/app.ini + +# 3) Riavvio +systemctl restart gitea +sleep 5 + +# 4) Verifica: il listener ora deve esserci +ss -tlnp | grep -E ':(2222)\b' && echo "OK: 2222 in ascolto" || echo "ERRORE: 2222 assente" + +# 5) Verifica log avvio (liste meno, mostra le righe rilevanti) +journalctl -u gitea --since "-1 min" --no-pager | grep -iE 'ssh|listen|bind|error|warn' | tail -10 \ No newline at end of file diff --git a/fix_mailer_deprecation.sh b/fix_mailer_deprecation.sh new file mode 100644 index 0000000..022052d --- /dev/null +++ b/fix_mailer_deprecation.sh @@ -0,0 +1,26 @@ +# Correzione deprecazioni residue in [mailer] (Gitea moderno) +# Sostituisce: HOST, IS_TLS_ENABLED, SKIP_VERIFY -> SMTP_ADDR+SMTP_PORT, PROTOCOL, FORCE_TRUST_SERVER_CERT + +# 1) Backup e riscrittura della sezione [mailer] con opzioni moderne +cp /etc/gitea/app.ini /etc/gitea/app.ini.bak.$(date +%Y%m%d%H%M%S) + +# 2) Sostituisce le righe obsolete (lasciando PASSWD, FROM, USER, ENABLED intatti) +sed -i \ + -e 's|^HOST = .*|SMTP_ADDR = smtp.gmail.com\nSMTP_PORT = 587|' \ + -e 's|^IS_TLS_ENABLED = .*||' \ + -e 's|^SKIP_VERIFY = .*||' \ + /etc/gitea/app.ini + +# 3) Garantisce PROTOCOL corretto per il 587 (starttls esplicito) +sed -i 's|^PROTOCOL = smtp$|PROTOCOL = smtp+starttls|' /etc/gitea/app.ini + +# 4) Controlla il risultato (senza esporre PASSWD) +awk '/^\[mailer\]/{p=1} p{print} /^\[/ && !/\[mailer\]/{p=0}' /etc/gitea/app.ini | sed 's/^PASSWD.*/PASSWD = ***/' + +# 5) Riavvia Gitea +systemctl restart gitea +sleep 3 +systemctl status gitea --no-pager | head -6 + +# 6) Verifica che NON compaiano piu deprecazioni mailer all'avvio +journalctl -u gitea --since "-1 min" --no-pager | grep -i deprecat || echo "NESSUNA deprecazione residua" \ No newline at end of file diff --git a/fix_warning_gitea.sh b/fix_warning_gitea.sh new file mode 100644 index 0000000..428ce1c --- /dev/null +++ b/fix_warning_gitea.sh @@ -0,0 +1,12 @@ +# Correzione warning Gitea/Cloudflare +# 1) Rimuove "RequestHeader set Host" (causa Host=null nel warning giallo) +sed -i '/RequestHeader set Host/d' /etc/apache2/sites-available/git.zomas.net-ssl.conf +apache2ctl configtest && systemctl reload apache2 + +# 2) Corregge opzione deprecata MAILER_TYPE -> PROTOCOL +sed -i 's/^MAILER_TYPE = smtp/PROTOCOL = smtp/' /etc/gitea/app.ini +grep -nE '^MAILER_TYPE|^PROTOCOL' /etc/gitea/app.ini +systemctl restart gitea + +# 3) Legge le altre deprecazioni dai log (per completare) +journalctl -u gitea --no-pager | grep -i -E "deprecat|\[config\]" | tail -30 \ No newline at end of file diff --git a/gitea-theme-pack.tar.gz b/gitea-theme-pack.tar.gz new file mode 100644 index 0000000..7a9c91f Binary files /dev/null and b/gitea-theme-pack.tar.gz differ diff --git a/gitea-theme-pack/README.md b/gitea-theme-pack/README.md new file mode 100644 index 0000000..2207a77 --- /dev/null +++ b/gitea-theme-pack/README.md @@ -0,0 +1,95 @@ +# Gitea theme pack — git.zomas.net + +Homepage moderna + favicon/logo personalizzati per l'istanza Gitea. + +## Contenuto + +``` +custom/ + templates/home.tmpl # homepage pubblica ridisegnata + public/assets/img/logo.svg # logo (navbar + hero) + public/assets/img/logo.png + public/assets/img/favicon.svg # icona tab browser (SVG) + public/assets/img/favicon.png # favicon fallback (PNG) + public/assets/img/apple-touch-icon.png +install_gitea_theme.sh # installer — da eseguire come ROOT sul VPS +rollback_gitea_theme.sh # ripristino stato iniziale — da eseguire come ROOT +gitea_theme.sh # script UNICO: install o rollback (consigliato) +generate_theta.py # rigenera logo/favicon con theta greca (opzionale, serve PIL) +``` + +La homepage pubblica (la landing page che si vede su git.zomas.net +senza login) è ora un hero con gradiente, titolo, tagline e 4 +feature card. Usa solo CSS inline + variabili tematiche di Gitea, quindi +rispetta automaticamente tema chiaro/scuro. + +Il logo è una THETA MAIUSCOLA (Θ): un cerchio (anello) con una "H" +centrata. La H non tocca i bordi dell'anello (clearance verificata), +in bianco su quadrato arrotondato con gradiente viola→azzurro. +Niente badge "Self-hosted Git" sopra il logo (era esteticamente di +troppo) — il hero parte direttamente dal logo. + +## Requisiti / limitazione + +Installare questi file richiede **accesso root** (o appartenenza al +gruppo `gitea`) sul VPS: la cartella `/var/lib/gitea/custom` non è +scrivibile dall'utente SSH `deb_zomas_connection`. L'installer va quindi +lanciato da chi ha root. + +I file sono già stati caricati sul VPS in staging (dall'utente +`deb_zomas_connection`) in `/var/tmp/gitea-theme/` — pronto per essere +installato da root. + +## Applicazione (root sul VPS) — script UNICO + +I file sono già sul VPS. Da root, uno script solo gestisce tutto: + +```bash +cd /var/tmp/gitea-theme/gitea-theme-pack + +bash gitea_theme.sh install # applica homepage moderna + favicon +bash gitea_theme.sh rollback # torna allo stato iniziale (se non piace) +``` + +Lo script `gitea_theme.sh` è l'unico che serve: +- `install` salva il backup delle eventuali personalizzazioni in + `/var/lib/gitea/custom/.backup-*`, copia i file, imposta i permessi + `gitea:gitea`, scrive lo stato in `$CUSTOM_DIR/.gitea-theme-state`, + riavvia Gitea e verifica gli asset. +- `rollback` rimuove homepage+favicon custom, ripristina la precedente + personalizzazione dal backup (se esiste), riavvia Gitea. + +(Permangono anche `install_gitea_theme.sh` e `rollback_gitea_theme.sh` +come equivalenti separati, per chi preferisce un comando per azione.) + +3. Sul browser apri https://git.zomas.net premendo **Ctrl+Shift+R** + (hard reload) per bypassare la cache. + +## Ripristino + +Se la modifica non piace, da root sul VPS: + +```bash +cd /var/tmp/gitea-theme/gitea-theme-pack +bash gitea_theme.sh rollback +``` + +Lo script rimuove homepage + favicon custom, ripristina l'eventuale +personalizzazione precedente dal backup (se esiste), riavvia Gitea e +verifica. In alternativa il ripristino manuale è: + +```bash +rm -rf /var/lib/gitea/custom/templates/home.tmpl /var/lib/gitea/custom/public/assets/img +systemctl restart gitea +``` + +La vecchia homepage è comunque salvata anche su questo PC in +`/home/zomas/vps-admin/homepage-backup/homepage_original_20260901-152245.html`. + +## Note + +- Gitea 1.27.3. Homepage di riferimento: stock `templates/home.tmpl`. +- Le icone octicon usate (`git-branch`, `shield-check`, `telescope`, + `sign-in`, `repo`, `code`, `rocket`) e le chiavi locale + (`dashboard`, `explore_title`, `sign_in`, `home_title`) sono verificate + esistenti nel sorgente Gitea 1.27.3. diff --git a/gitea-theme-pack/custom/public/assets/img/apple-touch-icon.png b/gitea-theme-pack/custom/public/assets/img/apple-touch-icon.png new file mode 100644 index 0000000..7bc0161 Binary files /dev/null and b/gitea-theme-pack/custom/public/assets/img/apple-touch-icon.png differ diff --git a/gitea-theme-pack/custom/public/assets/img/favicon.png b/gitea-theme-pack/custom/public/assets/img/favicon.png new file mode 100644 index 0000000..05037b3 Binary files /dev/null and b/gitea-theme-pack/custom/public/assets/img/favicon.png differ diff --git a/gitea-theme-pack/custom/public/assets/img/favicon.svg b/gitea-theme-pack/custom/public/assets/img/favicon.svg new file mode 100644 index 0000000..0f22d50 --- /dev/null +++ b/gitea-theme-pack/custom/public/assets/img/favicon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gitea-theme-pack/custom/public/assets/img/logo.png b/gitea-theme-pack/custom/public/assets/img/logo.png new file mode 100644 index 0000000..9f732c3 Binary files /dev/null and b/gitea-theme-pack/custom/public/assets/img/logo.png differ diff --git a/gitea-theme-pack/custom/public/assets/img/logo.svg b/gitea-theme-pack/custom/public/assets/img/logo.svg new file mode 100644 index 0000000..0f22d50 --- /dev/null +++ b/gitea-theme-pack/custom/public/assets/img/logo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gitea-theme-pack/custom/templates/home.tmpl b/gitea-theme-pack/custom/templates/home.tmpl new file mode 100644 index 0000000..24ba6a6 --- /dev/null +++ b/gitea-theme-pack/custom/templates/home.tmpl @@ -0,0 +1,143 @@ +{{template "base/head" .}} + +
+
+ +

{{AppName}}

+

+ Il tuo spazio Git personale, veloce e affidabile. + Gestisci repository, collabora e tieni tutto sotto controllo, con un unico account. +

+ +
+
+
+
{{svg "octicon-rocket" 22}}
+

Veloce e leggero

+

Prestazioni elevate anche su risorse ridotte. Il tuo codice, sempre a portata di mano.

+
+
+
{{svg "octicon-shield-check" 22}}
+

Sicuro e privato

+

Accessi protetti e controllo completo sui tuoi repository, dalla creazione alla condivisione.

+
+
+
{{svg "octicon-git-branch" 22}}
+

Versioning semplice

+

Branches, pull request e collaborazione fluida, progettati per chi scrive codice ogni giorno.

+
+
+
{{svg "octicon-code" 22}}
+

Open source

+

Costruito con tecnologie aperte e libere. Nessun blocco, tutta la flessibilità di cui hai bisogno.

+
+
+
+{{template "base/footer" .}} diff --git a/gitea-theme-pack/generate_theta.py b/gitea-theme-pack/generate_theta.py new file mode 100644 index 0000000..54c6c3c --- /dev/null +++ b/gitea-theme-pack/generate_theta.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +# Logo/favicon Gitea: THETA MAIUSCOLA = cerchio (anello) con una "H" al centro. +# La H non tocca l'anello (clearance sicura). Niente coda. +# Emette sia gli SVG (logo/favicon) che i PNG (logo/favicon/apple-touch-icon) +# partendo dalla STESSA geometria, così SVG e PNG combaciano. +import os +from PIL import Image, ImageDraw + +OUT = "custom/public/assets/img" + +# --- geometria normalizzata (frazioni del lato quadrato) --- +INSET = 0.04 # bordo del riquadro arrotondato +RAD = 0.22 # raggio angoli del riquadro +CX, CY = 0.5, 0.5 # centro (simmetrico, nessuna coda) +RO = 0.41 # raggio esterno anello +RING = 0.05 # spessore anello -> raggio interno RI = RO - RING +# H centrale +HH = 0.26 # mezza altezza della H (stelo da CY-HH a CY+HH) +SPAC = 0.145 # distanza orizzontale dal centro agli steli +STEM = 0.05 # spessore steli +CROSS = 0.042 # spessore barra orizzontale + +C1, C2 = (124, 58, 237), (14, 165, 233) # viola -> azzurro + +RI = RO - RING + + +def lerp(a, b, t): + return int(a + (b - a) * t) + + +def grad_color(t): + return (lerp(C1[0], C2[0], t), lerp(C1[1], C2[1], t), lerp(C1[2], C2[2], t)) + + +def theta_geo(size): + cx, cy = CX * size, CY * size + ro, ri = RO * size, RI * size + stem = STEM * size + cross = CROSS * size + # steli: centro x = cx ± SPAC + left_x0 = (CX - SPAC - STEM / 2) * size + left_x1 = (CX - SPAC + STEM / 2) * size + right_x0 = (CX + SPAC - STEM / 2) * size + right_x1 = (CX + SPAC + STEM / 2) * size + st_y0, st_y1 = (CY - HH) * size, (CY + HH) * size + # barra: attraversa tutta la larghezza della H, centrata su CY + cb_y0, cb_y1 = CY * size - cross / 2, CY * size + cross / 2 + return dict(cx=cx, cy=cy, ro=ro, ri=ri, + left_x0=left_x0, left_x1=left_x1, + right_x0=right_x0, right_x1=right_x1, + st_y0=st_y0, st_y1=st_y1, + cb_x0=left_x0, cb_x1=right_x1, cb_y0=cb_y0, cb_y1=cb_y1, + stem=stem, cross=cross) + + +def circle_path(r, cx, cy, size): + lx, rx = cx - r, cx + r + return (f"M {lx:.2f} {cy:.2f} A {r:.2f} {r:.2f} 0 1 0 {rx:.2f} {cy:.2f} " + f"A {r:.2f} {r:.2f} 0 1 0 {lx:.2f} {cy:.2f} Z") + + +def svg_theta(size): + g = theta_geo(size) + inset, rad = INSET * size, RAD * size + w = size + + def e(x): + return f"{x:.2f}" + + outer = circle_path(g["ro"], g["cx"], g["cy"], size) + inner = circle_path(g["ri"], g["cx"], g["cy"], size) + + lines = [] + lines.append(f'') + lines.append(' ' + '') + lines.append(f' ') + # anello (theta maiuscola = cerchio) + lines.append(f' ') + # H centrale (steli + barra) + lines.append(f' ') + lines.append(f' ') + lines.append(f' ') + lines.append('') + return "\n".join(lines) + "\n" + + +def draw_theta_png(size, apple=False): + g = theta_geo(size) + img = Image.new("RGBA", (size, size), (0, 0, 0, 0)) + inset, rad = INSET * size, RAD * size + + # sfondo: riquadro arrotondato con gradiente verticale + sq = Image.new("L", (size, size), 0) + ImageDraw.Draw(sq).rounded_rectangle( + [inset, inset, size - inset, size - inset], radius=rad, fill=255) + grad = Image.new("RGBA", (size, size), (0, 0, 0, 0)) + gd = ImageDraw.Draw(grad) + for i in range(size * 2): + t = i / (size * 2 - 1) + gd.line([(i, 0), (i, size)], fill=grad_color(t)) + grad.putalpha(sq) + img.alpha_composite(grad) + + # theta+H come maschera bianca + mask = Image.new("L", (size, size), 0) + md = ImageDraw.Draw(mask) + md.ellipse([g["cx"] - g["ro"], g["cy"] - g["ro"], + g["cx"] + g["ro"], g["cy"] + g["ro"]], fill=255) + md.ellipse([g["cx"] - g["ri"], g["cy"] - g["ri"], + g["cx"] + g["ri"], g["cy"] + g["ri"]], fill=0) + md.rectangle([g["left_x0"], g["st_y0"], g["left_x1"], g["st_y1"]], fill=255) + md.rectangle([g["right_x0"], g["st_y0"], g["right_x1"], g["st_y1"]], fill=255) + md.rectangle([g["cb_x0"], g["cb_y0"], g["cb_x1"], g["cb_y1"]], fill=255) + + white = Image.new("RGBA", (size, size), (255, 255, 255, 255)) + white.putalpha(mask) + img.alpha_composite(white) + + if apple: + base = Image.new("RGBA", img.size, (255, 255, 255, 255)) + base.alpha_composite(img) + return base.convert("RGB") + return img + + +def make_assets(): + os.makedirs(OUT, exist_ok=True) + open(f"{OUT}/logo.svg", "w").write(svg_theta(64)) + open(f"{OUT}/favicon.svg", "w").write(svg_theta(64)) + draw_theta_png(220).save(f"{OUT}/logo.png") + draw_theta_png(64).save(f"{OUT}/favicon.png") + draw_theta_png(180, apple=True).save(f"{OUT}/apple-touch-icon.png") + print("theta (capital: circle + H) assets written to", OUT) + + +if __name__ == "__main__": + make_assets() diff --git a/gitea-theme-pack/gitea_theme.sh b/gitea-theme-pack/gitea_theme.sh new file mode 100755 index 0000000..c49fe4a --- /dev/null +++ b/gitea-theme-pack/gitea_theme.sh @@ -0,0 +1,133 @@ +#!/bin/bash +# Gitea theme manager — installa o ripristina homepage + favicon custom. +# DA ESEGUIRE COME ROOT SUL VPS (o con sudo). +# +# Uso: +# bash gitea_theme.sh install # applica la homepage moderna + favicon +# bash gitea_theme.sh rollback # torna allo stato iniziale +# bash gitea_theme.sh # come "install" +set -euo pipefail + +CUSTOM_DIR="${CUSTOM_DIR:-/var/lib/gitea/custom}" +SRC_DIR="$(cd "$(dirname "$0")" && pwd)/custom" +STATE_FILE="$CUSTOM_DIR/.gitea-theme-state" + +MODE="${1:-install}" +case "$MODE" in + install|rollback) : ;; + *) echo "Uso: $0 [install|rollback]"; exit 2 ;; +esac + +if [ "$(id -u)" != "0" ]; then + echo "ERRORE: devi eseguire questo script come root (o sudo)." + exit 1 +fi + +# ---------------------------------------------------------------- verifica +echo "==> Modalità: $MODE" +echo "==> Custom dir: $CUSTOM_DIR" + +# ---------------------------------------------------------------- install +install_theme() { + STAMP="$(date +%Y%m%d-%H%M%S)" + BACKUP_DIR="${CUSTOM_DIR}/.backup-${STAMP}" + + if [ ! -d "$SRC_DIR" ]; then + echo "ERRORE: cartella sorgente '$SRC_DIR' non trovata (script in cartella sbagliata?)." + exit 1 + fi + + # 1) Backup delle eventuali personalizzazioni esistenti + HAD_PREV=no + if [ -e "$CUSTOM_DIR/templates/home.tmpl" ] || [ -e "$CUSTOM_DIR/public/assets/img" ]; then + HAD_PREV=yes + mkdir -p "$BACKUP_DIR" + for p in templates/home.tmpl public/assets/img; do + if [ -e "$CUSTOM_DIR/$p" ]; then + mkdir -p "$BACKUP_DIR/$(dirname "$p")" + cp -a "$CUSTOM_DIR/$p" "$BACKUP_DIR/$p" + echo "==> Backup salvato: $BACKUP_DIR/$p" + fi + done + else + echo "==> Nessuna personalizzazione precedente, niente da salvare." + fi + + # 2) Copia dei nuovi file + mkdir -p "$CUSTOM_DIR/templates" "$CUSTOM_DIR/public/assets/img" + cp "$SRC_DIR/templates/home.tmpl" "$CUSTOM_DIR/templates/home.tmpl" + cp "$SRC_DIR/public/assets/img/"* "$CUSTOM_DIR/public/assets/img/" + echo "==> File copiati:" + ls -l "$CUSTOM_DIR/templates/home.tmpl" + ls -l "$CUSTOM_DIR/public/assets/img/" + + # 3) Permessi corretti (il processo gitea gira come utente gitea) + chown -R gitea:gitea "$CUSTOM_DIR" + echo "==> Permessi impostati (gitea:gitea)." + + # 4) Stato per il rollback + { + echo "installed_at=$STAMP" + echo "backup_dir=$BACKUP_DIR" + echo "had_custom=$HAD_PREV" + } > "$STATE_FILE" + echo "==> Stato rollback salvato in $STATE_FILE" +} + +# ---------------------------------------------------------------- rollback +rollback_theme() { + # 1) Leggi lo stato di installazione (se esiste) + BACKUP_DIR="" + HAD_PREV=no + if [ -f "$STATE_FILE" ]; then + source "$STATE_FILE" 2>/dev/null || true + echo "==> Stato trovato: installato $installed_at, backup=${backup_dir:-nessuno}, precedente=$had_custom" + fi + + # 2) Rimuovi i file del tema + rm -f "$CUSTOM_DIR/templates/home.tmpl" + rm -rf "$CUSTOM_DIR/public/assets/img" + echo "==> File del tema rimossi (home.tmpl e assets/img)." + + # 3) Ripristina l'eventuale personalizzazione precedente dal backup + if [ "$HAD_PREV" = "yes" ] && [ -n "${BACKUP_DIR:-}" ] && [ -d "$BACKUP_DIR" ]; then + echo "==> Ripristino personalizzazione precedente da $BACKUP_DIR" + if [ -f "$BACKUP_DIR/templates/home.tmpl" ]; then + mkdir -p "$CUSTOM_DIR/templates" + cp -a "$BACKUP_DIR/templates/home.tmpl" "$CUSTOM_DIR/templates/home.tmpl" + fi + if [ -d "$BACKUP_DIR/public/assets/img" ]; then + mkdir -p "$CUSTOM_DIR/public/assets/img" + cp -a "$BACKUP_DIR/public/assets/img/." "$CUSTOM_DIR/public/assets/img/" + fi + fi + + # 4) Rimuovi lo stato e le cartelle eventualmente vuote + rm -f "$STATE_FILE" + rmdir "$CUSTOM_DIR/public/assets/img" "$CUSTOM_DIR/public/assets" "$CUSTOM_DIR/public" 2>/dev/null || true + rmdir "$CUSTOM_DIR/templates" 2>/dev/null || true + echo "==> Stato rollback pulito." + + # 5) Permessi + chown -R gitea:gitea "$CUSTOM_DIR" 2>/dev/null || true +} + +# ---------------------------------------------------------------- esegui +if [ "$MODE" = "install" ]; then + install_theme +else + rollback_theme +fi + +# ---------------------------------------------------------------- restart+verify +systemctl restart gitea +sleep 6 +echo "==> Stato servizio: $(systemctl is-active gitea)" +if [ "$MODE" = "install" ]; then + echo "==> Verifica asset (favicon/logo):" + curl -sk -o /dev/null -w " /assets/img/favicon.svg -> %{http_code}\n" https://127.0.0.1/assets/img/favicon.svg 2>/dev/null || true + curl -sk -o /dev/null -w " /assets/img/logo.svg -> %{http_code}\n" https://127.0.0.1/assets/img/logo.svg 2>/dev/null || true +fi + +echo "" +echo "FATTO ($MODE). Ricarica https://git.zomas.net (Ctrl+Shift+R per bypassare la cache)." diff --git a/gitea-theme-pack/install_gitea_theme.sh b/gitea-theme-pack/install_gitea_theme.sh new file mode 100755 index 0000000..3797d52 --- /dev/null +++ b/gitea-theme-pack/install_gitea_theme.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# Installa homepage moderna + favicon personalizzate per Gitea. +# DA ESEGUIRE COME ROOT SUL VPS (o con sudo). +# Uso: bash install_gitea_theme.sh +set -euo pipefail + +CUSTOM_DIR="${CUSTOM_DIR:-/var/lib/gitea/custom}" +SRC_DIR="$(cd "$(dirname "$0")" && pwd)/custom" +STAMP="$(date +%Y%m%d-%H%M%S)" +BACKUP_DIR="${CUSTOM_DIR}/.backup-${STAMP}" + +if [ "$(id -u)" != "0" ]; then + echo "ERRORE: devi eseguire questo script come root (o sudo)." + exit 1 +fi + +if [ ! -d "$SRC_DIR" ]; then + echo "ERRORE: cartella sorgente '$SRC_DIR' non trovata (script in cartella sbagliata?)." + exit 1 +fi + +echo "==> Target custom dir: $CUSTOM_DIR" + +# 1) Backup delle eventuali personalizzazioni esistenti +HAD_PREV=no +if [ -e "$CUSTOM_DIR/templates/home.tmpl" ] || [ -e "$CUSTOM_DIR/public/assets/img" ]; then + HAD_PREV=yes + mkdir -p "$BACKUP_DIR" + for p in templates/home.tmpl public/assets/img; do + if [ -e "$CUSTOM_DIR/$p" ]; then + mkdir -p "$BACKUP_DIR/$(dirname "$p")" + cp -a "$CUSTOM_DIR/$p" "$BACKUP_DIR/$p" + echo "==> Backup salvato: $BACKUP_DIR/$p" + fi + done +else + echo "==> Nessuna personalizzazione precedente, niente da salvare." +fi + +# 2) Copia dei nuovi file +mkdir -p "$CUSTOM_DIR/templates" "$CUSTOM_DIR/public/assets/img" +cp "$SRC_DIR/templates/home.tmpl" "$CUSTOM_DIR/templates/home.tmpl" +cp "$SRC_DIR/public/assets/img/"* "$CUSTOM_DIR/public/assets/img/" +echo "==> File copiati:" +ls -l "$CUSTOM_DIR/templates/home.tmpl" +ls -l "$CUSTOM_DIR/public/assets/img/" + +# 3) Permessi corretti (il processo gitea gira come utente gitea) +chown -R gitea:gitea "$CUSTOM_DIR" +echo "==> Permessi impostati (gitea:gitea)." + +# 3b) Stato per il rollback +STATE_FILE="$CUSTOM_DIR/.gitea-theme-state" +{ + echo "installed_at=$STAMP" + echo "backup_dir=$BACKUP_DIR" + echo "had_custom=$HAD_PREV" +} > "$STATE_FILE" +echo "==> Stato rollback salvato in $STATE_FILE" + +# 4) Riavvio di Gitea +systemctl restart gitea +sleep 6 + +# 5) Verifica +echo "==> Stato servizio:" +systemctl is-active gitea +echo "==> Verifica favicon (HTTP code):" +curl -sk -o /dev/null -w " /assets/img/favicon.svg -> %{http_code}\n" https://127.0.0.1/assets/img/favicon.svg \ + || echo " (curl locale non disponibile, verificare via browser)" +echo "==> Verifica logo:" +curl -sk -o /dev/null -w " /assets/img/logo.svg -> %{http_code}\n" https://127.0.0.1/assets/img/logo.svg \ + || true + +echo "" +echo "FATTO. Ricarica https://git.zomas.net (con Ctrl+Shift+R per bypassare la cache del browser)." +echo "Per ripristinare la versione originale:" +echo " rm -rf $CUSTOM_DIR/templates/home.tmpl $CUSTOM_DIR/public/assets/img" +echo " systemctl restart gitea" +echo "Backup delle vecchie file (se esistenti): $BACKUP_DIR" diff --git a/gitea-theme-pack/rollback_gitea_theme.sh b/gitea-theme-pack/rollback_gitea_theme.sh new file mode 100755 index 0000000..f2b21b3 --- /dev/null +++ b/gitea-theme-pack/rollback_gitea_theme.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# Rimuove la homepage personalizzata e la favicon di Gitea, tornando allo +# stato originale (Gitea stock) o a una eventuale personalizzazione precedente. +# DA ESEGUIRE COME ROOT SUL VPS (o con sudo). +# Uso: bash rollback_gitea_theme.sh +set -euo pipefail + +CUSTOM_DIR="${CUSTOM_DIR:-/var/lib/gitea/custom}" +STATE_FILE="$CUSTOM_DIR/.gitea-theme-state" + +if [ "$(id -u)" != "0" ]; then + echo "ERRORE: devi eseguire questo script come root (o sudo)." + exit 1 +fi + +echo "==> Ripristino stato iniziale di Gitea (custom) in $CUSTOM_DIR" + +# 1) Leggi lo stato di installazione (se esiste) +BACKUP_DIR="" +HAD_PREV=no +if [ -f "$STATE_FILE" ]; then + source "$STATE_FILE" 2>/dev/null || true + echo "==> Stato trovato: installato $installed_at, backup=${backup_dir:-nessuno}, precedente=$had_custom" +fi + +# 2) Rimuovi i file del tema +rm -f "$CUSTOM_DIR/templates/home.tmpl" +rm -rf "$CUSTOM_DIR/public/assets/img" +echo "==> File del tema rimossi (home.tmpl e assets/img)." + +# 3) Ripristina una eventuale personalizzazione precedente dal backup +RESTORED=no +if [ "$HAD_PREV" = "yes" ] && [ -n "${BACKUP_DIR:-}" ] && [ -d "$BACKUP_DIR" ]; then + echo "==> Ripristino personalizzazione precedente da $BACKUP_DIR" + if [ -f "$BACKUP_DIR/templates/home.tmpl" ]; then + mkdir -p "$CUSTOM_DIR/templates" + cp -a "$BACKUP_DIR/templates/home.tmpl" "$CUSTOM_DIR/templates/home.tmpl" + RESTORED=yes + fi + if [ -d "$BACKUP_DIR/public/assets/img" ]; then + mkdir -p "$CUSTOM_DIR/public/assets/img" + cp -a "$BACKUP_DIR/public/assets/img/." "$CUSTOM_DIR/public/assets/img/" + fi +fi + +# 4) Rimuovi lo stato e le cartelle eventualmente vuote +rm -f "$STATE_FILE" +rmdir "$CUSTOM_DIR/public/assets/img" "$CUSTOM_DIR/public/assets" "$CUSTOM_DIR/public" 2>/dev/null || true +rmdir "$CUSTOM_DIR/templates" 2>/dev/null || true +echo "==> Stato rollback pulito." + +# 5) Permessi e riavvio +chown -R gitea:gitea "$CUSTOM_DIR" 2>/dev/null || true +systemctl restart gitea +sleep 6 + +# 6) Verifica +echo "==> Stato servizio: $(systemctl is-active gitea)" +curl -sk -o /dev/null -w " /assets/img/favicon.svg -> %{http_code} (200=stock Gitea, 404=custom rimosso)\n" https://127.0.0.1/assets/img/favicon.svg 2>/dev/null || true + +echo "" +echo "FATTO. Ricarica https://git.zomas.net (Ctrl+Shift+R per bypassare la cache)." diff --git a/homepage-backup/homepage_original_20260901-152245.html b/homepage-backup/homepage_original_20260901-152245.html new file mode 100644 index 0000000..ba996d6 --- /dev/null +++ b/homepage-backup/homepage_original_20260901-152245.html @@ -0,0 +1,245 @@ + + + + + + Zomas- Git + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+
+
+ +
+

+ Zomas- Git +

+

A painless, self-hosted Git service

+
+
+
+
+
+

+ Easy to install +

+

+ Simply run the binary for your platform, ship it with Docker, or get it packaged. +

+
+
+

+ Cross-platform +

+

+ Gitea runs anywhere Go can compile for: Windows, macOS, Linux, ARM, etc. Choose the one you love! +

+
+
+
+
+

+ Lightweight +

+

+ Gitea has low minimal requirements and can run on an inexpensive Raspberry Pi. Save your machine energy! +

+
+
+

+ Open Source +

+

+ Go get gitea.dev! Join us by contributing to make this project even better. Don't hesitate to contribute! +

+
+
+
+ + + +
+ + + + + + + + + diff --git a/install_backup_gitea.sh b/install_backup_gitea.sh new file mode 100644 index 0000000..7fa4322 --- /dev/null +++ b/install_backup_gitea.sh @@ -0,0 +1,59 @@ +# ============================================================ +# INSTALLAZIONE BACKUP AUTOMATICO GITEA (da eseguire da ROOT) +# Incolla tutto questo blocco nel terminale root del VPS. +# ============================================================ + +# 1) Crea la directory backup +mkdir -p /var/backups/gitea + +# 2) Scrivi lo script di backup in /usr/local/sbin (autosufficiente) +cat > /usr/local/sbin/backup_gitea.sh <<'EOF' +#!/bin/bash +# Backup automatico Gitea via `gitea dump` (db sqlite + repos + config in un unico zip). +# Retention: 14 giorni (modificare KEEP_DAYS). +set -euo pipefail + +BACKUP_DIR=/var/backups/gitea +KEEP_DAYS=14 +STAMP=$(date +%Y%m%d-%H%M%S) +ARC="$BACKUP_DIR/gitea-dump-$STAMP.zip" + +mkdir -p "$BACKUP_DIR" + +# Esegue il dump come utente 'gitea' (stesso user del servizio) +su -s /bin/bash gitea -c \ + "/usr/local/bin/gitea dump --config /etc/gitea/app.ini --file '$ARC' --type zip" \ + >/tmp/gitea-dump.log 2>&1 + +if [ ! -s "$ARC" ]; then + echo "ERRORE: dump non creato" >>/tmp/gitea-dump.log + exit 1 +fi + +# Pulisce i dump piu' vecchi di KEEP_DAYS +find "$BACKUP_DIR" -name 'gitea-dump-*.zip' -mtime +"$KEEP_DAYS" -delete + +echo "OK: $ARC ($(du -h "$ARC" | cut -f1))" +EOF +chmod 0755 /usr/local/sbin/backup_gitea.sh + +# 3) TEST: esegui un backup manuale adesso +/usr/local/sbin/backup_gitea.sh +ls -lh /var/backups/gitea/ + +# 4) Installa il cron giornaliero alle 02:30 via /etc/cron.d +cat > /etc/cron.d/gitea-backup <<'CRON' +# Backup giornaliero Gitea alle 02:30, stdout/stderr su log +30 2 * * * root /usr/local/sbin/backup_gitea.sh >>/tmp/gitea-dump.log 2>&1 +CRON +chmod 0644 /etc/cron.d/gitea-backup + +# 5) Verifica +echo "--- cron installato ---" +ls -l /etc/cron.d/gitea-backup +echo "--- contenuto ---" +cat /etc/cron.d/gitea-backup +echo "--- sistema crontab attivo? ---" +systemctl is-active cron 2>/dev/null || service cron status 2>/dev/null | head -2 || echo "cron non attivo (verificare)" +echo "--- ultimo backup (zona) ---" +ls -lh /var/backups/gitea/ \ No newline at end of file diff --git a/install_gitea_vps.sh b/install_gitea_vps.sh new file mode 100644 index 0000000..edd7d8d --- /dev/null +++ b/install_gitea_vps.sh @@ -0,0 +1,249 @@ +# Installazione Gitea su VPS OVH — copia/incolla (root/sudo) +# Obbiettivo: git.zomas.net (Gitea dietro Apache; non tocca zomas.net / zomas.org) +# VPS: Debian 12, 4 vCPU, 7.6GB RAM +# Chi esegue: TU (root o sudo). Esegui i blocchi in ordine. + +# +# ⚠️ PREREQUISITO DNS: prima del Passo 5 deve risolvere pubblicamente: +# dig +short git.zomas.net -> deve tornare 145.239.94.49 +# (finché dà NXDOMAIN, SALTA il Passo 5 e resta solo in HTTP) +# + +############################################################################### +# PASSO 1 — Installa Gitea (binario ufficiale + utente dedicato + sqlite) +############################################################################### + +apt-get update && apt-get upgrade -y +apt-get install -y git sqlite3 curl wget + +# utente di sistema dedicato (senza login) +adduser --system --group --disabled-password --home /var/lib/gitea gitea +mkdir -p /etc/gitea /var/lib/gitea/custom /var/lib/gitea/data /var/lib/gitea/log +chown -R root:gitea /etc/gitea +chown -R gitea:gitea /var/lib/gitea/ +chmod -R g+rws /var/lib/gitea/ +chmod -R g+rw /var/lib/gitea/ + +# ultima versione stabile +VERSION=$(curl -sL https://dl.gitea.com/gitea/version.json | python3 -c "import sys,json;print(json.load(sys.stdin)['latest']['version'])" 2>/dev/null || echo "1.22.0") +echo "Installazione Gitea $VERSION" +curl -sL -o /tmp/gitea "https://dl.gitea.com/gitea/$VERSION/gitea-$VERSION-linux-amd64" + +# sposta e rendi eseguibile +install -o root -g root -m 755 /tmp/gitea /usr/local/bin/gitea +/usr/local/bin/gitea --version + +############################################################################### +# PASSO 2 — Configurazione Gitea (app.ini) +############################################################################### + +cat > /etc/gitea/app.ini <<'EOF' +RUN_USER = gitea +RUN_MODE = prod + +[server] +; porta INTERNA: Apache farà da proxy verso questa +HTTP_PORT = 3000 +HTTP_ADDR = 127.0.0.1 +ROOT_URL = https://git.zomas.net/ +DOMAIN = git.zomas.net +DISABLE_SSH = false +SSH_PORT = 2222 +LFS_START_SERVER = true + +[database] +DB_TYPE = sqlite3 +PATH = /var/lib/gitea/data/gitea.db + +[repository] +ROOT = /var/lib/gitea/data/gitea-repositories + +[service] +DISABLE_REGISTRATION = false ; metti true quando vuoi bloccare le iscrizioni esterne +EOF + +chown -R gitea:gitea /etc/gitea + +############################################################################### +# PASSO 3 — Servizio systemd +############################################################################### + +tee /etc/systemd/system/gitea.service >/dev/null <<'EOF' +[Unit] +Description=Gitea (Git with a cup of tea) +After=syslog.target +After=network.target + +[Service] +RestartSec=2s +Type=simple +User=gitea +Group=gitea +WorkingDirectory=/var/lib/gitea/ +ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini +Restart=always +Environment=USER=gitea HOME=/var/lib/gitea GITEA_WORK_DIR=/var/lib/gitea + +[Install] +WantedBy=multi-user.target +EOF + +systemctl daemon-reload +systemctl enable gitea +systemctl start gitea +systemctl status gitea --no-pager | head -15 + +# verifica locale (deve rispondere HTTP) +curl -sI http://127.0.0.1:3000 | head -3 + +############################################################################### +# PASSO 4 — Virtualhost Apache (reverse proxy verso Gitea) +############################################################################### + +# abilita i moduli necessario (i siti zomas.net/zomas.org NON vengono toccati) +a2enmod proxy_http proxy ssl +systemctl reload apache2 + +# virtualhost HTTP (redirect -> https) +cat > /etc/apache2/sites-available/git.zomas.net.conf <<'EOF' + + ServerName git.zomas.net + Redirect permanent / https://git.zomas.net/ + +EOF + +# virtualhost HTTPS (proxy verso Gitea su 127.0.0.1:3000) — certbot poi aggiunge il SSL +cat > /etc/apache2/sites-available/git.zomas.net-ssl.conf <<'EOF' + + ServerName git.zomas.net + CustomLog /var/log/apache2/git.zomas.net-access.log combined + ErrorLog /var/log/apache2/git.zomas.net-error.log + + ProxyPreserveHost On + RequestHeader set Host %{HTTP_HOST}e + ProxyRequests Off + ProxyPass / http://127.0.0.1:3000/ + ProxyPassReverse / http://127.0.0.1:3000/ + +EOF + +# abilita i virtualhost (mantenendo net/org intatti) +a2ensite git.zomas.net.conf +a2ensite git.zomas.net-ssl.conf +systemctl reload apache2 + +# verifica: il vhost :80 deve rispondere +curl -sI http://127.0.0.1:80 -H "Host: git.zomas.net" | head -3 + +############################################################################### +# PASSO 5 — Certificato HTTPS con Let's Encrypt +# ⚠️ FAI SOLO QUANDO git.zomas.net risolve pubblicamente (dig +short = 145.239.94.49) +############################################################################### + +# richiedi il certificato per git.zomas.net (usa il vhost :80 come challenge) +certbot --apache -d git.zomas.net +# quando ti chiede il redirect HTTP->HTTPS scegli: 2 + +systemctl reload apache2 + +# verifica finale HTTPS +curl -sI https://git.zomas.net | head -3 + +############################################################################### +# PRIMO ACCESSO (dopo il Passo 3, già funziona in HTTP) +############################################################################### +# Apri nel browser: https://git.zomas.net (o http:// se non hai ancora il passo 5) +# Al primo avvio Gitea mostra la pagina di installazione: +# - DB: SQLite3 +# - Path DB: /var/lib/gitea/data/gitea.db +# - URL: https://git.zomas.net/ +# - Crea l'account amministratore (utente final, nome, email, password) +# Si può rilanciare la procedura con: su gitea -s /bin/bash -c "cd /var/lib/gitea && /usr/local/bin/gitea admin create-user --username admin --password 'ScegliPasswordSicura' --email you@example.com --admin" +# (poi applica via web) +# +# Nota SSH: Gitea usa la porta 2222 per git over SSH (oltre alla web). Da client: +# git clone ssh://git@git.zomas.net:2222//.git + +############################################################################### +# PASSO 6 — Certificati Let's Encrypt per origine (plugin dns-cloudflare) +# ⚠️ da eseguire come ROOT sul VPS. Il token CF è già in /tmp/cloudflare_tmp.ini +# Genera i cert con challenge DNS: funziona anche con i record messi "proxied". +# NON tocca i vhost esistenti di zomas.net / zomas.org (stesso --cert-name). +############################################################################### + +set -ea +mkdir -p /root/.config/letsencrypt +[ -f /tmp/cloudflare_tmp.ini ] && { cp /tmp/cloudflare_tmp.ini /root/.config/letsencrypt/cloudflare.ini; chmod 600 /root/.config/letsencrypt/cloudflare.ini; } || { echo "Manca /tmp/cloudflare_tmp.ini"; exit 1; } + +echo "=== 1/3 zomas.net + www ===" +certbot certonly --dns-cloudflare \ + --dns-cloudflare-credentials /root/.config/letsencrypt/cloudflare.ini \ + --dns-cloudflare-propagation-seconds 60 \ + -d zomas.net -d www.zomas.net \ + --cert-name zomas.net --non-interactive --agree-tos -m zomas@zomas.net --force-renewal + +echo "=== 2/3 zomas.org + www ===" +certbot certonly --dns-cloudflare \ + --dns-cloudflare-credentials /root/.config/letsencrypt/cloudflare.ini \ + --dns-cloudflare-propagation-seconds 60 \ + -d zomas.org -d www.zomas.org \ + --cert-name zomas.org --non-interactive --agree-tos -m zomas@zomas.org --force-renewal + +echo "=== 3/3 git.zomas.net ===" +certbot certonly --dns-cloudflare \ + --dns-cloudflare-credentials /root/.config/letsencrypt/cloudflare.ini \ + --dns-cloudflare-propagation-seconds 60 \ + -d git.zomas.net \ + --cert-name git.zomas.net --non-interactive --agree-tos -m zomas@zomas.net + +echo "=== file generati in /etc/letsencrypt/live ===" +ls -la /etc/letsencrypt/live/ +echo "=== certificati git ===" +ls -la /etc/letsencrypt/live/git.zomas.net/ + +############################################################################### +# PASSO 7 — (dopo aver generato i cert) Completare il vhost SSL di git +# e riabilitarlo. Il certificato git ora esiste in live/git.zomas.net. +# ⚠️ Leggi il contenuto di git.zomas.net-ssl.conf e COMPLETA il blocco +# aggiungendo: SSLEngine on + SSLCertificateFile/Key con i path git. +# Esempio (sostituisci tutto il contenuto del file): +############################################################################### + +cat > /etc/apache2/sites-available/git.zomas.net-ssl.conf <<'EOF' + + ServerName git.zomas.net + CustomLog /var/log/apache2/git.zomas.net-access.log combined + ErrorLog /var/log/apache2/git.zomas.net-error.log + + SSLEngine on + Include /etc/letsencrypt/options-ssl-apache.conf + SSLCertificateFile /etc/letsencrypt/live/git.zomas.net/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/git.zomas.net/privkey.pem + + ProxyPreserveHost On + RequestHeader set Host %{HTTP_HOST}e + ProxyRequests Off + ProxyPass / http://127.0.0.1:3000/ + ProxyPassReverse / http://127.0.0.1:3000/ + +EOF + +# riabilita il vhost SSL di git (dopo aver verificato che i cert esistono) +a2ensite git.zomas.net-ssl.conf +apache2ctl configtest +systemctl reload apache2 + +# verifica certificato da linea di comando +curl -sk -o /dev/null -w "https git (via IP/SNI) HTTP %{http_code}\n" https://127.0.0.1 -H "Host: git.zomas.net" --resolve git.zomas.net:443:127.0.0.1 + +############################################################################### +# PASSO 8 — Pannello Cloudflare: attiva il proxy (arancio) SOLO sui record web +# ⚠️ NON toccare: MX, mail.*, sole, calendar, docs, _dmarc, SPF, SRV +# Metti "Proxy (arancio)" su: +# - git.zomas.net (già arancio) +# - zomas.net (A) +# - www.zomas.net (CNAME) +# - zomas.org (A) +# - www.zomas.org (CNAME) +# Poi in SSL/TLS -> Overview seleziona: "Full (strict)" +###############################################################################