diff --git a/install.sh b/install.sh index f20c9cf..c677f60 100755 --- a/install.sh +++ b/install.sh @@ -625,11 +625,30 @@ grant_apache_log_access() { return 0 fi - # 1) Verzeichnisse aus der aktiven Conf ermitteln (nur die Wurzel, dann - # rekursiv — das haelt die ACL-Zahl klein). + # 1) Verzeichnisse aus der aktiven Conf ermitteln. + # + # REIHENFOLGE-BUG (real): diese Funktion liest + # /etc/telegraf/telegraf.d/apache.conf + # die erst SPAETER im Ablauf geschrieben wird. Beim ERSTEN Install ist sie + # nicht da -> _roots bleibt leer -> der Fallback unten greift auf die groben + # Panel-Wurzeln (/home/users, /var/www/vhosts) zu, also auf zehntausende + # Dateien inklusive Mails und Webinhalten. Beim zweiten Lauf (x22) existierte + # die Conf und lieferte die praezisen Domain-Ordner (83 Wu­rzeln). + # Deshalb: fehlt die Conf, wird sie hier aus den erkannten Pfaden erzeugt, + # BEVOR die ACL gesetzt wird. + # QUELLE DER PFADE, richtig herum: + # 1. die aktive apache.conf (Folge-Laeufe — dort stehen bereits die Muster) + # 2. sonst APACHE_LOG (in DIESEM Lauf erkannt; beim Erstinstall ist die Conf + # noch nicht geschrieben, und genau dann griff vorher der grobe Fallback) + _pfadquelle="" + if [ -f /etc/telegraf/telegraf.d/apache.conf ]; then + _pfadquelle="$(sed -n 's/^[[:space:]]*files = \[\(.*\)\].*/\1/p' \ + /etc/telegraf/telegraf.d/apache.conf 2>/dev/null | tr -d '"' | tr ',' ' ')" + fi + [ -n "$_pfadquelle" ] || _pfadquelle="${APACHE_LOG:-}" + _roots="" - for _f in $(sed -n 's/^[[:space:]]*files = \[\(.*\)\].*/\1/p' \ - /etc/telegraf/telegraf.d/apache.conf 2>/dev/null | tr -d '"' | tr ',' ' '); do + for _f in $_pfadquelle; do case "$_f" in */\**) _f="${_f%%/\**}" ;; # /a/b/** -> /a/b */*) _f="${_f%/*}" ;; # /a/b/*/x -> /a/b/* @@ -664,8 +683,22 @@ grant_apache_log_access() { esac for _t in $_targets; do [ -d "$_t" ] || continue - # Durchgangsrecht (x) auf die Elternverzeichnisse, Leserecht (r) auf die - # Dateien: rX vergibt x nur fuer Verzeichnisse. + # DURCHGANGSRECHT auf allen ELTERNVERZEICHNISSEN bis zur Wurzel. + # Realer Fehler: /home/users/ ist oft chmod 700. Ein setfacl -R auf + # ...//logs setzt nichts auf selbst — telegraf kommt dann + # nicht bis zur Datei, obwohl die Meldung "ACL gesetzt" erscheint. + _p="$(dirname "$_t")" + while [ -n "$_p" ] && [ "$_p" != "/" ] && [ "$_p" != "." ]; do + timeout 30 setfacl -m "u:$_u:x" "$_p" 2>/dev/null || true + # Default-ACL auf Zwischenverzeichnissen, damit neue Ordner erben + case "$_p" in + /home|/home/users|/var|/var/www|/usr|/usr/local) ;; + *) timeout 30 setfacl -d -m "u:$_u:x" "$_p" 2>/dev/null || true ;; + esac + _p="$(dirname "$_p")" + done + # Leserecht (r) auf die Dateien, Durchgang (x) auf die Ordner: + # rX vergibt x nur fuer Verzeichnisse. timeout 120 setfacl -R -m "u:$_u:rX" "$_t" 2>/dev/null && _n=$((_n+1)) # Neu angelegte Dateien/Ordner erben das Recht (default-ACL nur fuer dirs). timeout 120 setfacl -R -d -m "u:$_u:rX" "$_t" 2>/dev/null || true @@ -673,20 +706,33 @@ grant_apache_log_access() { done [ "$_n" -gt 0 ] && log "Log-Leserechte gesetzt (ACL fuer '$_u') auf $_n Wurzel(n)." - # 2) Gegentest: eine echte Datei als Dienst-Benutzer lesen. - _testfile="" - for _f in $(sed -n 's/^[[:space:]]*files = \[\(.*\)\].*/\1/p' \ - /etc/telegraf/telegraf.d/apache.conf 2>/dev/null | tr -d '"' | tr ',' ' '); do + # 2) Gegentest: JEDEN Logpfad als Dienst-Benutzer pruefen — nicht nur den ersten. + # + # Realer Fehler: der Test brach beim ersten Treffer ab. Auf einem KeyHelp-Host + # war das /var/log/apache2/keyhelp/access.log (root:adm, immer lesbar) — die + # Meldung lautete "Gegentest OK", waehrend ALLE Domain-Logs in den User-Homes + # unlesbar blieben. Ein Test, der beim ersten Erfolg abbricht, verdeckt genau + # die Pfade, fuer die er gedacht ist. + _tested=0; _fail=0; _firstfail="" + for _f in $_pfadquelle; do # shellcheck disable=SC2086 - _cand="$(ls $_f 2>/dev/null | head -1)" - if [ -n "$_cand" ] && [ -s "$_cand" ]; then _testfile="$_cand"; break; fi + for _cand in $(ls $_f 2>/dev/null); do + [ -s "$_cand" ] || continue + _tested=$((_tested+1)) + if ! su -s /bin/sh "$_u" -c "head -c 1 \"$_cand\" >/dev/null 2>&1"; then + _fail=$((_fail+1)) + [ -n "$_firstfail" ] || _firstfail="$_cand" + fi + done done - if [ -n "$_testfile" ]; then - if su -s /bin/sh "$_u" -c "head -c 1 \"$_testfile\" >/dev/null 2>&1"; then - log "Gegentest: '$_u' kann Apache-Logs lesen ($_testfile)." - else - log "WARNUNG: '$_u' kann $_testfile nicht lesen — --diagnose ausfuehren." - fi + if [ "$_tested" -eq 0 ]; then + log "HINWEIS: keine gefuellte Logdatei gefunden — Gegentest nicht moeglich." + elif [ "$_fail" -eq 0 ]; then + log "Gegentest: '$_u' kann alle $_tested Logdateien lesen." + else + log "WARNUNG: $_fail von $_tested Logdateien sind fuer '$_u' NICHT lesbar." + log " Beispiel: $_firstfail" + log " Pruefen mit: sh install.sh --diagnose" fi }