fix(apache): Glob-Muster in der Conf behalten (set -f statt Expansion) + ACL fuer User-Home-Logs (KeyHelp) + Diagnose entdoppelt
This commit is contained in:
1 parent
911823514d
commit
3c0c800f90
1 file changed
+133
-58
+133
-58
@@ -131,7 +131,9 @@ if [ "$DIAGNOSE" -eq 1 ]; then
|
|||||||
printf '\n-- Logpfade aus der aktiven Conf --\n'
|
printf '\n-- Logpfade aus der aktiven Conf --\n'
|
||||||
CF="/etc/telegraf/telegraf.d/apache.conf"
|
CF="/etc/telegraf/telegraf.d/apache.conf"
|
||||||
[ -f "$CF" ] || CF="/etc/telegraf/telegraf.conf"
|
[ -f "$CF" ] || CF="/etc/telegraf/telegraf.conf"
|
||||||
_files="$(sed -n 's/^[[:space:]]*files = \[\(.*\)\].*/\1/p' "$CF" | tr -d '"' | tr ',' ' ')"
|
# Beide files-Zeilen (journal + apache_access) lesen, aber entdoppeln —
|
||||||
|
# sonst erscheint jeder Pfad zweimal in der Ausgabe.
|
||||||
|
_files="$(sed -n 's/^[[:space:]]*files = \[\(.*\)\].*/\1/p' "$CF" | tr -d '"' | tr ',' '\n' | sed 's/^ *//; s/ *$//' | grep -v '^$' | sort -u | tr '\n' ' ')"
|
||||||
[ -n "$_files" ] || { printf ' (keine files-Liste gefunden)\n'; }
|
[ -n "$_files" ] || { printf ' (keine files-Liste gefunden)\n'; }
|
||||||
_n=0; _ok=0; _empty=0; _noread=0
|
_n=0; _ok=0; _empty=0; _noread=0
|
||||||
for _f in $_files; do
|
for _f in $_files; do
|
||||||
@@ -230,45 +232,21 @@ elif [ -e /dev/dri/renderD128 ]; then
|
|||||||
GPU="intel"
|
GPU="intel"
|
||||||
fi
|
fi
|
||||||
HAS_APACHE=0; { command -v apache2ctl >/dev/null 2>&1 || command -v httpd >/dev/null 2>&1; } && HAS_APACHE=1
|
HAS_APACHE=0; { command -v apache2ctl >/dev/null 2>&1 || command -v httpd >/dev/null 2>&1; } && HAS_APACHE=1
|
||||||
# Apache-Logpfad ermitteln: erst explizit gesetzter Wert, dann uebliche Orte,
|
|
||||||
# dann die von Apache selbst konfigurierte CustomLog-Direktive.
|
|
||||||
if [ "$HAS_APACHE" -eq 1 ] && [ -z "$APACHE_LOG" ]; then
|
if [ "$HAS_APACHE" -eq 1 ] && [ -z "$APACHE_LOG" ]; then
|
||||||
# Erst die von Apache selbst konfigurierten Pfade — das ist die einzige
|
# ---------------------------------------------------------------------------
|
||||||
# verlaessliche Quelle. Viele Panels (KeyHelp, Plesk) setzen pro VHost eigene
|
# Apache-Logpfade ermitteln — MUSTER, nicht expandierte Einzelpfade.
|
||||||
# CustomLog-Pfade; der "globale" Standardpfad existiert dann oft leer, und
|
#
|
||||||
# ein Input darauf liefert still nichts.
|
# Warum Muster: KeyHelp/Plesk legen pro Domain eigene Logs an, und es kommen
|
||||||
_cl="$(grep -rhoE '^[[:space:]]*CustomLog[[:space:]]+(\S+|"[^"]+")' \
|
# laufend neue dazu. Eine Conf mit 43 festen Pfaden verliert jede neue Domain,
|
||||||
/etc/apache2/ /etc/httpd/ /etc/apache2/sites-enabled/ 2>/dev/null \
|
# bis der Installer erneut laeuft. Ein Glob deckt sie sofort mit ab.
|
||||||
| sed -E 's/^[[:space:]]*CustomLog[[:space:]]+//; s/^"//; s/"$//' \
|
#
|
||||||
| grep -v '^|' | grep -v '^/dev/' | sort -u)"
|
# Verifizierte Strukturen (auf x22 real vorgefunden):
|
||||||
if [ -n "$_cl" ]; then
|
# KeyHelp : /home/users/<user>/logs/<domain>/access.log (zweistufig!)
|
||||||
# Alle konfigurierten Pfade als Glob-Liste (Telegraf akzeptiert Listen).
|
# /var/log/apache2/<vhost>/access.log (z.B. keyhelp/)
|
||||||
_found=""
|
|
||||||
for _p in $_cl; do
|
|
||||||
# Variablen wie ${APACHE_LOG_DIR} aufloesen
|
|
||||||
_p="$(printf '%s' "$_p" | sed "s#\${APACHE_LOG_DIR}#/var/log/apache2#g; s#\${APACHE_LOG_DIR:-/var/log/apache2}#/var/log/apache2#g")"
|
|
||||||
[ -r "$_p" ] && _found="$_found $_p"
|
|
||||||
done
|
|
||||||
[ -n "$_found" ] && APACHE_LOG="$(printf '%s' "$_found" | sed 's/^ //')"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$HAS_APACHE" -eq 1 ] && [ -z "$APACHE_LOG" ]; then
|
|
||||||
for _p in /var/log/apache2/access.log /var/log/httpd/access_log \
|
|
||||||
/var/log/apache2/other_vhosts_access.log /var/log/httpd/access.log; do
|
|
||||||
[ -r "$_p" ] && { APACHE_LOG="$_p"; break; }
|
|
||||||
done
|
|
||||||
# Panel-Hoster legen PRO DOMAIN eigene Logs an, oft ZWEISTUFIG
|
|
||||||
# (<user>/logs/<domain>/access.log). Ein einstufiges Glob trifft das nicht.
|
|
||||||
# Muster je Panel — die reale Struktur wurde auf x22 (KeyHelp) verifiziert:
|
|
||||||
# KeyHelp : /home/users/<user>/logs/<domain>/access.log
|
|
||||||
# Plesk : /var/www/vhosts/<domain>/logs/access_log
|
# Plesk : /var/www/vhosts/<domain>/logs/access_log
|
||||||
# cPanel : /usr/local/apache/domlogs/<domain> (bzw. /home/<user>/logs)
|
# cPanel : /usr/local/apache/domlogs/<domain>
|
||||||
# ALLE passenden Muster sammeln, nicht nur das erste: auf einem KeyHelp-Host
|
# klassisch: /var/log/apache2/access.log, /var/log/httpd/access_log
|
||||||
# existieren oft BEIDE Strukturen — /var/log/apache2/keyhelp/access.log UND
|
# ---------------------------------------------------------------------------
|
||||||
# /home/users/<user>/logs/<domain>/access.log. Nur eines zu waehlen verliert
|
|
||||||
# die Haelfte der Requests.
|
|
||||||
if [ -z "$APACHE_LOG" ]; then
|
|
||||||
_pats=""
|
_pats=""
|
||||||
for _pat in \
|
for _pat in \
|
||||||
"/var/log/apache2/*/access.log" \
|
"/var/log/apache2/*/access.log" \
|
||||||
@@ -282,39 +260,49 @@ if [ "$HAS_APACHE" -eq 1 ] && [ -z "$APACHE_LOG" ]; then
|
|||||||
_pats="$_pats $_pat"
|
_pats="$_pats $_pat"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
# Globale Standarddatei nur, wenn sie NICHT leer ist (auf KeyHelp ist
|
# Klassische Einzeldateien nur, wenn sie NICHT leer sind: auf KeyHelp ist
|
||||||
# /var/log/apache2/access.log oft vorhanden, aber 0 Bytes).
|
# /var/log/apache2/access.log vorhanden, aber 0 Bytes — ein Input darauf
|
||||||
for _p in /var/log/apache2/access.log /var/log/httpd/access_log; do
|
# liefert still nichts.
|
||||||
|
for _p in /var/log/apache2/access.log /var/log/httpd/access_log \
|
||||||
|
/var/log/apache2/other_vhosts_access.log; do
|
||||||
[ -s "$_p" ] && _pats="$_pats $_p"
|
[ -s "$_p" ] && _pats="$_pats $_p"
|
||||||
done
|
done
|
||||||
[ -n "$_pats" ] && APACHE_LOG="$(printf '%s' "$_pats" | sed 's/^ //')"
|
# Nichts gefunden? Dann die CustomLog-Direktive befragen (verlaesslichste
|
||||||
fi
|
# Quelle bei exotischen Setups) — ${APACHE_LOG_DIR} wird aufgeloest.
|
||||||
# Einzelne, flache Faelle weiterhin abdecken
|
if [ -z "$_pats" ]; then
|
||||||
if [ -z "$APACHE_LOG" ]; then
|
_cl_dir="$(grep -rhoE '^[[:space:]]*CustomLog[[:space:]]+(\S+|"[^"]+")' \
|
||||||
for _d in /var/log/apache2 /var/log/httpd; do
|
/etc/apache2/ /etc/httpd/ /etc/apache2/sites-enabled/ 2>/dev/null \
|
||||||
[ -d "$_d" ] || continue
|
| sed -E 's/^[[:space:]]*CustomLog[[:space:]]+//; s/^"//; s/"$//' \
|
||||||
if ls "$_d"/*access*.log "$_d"/access_log >/dev/null 2>&1; then
|
| grep -v '^|' | grep -v '^/dev/' | sort -u)"
|
||||||
APACHE_LOG="$_d/*access*.log"
|
for _p in $_cl_dir; do
|
||||||
break
|
_p="$(printf '%s' "$_p" | sed "s#\${APACHE_LOG_DIR}#/var/log/apache2#g")"
|
||||||
fi
|
[ -r "$_p" ] && _pats="$_pats $_p"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
if [ -z "$APACHE_LOG" ]; then
|
# Letzter Ausweg: breiter Scan der ueblichen Wurzelverzeichnisse.
|
||||||
# Aus der Config lesen (KeyHelp/Plesk setzen eigene Pfade)
|
if [ -z "$_pats" ]; then
|
||||||
_cl="$(grep -rhoE '^\s*CustomLog\s+\S+' /etc/apache2/ /etc/httpd/ 2>/dev/null \
|
_pats="$(find /var/log/apache2 /var/log/httpd /home -maxdepth 4 \
|
||||||
| awk '{print $2}' | grep -v '^|' | head -1)"
|
-name 'access.log' -o -name 'access_log' 2>/dev/null | head -200 | tr '\n' ' ')"
|
||||||
[ -n "$_cl" ] && [ -r "$_cl" ] && APACHE_LOG="$_cl"
|
|
||||||
fi
|
fi
|
||||||
|
[ -n "$_pats" ] && APACHE_LOG="$(printf '%s' "$_pats" | sed 's/^ *//; s/ *$//')"
|
||||||
[ -n "$APACHE_LOG" ] || APACHE_LOG="/var/log/apache2/access.log"
|
[ -n "$APACHE_LOG" ] || APACHE_LOG="/var/log/apache2/access.log"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# APACHE_LOG kann mehrere, leerzeichengetrennte Pfade enthalten -> als
|
# APACHE_LOG kann mehrere, leerzeichengetrennte Pfade enthalten -> als
|
||||||
# TOML-Liste rendern. Achtung: Pfade mit Leerzeichen sind in Apache-Logs
|
# TOML-Liste rendern. Achtung: Pfade mit Leerzeichen sind in Apache-Logs
|
||||||
# ungewoehnlich; wir quoten jeden Eintrag einzeln.
|
# ungewoehnlich; wir quoten jeden Eintrag einzeln.
|
||||||
if [ "$HAS_APACHE" -eq 1 ]; then
|
if [ "$HAS_APACHE" -eq 1 ]; then
|
||||||
APACHE_FILES=""
|
APACHE_FILES=""
|
||||||
|
# set -f: Pfadnamen-Expansion abschalten! Sonst ersetzt die Shell die
|
||||||
|
# Glob-Muster durch die aktuell vorhandenen Dateien — die Conf enthielte
|
||||||
|
# feste Einzelpfade und jede NEUE Domain fiele heraus, bis der Installer
|
||||||
|
# erneut laeuft. Wir wollen die Muster in der Conf, Telegraf loest sie bei
|
||||||
|
# jedem Lauf selbst auf.
|
||||||
|
set -f
|
||||||
for _p in $APACHE_LOG; do
|
for _p in $APACHE_LOG; do
|
||||||
APACHE_FILES="${APACHE_FILES:+$APACHE_FILES, }\"$_p\""
|
APACHE_FILES="${APACHE_FILES:+$APACHE_FILES, }\"$_p\""
|
||||||
done
|
done
|
||||||
|
set +f
|
||||||
[ -n "$APACHE_FILES" ] || APACHE_FILES='"/var/log/apache2/access.log"'
|
[ -n "$APACHE_FILES" ] || APACHE_FILES='"/var/log/apache2/access.log"'
|
||||||
APACHE_FILES="[$APACHE_FILES]"
|
APACHE_FILES="[$APACHE_FILES]"
|
||||||
export APACHE_FILES
|
export APACHE_FILES
|
||||||
@@ -437,6 +425,87 @@ else
|
|||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# Log-Leserechte fuer den Dienst-Benutzer
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# Zwei verschiedene Rechte-Welten bei Apache-Logs:
|
||||||
|
# /var/log/apache2/... root:adm 0640 -> usermod -aG adm genuegt
|
||||||
|
# /home/users/<u>/logs/... <u>:<u> 0640 -> adm hilft NICHT
|
||||||
|
# KeyHelp/Plesk legen die VHost-Logs in den User-Homes ab (auf x22: 64 von 84
|
||||||
|
# Pfaden waren fuer 'telegraf' unlesbar). inputs.tail meldet das NICHT — es
|
||||||
|
# liefert einfach nichts, und der Node sieht "aktiv" aus.
|
||||||
|
# Loesung: ein ACL fuer den Dienst-Benutzer, rekursiv und vererbbar. Damit
|
||||||
|
# bleibt der Dienst im eingeschraenkten Konto (kein root noetig) und neue
|
||||||
|
# Domain-Ordner erben das Recht automatisch.
|
||||||
|
grant_apache_log_access() {
|
||||||
|
[ "$HAS_APACHE" -eq 1 ] || return 0
|
||||||
|
_u="telegraf"
|
||||||
|
id "$_u" >/dev/null 2>&1 || return 0
|
||||||
|
if ! command -v setfacl >/dev/null 2>&1; then
|
||||||
|
# acl-Paket nachziehen, sonst ist die Rechtevergabe nicht moeglich.
|
||||||
|
if command -v apt-get >/dev/null; then
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq acl >/dev/null 2>&1 || true
|
||||||
|
elif command -v dnf >/dev/null; then dnf install -y -q acl >/dev/null 2>&1 || true
|
||||||
|
elif command -v yum >/dev/null; then yum install -y -q acl >/dev/null 2>&1 || true
|
||||||
|
elif command -v apk >/dev/null; then apk add --no-cache -q acl >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if ! command -v setfacl >/dev/null 2>&1; then
|
||||||
|
log "HINWEIS: setfacl fehlt — Apache-Logs in User-Homes bleiben evtl. unlesbar."
|
||||||
|
log " Pruefen mit: sh install.sh --diagnose"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1) Verzeichnisse aus der aktiven Conf ermitteln (nur die Wurzel, dann
|
||||||
|
# rekursiv — das haelt die ACL-Zahl klein).
|
||||||
|
_roots=""
|
||||||
|
for _f in $(sed -n 's/^[[:space:]]*files = \[\(.*\)\].*/\1/p' \
|
||||||
|
/etc/telegraf/telegraf.d/apache.conf 2>/dev/null | tr -d '"' | tr ',' ' '); do
|
||||||
|
case "$_f" in
|
||||||
|
*/\**) _f="${_f%%/\**}" ;; # /a/b/** -> /a/b
|
||||||
|
*/*) _f="${_f%/*}" ;; # /a/b/*/x -> /a/b/*
|
||||||
|
esac
|
||||||
|
case "$_f" in
|
||||||
|
*/\*|*/\*/*) _f="${_f%%\**}" ;; # Glob-Rest abschneiden
|
||||||
|
esac
|
||||||
|
_f="${_f%/}"
|
||||||
|
[ -d "$_f" ] && _roots="$_roots $_f"
|
||||||
|
done
|
||||||
|
# Panel-typische Wurzeln direkt mitnehmen (auch wenn die Conf sie globt)
|
||||||
|
for _d in /home/users /home/*/logs /var/www/vhosts /usr/local/apache/domlogs; do
|
||||||
|
[ -d "$_d" ] && _roots="$_roots $_d"
|
||||||
|
done
|
||||||
|
[ -n "$_roots" ] || return 0
|
||||||
|
|
||||||
|
_n=0
|
||||||
|
for _r in $_roots; do
|
||||||
|
# Durchgangsrecht (x) auf die Elternverzeichnisse, Leserecht (r) auf die
|
||||||
|
# Dateien: rX vergibt x nur fuer Verzeichnisse.
|
||||||
|
setfacl -R -m "u:$_u:rX" "$_r" 2>/dev/null && _n=$((_n+1))
|
||||||
|
# Neu angelegte Dateien/Ordner erben das Recht (default-ACL nur fuer dirs).
|
||||||
|
if [ -d "$_r" ]; then
|
||||||
|
setfacl -R -d -m "u:$_u:rX" "$_r" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
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
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
_cand="$(ls $_f 2>/dev/null | head -1)"
|
||||||
|
if [ -n "$_cand" ] && [ -s "$_cand" ]; then _testfile="$_cand"; break; fi
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# Konfiguration
|
# Konfiguration
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
@@ -530,11 +599,17 @@ case "$ROLE" in
|
|||||||
commands = ["/etc/telegraf/proxmox-ve.sh"]
|
commands = ["/etc/telegraf/proxmox-ve.sh"]
|
||||||
EOF
|
EOF
|
||||||
log "Proxmox: pvesh-Input aktiv (VM/CT-Metriken, kein API-Token noetig)." ;;
|
log "Proxmox: pvesh-Input aktiv (VM/CT-Metriken, kein API-Token noetig)." ;;
|
||||||
apache) fetch_conf telegraf/apache.conf /etc/telegraf/telegraf.d/apache.conf; usermod -aG adm telegraf 2>/dev/null || true ;;
|
apache) fetch_conf telegraf/apache.conf /etc/telegraf/telegraf.d/apache.conf
|
||||||
|
usermod -aG adm telegraf 2>/dev/null || true
|
||||||
|
grant_apache_log_access ;;
|
||||||
docker|none) ;;
|
docker|none) ;;
|
||||||
*) die "Unbekannte Rolle: $ROLE" ;;
|
*) die "Unbekannte Rolle: $ROLE" ;;
|
||||||
esac
|
esac
|
||||||
[ "$HAS_APACHE" -eq 1 ] && [ "$ROLE" != "apache" ] && { fetch_conf telegraf/apache.conf /etc/telegraf/telegraf.d/apache.conf; usermod -aG adm telegraf 2>/dev/null || true; }
|
[ "$HAS_APACHE" -eq 1 ] && [ "$ROLE" != "apache" ] && {
|
||||||
|
fetch_conf telegraf/apache.conf /etc/telegraf/telegraf.d/apache.conf
|
||||||
|
usermod -aG adm telegraf 2>/dev/null || true
|
||||||
|
grant_apache_log_access
|
||||||
|
}
|
||||||
|
|
||||||
# --- System-Logs (journald) → Loki — nur auf systemd-Systemen ---
|
# --- System-Logs (journald) → Loki — nur auf systemd-Systemen ---
|
||||||
if command -v journalctl >/dev/null 2>&1 && [ -d /run/systemd/system ]; then
|
if command -v journalctl >/dev/null 2>&1 && [ -d /run/systemd/system ]; then
|
||||||
|
|||||||
Reference in new issue
Block a user