fix(acl): Durchgangsrecht auf Elternverzeichnisse + Gegentest prueft ALLE Pfade
Zwei reale Fehler, beide still: 1. setfacl -R lief nur ab dem logs/-Verzeichnis. /home/users/<user> ist auf Panel-Hostern chmod 700 — ohne Durchgangsrecht (x) auf den ELTERNTEIL kommt telegraf nicht bis zur Datei. Die Meldung sagte trotzdem "ACL gesetzt". Fix: x auf allen Elternverzeichnissen bis zur Wurzel + Default-ACL, damit neu angelegte Domain-Ordner erben. 2. Der Gegentest brach beim ERSTEN Treffer ab. Das war /var/log/apache2/keyhelp/access.log (root:adm, immer lesbar) -> Meldung "Gegentest OK", waehrend ALLE Domain-Logs in den User-Homes unlesbar blieben. Fix: jeden Logpfad pruefen und die Anzahl der Fehlschlaege melden. Verifiziert in Debian-12 mit KeyHelp-aehnlichen Rechten (Home 700, Logs 640).
This commit is contained in:
1 parent
360f91f8a1
commit
6a881ce674
1 file changed
+64
-18
+64
-18
@@ -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 Wurzeln).
|
||||
# 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/<user> ist oft chmod 700. Ein setfacl -R auf
|
||||
# .../<user>/logs setzt nichts auf <user> 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
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user